76a57b1d6fcde3f05e9024586b2c3095d25ea4cf
Adds isPortalDisabledGlobally() helper that returns true when every configured per-port client_portal_enabled row is false. The (portal) layout calls it and renders a "Portal not available" notice instead of the login/activate/reset pages when the kill switch is flipped. Closes the gap where flipping the admin System Settings toggle would leave /portal/login publicly reachable as a form that rejects every submit with a ConflictError. Now a clean notice page appears instead. Single-port deployments get a global toggle out of this — the existing per-port admin UI in System Settings effectively becomes the master switch. Multi-port future will need URL-level port discrimination (subdomain or path prefix) before the all-ports-off heuristic should be replaced with a per-port resolution. API routes (/api/portal/*) stay on the existing service-layer gate (every portal-auth function checks isPortalEnabledForPort). Direct curl gets a per-call ConflictError, which is acceptable for non-human clients; the UI gate is what matters for accidental discovery. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Description
No description provided
Languages
TypeScript
98.7%
HTML
1%
CSS
0.1%
Shell
0.1%