- Introduced utility functions for managing access tokens in cookies, including setting, getting, and clearing tokens. - Updated various components and server routes to utilize the new access token functions for better consistency and maintainability. - Removed redundant cookie handling code across the application, streamlining the authentication process.
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import { browser } from '$app/environment';
|
|
import {
|
|
ACCESS_TOKEN_CHUNK_COUNT,
|
|
accessTokenChunkName,
|
|
splitAccessTokenForCookies,
|
|
ACCESS_TOKEN_MAX_CHUNKS
|
|
} from '$lib/access-token-cookie.shared';
|
|
|
|
function readCookieRaw(name: string): string | null {
|
|
if (!browser) return null;
|
|
const value = `; ${document.cookie}`;
|
|
const parts = value.split(`; ${name}=`);
|
|
if (parts.length === 2) return parts.pop()?.split(';').shift() ?? null;
|
|
return null;
|
|
}
|
|
|
|
export function getAccessTokenFromDocument(): string | null {
|
|
if (!browser) return null;
|
|
const countRaw = readCookieRaw(ACCESS_TOKEN_CHUNK_COUNT);
|
|
if (countRaw) {
|
|
const n = parseInt(countRaw, 10);
|
|
if (!Number.isFinite(n) || n < 1 || n > ACCESS_TOKEN_MAX_CHUNKS) return null;
|
|
let out = '';
|
|
for (let i = 0; i < n; i++) {
|
|
const p = readCookieRaw(accessTokenChunkName(i));
|
|
if (p == null) return null;
|
|
out += p;
|
|
}
|
|
return out;
|
|
}
|
|
return readCookieRaw('access_token');
|
|
}
|
|
|
|
export function hasAccessTokenInDocument(): boolean {
|
|
if (!browser) return false;
|
|
return !!(readCookieRaw('access_token') || readCookieRaw(ACCESS_TOKEN_CHUNK_COUNT));
|
|
}
|
|
|
|
export function clearAccessTokenOnDocument() {
|
|
if (!browser) return;
|
|
const secure = window.location.protocol === 'https:' ? '; Secure' : '';
|
|
const blank = `; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC; SameSite=Lax${secure}`;
|
|
const clear = (name: string) => {
|
|
document.cookie = `${name}=${blank}`;
|
|
};
|
|
clear('access_token');
|
|
clear(ACCESS_TOKEN_CHUNK_COUNT);
|
|
for (let i = 0; i < ACCESS_TOKEN_MAX_CHUNKS; i++) {
|
|
clear(accessTokenChunkName(i));
|
|
}
|
|
}
|
|
|
|
/** Misma política que auth setCookie: expires + SameSite + Secure en HTTPS. */
|
|
export function setAccessTokenOnDocument(token: string, days: number = 7) {
|
|
if (!browser) return;
|
|
clearAccessTokenOnDocument();
|
|
const exp = new Date();
|
|
exp.setDate(exp.getDate() + days);
|
|
const secure = window.location.protocol === 'https:' ? '; Secure' : '';
|
|
const suffix = `; path=/; expires=${exp.toUTCString()}; SameSite=Lax${secure}`;
|
|
|
|
const split = splitAccessTokenForCookies(token);
|
|
if (split.kind === 'single') {
|
|
document.cookie = `access_token=${split.value}${suffix}`;
|
|
return;
|
|
}
|
|
document.cookie = `${ACCESS_TOKEN_CHUNK_COUNT}=${split.parts.length}${suffix}`;
|
|
split.parts.forEach((part, i) => {
|
|
document.cookie = `${accessTokenChunkName(i)}=${part}${suffix}`;
|
|
});
|
|
}
|