You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wiki/ux/src/stores/user.js

96 lines
2.7 KiB

import { defineStore } from 'pinia'
import jwtDecode from 'jwt-decode'
import Cookies from 'js-cookie'
import gql from 'graphql-tag'
import { DateTime } from 'luxon'
export const useUserStore = defineStore('user', {
state: () => ({
id: '10000000-0000-4000-8000-000000000001',
email: '',
name: '',
pictureUrl: '',
localeCode: '',
timezone: '',
dateFormat: 'YYYY-MM-DD',
timeFormat: '12h',
appearance: 'site',
permissions: [],
iat: 0,
exp: null,
authenticated: false,
token: '',
profileLoaded: false
}),
getters: {},
actions: {
async refreshAuth () {
const jwtCookie = Cookies.get('jwt')
if (jwtCookie) {
try {
const jwtData = jwtDecode(jwtCookie)
this.id = jwtData.id
this.email = jwtData.email
this.iat = jwtData.iat
this.exp = DateTime.fromSeconds(jwtData.exp, { zone: 'utc' })
this.token = jwtCookie
if (this.exp <= DateTime.utc()) {
console.info('Token has expired. Attempting renew...')
} else {
this.authenticated = true
}
} catch (err) {
console.debug('Invalid JWT. Silent authentication skipped.')
}
}
},
async refreshProfile () {
if (!this.authenticated || !this.id) {
return
}
try {
const respRaw = await APOLLO_CLIENT.query({
query: gql`
query refreshProfile (
$id: UUID!
) {
userById(id: $id) {
id
name
email
meta
prefs
lastLoginAt
groups {
id
name
}
}
}
`,
variables: {
id: this.id
}
})
const resp = respRaw?.data?.userById
if (!resp || resp.id !== this.id) {
throw new Error('Failed to fetch user profile!')
}
this.name = resp.name || 'Unknown User'
this.email = resp.email
this.pictureUrl = (resp.pictureUrl === 'local') ? `/_user/${this.id}/avatar` : resp.pictureUrl
this.location = resp.meta.location || ''
this.jobTitle = resp.meta.jobTitle || ''
this.pronouns = resp.meta.pronouns || ''
this.timezone = resp.prefs.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone || ''
this.dateFormat = resp.prefs.dateFormat || ''
this.timeFormat = resp.prefs.timeFormat || '12h'
this.appearance = resp.prefs.appearance || 'site'
this.profileLoaded = true
} catch (err) {
console.warn(err)
}
}
}
})