public
anord
read
Ledger
Why work hard when you can work easier?
Languages
Repository composition by tracked source files.
TypeScript
86%
CSS
10%
SQL
3%
Shell
1%
HTML
0%
Trace
apps/api/src/http/routes/settings.ts
Trace helps you understand code history line by line. See who changed each line, when it changed, and which commit introduced it.
Author
Date
Commit
Line
Code
1
import { Router } from "express";
2
import { z } from "zod";
3
import { requireAdmin } from "../middleware/auth.js";
4
import { getAdminSettingsBundle, getBrandingSettings, upsertBrandingSettings } from "../../services/settings.js";
5
import { logAudit } from "../../services/audit.js";
7
const brandingSchema = z.object({
8
siteName: z.string().min(2),
9
logoUrl: z.string().url().nullable(),
10
brandColor: z.string().regex(/^#[0-9a-fA-F]{6}$/),
11
publicKnowledgeBaseEnabled: z.boolean(),
12
footerLinks: z.array(
13
z.object({
14
label: z.string().min(1),
15
href: z.string().url()
16
})
17
).default([])
18
});
20
export const settingsRouter = Router();
22
settingsRouter.get("/public", async (_req, res) => {
23
const branding = await getBrandingSettings();
24
return res.json({
25
branding: {
26
siteName: branding.site_name,
27
logoUrl: branding.logo_url,
28
brandColor: branding.brand_color,
29
publicKnowledgeBaseEnabled: branding.public_knowledge_base_enabled,
30
footerLinks: branding.footer_links ?? []
31
}
32
});
33
});
35
settingsRouter.get("/admin", requireAdmin, async (_req, res) => {
36
const settings = await getAdminSettingsBundle();
37
return res.json(settings);
38
});
40
settingsRouter.put("/branding", requireAdmin, async (req, res) => {
41
const input = brandingSchema.parse(req.body);
42
const updated = await upsertBrandingSettings(input);
43
await logAudit(req.user!.id, "settings.branding.update", "branding_settings", updated.id);
44
return res.json(updated);
45
});