Extracted domain-specific sub-routers from monolithic `server/routes/admin.ts` and `server/routes/auth.ts` into isolated modules within `server/routes/admin/` and `server/routes/auth/` respectively. The original entry routers were updated to import and assemble these sub-routers without breaking their current HTTP interface or rate limiting/authorization middleware. Testing and linting were run ensuring perfect functionality and 100% test passing score. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
91 lines
2.4 KiB
TypeScript
91 lines
2.4 KiB
TypeScript
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 });
|
|
});
|