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