session.ts
⎇
Raw
1import { ADMIN_USERNAME } from "../constants.ts";
2import { db } from "../db";
3import { redirect } from "../lib/redirect.ts";
4
5export interface SessionUser {
6 id: number;
7 username: string;
8 isAdmin: boolean;
9 avatar_version: number;
10}
11
12export async function resolveSession(
13 cookie: string | undefined,
14): Promise<SessionUser | null> {
15 if (!cookie) return null;
16 const now = new Date().toISOString();
17 const session = await db
18 .selectFrom("sessions")
19 .innerJoin("users", "users.id", "sessions.user_id")
20 .select([
21 "users.id",
22 "users.username",
23 "users.avatar_version",
24 "sessions.expires_at",
25 ])
26 .where("sessions.id", "=", cookie)
27 .where("sessions.expires_at", ">", now)
28 .where("users.is_pending", "=", 0)
29 .executeTakeFirst();
30 if (!session) return null;
31 return {
32 id: session.id,
33 username: session.username,
34 isAdmin: session.username === ADMIN_USERNAME,
35 avatar_version: session.avatar_version,
36 };
37}
38
39export function requireAuth(user: SessionUser | null): Response | null {
40 return user ? null : redirect("/login");
41}
42
43export function requireAdmin(user: SessionUser | null): Response | null {
44 if (!user) return redirect("/login");
45 if (!user.isAdmin) {
46 return new Response("Forbidden", {
47 status: 403,
48 headers: { "Content-Type": "text/plain; charset=utf-8" },
49 });
50 }
51 return null;
52}
53