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>
This commit is contained in:
@@ -6,3 +6,17 @@ export type HealthResponse = z.infer<typeof HealthResponse>;
|
||||
export const PasswordBody = z.object({ password: z.string().min(8).max(200) });
|
||||
export const MeResponse = z.object({ needsSetup: z.boolean(), authenticated: z.boolean() });
|
||||
export type MeResponse = z.infer<typeof MeResponse>;
|
||||
|
||||
export const SettingsResponse = z.object({
|
||||
llmBaseUrl: z.string(),
|
||||
llmModel: z.string(),
|
||||
llmKeyMasked: z.string().nullable(),
|
||||
});
|
||||
export type SettingsResponse = z.infer<typeof SettingsResponse>;
|
||||
|
||||
export const SettingsUpdate = z.object({
|
||||
llmBaseUrl: z.string().url().optional(),
|
||||
llmModel: z.string().min(1).optional(),
|
||||
llmKey: z.string().min(1).optional(),
|
||||
});
|
||||
export type SettingsUpdate = z.infer<typeof SettingsUpdate>;
|
||||
|
||||
Reference in New Issue
Block a user