@adonis-agora/authkit-server 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +158 -0
- package/build/assets/grafana/authkit-dashboard.json +118 -0
- package/build/commands/clients_create.d.ts +27 -0
- package/build/commands/clients_create.js +121 -0
- package/build/commands/commands.json +292 -0
- package/build/commands/configure.d.ts +2 -0
- package/build/commands/configure.js +45 -0
- package/build/commands/doctor.d.ts +10 -0
- package/build/commands/doctor.js +113 -0
- package/build/commands/eject.d.ts +11 -0
- package/build/commands/eject.js +96 -0
- package/build/commands/expire_scan.d.ts +28 -0
- package/build/commands/expire_scan.js +92 -0
- package/build/commands/import_users.d.ts +17 -0
- package/build/commands/import_users.js +80 -0
- package/build/commands/keys_rotate.d.ts +21 -0
- package/build/commands/keys_rotate.js +126 -0
- package/build/commands/main.d.ts +12 -0
- package/build/commands/main.js +38 -0
- package/build/commands/settings_get.d.ts +18 -0
- package/build/commands/settings_get.js +43 -0
- package/build/commands/settings_list.d.ts +17 -0
- package/build/commands/settings_list.js +39 -0
- package/build/commands/settings_set.d.ts +20 -0
- package/build/commands/settings_set.js +55 -0
- package/build/commands/settings_unset.d.ts +18 -0
- package/build/commands/settings_unset.js +46 -0
- package/build/commands/ui_preset.d.ts +4 -0
- package/build/commands/ui_preset.js +32 -0
- package/build/database/migrations/make_authkit_oidc_table.d.ts +6 -0
- package/build/database/migrations/make_authkit_oidc_table.js +19 -0
- package/build/host/ui/admin.html +29 -0
- package/build/host/views/account/apps.edge +59 -0
- package/build/host/views/account/confirm.edge +70 -0
- package/build/host/views/account/email-confirmed.edge +16 -0
- package/build/host/views/account/login.edge +33 -0
- package/build/host/views/account/mfa.edge +152 -0
- package/build/host/views/account/orgs.edge +58 -0
- package/build/host/views/account/security.edge +215 -0
- package/build/host/views/account/tokens.edge +75 -0
- package/build/host/views/consent.edge +20 -0
- package/build/host/views/forgot.edge +43 -0
- package/build/host/views/login.edge +251 -0
- package/build/host/views/maintenance.edge +32 -0
- package/build/host/views/mfa-challenge.edge +107 -0
- package/build/host/views/otp-unlock.edge +40 -0
- package/build/host/views/partials/styles.edge +2 -0
- package/build/host/views/reset.edge +30 -0
- package/build/host/views/signup.edge +62 -0
- package/build/host/views/verify-email.edge +17 -0
- package/build/index.d.ts +115 -0
- package/build/index.js +76 -0
- package/build/password/common_passwords.txt +10000 -0
- package/build/providers/authkit_server_provider.d.ts +27 -0
- package/build/providers/authkit_server_provider.js +242 -0
- package/build/src/accounts/account_store.d.ts +578 -0
- package/build/src/accounts/account_store.js +60 -0
- package/build/src/accounts/lucid_account_store.d.ts +156 -0
- package/build/src/accounts/lucid_account_store.js +294 -0
- package/build/src/accounts/lucid_store/core.d.ts +9 -0
- package/build/src/accounts/lucid_store/core.js +306 -0
- package/build/src/accounts/lucid_store/mfa.d.ts +15 -0
- package/build/src/accounts/lucid_store/mfa.js +108 -0
- package/build/src/accounts/lucid_store/organizations.d.ts +13 -0
- package/build/src/accounts/lucid_store/organizations.js +294 -0
- package/build/src/accounts/lucid_store/password_hygiene.d.ts +20 -0
- package/build/src/accounts/lucid_store/password_hygiene.js +130 -0
- package/build/src/accounts/lucid_store/provider_identity.d.ts +8 -0
- package/build/src/accounts/lucid_store/provider_identity.js +59 -0
- package/build/src/accounts/lucid_store/shared.d.ts +113 -0
- package/build/src/accounts/lucid_store/shared.js +130 -0
- package/build/src/accounts/lucid_store/status_profile.d.ts +34 -0
- package/build/src/accounts/lucid_store/status_profile.js +100 -0
- package/build/src/accounts/lucid_store/webauthn.d.ts +8 -0
- package/build/src/accounts/lucid_store/webauthn.js +140 -0
- package/build/src/accounts/lucid_stores.d.ts +45 -0
- package/build/src/accounts/lucid_stores.js +30 -0
- package/build/src/adapters/adapter_contract.d.ts +37 -0
- package/build/src/adapters/adapter_contract.js +1 -0
- package/build/src/adapters/database_adapter.d.ts +21 -0
- package/build/src/adapters/database_adapter.js +79 -0
- package/build/src/adapters/factory.d.ts +30 -0
- package/build/src/adapters/factory.js +43 -0
- package/build/src/adapters/redis_adapter.d.ts +24 -0
- package/build/src/adapters/redis_adapter.js +122 -0
- package/build/src/audit/audit_sink.d.ts +63 -0
- package/build/src/audit/audit_sink.js +1 -0
- package/build/src/audit/lucid_audit_sink.d.ts +10 -0
- package/build/src/audit/lucid_audit_sink.js +99 -0
- package/build/src/commands/expire_scan_command.d.ts +60 -0
- package/build/src/commands/expire_scan_command.js +229 -0
- package/build/src/commands/import_clients.d.ts +40 -0
- package/build/src/commands/import_clients.js +79 -0
- package/build/src/commands/import_users.d.ts +51 -0
- package/build/src/commands/import_users.js +94 -0
- package/build/src/commands/resolve_config.d.ts +13 -0
- package/build/src/commands/resolve_config.js +18 -0
- package/build/src/commands/settings_commands.d.ts +47 -0
- package/build/src/commands/settings_commands.js +270 -0
- package/build/src/controllers/oidc_callback_controller.d.ts +22 -0
- package/build/src/controllers/oidc_callback_controller.js +33 -0
- package/build/src/define_config.d.ts +772 -0
- package/build/src/define_config.js +351 -0
- package/build/src/doctor/checks.d.ts +197 -0
- package/build/src/doctor/checks.js +858 -0
- package/build/src/events/dispatcher.d.ts +45 -0
- package/build/src/events/dispatcher.js +117 -0
- package/build/src/host/account_api/account_api_controller.d.ts +245 -0
- package/build/src/host/account_api/account_api_controller.js +827 -0
- package/build/src/host/account_deletion_ops.d.ts +80 -0
- package/build/src/host/account_deletion_ops.js +118 -0
- package/build/src/host/account_deletion_service.d.ts +63 -0
- package/build/src/host/account_deletion_service.js +133 -0
- package/build/src/host/account_export_service.d.ts +76 -0
- package/build/src/host/account_export_service.js +140 -0
- package/build/src/host/account_home.d.ts +11 -0
- package/build/src/host/account_home.js +11 -0
- package/build/src/host/account_lockout.d.ts +86 -0
- package/build/src/host/account_lockout.js +185 -0
- package/build/src/host/active_org_cookie.d.ts +28 -0
- package/build/src/host/active_org_cookie.js +47 -0
- package/build/src/host/admin_api/admin_api_guard.d.ts +16 -0
- package/build/src/host/admin_api/admin_api_guard.js +59 -0
- package/build/src/host/admin_api/admin_orgs_service.d.ts +125 -0
- package/build/src/host/admin_api/admin_orgs_service.js +324 -0
- package/build/src/host/admin_api/admin_users_service.d.ts +163 -0
- package/build/src/host/admin_api/admin_users_service.js +308 -0
- package/build/src/host/admin_api/api_clients_controller.d.ts +54 -0
- package/build/src/host/admin_api/api_clients_controller.js +89 -0
- package/build/src/host/admin_api/api_keys_controller.d.ts +19 -0
- package/build/src/host/admin_api/api_keys_controller.js +36 -0
- package/build/src/host/admin_api/api_misc_controller.d.ts +19 -0
- package/build/src/host/admin_api/api_misc_controller.js +44 -0
- package/build/src/host/admin_api/api_orgs_controller.d.ts +108 -0
- package/build/src/host/admin_api/api_orgs_controller.js +189 -0
- package/build/src/host/admin_api/api_settings_controller.d.ts +55 -0
- package/build/src/host/admin_api/api_settings_controller.js +134 -0
- package/build/src/host/admin_api/api_users_controller.d.ts +108 -0
- package/build/src/host/admin_api/api_users_controller.js +187 -0
- package/build/src/host/admin_api/dto.d.ts +131 -0
- package/build/src/host/admin_api/dto.js +122 -0
- package/build/src/host/admin_api/token_verify_service.d.ts +34 -0
- package/build/src/host/admin_api/token_verify_service.js +74 -0
- package/build/src/host/admin_clients_service.d.ts +88 -0
- package/build/src/host/admin_clients_service.js +181 -0
- package/build/src/host/admin_console/admin_shell_controller.d.ts +27 -0
- package/build/src/host/admin_console/admin_shell_controller.js +167 -0
- package/build/src/host/admin_console/console_audit_controller.d.ts +17 -0
- package/build/src/host/admin_console/console_audit_controller.js +25 -0
- package/build/src/host/admin_console/console_clients_controller.d.ts +53 -0
- package/build/src/host/admin_console/console_clients_controller.js +102 -0
- package/build/src/host/admin_console/console_impersonation_controller.d.ts +23 -0
- package/build/src/host/admin_console/console_impersonation_controller.js +45 -0
- package/build/src/host/admin_console/console_keys_controller.d.ts +24 -0
- package/build/src/host/admin_console/console_keys_controller.js +41 -0
- package/build/src/host/admin_console/console_orgs_controller.d.ts +96 -0
- package/build/src/host/admin_console/console_orgs_controller.js +238 -0
- package/build/src/host/admin_console/console_overview_controller.d.ts +27 -0
- package/build/src/host/admin_console/console_overview_controller.js +44 -0
- package/build/src/host/admin_console/console_roles_controller.d.ts +31 -0
- package/build/src/host/admin_console/console_roles_controller.js +108 -0
- package/build/src/host/admin_console/console_sessions_controller.d.ts +91 -0
- package/build/src/host/admin_console/console_sessions_controller.js +125 -0
- package/build/src/host/admin_console/console_settings_controller.d.ts +47 -0
- package/build/src/host/admin_console/console_settings_controller.js +115 -0
- package/build/src/host/admin_console/console_users_controller.d.ts +110 -0
- package/build/src/host/admin_console/console_users_controller.js +212 -0
- package/build/src/host/admin_prefix.d.ts +50 -0
- package/build/src/host/admin_prefix.js +77 -0
- package/build/src/host/admin_sessions_service.d.ts +119 -0
- package/build/src/host/admin_sessions_service.js +284 -0
- package/build/src/host/admin_stats_service.d.ts +44 -0
- package/build/src/host/admin_stats_service.js +130 -0
- package/build/src/host/admin_validators.d.ts +247 -0
- package/build/src/host/admin_validators.js +197 -0
- package/build/src/host/augmentations.d.ts +12 -0
- package/build/src/host/augmentations.js +1 -0
- package/build/src/host/auth_host_config.d.ts +22 -0
- package/build/src/host/auth_host_config.js +13 -0
- package/build/src/host/avatar_storage.d.ts +68 -0
- package/build/src/host/avatar_storage.js +166 -0
- package/build/src/host/bot_protection.d.ts +187 -0
- package/build/src/host/bot_protection.js +132 -0
- package/build/src/host/branding.d.ts +19 -0
- package/build/src/host/branding.js +8 -0
- package/build/src/host/config_locks.d.ts +38 -0
- package/build/src/host/config_locks.js +70 -0
- package/build/src/host/console_session.d.ts +27 -0
- package/build/src/host/console_session.js +36 -0
- package/build/src/host/controllers/account_apps_controller.d.ts +15 -0
- package/build/src/host/controllers/account_apps_controller.js +61 -0
- package/build/src/host/controllers/account_confirm_controller.d.ts +24 -0
- package/build/src/host/controllers/account_confirm_controller.js +144 -0
- package/build/src/host/controllers/account_mfa_controller.d.ts +28 -0
- package/build/src/host/controllers/account_mfa_controller.js +208 -0
- package/build/src/host/controllers/account_orgs_controller.d.ts +80 -0
- package/build/src/host/controllers/account_orgs_controller.js +401 -0
- package/build/src/host/controllers/account_security_controller.d.ts +43 -0
- package/build/src/host/controllers/account_security_controller.js +546 -0
- package/build/src/host/controllers/account_session_controller.d.ts +21 -0
- package/build/src/host/controllers/account_session_controller.js +113 -0
- package/build/src/host/controllers/account_tokens_controller.d.ts +7 -0
- package/build/src/host/controllers/account_tokens_controller.js +67 -0
- package/build/src/host/controllers/interaction_controller.d.ts +125 -0
- package/build/src/host/controllers/interaction_controller.js +981 -0
- package/build/src/host/controllers/pat_introspection_controller.d.ts +22 -0
- package/build/src/host/controllers/pat_introspection_controller.js +46 -0
- package/build/src/host/controllers/registration_controller.d.ts +18 -0
- package/build/src/host/controllers/registration_controller.js +382 -0
- package/build/src/host/controllers/social_controller.d.ts +8 -0
- package/build/src/host/controllers/social_controller.js +89 -0
- package/build/src/host/csrf.d.ts +29 -0
- package/build/src/host/csrf.js +14 -0
- package/build/src/host/default_mailer.d.ts +112 -0
- package/build/src/host/default_mailer.js +417 -0
- package/build/src/host/durable/account_deletion_workflow.d.ts +48 -0
- package/build/src/host/durable/account_deletion_workflow.js +86 -0
- package/build/src/host/durable/account_export_workflow.d.ts +68 -0
- package/build/src/host/durable/account_export_workflow.js +93 -0
- package/build/src/host/durable/index.d.ts +68 -0
- package/build/src/host/durable/index.js +77 -0
- package/build/src/host/email_templates.d.ts +39 -0
- package/build/src/host/email_templates.js +69 -0
- package/build/src/host/geo.d.ts +22 -0
- package/build/src/host/geo.js +39 -0
- package/build/src/host/i18n.d.ts +1416 -0
- package/build/src/host/i18n.js +1583 -0
- package/build/src/host/impersonation.d.ts +25 -0
- package/build/src/host/impersonation.js +31 -0
- package/build/src/host/key_rotation.d.ts +14 -0
- package/build/src/host/key_rotation.js +27 -0
- package/build/src/host/key_rotation_actions.d.ts +42 -0
- package/build/src/host/key_rotation_actions.js +27 -0
- package/build/src/host/login_attempt.d.ts +98 -0
- package/build/src/host/login_attempt.js +211 -0
- package/build/src/host/login_notify.d.ts +27 -0
- package/build/src/host/login_notify.js +142 -0
- package/build/src/host/middleware/account_auth.d.ts +7 -0
- package/build/src/host/middleware/account_auth.js +11 -0
- package/build/src/host/otp_lockout.d.ts +103 -0
- package/build/src/host/otp_lockout.js +221 -0
- package/build/src/host/rate_limit.d.ts +39 -0
- package/build/src/host/rate_limit.js +94 -0
- package/build/src/host/register_auth_host.d.ts +97 -0
- package/build/src/host/register_auth_host.js +466 -0
- package/build/src/host/renderers/edge_renderer.d.ts +12 -0
- package/build/src/host/renderers/edge_renderer.js +38 -0
- package/build/src/host/renderers/inertia_renderer.d.ts +70 -0
- package/build/src/host/renderers/inertia_renderer.js +54 -0
- package/build/src/host/runtime_settings.d.ts +181 -0
- package/build/src/host/runtime_settings.js +307 -0
- package/build/src/host/runtime_toggles.d.ts +807 -0
- package/build/src/host/runtime_toggles.js +784 -0
- package/build/src/host/security_notice_service.d.ts +36 -0
- package/build/src/host/security_notice_service.js +87 -0
- package/build/src/host/session_context.d.ts +23 -0
- package/build/src/host/session_context.js +89 -0
- package/build/src/host/sudo_mode.d.ts +56 -0
- package/build/src/host/sudo_mode.js +99 -0
- package/build/src/host/svg_chart.d.ts +15 -0
- package/build/src/host/svg_chart.js +45 -0
- package/build/src/host/trusted_device.d.ts +61 -0
- package/build/src/host/trusted_device.js +65 -0
- package/build/src/host/ui-dist/assets/index-CRWcmsex.js +137 -0
- package/build/src/host/ui-dist/assets/index-DTSmD4RU.css +1 -0
- package/build/src/host/ui-dist/index.html +17 -0
- package/build/src/host/user_agent.d.ts +18 -0
- package/build/src/host/user_agent.js +50 -0
- package/build/src/host/validators.d.ts +127 -0
- package/build/src/host/validators.js +53 -0
- package/build/src/keys/jwks_manager.d.ts +6 -0
- package/build/src/keys/jwks_manager.js +11 -0
- package/build/src/keys/keystore.d.ts +52 -0
- package/build/src/keys/keystore.js +68 -0
- package/build/src/keys/keystore_codec.d.ts +20 -0
- package/build/src/keys/keystore_codec.js +42 -0
- package/build/src/keys/keystore_crypto.d.ts +9 -0
- package/build/src/keys/keystore_crypto.js +27 -0
- package/build/src/keys/keystore_manager.d.ts +43 -0
- package/build/src/keys/keystore_manager.js +104 -0
- package/build/src/keys/keystore_vault.d.ts +113 -0
- package/build/src/keys/keystore_vault.js +265 -0
- package/build/src/mixins/json_column.d.ts +33 -0
- package/build/src/mixins/json_column.js +38 -0
- package/build/src/mixins/with_audit_log.d.ts +19 -0
- package/build/src/mixins/with_audit_log.js +39 -0
- package/build/src/mixins/with_auth_user.d.ts +24 -0
- package/build/src/mixins/with_auth_user.js +46 -0
- package/build/src/mixins/with_credentials.d.ts +20 -0
- package/build/src/mixins/with_credentials.js +29 -0
- package/build/src/mixins/with_mfa.d.ts +35 -0
- package/build/src/mixins/with_mfa.js +21 -0
- package/build/src/mixins/with_personal_access_token.d.ts +19 -0
- package/build/src/mixins/with_personal_access_token.js +42 -0
- package/build/src/mixins/with_provider_identity.d.ts +20 -0
- package/build/src/mixins/with_provider_identity.js +32 -0
- package/build/src/mixins/with_webauthn_credential.d.ts +37 -0
- package/build/src/mixins/with_webauthn_credential.js +46 -0
- package/build/src/observability/diagnostics_bridge.d.ts +6 -0
- package/build/src/observability/diagnostics_bridge.js +27 -0
- package/build/src/observability/metrics_controller.d.ts +5 -0
- package/build/src/observability/metrics_controller.js +24 -0
- package/build/src/observability/metrics_service.d.ts +2 -0
- package/build/src/observability/metrics_service.js +7 -0
- package/build/src/observability/otel_recorder.d.ts +10 -0
- package/build/src/observability/otel_recorder.js +59 -0
- package/build/src/observability/telescope/data_providers.d.ts +24 -0
- package/build/src/observability/telescope/data_providers.js +235 -0
- package/build/src/observability/telescope/extension.d.ts +29 -0
- package/build/src/observability/telescope/extension.js +167 -0
- package/build/src/observability/telescope/index.d.ts +8 -0
- package/build/src/observability/telescope/index.js +8 -0
- package/build/src/observability/wire_provider_events.d.ts +12 -0
- package/build/src/observability/wire_provider_events.js +30 -0
- package/build/src/password/common_passwords.d.ts +31 -0
- package/build/src/password/common_passwords.js +73 -0
- package/build/src/password/password_manager.d.ts +163 -0
- package/build/src/password/password_manager.js +191 -0
- package/build/src/password/policy.d.ts +71 -0
- package/build/src/password/policy.js +55 -0
- package/build/src/password/pwned.d.ts +36 -0
- package/build/src/password/pwned.js +52 -0
- package/build/src/pat/lucid_pat_store.d.ts +6 -0
- package/build/src/pat/lucid_pat_store.js +62 -0
- package/build/src/pat/pat_store.d.ts +31 -0
- package/build/src/pat/pat_store.js +1 -0
- package/build/src/pat/pat_tokens.d.ts +4 -0
- package/build/src/pat/pat_tokens.js +9 -0
- package/build/src/provider/build_provider.d.ts +45 -0
- package/build/src/provider/build_provider.js +219 -0
- package/build/src/provider/device_sources.d.ts +6 -0
- package/build/src/provider/device_sources.js +65 -0
- package/build/src/provider/interaction_actions.d.ts +36 -0
- package/build/src/provider/interaction_actions.js +55 -0
- package/build/src/provider/key_rotation_scheduler.d.ts +28 -0
- package/build/src/provider/key_rotation_scheduler.js +40 -0
- package/build/src/provider/keystore_reload.d.ts +21 -0
- package/build/src/provider/keystore_reload.js +39 -0
- package/build/src/provider/logout_sources.d.ts +13 -0
- package/build/src/provider/logout_sources.js +64 -0
- package/build/src/provider/oidc_service.d.ts +81 -0
- package/build/src/provider/oidc_service.js +254 -0
- package/build/src/provider/single_flight_lock.d.ts +18 -0
- package/build/src/provider/single_flight_lock.js +31 -0
- package/build/src/provider/token_exchange.d.ts +21 -0
- package/build/src/provider/token_exchange.js +124 -0
- package/build/src/register_routes.d.ts +16 -0
- package/build/src/register_routes.js +21 -0
- package/build/src/schema/ensure.d.ts +41 -0
- package/build/src/schema/ensure.js +262 -0
- package/build/stubs/config/authkit.stub +20 -0
- package/build/stubs/config/authkit_react.stub +52 -0
- package/build/stubs/main.d.ts +1 -0
- package/build/stubs/main.js +2 -0
- package/build/stubs/models/auth_user.stub +22 -0
- package/build/stubs/ui/edge/views/consent.edge +13 -0
- package/build/stubs/ui/edge/views/login.edge +19 -0
- package/build/stubs/ui/react/components/auth_shell.tsx +67 -0
- package/build/stubs/ui/react/pages/account/login.tsx +56 -0
- package/build/stubs/ui/react/pages/account/mfa.tsx +132 -0
- package/build/stubs/ui/react/pages/account/tokens.tsx +88 -0
- package/build/stubs/ui/react/pages/consent.tsx +39 -0
- package/build/stubs/ui/react/pages/forgot.tsx +44 -0
- package/build/stubs/ui/react/pages/login.tsx +171 -0
- package/build/stubs/ui/react/pages/mfa-challenge.tsx +72 -0
- package/build/stubs/ui/react/pages/reset.tsx +58 -0
- package/build/stubs/ui/react/pages/signup.tsx +78 -0
- package/build/stubs/ui/react/pages/verify-email.tsx +24 -0
- package/build/types.d.ts +7 -0
- package/build/types.js +1 -0
- package/package.json +147 -0
- package/stubs/config/authkit.stub +20 -0
- package/stubs/config/authkit_react.stub +52 -0
- package/stubs/main.ts +2 -0
- package/stubs/models/auth_user.stub +22 -0
- package/stubs/ui/edge/views/consent.edge +13 -0
- package/stubs/ui/edge/views/login.edge +19 -0
- package/stubs/ui/react/components/auth_shell.tsx +67 -0
- package/stubs/ui/react/pages/account/login.tsx +56 -0
- package/stubs/ui/react/pages/account/mfa.tsx +132 -0
- package/stubs/ui/react/pages/account/tokens.tsx +88 -0
- package/stubs/ui/react/pages/consent.tsx +39 -0
- package/stubs/ui/react/pages/forgot.tsx +44 -0
- package/stubs/ui/react/pages/login.tsx +171 -0
- package/stubs/ui/react/pages/mfa-challenge.tsx +72 -0
- package/stubs/ui/react/pages/reset.tsx +58 -0
- package/stubs/ui/react/pages/signup.tsx +78 -0
- package/stubs/ui/react/pages/verify-email.tsx +24 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { DEFAULT_MESSAGES } from '../i18n.js';
|
|
2
|
+
import { renderEdgeView } from './edge_renderer.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve o catálogo de mensagens ativo a partir do `authkit.server`. Defensivo:
|
|
5
|
+
* sem container/serviço (ex.: teste unitário com ctx mockado), cai no default
|
|
6
|
+
* pt-BR embutido.
|
|
7
|
+
*/
|
|
8
|
+
async function resolveMessagesFromCtx(ctx) {
|
|
9
|
+
try {
|
|
10
|
+
const service = await ctx.containerResolver?.make?.('authkit.server');
|
|
11
|
+
const messages = service?.config?.messages;
|
|
12
|
+
if (messages)
|
|
13
|
+
return messages;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// sem container/serviço — usa o default
|
|
17
|
+
}
|
|
18
|
+
return { ...DEFAULT_MESSAGES };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Renderer do seam para hosts Inertia/React.
|
|
22
|
+
*
|
|
23
|
+
* As páginas React vivem no host em `inertia/pages/<prefix>/<view>`.
|
|
24
|
+
* (O console admin não passa por aqui: é a SPA self-contained da lib,
|
|
25
|
+
* servida pelo shell controller.)
|
|
26
|
+
*
|
|
27
|
+
* Quando `views` é fornecido (allowlist), apenas as views listadas vão ao Inertia;
|
|
28
|
+
* qualquer outra view recai no Edge renderer built-in sem erro.
|
|
29
|
+
*
|
|
30
|
+
* ---
|
|
31
|
+
*
|
|
32
|
+
* ### Props da tela `account/login`
|
|
33
|
+
*
|
|
34
|
+
* | Prop | Tipo | Descrição |
|
|
35
|
+
* |-------------|---------------------|-----------|
|
|
36
|
+
* | `csrfToken` | `string` | Token CSRF para o campo `_csrf` do formulário. |
|
|
37
|
+
* | `returnTo` | `string \| null` | Caminho interno de destino pós-login (já validado pelo servidor — só caminhos internos). Quando presente, o formulário deve incluir `<input type="hidden" name="return_to" value={returnTo} />`. O servidor revalida o valor no POST; hosts com tela custom precisam propagar esse hidden input. |
|
|
38
|
+
* | `error` | `string \| undefined` | Mensagem de erro de autenticação localizada (credenciais inválidas, conta bloqueada, etc.). |
|
|
39
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
40
|
+
*/
|
|
41
|
+
export function inertiaRenderer(opts) {
|
|
42
|
+
const allowed = opts.views ? new Set(opts.views) : null;
|
|
43
|
+
return async (ctx, view, props) => {
|
|
44
|
+
// Allowlist: se `views` foi fornecido e a view não está na lista,
|
|
45
|
+
// usa o fallback Edge silenciosamente (evita SSR crash por página inexistente no host).
|
|
46
|
+
if (allowed !== null && !allowed.has(view)) {
|
|
47
|
+
return renderEdgeView(ctx, view, props);
|
|
48
|
+
}
|
|
49
|
+
// Happy path: view vai ao Inertia.
|
|
50
|
+
// `messages` vai como shared prop para as páginas React traduzirem.
|
|
51
|
+
const messages = await resolveMessagesFromCtx(ctx);
|
|
52
|
+
return ctx.inertia.render(`${opts.prefix}/${view}`, { ...props, messages });
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Settings — mecanismo genérico de configuração persistida em banco.
|
|
3
|
+
*
|
|
4
|
+
* A tabela `auth_settings` é OPCIONAL (capability-probed via SELECT tentativo).
|
|
5
|
+
* Se a tabela não existir, todas as operações retornam null/empty sem erro — os
|
|
6
|
+
* callers devem usar o fallback de config estático. A leitura usa cache em
|
|
7
|
+
* memória com TTL curto (default 15s) para eliminar overhead por request; o
|
|
8
|
+
* método `invalidate()` limpa o cache imediatamente (chamado após escrita).
|
|
9
|
+
*
|
|
10
|
+
* FAIL-SAFE TOTAL: qualquer erro de DB ou de probe → null + caller usa config.
|
|
11
|
+
* Disponibilidade > proteção, consistente com o padrão de bot-protection.
|
|
12
|
+
*
|
|
13
|
+
* PROBE SEARCHPATH-AWARE: o probe usa `SELECT key FROM auth_settings LIMIT 1`
|
|
14
|
+
* em vez de `schema.hasTable`, que ignora o search_path do Postgres. Assim,
|
|
15
|
+
* quando a tabela existe num schema nomeado (ex.: `auth` com searchPath), o
|
|
16
|
+
* probe detecta corretamente.
|
|
17
|
+
*
|
|
18
|
+
* CONEXÃO NOMEADA: quando `options.connection` for fornecido, todas as queries
|
|
19
|
+
* usam `db.connection(name)` em vez da conexão default — necessário quando o
|
|
20
|
+
* auth vive num schema/conexão separados (ex.: host com `auth` connection).
|
|
21
|
+
*
|
|
22
|
+
* ESCOPO DE ORG: settings podem ser globais (organization_id NULL) ou escopadas
|
|
23
|
+
* a uma organização (organization_id = uuid). A resolução efetiva segue a cadeia
|
|
24
|
+
* org → global → null, implementada em `getEffective(key, orgId?)`.
|
|
25
|
+
*
|
|
26
|
+
* Keys org-scopáveis: `organizations_policy`, `roles_catalog`.
|
|
27
|
+
* As demais keys são GLOBAIS (a UI não oferece escopo por org para elas).
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const settings = new RuntimeSettings(db)
|
|
32
|
+
* const raw = await settings.getSetting('bot_protection')
|
|
33
|
+
* // raw é `unknown | null`. Null = tabela ausente ou key inexistente.
|
|
34
|
+
* const botSetting = raw as BotProtectionSetting | null
|
|
35
|
+
*
|
|
36
|
+
* // Resolução org→global→null:
|
|
37
|
+
* const effective = await settings.getEffective('organizations_policy', orgId)
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* Schema esperado da tabela `auth_settings`:
|
|
41
|
+
* ```sql
|
|
42
|
+
* CREATE TABLE auth_settings (
|
|
43
|
+
* key TEXT NOT NULL,
|
|
44
|
+
* organization_id TEXT, -- NULL = global
|
|
45
|
+
* value TEXT NOT NULL, -- JSON
|
|
46
|
+
* updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
47
|
+
* updated_by TEXT, -- nullable accountId do admin
|
|
48
|
+
* UNIQUE (key, organization_id) -- NULL tratado como distinct via UNIQUE NULLS NOT DISTINCT
|
|
49
|
+
* -- ou via unique index parcial (ver migração)
|
|
50
|
+
* );
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
54
|
+
/** Uma entrada da tabela `auth_settings`. */
|
|
55
|
+
export interface SettingRow {
|
|
56
|
+
key: string;
|
|
57
|
+
organizationId: string | null;
|
|
58
|
+
value: unknown;
|
|
59
|
+
updatedAt: Date | string | null;
|
|
60
|
+
updatedBy: string | null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Capacidade de runtime settings. Presente quando a tabela `auth_settings`
|
|
64
|
+
* existe. Use `supportsSettings` para verificar em runtime.
|
|
65
|
+
*/
|
|
66
|
+
export interface SettingsCapability {
|
|
67
|
+
/**
|
|
68
|
+
* Lê uma key no escopo especificado (global se orgId omitido).
|
|
69
|
+
* Retorna null se ausente ou tabela inexistente. Usa cache TTL.
|
|
70
|
+
*/
|
|
71
|
+
getSetting(key: string, orgId?: string | null): Promise<unknown | null>;
|
|
72
|
+
/**
|
|
73
|
+
* Grava (upsert) uma key no escopo especificado.
|
|
74
|
+
* Invalida o cache para essa (key, orgId).
|
|
75
|
+
*/
|
|
76
|
+
setSetting(key: string, value: unknown, updatedBy?: string | null, orgId?: string | null): Promise<void>;
|
|
77
|
+
/** Remove uma key no escopo especificado. Invalida o cache. */
|
|
78
|
+
deleteSetting(key: string, orgId?: string | null): Promise<void>;
|
|
79
|
+
/** Lista settings. Sem orgId = todas; com orgId = apenas escopo da org. */
|
|
80
|
+
listSettings(orgId?: string | null): Promise<SettingRow[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Resolve efetivamente: org-setting → global-setting → null.
|
|
83
|
+
* Sem orgId equivale a getSetting(key) (global apenas).
|
|
84
|
+
*/
|
|
85
|
+
getEffective(key: string, orgId?: string | null): Promise<unknown | null>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Type guard: o objeto (store ou serviço) expõe SettingsCapability?
|
|
89
|
+
*/
|
|
90
|
+
export declare function supportsSettings(obj: unknown): obj is SettingsCapability;
|
|
91
|
+
export interface RuntimeSettingsOptions {
|
|
92
|
+
/** TTL do cache em ms. Default: 15_000 (15s). */
|
|
93
|
+
ttlMs?: number;
|
|
94
|
+
/**
|
|
95
|
+
* Nome da conexão Lucid a usar (ex.: 'auth'). Quando presente, todas as
|
|
96
|
+
* queries usam `db.connection(name)` em vez da conexão default. Necessário
|
|
97
|
+
* quando o schema de auth vive numa conexão nomeada com searchPath próprio.
|
|
98
|
+
* Ausente (ou undefined) → conexão default (back-compat total).
|
|
99
|
+
*/
|
|
100
|
+
connection?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Implementação default do SettingsCapability sobre um `Database` Lucid.
|
|
104
|
+
*
|
|
105
|
+
* Tabela esperada: ver módulo JSDoc acima.
|
|
106
|
+
*/
|
|
107
|
+
export declare class RuntimeSettings implements SettingsCapability {
|
|
108
|
+
private readonly db;
|
|
109
|
+
private readonly ttlMs;
|
|
110
|
+
private readonly connectionName;
|
|
111
|
+
private cache;
|
|
112
|
+
/** null = não foi verificado ainda; false = tabela ausente; true = presente */
|
|
113
|
+
private tablePresent;
|
|
114
|
+
constructor(db: any, opts?: RuntimeSettingsOptions);
|
|
115
|
+
/**
|
|
116
|
+
* Retorna o objeto de conexão Lucid correto.
|
|
117
|
+
* Quando `connectionName` está definido, usa `db.connection(name)`;
|
|
118
|
+
* caso contrário usa o `db` diretamente (conexão default).
|
|
119
|
+
*/
|
|
120
|
+
private conn;
|
|
121
|
+
/**
|
|
122
|
+
* Verifica (e memoriza) se a tabela `auth_settings` existe.
|
|
123
|
+
*
|
|
124
|
+
* Usa `SELECT key FROM auth_settings LIMIT 1` em vez de `schema.hasTable`
|
|
125
|
+
* para ser searchPath-aware: `schema.hasTable` no Postgres ignora o
|
|
126
|
+
* search_path e reporta "ausente" quando a tabela existe apenas no schema
|
|
127
|
+
* configurado via searchPath da conexão. A tentativa de SELECT em try/catch
|
|
128
|
+
* detecta a tabela corretamente independente do schema.
|
|
129
|
+
*
|
|
130
|
+
* Fail-safe: qualquer erro → false (tabela considerada ausente, sem lançar).
|
|
131
|
+
*/
|
|
132
|
+
private hasTable;
|
|
133
|
+
getSetting(key: string, orgId?: string | null): Promise<unknown | null>;
|
|
134
|
+
/**
|
|
135
|
+
* Resolve efetivamente: org-setting → global-setting → null.
|
|
136
|
+
* Se orgId não fornecido, equivale a getSetting(key) (global apenas).
|
|
137
|
+
*/
|
|
138
|
+
getEffective(key: string, orgId?: string | null): Promise<unknown | null>;
|
|
139
|
+
setSetting(key: string, value: unknown, updatedBy?: string | null, orgId?: string | null): Promise<void>;
|
|
140
|
+
deleteSetting(key: string, orgId?: string | null): Promise<void>;
|
|
141
|
+
listSettings(orgId?: string | null): Promise<SettingRow[]>;
|
|
142
|
+
/**
|
|
143
|
+
* Verifica se a tabela `auth_settings` está presente (mesmo resultado de
|
|
144
|
+
* `hasTable()` privado, mas exposto para casos de diagnóstico como a UI admin).
|
|
145
|
+
*/
|
|
146
|
+
isTablePresent(): Promise<boolean>;
|
|
147
|
+
/**
|
|
148
|
+
* Invalida o cache em memória. Sem argumento: limpa tudo.
|
|
149
|
+
* Chamado AUTOMATICAMENTE após setSetting/deleteSetting.
|
|
150
|
+
* Chame externamente após writes que contornam este serviço.
|
|
151
|
+
*/
|
|
152
|
+
invalidate(key?: string, orgId?: string | null): void;
|
|
153
|
+
private _cache;
|
|
154
|
+
private _parse;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Fábrica canônica de {@link RuntimeSettings} a partir de um `HttpContext`.
|
|
158
|
+
*
|
|
159
|
+
* Resolve o `lucid.db` e o `authkit.server` do container, deriva a conexão
|
|
160
|
+
* nomeada do `accountStore` (para que o probe da tabela `auth_settings` seja
|
|
161
|
+
* searchPath-aware quando o auth vive numa conexão/schema próprios) e monta o
|
|
162
|
+
* `RuntimeSettings`.
|
|
163
|
+
*
|
|
164
|
+
* FAIL-SAFE → null: qualquer erro de resolução (DB ausente, serviço não
|
|
165
|
+
* registrado, etc.) retorna `null` em vez de lançar. Os callers usam o `null`
|
|
166
|
+
* tanto como sinal de "settings runtime indisponíveis" (caem no config estático)
|
|
167
|
+
* quanto, em alguns endpoints, como sinal de `capability_unsupported` (404) — a
|
|
168
|
+
* semântica do `!rs`/`!svc` de cada caller é preservada.
|
|
169
|
+
*
|
|
170
|
+
* Esta fábrica SUBSTITUI ~16 cópias do mesmo bloco db/connection que viviam sob
|
|
171
|
+
* nomes distintos (`getRuntimeSettings`, `getSettingsService`,
|
|
172
|
+
* `getRuntimeSettingsForSudo`) e elimina o cast `as any` (via `connectionName`
|
|
173
|
+
* tipado em {@link AccountStore}).
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* const rs = await resolveRuntimeSettings(ctx)
|
|
178
|
+
* if (!rs) return response.notFound({ error: 'capability_unsupported' })
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export declare function resolveRuntimeSettings(ctx: HttpContext): Promise<RuntimeSettings | null>;
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Settings — mecanismo genérico de configuração persistida em banco.
|
|
3
|
+
*
|
|
4
|
+
* A tabela `auth_settings` é OPCIONAL (capability-probed via SELECT tentativo).
|
|
5
|
+
* Se a tabela não existir, todas as operações retornam null/empty sem erro — os
|
|
6
|
+
* callers devem usar o fallback de config estático. A leitura usa cache em
|
|
7
|
+
* memória com TTL curto (default 15s) para eliminar overhead por request; o
|
|
8
|
+
* método `invalidate()` limpa o cache imediatamente (chamado após escrita).
|
|
9
|
+
*
|
|
10
|
+
* FAIL-SAFE TOTAL: qualquer erro de DB ou de probe → null + caller usa config.
|
|
11
|
+
* Disponibilidade > proteção, consistente com o padrão de bot-protection.
|
|
12
|
+
*
|
|
13
|
+
* PROBE SEARCHPATH-AWARE: o probe usa `SELECT key FROM auth_settings LIMIT 1`
|
|
14
|
+
* em vez de `schema.hasTable`, que ignora o search_path do Postgres. Assim,
|
|
15
|
+
* quando a tabela existe num schema nomeado (ex.: `auth` com searchPath), o
|
|
16
|
+
* probe detecta corretamente.
|
|
17
|
+
*
|
|
18
|
+
* CONEXÃO NOMEADA: quando `options.connection` for fornecido, todas as queries
|
|
19
|
+
* usam `db.connection(name)` em vez da conexão default — necessário quando o
|
|
20
|
+
* auth vive num schema/conexão separados (ex.: host com `auth` connection).
|
|
21
|
+
*
|
|
22
|
+
* ESCOPO DE ORG: settings podem ser globais (organization_id NULL) ou escopadas
|
|
23
|
+
* a uma organização (organization_id = uuid). A resolução efetiva segue a cadeia
|
|
24
|
+
* org → global → null, implementada em `getEffective(key, orgId?)`.
|
|
25
|
+
*
|
|
26
|
+
* Keys org-scopáveis: `organizations_policy`, `roles_catalog`.
|
|
27
|
+
* As demais keys são GLOBAIS (a UI não oferece escopo por org para elas).
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const settings = new RuntimeSettings(db)
|
|
32
|
+
* const raw = await settings.getSetting('bot_protection')
|
|
33
|
+
* // raw é `unknown | null`. Null = tabela ausente ou key inexistente.
|
|
34
|
+
* const botSetting = raw as BotProtectionSetting | null
|
|
35
|
+
*
|
|
36
|
+
* // Resolução org→global→null:
|
|
37
|
+
* const effective = await settings.getEffective('organizations_policy', orgId)
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* Schema esperado da tabela `auth_settings`:
|
|
41
|
+
* ```sql
|
|
42
|
+
* CREATE TABLE auth_settings (
|
|
43
|
+
* key TEXT NOT NULL,
|
|
44
|
+
* organization_id TEXT, -- NULL = global
|
|
45
|
+
* value TEXT NOT NULL, -- JSON
|
|
46
|
+
* updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
47
|
+
* updated_by TEXT, -- nullable accountId do admin
|
|
48
|
+
* UNIQUE (key, organization_id) -- NULL tratado como distinct via UNIQUE NULLS NOT DISTINCT
|
|
49
|
+
* -- ou via unique index parcial (ver migração)
|
|
50
|
+
* );
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
import { isSettingLocked, SettingLockedError } from './config_locks.js';
|
|
54
|
+
/**
|
|
55
|
+
* Type guard: o objeto (store ou serviço) expõe SettingsCapability?
|
|
56
|
+
*/
|
|
57
|
+
export function supportsSettings(obj) {
|
|
58
|
+
return !!obj && typeof obj.getSetting === 'function';
|
|
59
|
+
}
|
|
60
|
+
/** Chave de cache: combina key + escopo de org (null = global). */
|
|
61
|
+
function cacheKey(key, orgId) {
|
|
62
|
+
return orgId ? `${key}\x00${orgId}` : key;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Implementação default do SettingsCapability sobre um `Database` Lucid.
|
|
66
|
+
*
|
|
67
|
+
* Tabela esperada: ver módulo JSDoc acima.
|
|
68
|
+
*/
|
|
69
|
+
export class RuntimeSettings {
|
|
70
|
+
db;
|
|
71
|
+
ttlMs;
|
|
72
|
+
connectionName;
|
|
73
|
+
cache = new Map();
|
|
74
|
+
/** null = não foi verificado ainda; false = tabela ausente; true = presente */
|
|
75
|
+
tablePresent = null;
|
|
76
|
+
constructor(db, opts = {}) {
|
|
77
|
+
this.db = db;
|
|
78
|
+
this.ttlMs = opts.ttlMs ?? 15_000;
|
|
79
|
+
this.connectionName = opts.connection;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Retorna o objeto de conexão Lucid correto.
|
|
83
|
+
* Quando `connectionName` está definido, usa `db.connection(name)`;
|
|
84
|
+
* caso contrário usa o `db` diretamente (conexão default).
|
|
85
|
+
*/
|
|
86
|
+
conn() {
|
|
87
|
+
return this.connectionName ? this.db.connection(this.connectionName) : this.db;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Verifica (e memoriza) se a tabela `auth_settings` existe.
|
|
91
|
+
*
|
|
92
|
+
* Usa `SELECT key FROM auth_settings LIMIT 1` em vez de `schema.hasTable`
|
|
93
|
+
* para ser searchPath-aware: `schema.hasTable` no Postgres ignora o
|
|
94
|
+
* search_path e reporta "ausente" quando a tabela existe apenas no schema
|
|
95
|
+
* configurado via searchPath da conexão. A tentativa de SELECT em try/catch
|
|
96
|
+
* detecta a tabela corretamente independente do schema.
|
|
97
|
+
*
|
|
98
|
+
* Fail-safe: qualquer erro → false (tabela considerada ausente, sem lançar).
|
|
99
|
+
*/
|
|
100
|
+
async hasTable() {
|
|
101
|
+
if (this.tablePresent !== null)
|
|
102
|
+
return this.tablePresent;
|
|
103
|
+
try {
|
|
104
|
+
await this.conn().from('auth_settings').select('key').limit(1);
|
|
105
|
+
this.tablePresent = true;
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
this.tablePresent = false;
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async getSetting(key, orgId) {
|
|
114
|
+
// Travada por defineConfig → comporta-se como ausente, então os resolvers caem
|
|
115
|
+
// no configDefault (= o valor do config). Config vence; a UI não pode sobrescrever.
|
|
116
|
+
if (isSettingLocked(key))
|
|
117
|
+
return null;
|
|
118
|
+
const ck = cacheKey(key, orgId ?? null);
|
|
119
|
+
// Cache hit?
|
|
120
|
+
const cached = this.cache.get(ck);
|
|
121
|
+
if (cached && cached.expiresAt > Date.now())
|
|
122
|
+
return cached.value;
|
|
123
|
+
if (!(await this.hasTable())) {
|
|
124
|
+
this._cache(ck, null);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
let q = this.conn().from('auth_settings').where('key', key);
|
|
129
|
+
if (orgId) {
|
|
130
|
+
q = q.where('organization_id', orgId);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
q = q.whereNull('organization_id');
|
|
134
|
+
}
|
|
135
|
+
const row = await q.first();
|
|
136
|
+
const value = row ? this._parse(row.value) : null;
|
|
137
|
+
this._cache(ck, value);
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// FAIL-SAFE: erro de DB → null, caller usa config estático.
|
|
142
|
+
this._cache(ck, null);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Resolve efetivamente: org-setting → global-setting → null.
|
|
148
|
+
* Se orgId não fornecido, equivale a getSetting(key) (global apenas).
|
|
149
|
+
*/
|
|
150
|
+
async getEffective(key, orgId) {
|
|
151
|
+
if (orgId) {
|
|
152
|
+
const orgValue = await this.getSetting(key, orgId);
|
|
153
|
+
if (orgValue !== null)
|
|
154
|
+
return orgValue;
|
|
155
|
+
}
|
|
156
|
+
return this.getSetting(key, null);
|
|
157
|
+
}
|
|
158
|
+
async setSetting(key, value, updatedBy = null, orgId) {
|
|
159
|
+
// Travada por defineConfig → recusa a escrita (write path da Admin API/console mapeia p/ 423).
|
|
160
|
+
if (isSettingLocked(key))
|
|
161
|
+
throw new SettingLockedError(key);
|
|
162
|
+
if (!(await this.hasTable()))
|
|
163
|
+
return;
|
|
164
|
+
const json = JSON.stringify(value);
|
|
165
|
+
const resolvedOrgId = orgId ?? null;
|
|
166
|
+
try {
|
|
167
|
+
// Delete first then insert = upsert (compatível com sqlite + pg sem UPSERT syntax).
|
|
168
|
+
let q = this.conn().from('auth_settings').where('key', key);
|
|
169
|
+
if (resolvedOrgId) {
|
|
170
|
+
q = q.where('organization_id', resolvedOrgId);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
q = q.whereNull('organization_id');
|
|
174
|
+
}
|
|
175
|
+
await q.delete();
|
|
176
|
+
await this.conn().table('auth_settings').insert({
|
|
177
|
+
key,
|
|
178
|
+
organization_id: resolvedOrgId,
|
|
179
|
+
value: json,
|
|
180
|
+
updated_at: new Date(),
|
|
181
|
+
updated_by: updatedBy,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// Fail-safe: não lança.
|
|
186
|
+
}
|
|
187
|
+
this.invalidate(key, resolvedOrgId);
|
|
188
|
+
}
|
|
189
|
+
async deleteSetting(key, orgId) {
|
|
190
|
+
if (isSettingLocked(key))
|
|
191
|
+
throw new SettingLockedError(key);
|
|
192
|
+
if (!(await this.hasTable()))
|
|
193
|
+
return;
|
|
194
|
+
const resolvedOrgId = orgId ?? null;
|
|
195
|
+
try {
|
|
196
|
+
let q = this.conn().from('auth_settings').where('key', key);
|
|
197
|
+
if (resolvedOrgId) {
|
|
198
|
+
q = q.where('organization_id', resolvedOrgId);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
q = q.whereNull('organization_id');
|
|
202
|
+
}
|
|
203
|
+
await q.delete();
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// Fail-safe.
|
|
207
|
+
}
|
|
208
|
+
this.invalidate(key, resolvedOrgId);
|
|
209
|
+
}
|
|
210
|
+
async listSettings(orgId) {
|
|
211
|
+
if (!(await this.hasTable()))
|
|
212
|
+
return [];
|
|
213
|
+
try {
|
|
214
|
+
let q = this.conn().from('auth_settings').select('*');
|
|
215
|
+
if (orgId !== undefined) {
|
|
216
|
+
// orgId fornecido: filtra pelo escopo
|
|
217
|
+
if (orgId) {
|
|
218
|
+
q = q.where('organization_id', orgId);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
q = q.whereNull('organization_id');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// orgId undefined = lista tudo (global + todos os orgs)
|
|
225
|
+
const rows = await q;
|
|
226
|
+
return rows.map((r) => ({
|
|
227
|
+
key: r.key,
|
|
228
|
+
organizationId: r.organization_id ?? null,
|
|
229
|
+
value: this._parse(r.value),
|
|
230
|
+
updatedAt: r.updated_at ?? null,
|
|
231
|
+
updatedBy: r.updated_by ?? null,
|
|
232
|
+
}));
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Verifica se a tabela `auth_settings` está presente (mesmo resultado de
|
|
240
|
+
* `hasTable()` privado, mas exposto para casos de diagnóstico como a UI admin).
|
|
241
|
+
*/
|
|
242
|
+
async isTablePresent() {
|
|
243
|
+
return this.hasTable();
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Invalida o cache em memória. Sem argumento: limpa tudo.
|
|
247
|
+
* Chamado AUTOMATICAMENTE após setSetting/deleteSetting.
|
|
248
|
+
* Chame externamente após writes que contornam este serviço.
|
|
249
|
+
*/
|
|
250
|
+
invalidate(key, orgId) {
|
|
251
|
+
if (key !== undefined) {
|
|
252
|
+
this.cache.delete(cacheKey(key, orgId ?? null));
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.cache.clear();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
_cache(key, value) {
|
|
259
|
+
this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs });
|
|
260
|
+
}
|
|
261
|
+
_parse(raw) {
|
|
262
|
+
if (!raw)
|
|
263
|
+
return null;
|
|
264
|
+
try {
|
|
265
|
+
return JSON.parse(raw);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Fábrica canônica de {@link RuntimeSettings} a partir de um `HttpContext`.
|
|
274
|
+
*
|
|
275
|
+
* Resolve o `lucid.db` e o `authkit.server` do container, deriva a conexão
|
|
276
|
+
* nomeada do `accountStore` (para que o probe da tabela `auth_settings` seja
|
|
277
|
+
* searchPath-aware quando o auth vive numa conexão/schema próprios) e monta o
|
|
278
|
+
* `RuntimeSettings`.
|
|
279
|
+
*
|
|
280
|
+
* FAIL-SAFE → null: qualquer erro de resolução (DB ausente, serviço não
|
|
281
|
+
* registrado, etc.) retorna `null` em vez de lançar. Os callers usam o `null`
|
|
282
|
+
* tanto como sinal de "settings runtime indisponíveis" (caem no config estático)
|
|
283
|
+
* quanto, em alguns endpoints, como sinal de `capability_unsupported` (404) — a
|
|
284
|
+
* semântica do `!rs`/`!svc` de cada caller é preservada.
|
|
285
|
+
*
|
|
286
|
+
* Esta fábrica SUBSTITUI ~16 cópias do mesmo bloco db/connection que viviam sob
|
|
287
|
+
* nomes distintos (`getRuntimeSettings`, `getSettingsService`,
|
|
288
|
+
* `getRuntimeSettingsForSudo`) e elimina o cast `as any` (via `connectionName`
|
|
289
|
+
* tipado em {@link AccountStore}).
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```ts
|
|
293
|
+
* const rs = await resolveRuntimeSettings(ctx)
|
|
294
|
+
* if (!rs) return response.notFound({ error: 'capability_unsupported' })
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
export async function resolveRuntimeSettings(ctx) {
|
|
298
|
+
try {
|
|
299
|
+
const db = await ctx.containerResolver.make('lucid.db');
|
|
300
|
+
const service = await ctx.containerResolver.make('authkit.server').catch(() => null);
|
|
301
|
+
const connection = service?.config?.accountStore?.connectionName;
|
|
302
|
+
return new RuntimeSettings(db, connection ? { connection } : {});
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
}
|