Files
helios/server/src/app.ts
marcuspaico f33d395b71 feat(settings): LLM config API with AES-GCM sealed key, masked reads
- 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>
2026-08-17 14:14:53 -07:00

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;
}