Files

91 lines
3.0 KiB
JavaScript

import { deriveKeyFromSecret, encryptJSON, decryptToJSON } from '/static/js/crypto.js';
async function getAppSecret() {
const meta = document.querySelector('meta[name="app-secret"]');
return meta ? meta.getAttribute('content') : null;
}
export async function setCookie(name, value, days = 180) {
const appSecret = await getAppSecret();
let cookieValue;
if (!appSecret) {
console.warn('APP SECRET is missing — cookies will be stored without client-side encryption.');
cookieValue = encodeURIComponent(JSON.stringify(value));
} else {
try {
const key = await deriveKeyFromSecret(appSecret);
cookieValue = await encryptJSON(key, value);
} catch (error) {
console.error('Encryption failed:', error);
cookieValue = encodeURIComponent(JSON.stringify(value));
}
}
const expires = new Date(Date.now() + days * 864e5).toUTCString();
const encodedName = encodeURIComponent(name);
document.cookie = `${encodedName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;`;
document.cookie = `${encodedName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; Secure;`;
// ---------- 1. Пытаемся установить безопасную куку ----------
let secureCookie = `${encodedName}=${cookieValue}; expires=${expires}; path=/; Secure; SameSite=Lax`;
document.cookie = secureCookie;
// ---------- 2. Проверяем, записалась ли она ----------
const isSet = document.cookie.split('; ')
.some(c => c.startsWith(`${encodedName}=`));
if (isSet) {
return true; // безопасная кука успешно установлена
}
// ---------- 3. Фолбэк: ставим обычную (без Secure) ----------
let normalCookie = `${encodedName}=${cookieValue}; expires=${expires}; path=/; SameSite=Lax`;
document.cookie = normalCookie;
return false; // безопасную куку установить не удалось
}
export async function getCookie(name) {
const cookies = document.cookie ? document.cookie.split('; ') : [];
for (const c of cookies) {
const parts = c.split('=');
if (parts.length < 2) continue;
const cookieName = decodeURIComponent(parts[0]);
if (cookieName !== name) continue;
const cookieValue = parts.slice(1).join('=');
const appSecret = await getAppSecret();
if (appSecret) {
try {
const key = await deriveKeyFromSecret(appSecret);
const decrypted = await decryptToJSON(key, cookieValue);
return JSON.parse(decrypted);
} catch (error) {
console.error('Decryption failed for cookie', name, error);
return
}
} else {
try {
return JSON.parse(decodeURIComponent(cookieValue));
} catch (e) {
return decodeURIComponent(cookieValue);
}
}
}
return null;
}
export function deleteCookie(name) {
try {
document.cookie = `${encodeURIComponent(name)}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
} catch (e) {
console.error(e)
}
}