Make session cookie permament

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.
This commit is contained in:
Hornwitser 2025-03-11 16:30:51 +01:00
parent c940f785c5
commit 29b34deef0
3 changed files with 11 additions and 3 deletions

View file

@ -11,6 +11,8 @@ export default defineEventHandler(async (event): Promise<AccountSession | undefi
subscriptions.find(sub => sub.type === "push" && sub.sessionId === session.id)
);
await refreshAccountSession(event, session);
return {
id: session.id,
account: accounts.find(account => account.id === session.accountId)!,

View file

@ -2,6 +2,8 @@ import type { H3Event } from "h3";
import { nextSessionId, readSessions, readSubscriptions, writeSessions, writeSubscriptions } from "~/server/database";
import { Session } from "~/shared/types/account";
const oneYearSeconds = 365 * 24 * 60 * 60;
async function removeSessionSubscription(sessionId: number) {
const subscriptions = await readSubscriptions();
const index = subscriptions.findIndex(subscription => subscription.sessionId === sessionId);
@ -44,7 +46,11 @@ export async function setAccountSession(event: H3Event, accountId: number) {
sessions.push(newSession);
await writeSessions(sessions);
await setSignedCookie(event, "session", String(newSession.id))
await setSignedCookie(event, "session", String(newSession.id), oneYearSeconds)
}
export async function refreshAccountSession(event: H3Event, session: Session) {
await setSignedCookie(event, "session", String(session.id), oneYearSeconds)
}
export async function getAccountSession(event: H3Event) {

View file

@ -15,11 +15,11 @@ export async function useCookieSecret(event: H3Event) {
);
}
export async function setSignedCookie(event: H3Event, name: string, value: string) {
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 });
setCookie(event, name, cookie, { httpOnly: true, secure: true, sameSite: true, maxAge });
}
export async function getSignedCookie(event: H3Event, name: string) {