Replace hardcoded Cloudflare DNS-01 with a data-driven provider registry
supporting 11 providers (Cloudflare, Route 53, DigitalOcean, Duck DNS,
Hetzner, Vultr, Porkbun, GoDaddy, Namecheap, OVH, Linode). Users can
configure multiple providers with encrypted credentials and select a
default. Per-certificate provider override is supported via providerOptions.
- Add src/lib/dns-providers.ts with provider definitions, credential
encrypt/decrypt, and Caddy config builder
- Change DnsProviderSettings to multi-provider format with default selection
- Auto-migrate legacy Cloudflare settings on startup (db.ts)
- Normalize old single-provider format on read (getDnsProviderSettings)
- Refactor buildTlsAutomation() to use provider registry
- Add GET /api/v1/dns-providers endpoint for provider discovery
- Add dns-provider settings group to REST API and instance sync
- Replace Cloudflare settings card with multi-provider UI (add/remove
providers, set default, dynamic credential forms)
- Add 10 DNS provider modules to Caddy Dockerfile
- Update OpenAPI spec, E2E tests, and unit test mocks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tighten login rate limit from 200/10s to 5/60s to prevent brute-force
- Encrypt OAuth tokens (access/refresh/id) in accounts table via databaseHooks
- Sync password changes to accounts.password so old passwords stop working
- Redact OAuth client secrets in server actions before returning to client
- Add trustHost config (default false) to prevent Host header poisoning
- Add audit logging for successful logins via session create hook
- Add audit logging to OAuth provider update/delete server actions
- Fix provider ID collision by appending name hash suffix to slug
- Fix nullable provider field causing incorrect hasOAuth detection
- Refuse to store plaintext secrets if encryption module fails to load
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Production (Docker): src/lib/db.ts now uses bun:sqlite + drizzle-orm/bun-sqlite.
No native addon compilation needed — bun:sqlite is a Bun built-in. The Dockerfile
drops all native build tools (python3, make, g++) and uses --ignore-scripts.
Tests (Vitest/Node.js): bun:sqlite is unavailable under Node.js, so:
- tests/helpers/db.ts keeps better-sqlite3 + drizzle-orm/better-sqlite3 for
integration tests that need a real in-memory SQLite
- vitest.config.ts aliases bun:sqlite → a thin better-sqlite3 shim and
drizzle-orm/bun-sqlite → drizzle-orm/better-sqlite3 for unit tests that
transitively import src/lib/db.ts without executing any queries
- better-sqlite3 stays as a devDependency (test-only, not built in Docker)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- accept wildcard proxy host domains like *.example.com with validation and normalization
- make exact hosts win over overlapping wildcards in generated routes and TLS policies
- add unit coverage for host-pattern priority and wildcard domain handling
- add a single test:all entry point and clean up lint/typecheck issues so the suite runs cleanly
- run mobile layout Playwright checks under both chromium and mobile-iphone