- Add GET/PUT /api/settings for encrypted LLM configuration - SettingsResponse with masked key display - SettingsUpdate validation with optional fields - Defaults: llmBaseUrl "https://openrouter.ai/api/v1", llmModel "anthropic/claude-sonnet-4.5" - Encrypted storage with AES-256-GCM for llm_key - getSetting() export for future route groups - Comprehensive test coverage: defaults, updates, masking, encryption at rest, validation Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
25 lines
878 B
TypeScript
25 lines
878 B
TypeScript
import { Hono } from "hono";
|
|
import { getCookie } from "hono/cookie";
|
|
import type { Db } from "./db";
|
|
import { authRoutes, isAuthenticated } from "./routes/auth";
|
|
import { settingsRoutes } from "./routes/settings";
|
|
|
|
export type Deps = { db: Db; key: Buffer };
|
|
const PUBLIC = new Set(["/api/health", "/api/me", "/api/setup", "/api/login"]);
|
|
|
|
export function createApp(deps: Deps) {
|
|
const app = new Hono();
|
|
app.get("/api/health", (c) => c.json({ ok: true }));
|
|
app.use("/api/*", async (c, next) => {
|
|
if (PUBLIC.has(c.req.path)) return next();
|
|
if (!(await isAuthenticated(deps.db, getCookie(c, "helios_session")))) {
|
|
return c.json({ error: "unauthenticated" }, 401);
|
|
}
|
|
return next();
|
|
});
|
|
app.route("/api", authRoutes({ db: deps.db }));
|
|
app.route("/api", settingsRoutes(deps));
|
|
// Later route groups (connectors, chat) mount here.
|
|
return app;
|
|
}
|