frontend-taskdone/src/store/modules/auth.js
konrad 1935af83c3 Allow setting api url from the login screen (#264)
Cleanup

Use the http factory everywhere instead of the created element

Use the current domain if the api path is relative to the frontend host

Format

Prevent setting an empty url

Fix styling

Add changing api url

Add change url component

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: vikunja/frontend#264
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
2020-10-11 10:13:35 +00:00

158 lines
4.0 KiB
JavaScript

import {HTTPFactory} from '@/http-common'
import {ERROR_MESSAGE, LOADING} from '../mutation-types'
import UserModel from '../../models/user'
export default {
namespaced: true,
state: () => ({
authenticated: false,
isLinkShareAuth: false,
info: {},
needsTotpPasscode: false,
avatarUrl: '',
}),
mutations: {
info(state, info) {
state.info = info
state.avatarUrl = info.getAvatarUrl()
},
authenticated(state, authenticated) {
state.authenticated = authenticated
},
isLinkShareAuth(state, is) {
state.isLinkShareAuth = is
},
needsTotpPasscode(state, needs) {
state.needsTotpPasscode = needs
},
reloadAvatar(state) {
state.avatarUrl = `${state.info.getAvatarUrl()}&=${+new Date()}`
},
},
actions: {
// Logs a user in with a set of credentials.
login(ctx, credentials) {
const HTTP = HTTPFactory()
ctx.commit(LOADING, true, {root: true})
// Delete an eventually preexisting old token
localStorage.removeItem('token')
const data = {
username: credentials.username,
password: credentials.password,
}
if (credentials.totpPasscode) {
data.totp_passcode = credentials.totpPasscode
}
return 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
ctx.commit('isLinkShareAuth', false)
ctx.dispatch('checkAuth')
return Promise.resolve()
})
.catch(e => {
if (e.response) {
if (e.response.data.code === 1017 && !credentials.totpPasscode) {
ctx.commit('needsTotpPasscode', true)
return Promise.reject()
}
let errorMsg = e.response.data.message
if (e.response.status === 401) {
errorMsg = 'Wrong username or password.'
}
ctx.commit(ERROR_MESSAGE, errorMsg, {root: true})
}
return Promise.reject()
})
.finally(() => {
ctx.commit(LOADING, false, {root: true})
})
},
// Registers a new user and logs them in.
// Not sure if this is the right place to put the logic in, maybe a seperate js component would be better suited.
register(ctx, credentials) {
const HTTP = HTTPFactory()
return HTTP.post('register', {
username: credentials.username,
email: credentials.email,
password: credentials.password,
})
.then(() => {
return ctx.dispatch('login', credentials)
})
.catch(e => {
if (e.response) {
ctx.commit(ERROR_MESSAGE, e.response.data.message, {root: true})
}
return Promise.reject()
})
.finally(() => {
ctx.commit(LOADING, false, {root: true})
})
},
linkShareAuth(ctx, hash) {
const HTTP = HTTPFactory()
return HTTP.post('/shares/' + hash + '/auth')
.then(r => {
localStorage.setItem('token', r.data.token)
ctx.dispatch('checkAuth')
return Promise.resolve(r.data)
}).catch(e => {
return Promise.reject(e)
})
},
// Populates user information from jwt token saved in local storage in store
checkAuth(ctx) {
const jwt = localStorage.getItem('token')
let authenticated = false
if (jwt) {
const base64 = jwt
.split('.')[1]
.replace('-', '+')
.replace('_', '/')
const info = new UserModel(JSON.parse(window.atob(base64)))
const ts = Math.round((new Date()).getTime() / 1000)
if (info.exp >= ts) {
authenticated = true
}
ctx.commit('info', info)
}
ctx.commit('authenticated', authenticated)
return Promise.resolve()
},
// Renews the api token and saves it to local storage
renewToken(ctx) {
const HTTP = HTTPFactory()
if (!ctx.state.authenticated) {
return
}
HTTP.post('user/token', null, {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token'),
},
})
.then(r => {
localStorage.setItem('token', r.data.token)
ctx.dispatch('checkAuth')
})
.catch(e => {
// eslint-disable-next-line
console.log('Error renewing token: ', e)
})
},
logout(ctx) {
localStorage.removeItem('token')
ctx.dispatch('checkAuth')
},
},
}