feat: auth-gate demo chat + budget circuit breaker
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 2m10s
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 2m10s
Gate the demo chat behind Supabase auth: the widget now fetches Supabase config on open, shows a compact sign-in pane (Google OAuth or email/password) when the user is unauthenticated, and passes the access_token to /api/demo. The server verifies the token via supabase_auth_user() before any processing and uses the verified user ID as the rate-limit key. Add a budget kill switch: a demo_config table in Supabase holds a demo_enabled flag that /api/demo polls every 60s (cached, fails open). A Cloud Function (demo-budget-guard) is triggered by a GCP Pub/Sub budget alert and sets demo_enabled = 'false' when spend crosses 90% of the $150 daily budget. Budget and topic are provisioned; function is live in us-central1.
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+85
@@ -1794,6 +1794,91 @@ el_val_t page_css(void) {
|
||||
" }\n"
|
||||
" #neuron-demo-send:hover { background: #0078D4; }\n"
|
||||
" #neuron-demo-send:disabled { opacity: 0.5; cursor: not-allowed; }\n"
|
||||
" #neuron-demo-auth {\n"
|
||||
" flex-direction: column;\n"
|
||||
" align-items: center;\n"
|
||||
" gap: 0.75rem;\n"
|
||||
" padding: 1.5rem 1.25rem;\n"
|
||||
" flex: 1;\n"
|
||||
" }\n"
|
||||
" .demo-auth-heading {\n"
|
||||
" font-family: var(--body);\n"
|
||||
" font-size: 0.85rem;\n"
|
||||
" font-weight: 600;\n"
|
||||
" color: var(--t1);\n"
|
||||
" text-align: center;\n"
|
||||
" margin: 0 0 0.25rem;\n"
|
||||
" }\n"
|
||||
" .demo-auth-google-btn {\n"
|
||||
" display: flex;\n"
|
||||
" align-items: center;\n"
|
||||
" gap: 0.6rem;\n"
|
||||
" width: 100%;\n"
|
||||
" padding: 0.65rem 1rem;\n"
|
||||
" font-family: var(--body);\n"
|
||||
" font-size: 0.82rem;\n"
|
||||
" font-weight: 500;\n"
|
||||
" color: var(--t1);\n"
|
||||
" background: #fff;\n"
|
||||
" border: 1px solid var(--border);\n"
|
||||
" border-radius: 6px;\n"
|
||||
" cursor: pointer;\n"
|
||||
" justify-content: center;\n"
|
||||
" transition: border-color 180ms, box-shadow 180ms;\n"
|
||||
" }\n"
|
||||
" .demo-auth-google-btn:hover {\n"
|
||||
" border-color: rgba(0,82,160,0.45);\n"
|
||||
" box-shadow: 0 0 0 3px rgba(0,82,160,0.08);\n"
|
||||
" }\n"
|
||||
" .demo-auth-email-toggle {\n"
|
||||
" background: none;\n"
|
||||
" border: none;\n"
|
||||
" cursor: pointer;\n"
|
||||
" font-family: var(--body);\n"
|
||||
" font-size: 0.78rem;\n"
|
||||
" color: var(--t3);\n"
|
||||
" text-decoration: underline;\n"
|
||||
" padding: 0;\n"
|
||||
" }\n"
|
||||
" .demo-auth-email-form {\n"
|
||||
" display: none;\n"
|
||||
" flex-direction: column;\n"
|
||||
" gap: 0.5rem;\n"
|
||||
" width: 100%;\n"
|
||||
" }\n"
|
||||
" .demo-auth-email-form input {\n"
|
||||
" width: 100%;\n"
|
||||
" padding: 0.6rem 0.75rem;\n"
|
||||
" font-family: var(--body);\n"
|
||||
" font-size: 0.82rem;\n"
|
||||
" color: var(--t1);\n"
|
||||
" background: var(--bg);\n"
|
||||
" border: 1px solid var(--border);\n"
|
||||
" border-radius: 6px;\n"
|
||||
" outline: none;\n"
|
||||
" }\n"
|
||||
" .demo-auth-email-form input:focus { border-color: var(--navy); }\n"
|
||||
" .demo-auth-submit-btn {\n"
|
||||
" width: 100%;\n"
|
||||
" padding: 0.6rem 1rem;\n"
|
||||
" font-family: var(--body);\n"
|
||||
" font-size: 0.82rem;\n"
|
||||
" font-weight: 600;\n"
|
||||
" color: #fff;\n"
|
||||
" background: var(--navy);\n"
|
||||
" border: none;\n"
|
||||
" border-radius: 6px;\n"
|
||||
" cursor: pointer;\n"
|
||||
" transition: background 180ms;\n"
|
||||
" }\n"
|
||||
" .demo-auth-submit-btn:hover { background: #0078D4; }\n"
|
||||
" .demo-auth-submit-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n"
|
||||
" .demo-auth-msg {\n"
|
||||
" font-family: var(--body);\n"
|
||||
" font-size: 0.75rem;\n"
|
||||
" margin: 0;\n"
|
||||
" text-align: center;\n"
|
||||
" }\n"
|
||||
" @media (max-width: 600px) {\n"
|
||||
" #neuron-demo-text { font-size: 1rem; padding: 1rem; }\n"
|
||||
" #neuron-demo-send { padding: 1rem 1.25rem; min-width: 64px; }\n"
|
||||
|
||||
Reference in New Issue
Block a user