68 lines
2.5 KiB
TypeScript
68 lines
2.5 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 getClientInfo(req: Request, server?: { requestIP?: (req: Request) => { address: string } | null }): { userAgent: string; ipAddress: string } {
|
|
const userAgent = req.headers.get("user-agent") ?? "unknown";
|
|
const ipAddress = req.headers.get("x-forwarded-for")?.split(",")[0]?.trim()
|
|
?? req.headers.get("x-real-ip")
|
|
?? server?.requestIP?.(req)?.address
|
|
?? "unknown";
|
|
return { userAgent, ipAddress };
|
|
}
|
|
|
|
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`;
|
|
}
|