this repo has no description
at export-config 83 lines 2.7 kB view raw
1import { Hono } from "hono"; 2import { serveStatic } from "hono/bun"; 3import { getCookie, setCookie, deleteCookie } from "hono/cookie"; 4import { authRoutes } from "./routes/auth"; 5import { publicationRoutes } from "./routes/publication"; 6import { documentRoutes } from "./routes/documents"; 7import { layout } from "./views/layouts/main"; 8import { homePage } from "./views/home"; 9import { getSession } from "./lib/session"; 10import { getClientMetadata, getJwks } from "./lib/oauth"; 11import { csrfProtection, getCSRFToken } from "./lib/csrf"; 12import type { AppVariables } from "./types"; 13 14export const app = new Hono<{ Variables: AppVariables }>(); 15 16// Static files 17app.use("/public/*", serveStatic({ root: "./" })); 18 19// OAuth metadata endpoints at root level 20// These MUST be publicly accessible (no authentication) 21app.get("/client-metadata.json", async (c) => { 22 try { 23 const metadata = await getClientMetadata(); 24 // Set appropriate cache headers 25 c.header("Cache-Control", "public, max-age=600"); // Cache for 10 minutes 26 c.header("Access-Control-Allow-Origin", "*"); 27 return c.json(metadata); 28 } catch (error) { 29 console.error("Error getting client metadata:", error); 30 return c.json({ error: "Failed to get client metadata" }, 500); 31 } 32}); 33 34app.get("/jwks.json", async (c) => { 35 try { 36 const jwks = await getJwks(); 37 // Set appropriate cache headers 38 c.header("Cache-Control", "public, max-age=600"); // Cache for 10 minutes 39 c.header("Access-Control-Allow-Origin", "*"); 40 return c.json(jwks); 41 } catch (error) { 42 console.error("Error getting JWKS:", error); 43 return c.json({ error: "Failed to get JWKS" }, 500); 44 } 45}); 46 47// Session middleware - adds session and CSRF token to context 48app.use("*", async (c, next) => { 49 const session = await getSession(c); 50 c.set("session", session); 51 // Generate CSRF token for all requests (sets cookie if not present) 52 const csrfToken = getCSRFToken(c); 53 c.set("csrfToken", csrfToken); 54 await next(); 55}); 56 57// CSRF protection for state-changing requests 58// Applied after session middleware but before routes 59app.use("/auth/*", csrfProtection); 60app.use("/publication/*", csrfProtection); 61app.use("/documents/*", csrfProtection); 62 63// Home page 64app.get("/", async (c) => { 65 const session = c.get("session"); 66 return c.html(layout(homePage(session), { session })); 67}); 68 69// Mount routes 70app.route("/auth", authRoutes); 71app.route("/publication", publicationRoutes); 72app.route("/documents", documentRoutes); 73 74const port = parseInt(process.env.PORT || "8000"); 75console.log(`Starting server on http://localhost:${port}`); 76console.log( 77 `Public URL: ${process.env.PUBLIC_URL || "http://localhost:" + port}`, 78); 79 80export default { 81 port, 82 fetch: app.fetch, 83};