File size: 3,022 Bytes
85270f9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | "use client";
import { refreshSession } from "@/lib/api";
import { buildSessionExpiresAt, clearStoredAuthSession, getStoredAuthSession, setStoredAuthSession, type StoredAuthSession } from "@/store/auth";
const VALIDATION_CACHE_MS = 10_000;
let cachedSession: StoredAuthSession | null = null;
let cachedAt = 0;
let validationPromise: Promise<StoredAuthSession | null> | null = null;
let validationKey = "";
function isUnauthorizedError(error: unknown) {
if (!error || typeof error !== "object") {
return false;
}
const item = error as { status?: unknown };
return item.status === 401;
}
export async function getValidatedAuthSession(options: { force?: boolean } = {}): Promise<StoredAuthSession | null> {
const storedSession = await getStoredAuthSession();
if (!storedSession) {
cachedSession = null;
cachedAt = 0;
return null;
}
const now = Date.now();
if (!options.force && cachedSession?.key === storedSession.key && now - cachedAt < VALIDATION_CACHE_MS) {
return cachedSession;
}
if (validationPromise && validationKey === storedSession.key) {
return validationPromise;
}
validationKey = storedSession.key;
validationPromise = validateStoredSession(storedSession).finally(() => {
validationPromise = null;
validationKey = "";
});
return validationPromise;
}
async function validateStoredSession(storedSession: StoredAuthSession): Promise<StoredAuthSession | null> {
try {
const data = await refreshSession(storedSession.key);
const nextSession: StoredAuthSession = {
key: storedSession.key,
role: data.role,
subjectId: data.subject_id,
name: data.name,
accountPoolEnabled: Boolean(data.account_pool_enabled),
imageMemoryButtonEnabled: data.image_memory_button_enabled === true,
imageShareEvidenceEnabled: data.image_share_evidence_enabled === true,
wechatOpenid: storedSession.wechatOpenid,
expiresAt: storedSession.expiresAt || buildSessionExpiresAt(data.login_session_duration_hours),
};
const sessionChanged =
storedSession.role !== nextSession.role
|| storedSession.subjectId !== nextSession.subjectId
|| storedSession.name !== nextSession.name
|| storedSession.accountPoolEnabled !== nextSession.accountPoolEnabled
|| storedSession.imageMemoryButtonEnabled !== nextSession.imageMemoryButtonEnabled
|| storedSession.imageShareEvidenceEnabled !== nextSession.imageShareEvidenceEnabled
|| storedSession.wechatOpenid !== nextSession.wechatOpenid
|| storedSession.expiresAt !== nextSession.expiresAt;
if (sessionChanged) {
await setStoredAuthSession(nextSession);
}
cachedSession = nextSession;
cachedAt = Date.now();
return nextSession;
} catch (error) {
if (isUnauthorizedError(error)) {
await clearStoredAuthSession();
cachedSession = null;
cachedAt = 0;
return null;
}
cachedSession = storedSession;
cachedAt = Date.now();
return storedSession;
}
}
|