mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-13 11:22:14 +02:00
* feat(auth): gate OSS signup behind ENABLE_SIGNUP flag
## Problem
The `POST /api/v1/auth/signup` endpoint is unconditionally exposed on
every OSS install. Operators running an invite-only deployment (private
customer instances, staging environments, internal-only tenants) have
no way to disable public account creation without patching the codebase.
The UI also shows the "Sign up" link on `/auth/login` regardless of
whether signup is available, so a locked-down deployment leaves broken
navigation on the login page.
## Fix
Introduce a single `ENABLE_SIGNUP` env var (default `true` — no behavior
change for existing installs) that controls signup end-to-end:
- **Backend** — `api/constants.ENABLE_SIGNUP` is read at module load.
The signup handler returns 403 when it's false. Also exposed on
`GET /api/v1/health` as `signup_enabled: bool` so the UI can mirror
the operator's choice at runtime instead of at bundle-build time.
- **UI** — `getSignupEnabled()` in `lib/auth/config.ts` proxies the
health field, `/api/config/auth` surfaces it to the browser, the
login page conditionally renders the "Sign up" link via a one-shot
`fetch("/api/config/auth")` in `useEffect`, and the middleware
redirects `/auth/signup` → `/auth/login` when disabled (fires before
Next.js can serve the statically-prerendered signup page).
- **Helm** — `config.enableSignup` (default `true`) is rendered into
the ConfigMap as `ENABLE_SIGNUP` so operators can flip it via
`--set config.enableSignup=false` at install/upgrade time.
Fallbacks default to `signupEnabled: true` in every layer so a fresh
install "just works" and matches the backend default.
* address review: rollout on ConfigMap change, cache TTL, no signup-link flash
Four review points on #514:
**P1 — ConfigMap Change Skips Rollout** (`configmap.yaml`). `helm upgrade
--set config.enableSignup=false` updated the ConfigMap but did NOT roll
the api pods, so running processes kept the ENABLE_SIGNUP env from
startup and continued serving the old signup behavior — including
divergence between replicas mid-upgrade.
Fix: add the standard `checksum/config` pod-template annotation on the
four backend Deployments that `envFrom` the ConfigMap (`web`,
`arq-worker`, `ari-manager`, `campaign-orchestrator`). Verified with
`helm template`: all four Deployments share the same checksum on any
given render, and flipping `config.enableSignup` changes the checksum
uniformly so kubectl sees a pod-template diff and rolls all four.
**P1 — Signup Flag Stays Cached (server)** (`ui/src/lib/auth/config.ts`).
Module-scoped cache had no TTL. `revalidate: 300` was passed on the
underlying `fetch()` but the in-memory short-circuit above ran first, so
the value never refreshed until the UI pod restarted.
Fix: add `AUTH_CONFIG_TTL_MS = 5 * 60 * 1000` (matching the fetch
revalidate hint) so the module cache and the Next fetch cache stay in
sync. Backend flag flips propagate within 5 minutes without a pod
restart.
**P1 — Middleware Redirect Uses Stale State** (`ui/src/middleware.ts`).
Same shape as above — a separate module cache with no expiry could keep
redirecting `/auth/signup → /auth/login` after signup was re-enabled, or
keep serving the statically-prerendered signup page after lockdown.
Fix: same `SERVER_CONFIG_TTL_MS = 5 * 60 * 1000` TTL on the middleware
cache.
**P2 — Signup link flash on login page** (`ui/src/app/auth/login/page.tsx`).
Initial `signupEnabled` state was `null`, so `{signupEnabled && ...}`
hid the link on first paint and it popped in after the fetch resolved
— a CLS on every login-page load on stock installs where signup is
enabled.
Fix: initialise the state to `true` (matches the backend default). The
fetch still overrides to `false` when the operator has actually
disabled signup, so the lockdown UI behavior is unchanged; only the
happy-path flash is gone.
* simplify signup flag: drop TTL caches and middleware redirect
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* resolve signup flag server-side to avoid signup link flicker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: prabhat pankaj <prabhatiitbhu@gmail.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| dto_fixtures | ||
| integrations | ||
| support | ||
| telephony | ||
| __init__.py | ||
| conftest.py | ||
| test_active_calls.py | ||
| test_add_call_disposition_code.py | ||
| test_agent_stream_route.py | ||
| test_aggregation_fix.py | ||
| test_ai_model_configuration_v2.py | ||
| test_auth_depends.py | ||
| test_auth_routes.py | ||
| test_azure_realtime_wrapper.py | ||
| test_azure_speech_service_factory.py | ||
| test_backfill_org_model_configuration_v2_migration.py | ||
| test_call_concurrency.py | ||
| test_camb_tts_integration.py | ||
| test_campaign_call_dispatcher.py | ||
| test_campaign_tasks.py | ||
| test_cartesia_stt_service_factory.py | ||
| test_cartesia_tts_service_factory.py | ||
| test_circuit_breaker.py | ||
| test_custom_tools.py | ||
| test_custom_tools_context_integration.py | ||
| test_deepgram_flux_service_factory.py | ||
| test_display_options_evaluator.py | ||
| test_dograh_embedding_service.py | ||
| test_dograh_managed_correlation.py | ||
| test_dograh_sdk.py | ||
| test_dograh_sdk_typed.py | ||
| test_dograh_stt_service_factory.py | ||
| test_dto.py | ||
| test_from_number_pool_isolation.py | ||
| test_gemini_json_schema_adapter.py | ||
| test_gemini_live_reconnect_tool_results.py | ||
| test_get_backend_endpoints.py | ||
| test_google_stt_service_factory.py | ||
| test_google_tts_service_factory.py | ||
| test_google_vertex_llm_service_factory.py | ||
| test_grok_realtime_wrapper.py | ||
| test_huggingface_stt_service_factory.py | ||
| test_inworld_tts_service_factory.py | ||
| test_is_private_ip_candidate.py | ||
| test_json_parser.py | ||
| test_knowledge_base_processing_embeddings.py | ||
| test_layout.py | ||
| test_masked_key_rejection.py | ||
| test_mcp_auth.py | ||
| test_mcp_create_workflow.py | ||
| test_mcp_custom_tool_manager.py | ||
| test_mcp_docs_search.py | ||
| test_mcp_get_workflow.py | ||
| test_mcp_instructions_drift.py | ||
| test_mcp_integration.py | ||
| test_mcp_save_workflow.py | ||
| test_mcp_tool_creation.py | ||
| test_mcp_tool_definition.py | ||
| test_mcp_tool_route.py | ||
| test_mcp_tool_session.py | ||
| test_message_sanitization.py | ||
| test_minimax_service_factory.py | ||
| test_mps_service_key_client.py | ||
| test_node_specs.py | ||
| test_onboarding_state.py | ||
| test_openai_realtime_initial_context.py | ||
| test_openai_tts_service_factory.py | ||
| test_organization_usage_billing.py | ||
| test_pipecat_engine_callbacks.py | ||
| test_pipecat_engine_context_update.py | ||
| test_pipecat_engine_end_call.py | ||
| test_pipecat_engine_node_switch_with_user_speech.py | ||
| test_pipecat_engine_tool_calls.py | ||
| test_pipecat_engine_transition_mute.py | ||
| test_pipecat_engine_variable_extraction.py | ||
| test_pipeline_cancellation.py | ||
| test_posthog_client.py | ||
| test_pre_call_fetch.py | ||
| test_public_agent_routes.py | ||
| test_public_embed_cors.py | ||
| test_public_signaling_origin.py | ||
| test_qa_analysis_non_dict_response.py | ||
| test_quota_service.py | ||
| test_realtime_feedback_events.py | ||
| test_realtime_feedback_observer.py | ||
| test_realtime_message_append.py | ||
| test_recording_router_processor.py | ||
| test_resolve_effective_config.py | ||
| test_run_integrations_webhook.py | ||
| test_run_pipeline_realtime_turn_config.py | ||
| test_run_usage_response.py | ||
| test_s3_signed_url.py | ||
| test_sarvam_service_factory.py | ||
| test_sdk_sync.py | ||
| test_smallest_service_factory.py | ||
| test_speaches_service_factory.py | ||
| test_telephony_factory.py | ||
| test_telephony_routes.py | ||
| test_template_renderer.py | ||
| test_text_and_audio_playback.py | ||
| test_text_chat_logs.py | ||
| test_text_chat_session_service.py | ||
| test_tool_schema.py | ||
| test_trigger_path_validation.py | ||
| test_ts_bridge.py | ||
| test_tts_endframe_with_audio_write_failure.py | ||
| test_ultravox_realtime_wrapper.py | ||
| test_unregistered_function_call.py | ||
| test_user_configuration_upsert.py | ||
| test_user_configuration_validation.py | ||
| test_user_configured_service_url_security.py | ||
| test_user_email_case_insensitive.py | ||
| test_user_idle_handler.py | ||
| test_user_muting_during_bot_speech.py | ||
| test_voicemail_detector.py | ||
| test_webrtc_signaling_concurrency.py | ||
| test_workflow_configurations_schema.py | ||
| test_workflow_create_route.py | ||
| test_workflow_graph_constraints.py | ||
| test_workflow_list_route.py | ||
| test_workflow_qa_masking.py | ||
| test_workflow_run_billing.py | ||
| test_workflow_text_chat.py | ||
| test_workflow_versioning.py | ||
| test_xai_tts_service_factory.py | ||