Set a max age for the session cookie to prevent it from expiring when the browser is closed. To prevent the age limit from being being reached the session cookie is refreshed every time the session is loaded. This should fix login being lost when the browser is stopped.
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import type { H3Event } from "h3";
|
|
|
|
let cachedCookieSecret: CryptoKey;
|
|
export async function useCookieSecret(event: H3Event) {
|
|
if (cachedCookieSecret)
|
|
return cachedCookieSecret;
|
|
|
|
const runtimeConfig = useRuntimeConfig(event);
|
|
return cachedCookieSecret = await crypto.subtle.importKey(
|
|
"raw",
|
|
Buffer.from(runtimeConfig.cookieSecretKey, "base64url"),
|
|
{ name: "HMAC", hash: "SHA-256" },
|
|
false,
|
|
["sign", "verify"],
|
|
);
|
|
}
|
|
|
|
export async function setSignedCookie(event: H3Event, name: string, value: string, maxAge?: number) {
|
|
const secret = await useCookieSecret(event);
|
|
const signature = await crypto.subtle.sign("HMAC", secret, Buffer.from(value));
|
|
const cookie = `${value}.${Buffer.from(signature).toString("base64url")}`
|
|
setCookie(event, name, cookie, { httpOnly: true, secure: true, sameSite: true, maxAge });
|
|
}
|
|
|
|
export async function getSignedCookie(event: H3Event, name: string) {
|
|
const cookie = getCookie(event, name);
|
|
if (!cookie)
|
|
return;
|
|
|
|
const rightDot = cookie.lastIndexOf(".");
|
|
if (rightDot === -1)
|
|
return;
|
|
|
|
const value = cookie.slice(0, rightDot);
|
|
const secret = await useCookieSecret(event);
|
|
const signature = Buffer.from(cookie.slice(rightDot + 1), "base64url");
|
|
const valid = await crypto.subtle.verify("HMAC", secret, signature, Buffer.from(value));
|
|
if (!valid)
|
|
return
|
|
|
|
return value;
|
|
}
|