/* SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ import type { H3Event } from "h3"; import { nextSessionId, readSessions, readSubscriptions, type ServerSession, type ServerUser, writeSessions, writeSubscriptions } from "~/server/database"; 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 clearServerSessionInternal(event: H3Event, sessions: ServerSession[]) { 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 clearServerSession(event: H3Event) { const sessions = await readSessions(); if (await clearServerSessionInternal(event, sessions)) { await writeSessions(sessions); } deleteCookie(event, "session"); } export async function setServerSession(event: H3Event, account: ServerUser) { const sessions = await readSessions(); await clearServerSessionInternal(event, sessions); const newSession: ServerSession = { account, id: await nextSessionId(), }; sessions.push(newSession); await writeSessions(sessions); await setSignedCookie(event, "session", String(newSession.id), oneYearSeconds) } export async function refreshServerSession(event: H3Event, session: ServerSession) { await setSignedCookie(event, "session", String(session.id), oneYearSeconds) } export async function getServerSession(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 requireServerSession(event: H3Event) { const session = await getServerSession(event); if (!session) throw createError({ status: 401, message: "Account session required", }); return session; } export async function requireServerSessionWithAdmin(event: H3Event) { const session = await requireServerSession(event); if (session.account.type !== "admin") { throw createError({ statusCode: 403, statusMessage: "Forbidden", }); } return session; }