import { defineStore } from 'pinia' import { ref, computed } from 'vue' import type { AuthConfig, UserInfo } from '../types' import { canAccessAdmin as canUserAccessAdmin, canAccessPlugin as canUserAccessPlugin, getAccessAudience, getUserPermissions, hasAllPermissions, hasAnyPermission, isAdminUser, } from '../permissions' const AUTH_TOKEN_KEY = 'mint-auth-token' const AUTH_EXPIRES_KEY = 'mint-auth-expires' function getLocalStorage(): Storage | null { try { const storage = globalThis.localStorage return typeof storage?.getItem === 'function' ? storage : null } catch { return null } } function readStoredItem(key: string): string | null { try { return getLocalStorage()?.getItem(key) ?? null } catch { return null } } function writeStoredItem(key: string, value: string): void { try { getLocalStorage()?.setItem(key, value) } catch { // Keep auth usable in-memory when browser storage is blocked. } } function removeStoredItem(key: string): void { try { getLocalStorage()?.removeItem(key) } catch { // Keep auth cleanup usable in-memory when browser storage is blocked. } } export const useAuthStore = defineStore('mint-auth', () => { // State const token = ref(null) const tokenExpires = ref(null) const username = ref(null) const userInfo = ref(null) const authConfig = ref({ authRequired: true, passkeyEnabled: false, passkeyRegistered: false, registrationEnabled: false, databaseMode: 'none', experimentVisibilityMode: 'open', }) const isInitialized = ref(false) const isLoading = ref(false) const error = ref(null) // Computed const isAuthenticated = computed(() => { if (!authConfig.value.authRequired) { return true } if (!token.value) { return false } if (tokenExpires.value && tokenExpires.value < new Date()) { return false } return true }) const needsAuth = computed(() => { return authConfig.value.authRequired && !isAuthenticated.value }) const isAdmin = computed(() => isAdminUser(userInfo.value)) const userType = computed(() => getAccessAudience(userInfo.value)) const permissions = computed(() => getUserPermissions(userInfo.value)) const canAccessAdmin = computed(() => canUserAccessAdmin(userInfo.value)) const canRegister = computed(() => { return authConfig.value.registrationEnabled }) // Actions function initialize() { const storedToken = readStoredItem(AUTH_TOKEN_KEY) const storedExpires = readStoredItem(AUTH_EXPIRES_KEY) if (storedToken) { token.value = storedToken if (storedExpires) { const expires = new Date(storedExpires) if (expires > new Date()) { tokenExpires.value = expires } else { clearToken() } } } isInitialized.value = true } function setToken(accessToken: string, expiresIn: number) { token.value = accessToken const expires = new Date(Date.now() + expiresIn * 1000) tokenExpires.value = expires writeStoredItem(AUTH_TOKEN_KEY, accessToken) writeStoredItem(AUTH_EXPIRES_KEY, expires.toISOString()) } function clearToken() { token.value = null tokenExpires.value = null username.value = null userInfo.value = null removeStoredItem(AUTH_TOKEN_KEY) removeStoredItem(AUTH_EXPIRES_KEY) } function setUserInfo(info: UserInfo) { userInfo.value = info username.value = info.username } function hasPermission(...perms: string[]): boolean { return hasAllPermissions(userInfo.value, perms) } function hasAnyPermissionForUser(...perms: string[]): boolean { return hasAnyPermission(userInfo.value, perms) } function canAccessPlugin(pluginName: string): boolean { return canUserAccessPlugin(userInfo.value, pluginName) } function setAuthConfig(config: AuthConfig) { authConfig.value = config } function setUsername(name: string) { username.value = name } function setError(message: string | null) { error.value = message } function setLoading(loading: boolean) { isLoading.value = loading } function logout() { clearToken() } return { // State token, tokenExpires, username, userInfo, authConfig, isInitialized, isLoading, error, // Computed isAuthenticated, needsAuth, isAdmin, userType, permissions, canAccessAdmin, canRegister, // Actions initialize, setToken, clearToken, setAuthConfig, setUsername, setUserInfo, setError, setLoading, hasPermission, hasAnyPermission: hasAnyPermissionForUser, canAccessPlugin, logout, } })