/** @jsxImportSource hono/jsx */ import type { FC } from "hono/jsx" // --------------------------------------------------------------------------- // Security headers applied to every /admin response // --------------------------------------------------------------------------- export const ADMIN_SECURITY_HEADERS = { "Content-Security-Policy": "default-src 'self'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'", "X-Frame-Options": "DENY", "Referrer-Policy": "no-referrer", "X-Content-Type-Options": "nosniff", } as const // --------------------------------------------------------------------------- // Layout component // --------------------------------------------------------------------------- interface LayoutProps { title?: string active?: "index" | "keys" | "usage" | "audit" | "traces" | "settings" /** CSRF token for the logout form (required for session-protected pages). */ csrfToken?: string /** Number of keys with debug_enabled=1 — when > 0, a warning banner is shown */ debugKeyCount?: number children?: unknown } export const Layout: FC = ({ title = "Admin", active, csrfToken, debugKeyCount = 0, children, }) => { const navItems: Array<{ href: string label: string key: LayoutProps["active"] }> = [ { href: "/admin", label: "Overview", key: "index" }, { href: "/admin/keys", label: "Keys", key: "keys" }, { href: "/admin/usage", label: "Usage", key: "usage" }, { href: "/admin/audit", label: "Audit", key: "audit" }, { href: "/admin/traces", label: "Traces", key: "traces" }, { href: "/admin/settings", label: "Settings", key: "settings" }, ] return ( {title} — Copilot API Admin
{/* CSRF hidden field: required because HTML forms cannot send custom headers. The session middleware also accepts the token from the form body. */} {csrfToken && ( )}
{debugKeyCount > 0 && ( )}
{children}
) } // --------------------------------------------------------------------------- // Login layout (no nav) // --------------------------------------------------------------------------- interface LoginLayoutProps { children?: unknown } export const LoginLayout: FC = ({ children }) => ( Login — Copilot API Admin
{children}
)