feat: 项目初始化
This commit is contained in:
104
src/lib/auth/auth-session.ts
Normal file
104
src/lib/auth/auth-session.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import type { AuthSessionInput, AuthUser } from '@/store/auth-store'
|
||||
import { useAuthStore } from '@/store/auth-store'
|
||||
|
||||
export type CurrentUserInitializer = () => Promise<AuthUser | null>
|
||||
export type RefreshSessionHandler = (
|
||||
refreshToken: string,
|
||||
) => Promise<AuthSessionInput | null>
|
||||
|
||||
let currentUserInitializer: CurrentUserInitializer | null = null
|
||||
let refreshSessionHandler: RefreshSessionHandler | null = null
|
||||
let authInitializationPromise: Promise<void> | null = null
|
||||
let refreshSessionPromise: Promise<boolean> | null = null
|
||||
|
||||
export function registerCurrentUserInitializer(
|
||||
initializer: CurrentUserInitializer | null,
|
||||
) {
|
||||
currentUserInitializer = initializer
|
||||
}
|
||||
|
||||
export function registerRefreshSessionHandler(
|
||||
handler: RefreshSessionHandler | null,
|
||||
) {
|
||||
refreshSessionHandler = handler
|
||||
}
|
||||
|
||||
export function isAuthenticated() {
|
||||
const snapshot = useAuthStore.getState()
|
||||
|
||||
return snapshot.status === 'authenticated' && Boolean(snapshot.accessToken)
|
||||
}
|
||||
|
||||
export function handleUnauthorizedSession() {
|
||||
useAuthStore.getState().markUnauthorized()
|
||||
}
|
||||
|
||||
export async function initializeAuthSession() {
|
||||
if (authInitializationPromise) {
|
||||
return authInitializationPromise
|
||||
}
|
||||
|
||||
authInitializationPromise = (async () => {
|
||||
await useAuthStore.persist.rehydrate()
|
||||
|
||||
const snapshot = useAuthStore.getState()
|
||||
|
||||
if (
|
||||
!snapshot.accessToken ||
|
||||
snapshot.currentUser ||
|
||||
!currentUserInitializer
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentUser = await currentUserInitializer()
|
||||
|
||||
useAuthStore.getState().setCurrentUser(currentUser)
|
||||
})().finally(() => {
|
||||
authInitializationPromise = null
|
||||
})
|
||||
|
||||
return authInitializationPromise
|
||||
}
|
||||
|
||||
export async function tryRefreshAuthSession() {
|
||||
if (refreshSessionPromise) {
|
||||
return refreshSessionPromise
|
||||
}
|
||||
|
||||
const snapshot = useAuthStore.getState()
|
||||
|
||||
if (!snapshot.refreshToken || !refreshSessionHandler) {
|
||||
return false
|
||||
}
|
||||
|
||||
const refreshToken = snapshot.refreshToken
|
||||
|
||||
refreshSessionPromise = (async () => {
|
||||
try {
|
||||
const nextSession = await refreshSessionHandler(refreshToken)
|
||||
|
||||
if (!nextSession?.accessToken) {
|
||||
handleUnauthorizedSession()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
useAuthStore.getState().startSession({
|
||||
accessToken: nextSession.accessToken,
|
||||
currentUser: nextSession.currentUser ?? snapshot.currentUser,
|
||||
refreshToken: nextSession.refreshToken ?? snapshot.refreshToken,
|
||||
})
|
||||
|
||||
return true
|
||||
} catch {
|
||||
handleUnauthorizedSession()
|
||||
|
||||
return false
|
||||
} finally {
|
||||
refreshSessionPromise = null
|
||||
}
|
||||
})()
|
||||
|
||||
return refreshSessionPromise
|
||||
}
|
||||
Reference in New Issue
Block a user