Provide a basic account system with login and server side session store identified by a cookie. Upon successful login a signed session cookie is set by the server with the session stored on the server identifying which account it is logged in as. The client uses a shared useFetch on the session endpoint to identify if it's logged in and which account it is logged in as, and refreshes this when loggin in or out.
57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import type { H3Event } from "h3";
|
|
import { nextSessionId, readSessions, writeSessions } from "~/server/database";
|
|
import { Session } from "~/shared/types/account";
|
|
|
|
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);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
export async function clearAccountSession(event: H3Event) {
|
|
const sessions = await readSessions();
|
|
if (await clearAccountSessionInternal(event, sessions)) {
|
|
await writeSessions(sessions);
|
|
}
|
|
setCookie(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))
|
|
}
|
|
|
|
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;
|
|
}
|