owltide/server/utils/session.ts
Hornwitser 29b34deef0 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.
2025-03-11 16:30:51 +01:00

73 lines
2.3 KiB
TypeScript

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);
if (index !== -1) {
subscriptions.splice(index, 1);
await writeSubscriptions(subscriptions);
}
}
async function clearAccountSessionInternal(event: H3Event, sessions: Session[]) {
const existingSessionCookie = await getSignedCookie(event, "session");
if (existingSessionCookie) {
const sessionId = parseInt(existingSessionCookie, 10);
const sessionIndex = sessions.findIndex(session => session.id === sessionId);
if (sessionIndex !== -1) {
sessions.splice(sessionIndex, 1);
await removeSessionSubscription(sessionId);
return true;
}
}
return false;
}
export async function clearAccountSession(event: H3Event) {
const sessions = await readSessions();
if (await clearAccountSessionInternal(event, sessions)) {
await writeSessions(sessions);
}
deleteCookie(event, "session");
}
export async function setAccountSession(event: H3Event, accountId: number) {
const sessions = await readSessions();
await clearAccountSessionInternal(event, sessions);
const newSession: Session = {
accountId,
id: await nextSessionId(),
};
sessions.push(newSession);
await writeSessions(sessions);
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) {
const sessionCookie = await getSignedCookie(event, "session");
if (sessionCookie) {
const sessionId = parseInt(sessionCookie, 10);
const sessions = await readSessions();
return sessions.find(session => session.id === sessionId);
}
}
export async function requireAccountSession(event: H3Event) {
const session = await getAccountSession(event);
if (!session)
throw createError({
status: 401,
message: "Account session required",
});
return session;
}