95 lines
2.1 KiB
TypeScript
95 lines
2.1 KiB
TypeScript
import { computed, ref } from 'vue'
|
|
import { defineStore } from 'pinia'
|
|
import { getCurrentUserApi, loginApi } from '../services/auth'
|
|
import { hasAnyPermission, hasPermission } from '../services/access'
|
|
import type { CurrentUser } from '../types/auth'
|
|
|
|
const TOKEN_KEY = 'teapot-system-token'
|
|
const USER_KEY = 'teapot-system-user'
|
|
|
|
function readUserFromStorage() {
|
|
const raw = window.localStorage.getItem(USER_KEY)
|
|
if (!raw) {
|
|
return null
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(raw) as CurrentUser
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export const useAuthStore = defineStore('auth', () => {
|
|
const token = ref(window.localStorage.getItem(TOKEN_KEY) ?? '')
|
|
const user = ref<CurrentUser | null>(readUserFromStorage())
|
|
const initialized = ref(false)
|
|
|
|
const isAuthenticated = computed(() => Boolean(token.value && user.value))
|
|
|
|
function persistSession() {
|
|
if (token.value) {
|
|
window.localStorage.setItem(TOKEN_KEY, token.value)
|
|
} else {
|
|
window.localStorage.removeItem(TOKEN_KEY)
|
|
}
|
|
|
|
if (user.value) {
|
|
window.localStorage.setItem(USER_KEY, JSON.stringify(user.value))
|
|
} else {
|
|
window.localStorage.removeItem(USER_KEY)
|
|
}
|
|
}
|
|
|
|
async function login(username: string, password: string) {
|
|
const payload = await loginApi({ username, password })
|
|
token.value = payload.token
|
|
user.value = payload.user
|
|
initialized.value = true
|
|
persistSession()
|
|
}
|
|
|
|
async function bootstrap() {
|
|
if (!token.value) {
|
|
initialized.value = true
|
|
return
|
|
}
|
|
|
|
try {
|
|
user.value = await getCurrentUserApi(token.value)
|
|
} catch {
|
|
token.value = ''
|
|
user.value = null
|
|
persistSession()
|
|
} finally {
|
|
initialized.value = true
|
|
}
|
|
}
|
|
|
|
function logout() {
|
|
token.value = ''
|
|
user.value = null
|
|
initialized.value = true
|
|
persistSession()
|
|
}
|
|
|
|
function can(permission: string) {
|
|
return hasPermission(user.value, permission)
|
|
}
|
|
|
|
function canAny(permissions: string[]) {
|
|
return hasAnyPermission(user.value, permissions)
|
|
}
|
|
|
|
return {
|
|
token,
|
|
user,
|
|
initialized,
|
|
isAuthenticated,
|
|
login,
|
|
bootstrap,
|
|
logout,
|
|
can,
|
|
canAny,
|
|
}
|
|
}) |