WP-02: encrypted settings, SMTP mail, job runner and cron scheduler
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / ui (push) Has been cancelled

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:
Dennis Nemec
2026-09-02 22:16:56 +02:00
parent 6113af0a19
commit fa9ac9a6bc
31 changed files with 1632 additions and 58 deletions

View File

@ -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()?,