import { Hono } from "jsr:@hono/hono@4"; import { deleteCookie, setCookie } from "jsr:@hono/hono@4/cookie"; import { encodeBase64Url } from "jsr:@std/encoding@1/base64url"; import { sqlWrapper } from "../../db.ts"; import { valkey } from "../../valkey.ts"; import { extractAllSessionIds } from "../../auth-session.ts"; import { getCookieDomain } from "./utils.ts"; export const guestAuthRoutes = new Hono(); const rpID = Deno.env.get("RP_ID") || (import.meta.main ? undefined : "localhost"); // Generate Ephemeral Guest Sandbox guestAuthRoutes.post("/api/guests/sandbox", async (c) => { const guestUuid = crypto.randomUUID(); const sessionId = encodeBase64Url(crypto.getRandomValues(new Uint8Array(32))); const username = `guest-${guestUuid.substring(0, 8)}`; await valkey.setex( sessionId, 7200, // 2-hour TTL JSON.stringify({ uuid: guestUuid, username, account_status: "guest" }), ); const cookieDomain = getCookieDomain(rpID); setCookie(c, "session_id", sessionId, { domain: cookieDomain, path: "/", httpOnly: true, secure: true, sameSite: "Lax", maxAge: 7200, }); return c.json({ success: true, sessionId, guestUuid }); }); // Revoke a session manually (used by layout logout) guestAuthRoutes.post("/api/revoke", async (c) => { // Try Authorization header first (SDK) let token = ""; const authHeader = c.req.header("Authorization"); if (authHeader && authHeader.startsWith("Bearer ")) { token = authHeader.split(" ")[1]; } if (!token) { // Fallback to session cookie (Web UI) const tokens = extractAllSessionIds(c); if (tokens.length === 0) { return c.json({ error: "Missing or invalid token" }, 401); } for (const t of tokens) { try { await valkey.del(t); await sqlWrapper.sql`DELETE FROM sessions WHERE id = ${t}`; } catch (_e) {} } } else { // SDK Token Path try { await valkey.del(token); await sqlWrapper.sql`DELETE FROM sessions WHERE id = ${token}`; } catch (_e) {} } const cookieDomain = getCookieDomain(rpID); if (cookieDomain) { deleteCookie(c, "session_id", { domain: cookieDomain, path: "/", httpOnly: true, secure: true, sameSite: "Lax", }); } deleteCookie(c, "session_id", { path: "/", httpOnly: true, secure: true, sameSite: "Lax", }); return c.json({ success: true }); });