From 5724b98358e90ef52fbf27177dfafacbd2706e53 Mon Sep 17 00:00:00 2001 From: konrad Date: Fri, 8 May 2020 18:43:51 +0000 Subject: [PATCH] Vuex (#126) Merge branch 'master' into feature/vuex Cleanup Move namespaces handling to store Move fullpage setting to store Move online/offline handling to store Remove debug log Fix loading namepaces Rename errorMsg Handle registering through the store Use store to determine wether or not a user is authenticated on login page Use store in edit team Use store to get the current user's avatar Use store to figure out if the current user belongs to a team Use store to figure out if the current user is list admin Use store to get user info when listing labels Use store to get username on home Use store to figure out if the user is namespace admin Use the store for configuration Use the store to check if a user is authenticated everywhere Only renew token if the user is logged in Fix renewing auth from jwt token Move logout to store Move renew token to store Move log in to store Only show enabled migrators Only show registration button if registration is enabled Put all config information from the backend in the store Remove old config handler Move config state to seperate module Add vuex and get the motd through it Co-authored-by: kolaente Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/126 --- package.json | 3 +- src/App.vue | 94 +++++-------- src/auth/index.js | 148 -------------------- src/components/Home.vue | 25 ++-- src/components/labels/ListLabels.vue | 14 +- src/components/lists/EditList.vue | 32 ++--- src/components/lists/NewList.vue | 13 +- src/components/lists/ShowList.vue | 8 -- src/components/migrator/migrate.vue | 13 +- src/components/namespaces/EditNamespace.vue | 23 +-- src/components/namespaces/NewNamespace.vue | 16 +-- src/components/sharing/linkSharing.vue | 8 +- src/components/sharing/linkSharingAuth.vue | 3 +- src/components/sharing/userTeam.vue | 8 +- src/components/tasks/reusable/comments.vue | 9 +- src/components/teams/EditTeam.vue | 21 ++- src/components/teams/ListTeams.vue | 8 -- src/components/teams/NewTeam.vue | 10 +- src/components/user/Login.vue | 77 +++++++--- src/components/user/Register.vue | 29 ++-- src/config.js | 16 --- src/main.js | 14 +- src/registerServiceWorker.js | 3 +- src/router/index.js | 2 +- src/store/index.js | 36 +++++ src/store/modules/auth.js | 148 ++++++++++++++++++++ src/store/modules/config.js | 37 +++++ src/store/modules/namespaces.js | 63 +++++++++ src/store/mutation-types.js | 7 + src/styles/components/migrator.scss | 1 + yarn.lock | 5 + 31 files changed, 501 insertions(+), 393 deletions(-) delete mode 100644 src/auth/index.js delete mode 100644 src/config.js create mode 100644 src/store/index.js create mode 100644 src/store/modules/auth.js create mode 100644 src/store/modules/config.js create mode 100644 src/store/modules/namespaces.js create mode 100644 src/store/mutation-types.js diff --git a/package.json b/package.json index 7819df4d3..7a3449a52 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "vue": "2.6.11", "vue-drag-resize": "1.3.2", "vue-easymde": "1.2.0", - "vue-smooth-dnd": "0.8.1" + "vue-smooth-dnd": "0.8.1", + "vuex": "^3.3.0" }, "devDependencies": { "@fortawesome/fontawesome-svg-core": "1.2.28", diff --git a/src/App.vue b/src/App.vue index 38d39cde9..fe8f2c504 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,10 +1,10 @@ diff --git a/src/auth/index.js b/src/auth/index.js deleted file mode 100644 index 9300f1fbf..000000000 --- a/src/auth/index.js +++ /dev/null @@ -1,148 +0,0 @@ -import {HTTP} from '../http-common' -import router from '../router' -import UserModel from '../models/user' -// const API_URL = 'http://localhost:8082/api/v1/' -// const LOGIN_URL = 'http://localhost:8082/login' - -export default { - - user: { - authenticated: false, - infos: {}, - }, - - login(context, credentials, redirect = '') { - localStorage.removeItem('token') // Delete an eventually preexisting old token - - const data = { - username: credentials.username, - password: credentials.password - } - - if(credentials.totpPasscode) { - data.totp_passcode = credentials.totpPasscode - } - - HTTP.post('login', data) - .then(response => { - // Save the token to local storage for later use - localStorage.setItem('token', response.data.token) - - // Tell others the user is autheticated - this.user.authenticated = true - this.user.isLinkShareAuth = false - - // Redirect if nessecary - if (redirect !== '') { - router.push({name: redirect}) - } - }) - .catch(e => { - if (e.response) { - if (e.response.data.code === 1017 && !credentials.totpPasscode) { - context.needsTotpPasscode = true - return - } - - context.errorMsg = e.response.data.message - if (e.response.status === 401) { - context.errorMsg = 'Wrong username or password.' - } - } - }) - .finally(() => { - context.loading = false - }) - }, - - register(context, creds, redirect) { - HTTP.post('register', { - username: creds.username, - email: creds.email, - password: creds.password - }) - .then(() => { - this.login(context, creds, redirect) - }) - .catch(e => { - // Hide the loader - context.loading = false - if (e.response) { - context.errorMsg = e.response.data.message - if (e.response.status === 401) { - context.errorMsg = 'Wrong username or password.' - } - } - }) - }, - - logout() { - localStorage.removeItem('token') - router.push({name: 'login'}) - this.user.authenticated = false - }, - - linkShareAuth(hash) { - return HTTP.post('/shares/' + hash + '/auth') - .then(r => { - localStorage.setItem('token', r.data.token) - this.getUserInfos() - return Promise.resolve(r.data) - }).catch(e => { - return Promise.reject(e) - }) - }, - - renewToken() { - HTTP.post('user/token', null, { - headers: { - Authorization: 'Bearer ' + localStorage.getItem('token'), - } - }) - .then(r => { - localStorage.setItem('token', r.data.token) - }) - .catch(e => { - // eslint-disable-next-line - console.log('Error renewing token: ', e) - }) - }, - - checkAuth() { - let jwt = localStorage.getItem('token') - this.getUserInfos() - this.user.authenticated = false - if (jwt) { - let ts = Math.round((new Date()).getTime() / 1000) - if (this.user.infos.exp >= ts) { - this.user.authenticated = true - } - } - }, - - getUserInfos() { - let jwt = localStorage.getItem('token') - if (jwt) { - this.user.infos = new UserModel(this.parseJwt(localStorage.getItem('token'))) - return this.user.infos - } else { - return {} - } - }, - - parseJwt(token) { - let base64Url = token.split('.')[1] - let base64 = base64Url.replace('-', '+').replace('_', '/') - return JSON.parse(window.atob(base64)) - }, - - getAuthHeader() { - return { - 'Authorization': 'Bearer ' + localStorage.getItem('token') - } - }, - - getToken() { - return localStorage.getItem('token') - } -} diff --git a/src/components/Home.vue b/src/components/Home.vue index 378b21420..b16d821f6 100644 --- a/src/components/Home.vue +++ b/src/components/Home.vue @@ -1,21 +1,26 @@ diff --git a/src/components/labels/ListLabels.vue b/src/components/labels/ListLabels.vue index df8bc1f59..14b011fa0 100644 --- a/src/components/labels/ListLabels.vue +++ b/src/components/labels/ListLabels.vue @@ -11,11 +11,11 @@ {{ l.title }} @@ -25,7 +25,7 @@ v-else> {{ l.title }} - +
@@ -102,10 +102,10 @@ diff --git a/src/components/namespaces/EditNamespace.vue b/src/components/namespaces/EditNamespace.vue index 1b6e57016..f0bbe3202 100644 --- a/src/components/namespaces/EditNamespace.vue +++ b/src/components/namespaces/EditNamespace.vue @@ -83,7 +83,6 @@ import verte from 'verte' import 'verte/dist/verte.css' - import auth from '../../auth' import router from '../../router' import manageSharing from '../sharing/userTeam' @@ -96,13 +95,11 @@ data() { return { namespaceService: NamespaceService, - userIsAdmin: false, manageUsersComponent: '', manageTeamsComponent: '', namespace: NamespaceModel, showDeleteModal: false, - user: auth.user, } }, components: { @@ -111,11 +108,6 @@ verte, }, beforeMount() { - // Check if the user is already logged in, if so, redirect him to the homepage - if (!auth.user.authenticated) { - router.push({name: 'home'}) - } - this.namespace.id = this.$route.params.id }, created() { @@ -127,15 +119,17 @@ // call again the method if the route changes '$route': 'loadNamespace' }, + computed: { + userIsAdmin() { + return this.namespace.owner && this.namespace.owner.id === this.$store.state.auth.info.id + }, + }, methods: { loadNamespace() { let namespace = new NamespaceModel({id: this.$route.params.id}) this.namespaceService.get(namespace) .then(r => { this.$set(this, 'namespace', r) - if (r.owner.id === this.user.infos.id) { - this.userIsAdmin = true - } // This will trigger the dynamic loading of components once we actually have all the data to pass to them this.manageTeamsComponent = 'manageSharing' this.manageUsersComponent = 'manageSharing' @@ -148,12 +142,7 @@ this.namespaceService.update(this.namespace) .then(r => { // Update the namespace in the parent - for (const n in this.$parent.namespaces) { - if (this.$parent.namespaces[n].id === r.id) { - r.lists = this.$parent.namespaces[n].lists - this.$set(this.$parent.namespaces, n, r) - } - } + this.$store.commit('namespaces/setNamespaceById', r) this.success({message: 'The namespace was successfully updated.'}, this) }) .catch(e => { diff --git a/src/components/namespaces/NewNamespace.vue b/src/components/namespaces/NewNamespace.vue index d5fc60e61..0ca4a1b7b 100644 --- a/src/components/namespaces/NewNamespace.vue +++ b/src/components/namespaces/NewNamespace.vue @@ -34,10 +34,10 @@