WIP! A BB-style forum, on the ATmosphere!
We're still working... we'll be back soon when we have something to show off!
node
typescript
hono
htmx
atproto
1import { Hono } from "hono";
2import { logger } from "../lib/logger.js";
3import type { WebAppEnv } from "../lib/theme-resolution.js";
4
5/**
6 * POST /logout → calls AppView logout, clears cookie, redirects to /
7 */
8export function createAuthRoutes(appviewUrl: string) {
9 return new Hono<WebAppEnv>()
10 /**
11 * POST /logout — logout should be a POST (not a link) to prevent CSRF.
12 *
13 * Calls AppView's logout endpoint to revoke tokens and clean up the
14 * server-side session, then clears the cookie on the web UI's domain and
15 * redirects to the homepage.
16 */
17 .post("/logout", async (c) => {
18 const cookieHeader = c.req.header("cookie") ?? "";
19
20 try {
21 const logoutRes = await fetch(`${appviewUrl}/api/auth/logout`, {
22 headers: { Cookie: cookieHeader },
23 });
24
25 if (!logoutRes.ok) {
26 logger.error("Auth proxy: AppView logout returned non-ok status", {
27 operation: "POST /logout",
28 status: logoutRes.status,
29 });
30 }
31 } catch (error) {
32 if (
33 error instanceof TypeError ||
34 error instanceof ReferenceError ||
35 error instanceof SyntaxError
36 ) {
37 throw error; // Re-throw programming errors — don't hide code bugs
38 }
39 logger.error("Auth proxy: Failed to call AppView logout", {
40 operation: "POST /logout",
41 error: error instanceof Error ? error.message : String(error),
42 });
43 // Continue — still clear local cookie
44 }
45
46 const headers = new Headers();
47 headers.set(
48 "set-cookie",
49 "atbb_session=; Path=/; HttpOnly; Max-Age=0; SameSite=Lax"
50 );
51 headers.set("location", "/");
52
53 return new Response(null, { status: 303, headers });
54 });
55}