2FAuth/resources/js/stores/user.js

151 lines
4.3 KiB
JavaScript
Vendored

import { defineStore } from 'pinia'
import authService from '@/services/authService'
import userService from '@/services/userService'
import router from '@/router'
import { useColorMode } from '@vueuse/core'
import { useTwofaccounts } from '@/stores/twofaccounts'
import { useGroups } from '@/stores/groups'
import { useNotifyStore } from '@/stores/notify'
export const useUserStore = defineStore({
id: 'user',
state: () => {
return {
id: undefined,
name: undefined,
email: undefined,
oauth_provider: undefined,
preferences: window.defaultPreferences,
isAdmin: false,
}
},
getters: {
isAuthenticated() {
return this.name != undefined
}
},
actions: {
/**
* Initializes the store for the given user
*
* @param {object} user
*/
async loginAs(user) {
this.$patch(user)
await this.initDataStores()
this.applyUserPrefs()
},
/**
* Initializes the user's data stores
*/
async initDataStores() {
const accounts = useTwofaccounts()
const groups = useGroups()
if (this.isAuthenticated) {
await accounts.fetch()
groups.fetch()
}
else {
accounts.$reset()
groups.$reset()
}
},
/**
* Logs the user out or moves to proxy logout url
*/
logout(options = {}) {
const { kicked } = options
const notify = useNotifyStore()
// async appLogout(evt) {
if (this.$2fauth.config.proxyAuth) {
if (this.$2fauth.config.proxyLogoutUrl) {
location.assign(this.$2fauth.config.proxyLogoutUrl)
}
else return false
}
else {
authService.logout({ returnError: true }).then(() => {
if (kicked) {
notify.clear()
notify.warn({ text: trans('auth.autolock_triggered_punchline'), duration:-1 })
}
this.tossOut()
})
.catch(error => {
// The logout request will receive a 401 response when the
// backend has already detect inactivity on its side. In this case we
// don't want any error to be displayed.
if (error.response.status !== 401) {
notify.error(error)
}
else this.tossOut()
})
}
},
/**
* Resets all user data and push out
*/
tossOut() {
this.$reset()
this.initDataStores()
this.applyUserPrefs()
router.push({ name: 'login' })
},
/**
* Applies user theme
*/
applyTheme() {
const mode = useColorMode({
attribute: 'data-theme',
})
mode.value = this.preferences.theme == 'system' ? 'auto' : this.preferences.theme
},
/**
* Applies user language
*/
applyLanguage() {
const { isSupported, language } = useNavigatorLanguage()
if (isSupported) {
loadLanguageAsync(this.preferences.lang == 'browser' ? language.value.slice(0, 2) : this.preferences.lang)
}
else loadLanguageAsync('en')
},
/**
* Applies both user theme & language
*/
applyUserPrefs() {
this.applyTheme()
this.applyLanguage()
},
/**
* Refresh user preferences with backend state
*/
refreshPreferences() {
userService.getPreferences({returnError: true})
.then(response => {
response.data.forEach(preference => {
this.preferences[preference.key] = preference.value
})
})
.catch(error => {
const notify = useNotifyStore()
notify.alert({ text: trans('errors.data_cannot_be_refreshed_from_server') })
})
}
},
})