Update cookie
This commit is contained in:
@@ -41,6 +41,7 @@ const API_BASE = resolveApiBase();
|
||||
const CSRF_COOKIE_NAME = "dcm_csrf";
|
||||
const CSRF_HEADER_NAME = "x-csrf-token";
|
||||
const CSRF_SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
|
||||
const CSRF_SESSION_STORAGE_KEY = "dcm_csrf_token";
|
||||
|
||||
type ApiRequestInit = Omit<RequestInit, 'headers'> & { headers?: HeadersInit };
|
||||
|
||||
@@ -65,7 +66,38 @@ function getCookieValue(name: string): string | undefined {
|
||||
* Resolves the runtime CSRF token from browser cookie storage for API requests.
|
||||
*/
|
||||
function resolveCsrfToken(): string | undefined {
|
||||
return getCookieValue(CSRF_COOKIE_NAME);
|
||||
const cookieToken = getCookieValue(CSRF_COOKIE_NAME);
|
||||
if (cookieToken) {
|
||||
return cookieToken;
|
||||
}
|
||||
return loadStoredCsrfToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the runtime CSRF token from browser session storage.
|
||||
*/
|
||||
function loadStoredCsrfToken(): string | undefined {
|
||||
if (typeof window === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
const rawValue = window.sessionStorage.getItem(CSRF_SESSION_STORAGE_KEY);
|
||||
const normalizedValue = rawValue?.trim();
|
||||
return normalizedValue ? normalizedValue : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists or clears a runtime CSRF token in browser session storage.
|
||||
*/
|
||||
function persistCsrfToken(token: string | undefined | null): void {
|
||||
if (typeof window === "undefined") {
|
||||
return;
|
||||
}
|
||||
const normalizedValue = typeof token === "string" ? token.trim() : "";
|
||||
if (!normalizedValue) {
|
||||
window.sessionStorage.removeItem(CSRF_SESSION_STORAGE_KEY);
|
||||
return;
|
||||
}
|
||||
window.sessionStorage.setItem(CSRF_SESSION_STORAGE_KEY, normalizedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +213,9 @@ export async function loginWithPassword(username: string, password: string): Pro
|
||||
}
|
||||
throw new Error('Login failed');
|
||||
}
|
||||
return response.json() as Promise<AuthLoginResponse>;
|
||||
const payload = await (response.json() as Promise<AuthLoginResponse>);
|
||||
persistCsrfToken(payload.csrf_token);
|
||||
return payload;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +230,9 @@ export async function getCurrentAuthSession(): Promise<AuthSessionInfo> {
|
||||
}
|
||||
throw new Error('Failed to load authentication session');
|
||||
}
|
||||
return response.json() as Promise<AuthSessionInfo>;
|
||||
const payload = await (response.json() as Promise<AuthSessionInfo>);
|
||||
persistCsrfToken(payload.csrf_token);
|
||||
return payload;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,6 +242,7 @@ export async function logoutCurrentSession(): Promise<void> {
|
||||
const response = await apiRequest(`${API_BASE}/auth/logout`, {
|
||||
method: 'POST',
|
||||
});
|
||||
persistCsrfToken(undefined);
|
||||
if (!response.ok && response.status !== 401) {
|
||||
const detail = await responseErrorDetail(response);
|
||||
if (detail) {
|
||||
|
||||
@@ -73,6 +73,7 @@ export interface AuthUser {
|
||||
export interface AuthSessionInfo {
|
||||
user: AuthUser;
|
||||
expires_at: string;
|
||||
csrf_token?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user