You've already forked agentic-coding-workflow
74 lines
1.6 KiB
TypeScript
74 lines
1.6 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { computed, ref } from 'vue'
|
|
|
|
export interface User {
|
|
id: string
|
|
email: string
|
|
display_name: string
|
|
is_admin: boolean
|
|
}
|
|
|
|
function safeReadJSON<T>(key: string, fallback: T): T {
|
|
try {
|
|
const raw = localStorage.getItem(key)
|
|
if (raw === null) return fallback
|
|
return JSON.parse(raw) as T
|
|
} catch {
|
|
// 脏数据 / 反序列化失败 → 清掉,回退默认。
|
|
try {
|
|
localStorage.removeItem(key)
|
|
} catch {
|
|
/* noop */
|
|
}
|
|
return fallback
|
|
}
|
|
}
|
|
|
|
function safeReadString(key: string): string | null {
|
|
try {
|
|
return localStorage.getItem(key)
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
function safeWrite(key: string, value: string) {
|
|
try {
|
|
localStorage.setItem(key, value)
|
|
} catch {
|
|
/* QuotaExceeded / disabled */
|
|
}
|
|
}
|
|
|
|
function safeRemove(key: string) {
|
|
try {
|
|
localStorage.removeItem(key)
|
|
} catch {
|
|
/* noop */
|
|
}
|
|
}
|
|
|
|
export const useAuthStore = defineStore('auth', () => {
|
|
const token = ref<string | null>(safeReadString('token'))
|
|
const user = ref<User | null>(safeReadJSON<User | null>('user', null))
|
|
|
|
const isAuthenticated = computed(() => !!token.value)
|
|
const isAdmin = computed(() => !!user.value?.is_admin)
|
|
|
|
function setSession(t: string, u: User) {
|
|
token.value = t
|
|
user.value = u
|
|
safeWrite('token', t)
|
|
safeWrite('user', JSON.stringify(u))
|
|
}
|
|
|
|
function clearSession() {
|
|
token.value = null
|
|
user.value = null
|
|
safeRemove('token')
|
|
safeRemove('user')
|
|
}
|
|
|
|
return { token, user, isAuthenticated, isAdmin, setSession, clearSession }
|
|
})
|