blastoise-archive/auth.ts

59 lines
2.0 KiB
TypeScript

import { validateSession, hasPermission, type User } from "./db";
const COOKIE_NAME = "musicroom_session";
export function getSessionToken(req: Request): string | null {
const cookie = req.headers.get("cookie");
if (!cookie) return null;
const match = cookie.match(new RegExp(`${COOKIE_NAME}=([^;]+)`));
return match ? match[1] : null;
}
export function getRequestMeta(req: Request, server?: { requestIP?: (req: Request) => { address: string } | null }): { userAgent?: string; ipAddress?: string } {
const userAgent = req.headers.get("user-agent") ?? undefined;
const ipAddress = req.headers.get("x-forwarded-for")?.split(",")[0]?.trim()
?? req.headers.get("x-real-ip")
?? server?.requestIP?.(req)?.address
?? undefined;
return { userAgent, ipAddress };
}
export function getUser(req: Request, server?: { requestIP?: (req: Request) => { address: string } | null }): User | null {
const token = getSessionToken(req);
if (!token) return null;
const { userAgent, ipAddress } = getRequestMeta(req, server);
return validateSession(token, userAgent, ipAddress);
}
export function requireUser(req: Request, server?: { requestIP?: (req: Request) => { address: string } | null }): User {
const user = getUser(req, server);
if (!user) {
throw new Response("Unauthorized", { status: 401 });
}
return user;
}
export function requirePermission(
req: Request,
resourceType: string,
resourceId: string | null,
permission: string,
server?: { requestIP?: (req: Request) => { address: string } | null }
): User {
const user = requireUser(req, server);
if (!user.is_admin && !hasPermission(user.id, resourceType, resourceId, permission)) {
throw new Response("Forbidden", { status: 403 });
}
return user;
}
export function setSessionCookie(token: string): string {
const maxAge = 7 * 24 * 60 * 60; // 7 days
return `${COOKIE_NAME}=${token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${maxAge}`;
}
export function clearSessionCookie(): string {
return `${COOKIE_NAME}=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0`;
}