WP-02: encrypted settings, SMTP mail, job runner and cron scheduler
AES-256-GCM secret storage keyed by MASTER_KEY, SMTP settings with test mail (lettre), persisted job runs with log and status, JobRunner with per-kind concurrency guard, 6-field cron schedules with defaults, scheduler loop. Settings and Jobs pages in the UI. FAKE_HOST mode for dev machines. Tests: 30 application, 8 infrastructure, 23 API, 16 Vitest, 6 Playwright. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@ -5,6 +5,10 @@ use std::net::SocketAddr;
|
||||
pub struct Config {
|
||||
pub database_url: String,
|
||||
pub jwt_secret: String,
|
||||
/// 64 hex chars; encrypts secrets at rest.
|
||||
pub master_key: String,
|
||||
/// Use fake host adapters (dev machines without apt/kubectl).
|
||||
pub fake_host: bool,
|
||||
pub bind: SocketAddr,
|
||||
pub bootstrap_admin: Option<(String, String)>,
|
||||
pub cookie_secure: bool,
|
||||
@ -20,10 +24,14 @@ impl Config {
|
||||
jwt_secret.len() >= 32,
|
||||
"JWT_SECRET must be at least 32 characters"
|
||||
);
|
||||
let master_key = env("MASTER_KEY")
|
||||
.ok_or_else(|| anyhow::anyhow!("MASTER_KEY is required (64 hex characters)"))?;
|
||||
Ok(Self {
|
||||
database_url: env("DATABASE_URL")
|
||||
.unwrap_or_else(|| "sqlite://data/monitoring.db?mode=rwc".into()),
|
||||
jwt_secret,
|
||||
master_key,
|
||||
fake_host: env("FAKE_HOST").is_some_and(|v| v == "true" || v == "1"),
|
||||
bind: env("BIND")
|
||||
.unwrap_or_else(|| "127.0.0.1:8080".into())
|
||||
.parse()?,
|
||||
|
||||
Reference in New Issue
Block a user