File size: 3,022 Bytes
bd4057b 263e0b9 519f85d bd4057b dbfb96e edd2023 263e0b9 bd4057b dbfb96e bd4057b dbfb96e 263e0b9 dbfb96e bd4057b 263e0b9 bd4057b 07dd5b7 263e0b9 2aabbd0 a318da0 519f85d bd4057b 263e0b9 2aabbd0 263e0b9 dbfb96e bd4057b edd2023 dbfb96e edd2023 dbfb96e edd2023 bd4057b | 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;
}
}
|