@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,466 @@
|
|
|
1
|
+
import { resolveRateLimit } from '../define_config.js';
|
|
2
|
+
import { createAuthThrottles } from './rate_limit.js';
|
|
3
|
+
import { ACCOUNT_SESSION_KEY } from './middleware/account_auth.js';
|
|
4
|
+
import { accountHome } from './account_home.js';
|
|
5
|
+
import { adminApiGuard } from './admin_api/admin_api_guard.js';
|
|
6
|
+
import { setAdminPrefix, normalizeAdminPrefix, setAdminApiPrefix, normalizeAdminApiPrefix, } from './admin_prefix.js';
|
|
7
|
+
import { resolveRuntimeSettings } from './runtime_settings.js';
|
|
8
|
+
import { resolveEffectiveSessionPolicy } from './runtime_toggles.js';
|
|
9
|
+
import { getAuthHostConfig } from './auth_host_config.js';
|
|
10
|
+
/** Chave da sessão Adonis que registra o timestamp da última atividade (idle timeout). */
|
|
11
|
+
export const ACCOUNT_LAST_SEEN_KEY = 'authkit_last_seen';
|
|
12
|
+
/**
|
|
13
|
+
* Verifica o idle timeout da sessão do console de conta. Lê `idleTimeoutMinutes`
|
|
14
|
+
* da setting `session_policy` (runtime, fail-safe). Se a sessão excedeu o idle,
|
|
15
|
+
* apaga a sessão e retorna true (caller deve redirecionar ao login).
|
|
16
|
+
*
|
|
17
|
+
* Sempre atualiza `authkit_last_seen` quando o idle não foi excedido.
|
|
18
|
+
*
|
|
19
|
+
* FAIL-SAFE: qualquer erro → nunca encerra a sessão (disponibilidade > segurança).
|
|
20
|
+
*/
|
|
21
|
+
async function checkAndRefreshIdle(ctx) {
|
|
22
|
+
try {
|
|
23
|
+
// Fábrica canônica (searchPath-aware via a conexão do accountStore). Null =
|
|
24
|
+
// container/DB indisponível → fail-safe: nunca encerra a sessão.
|
|
25
|
+
const runtimeSettings = await resolveRuntimeSettings(ctx);
|
|
26
|
+
if (!runtimeSettings)
|
|
27
|
+
return false;
|
|
28
|
+
const policy = await resolveEffectiveSessionPolicy(runtimeSettings);
|
|
29
|
+
const idleMs = policy.idleTimeoutMinutes * 60 * 1000;
|
|
30
|
+
if (idleMs <= 0)
|
|
31
|
+
return false; // idle desligado
|
|
32
|
+
const lastSeen = ctx.session?.get(ACCOUNT_LAST_SEEN_KEY);
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
if (lastSeen !== undefined && now - lastSeen > idleMs) {
|
|
35
|
+
// Idle excedido: encerra a sessão.
|
|
36
|
+
ctx.session?.forget(ACCOUNT_SESSION_KEY);
|
|
37
|
+
ctx.session?.forget(ACCOUNT_LAST_SEEN_KEY);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
// Atualiza o timestamp de última atividade.
|
|
41
|
+
ctx.session?.put(ACCOUNT_LAST_SEEN_KEY, now);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// FAIL-SAFE: nunca encerra a sessão em caso de erro.
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Constrói a URL de redirect para o login da conta, preservando o destino
|
|
51
|
+
* original como `return_to` (URL-encoded). A URL de destino é o path + query
|
|
52
|
+
* string da requisição atual (nunca o host — proteção contra open-redirect).
|
|
53
|
+
*
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
function buildLoginRedirect(ctx, extra) {
|
|
57
|
+
const url = ctx.request?.url?.() ?? '';
|
|
58
|
+
const qs = ctx.request?.parsedUrl?.search ?? '';
|
|
59
|
+
const dest = qs ? `${url}${qs}` : url;
|
|
60
|
+
// Só inclui return_to quando há um caminho real (não vazio, não é o próprio login).
|
|
61
|
+
if (dest && dest !== '/' && !dest.startsWith('/account/login')) {
|
|
62
|
+
const encoded = encodeURIComponent(dest);
|
|
63
|
+
const base = extra ? `/account/login?${extra}&return_to=${encoded}` : `/account/login?return_to=${encoded}`;
|
|
64
|
+
return base;
|
|
65
|
+
}
|
|
66
|
+
return extra ? `/account/login?${extra}` : '/account/login';
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Guard inline do console de conta. Usamos uma closure (forma confiável do
|
|
70
|
+
* `.use()` do AdonisJS) em vez de `() => import(middleware)` — a forma lazy de
|
|
71
|
+
* classe NÃO era aplicada em runtime num grupo, deixando /account/tokens e
|
|
72
|
+
* /account/mfa acessíveis sem sessão.
|
|
73
|
+
*/
|
|
74
|
+
const accountGuard = async (ctx, next) => {
|
|
75
|
+
if (!ctx.session?.get(ACCOUNT_SESSION_KEY)) {
|
|
76
|
+
return ctx.response.redirect(buildLoginRedirect(ctx));
|
|
77
|
+
}
|
|
78
|
+
// Idle timeout: encerra e redireciona com query param de motivo.
|
|
79
|
+
const idleExpired = await checkAndRefreshIdle(ctx);
|
|
80
|
+
if (idleExpired) {
|
|
81
|
+
return ctx.response.redirect(buildLoginRedirect(ctx, 'reason=idle'));
|
|
82
|
+
}
|
|
83
|
+
return next();
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Guard do console admin (B6). Como o `accountGuard`, é uma closure inline (forma
|
|
87
|
+
* confiável do `.use()` num grupo). Exige:
|
|
88
|
+
* 0. `config.admin.enabled` ligado (senão → 404; ver nota de flag-drift abaixo);
|
|
89
|
+
* 1. sessão de conta ativa (senão → /account/login);
|
|
90
|
+
* 2. a conta logada com pelo menos UMA das `config.admin.roles` nas roles globais
|
|
91
|
+
* (senão → /account/tokens, evitando vazar a existência do /admin).
|
|
92
|
+
* As roles permitidas são resolvidas em runtime do `authkit.server` (config lazy).
|
|
93
|
+
*/
|
|
94
|
+
export const adminGuard = async (ctx, next) => {
|
|
95
|
+
const service = await ctx.containerResolver.make('authkit.server');
|
|
96
|
+
const cfg = service.config;
|
|
97
|
+
// Defesa contra flag-drift: as rotas são montadas com `admin: true` em tempo de
|
|
98
|
+
// registro, ANTES de o config resolver. Se o config tiver `admin.enabled: false`,
|
|
99
|
+
// as rotas existem mas o console deve estar desligado — 404 (não vaza a existência).
|
|
100
|
+
if (!cfg.admin.enabled) {
|
|
101
|
+
return ctx.response.notFound();
|
|
102
|
+
}
|
|
103
|
+
const accountId = ctx.session?.get(ACCOUNT_SESSION_KEY);
|
|
104
|
+
if (!accountId) {
|
|
105
|
+
// `/account/login` é sempre o login da conta — NÃO muda com o prefixo admin.
|
|
106
|
+
return ctx.response.redirect(buildLoginRedirect(ctx));
|
|
107
|
+
}
|
|
108
|
+
// Idle timeout: também protege o console admin.
|
|
109
|
+
const idleExpired = await checkAndRefreshIdle(ctx);
|
|
110
|
+
if (idleExpired) {
|
|
111
|
+
return ctx.response.redirect(buildLoginRedirect(ctx, 'reason=idle'));
|
|
112
|
+
}
|
|
113
|
+
const allowed = cfg.admin.roles;
|
|
114
|
+
const account = await cfg.accountStore.findById(accountId);
|
|
115
|
+
const roles = account?.globalRoles ?? [];
|
|
116
|
+
const isAdmin = roles.some((r) => allowed.includes(r));
|
|
117
|
+
if (!isAdmin) {
|
|
118
|
+
// Evita vazar a existência do console admin: redireciona para o accountHome
|
|
119
|
+
// (sem mostrar a URL do admin).
|
|
120
|
+
return ctx.response.redirect(accountHome(cfg));
|
|
121
|
+
}
|
|
122
|
+
return next();
|
|
123
|
+
};
|
|
124
|
+
const C = {
|
|
125
|
+
oidc: () => import('../controllers/oidc_callback_controller.js'),
|
|
126
|
+
interaction: () => import('./controllers/interaction_controller.js'),
|
|
127
|
+
registration: () => import('./controllers/registration_controller.js'),
|
|
128
|
+
social: () => import('./controllers/social_controller.js'),
|
|
129
|
+
patIntrospection: () => import('./controllers/pat_introspection_controller.js'),
|
|
130
|
+
accountSession: () => import('./controllers/account_session_controller.js'),
|
|
131
|
+
accountTokens: () => import('./controllers/account_tokens_controller.js'),
|
|
132
|
+
accountSecurity: () => import('./controllers/account_security_controller.js'),
|
|
133
|
+
accountApps: () => import('./controllers/account_apps_controller.js'),
|
|
134
|
+
accountMfa: () => import('./controllers/account_mfa_controller.js'),
|
|
135
|
+
accountOrgs: () => import('./controllers/account_orgs_controller.js'),
|
|
136
|
+
accountConfirm: () => import('./controllers/account_confirm_controller.js'),
|
|
137
|
+
// Console React JSON API (session-authed, under {prefix}/api/*).
|
|
138
|
+
consoleShell: () => import('./admin_console/admin_shell_controller.js'),
|
|
139
|
+
consoleOverview: () => import('./admin_console/console_overview_controller.js'),
|
|
140
|
+
consoleUsers: () => import('./admin_console/console_users_controller.js'),
|
|
141
|
+
consoleSessions: () => import('./admin_console/console_sessions_controller.js'),
|
|
142
|
+
consoleClients: () => import('./admin_console/console_clients_controller.js'),
|
|
143
|
+
consoleRoles: () => import('./admin_console/console_roles_controller.js'),
|
|
144
|
+
consoleOrgs: () => import('./admin_console/console_orgs_controller.js'),
|
|
145
|
+
consoleAudit: () => import('./admin_console/console_audit_controller.js'),
|
|
146
|
+
consoleSettings: () => import('./admin_console/console_settings_controller.js'),
|
|
147
|
+
consoleKeys: () => import('./admin_console/console_keys_controller.js'),
|
|
148
|
+
consoleImpersonation: () => import('./admin_console/console_impersonation_controller.js'),
|
|
149
|
+
apiUsers: () => import('./admin_api/api_users_controller.js'),
|
|
150
|
+
apiClients: () => import('./admin_api/api_clients_controller.js'),
|
|
151
|
+
apiMisc: () => import('./admin_api/api_misc_controller.js'),
|
|
152
|
+
apiOrgs: () => import('./admin_api/api_orgs_controller.js'),
|
|
153
|
+
apiSettings: () => import('./admin_api/api_settings_controller.js'),
|
|
154
|
+
apiKeys: () => import('./admin_api/api_keys_controller.js'),
|
|
155
|
+
// Account self-service JSON API (session-authed, under /account/api/*).
|
|
156
|
+
accountApi: () => import('./account_api/account_api_controller.js'),
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Monta todas as rotas do host-kit do Authorization Server numa chamada.
|
|
160
|
+
* Substitui registerOidcRoutes + o hand-wiring do start/routes.ts do host.
|
|
161
|
+
*/
|
|
162
|
+
export function registerAuthHost(router, opts = {}) {
|
|
163
|
+
// Config resolvido (stashado no boot do provider) — fonte única; `opts` só faz
|
|
164
|
+
// OVERRIDE. Elimina o drift: o consumidor pode chamar `registerAuthHost(router)`
|
|
165
|
+
// e mountPath/social/rateLimit/admin/adminApi vêm do config/authkit.ts.
|
|
166
|
+
// Fallback p/ defaults quando o stash não está disponível (ex.: testes sem boot).
|
|
167
|
+
const hostCfg = getAuthHostConfig();
|
|
168
|
+
const mount = opts.mountPath ?? hostCfg?.mountPath ?? '/oidc';
|
|
169
|
+
// social: opt explícito > config. admin/adminApi: opt explícito > (config.enabled → monta).
|
|
170
|
+
const social = opts.social ?? hostCfg?.social;
|
|
171
|
+
const adminOpt = opts.admin ?? (hostCfg?.adminEnabled ? true : undefined);
|
|
172
|
+
const adminApiOpt = opts.adminApi ?? (hostCfg?.adminApiEnabled ? true : undefined);
|
|
173
|
+
// Throttles opt-in (anti-brute-force). `undefined` quando rate-limit desligado.
|
|
174
|
+
const resolvedRateLimit = opts.rateLimit !== undefined
|
|
175
|
+
? resolveRateLimit(opts.rateLimit)
|
|
176
|
+
: (hostCfg?.rateLimit ?? resolveRateLimit(undefined));
|
|
177
|
+
const throttles = createAuthThrottles(resolvedRateLimit);
|
|
178
|
+
// Helpers: aplicam o middleware de throttle quando presente; senão no-op.
|
|
179
|
+
const withLogin = (route) => {
|
|
180
|
+
if (throttles)
|
|
181
|
+
route.use([throttles.login]);
|
|
182
|
+
};
|
|
183
|
+
const withIntrospection = (route) => {
|
|
184
|
+
if (throttles)
|
|
185
|
+
route.use([throttles.introspection]);
|
|
186
|
+
};
|
|
187
|
+
// Provider OIDC (wildcard + root) — o que registerOidcRoutes fazia.
|
|
188
|
+
router.any(`${mount}/*`, [C.oidc]).as('authkit.oidc.wildcard');
|
|
189
|
+
router.any(mount, [C.oidc]).as('authkit.oidc.root');
|
|
190
|
+
// Interaction (login multi-step + consent + signup).
|
|
191
|
+
router.get('/auth/interaction/:uid', [C.interaction, 'show']);
|
|
192
|
+
router.post('/auth/interaction/:uid/identifier', [C.interaction, 'identifier']);
|
|
193
|
+
withLogin(router.post('/auth/interaction/:uid/login', [C.interaction, 'login']));
|
|
194
|
+
withLogin(router.post('/auth/interaction/:uid/mfa', [C.interaction, 'mfaVerify']));
|
|
195
|
+
// Troca de senha obrigatória quando a senha expirou (password expiration gate).
|
|
196
|
+
withLogin(router.post('/auth/interaction/:uid/password-expired', [C.interaction, 'changeExpiredPassword']));
|
|
197
|
+
// Passkey como 2º fator alternativo no login (begin/finish; challenge na sessão).
|
|
198
|
+
router.post('/auth/interaction/:uid/passkey/options', [C.interaction, 'passkeyOptions']);
|
|
199
|
+
withLogin(router.post('/auth/interaction/:uid/passkey/verify', [C.interaction, 'passkeyVerify']));
|
|
200
|
+
// Magic link (passwordless): POST emite (throttled), GET consome o token do link.
|
|
201
|
+
withLogin(router.post('/auth/interaction/:uid/magic', [C.interaction, 'magicLinkRequest']));
|
|
202
|
+
router.get('/auth/interaction/:uid/magic', [C.interaction, 'magicLinkConsume']);
|
|
203
|
+
router.post('/auth/interaction/:uid/consent', [C.interaction, 'consent']);
|
|
204
|
+
router.get('/auth/interaction/:uid/switch', [C.interaction, 'switchIdentifier']);
|
|
205
|
+
// OTP unlock: link enviado por e-mail quando o fator TOTP/recovery é travado.
|
|
206
|
+
router.get('/auth/otp-unlock/:token', [C.interaction, 'otpUnlock']);
|
|
207
|
+
router.get('/auth/interaction/:uid/signup', [C.registration, 'showSignup']);
|
|
208
|
+
withLogin(router.post('/auth/interaction/:uid/signup', [C.registration, 'signup']));
|
|
209
|
+
// Recuperação de senha (standalone).
|
|
210
|
+
router.get('/auth/forgot-password', [C.registration, 'showForgot']);
|
|
211
|
+
withLogin(router.post('/auth/forgot-password', [C.registration, 'forgot']));
|
|
212
|
+
router.get('/auth/reset-password', [C.registration, 'showReset']);
|
|
213
|
+
withLogin(router.post('/auth/reset-password', [C.registration, 'reset']));
|
|
214
|
+
// Verificação de e-mail (standalone, GET-only — consome o token do link).
|
|
215
|
+
router.get('/auth/verify-email', [C.registration, 'verifyEmail']);
|
|
216
|
+
// Login social (opt-in — do config ou opts).
|
|
217
|
+
if (social) {
|
|
218
|
+
router.get('/auth/:provider/redirect/:uid', [C.social, 'redirect']);
|
|
219
|
+
router.get('/auth/:provider/callback', [C.social, 'callback']);
|
|
220
|
+
}
|
|
221
|
+
// PAT introspection (server-to-server).
|
|
222
|
+
withIntrospection(router.post('/authkit/pat/introspect', [C.patIntrospection, 'handle']));
|
|
223
|
+
// Organizations — invitation accept (sem guard: controller lida com não-autenticado).
|
|
224
|
+
router.get('/account/orgs/invitations/:token/accept', [C.accountOrgs, 'showAcceptInvitation']);
|
|
225
|
+
router.post('/account/orgs/invitations/:token/accept', [C.accountOrgs, 'acceptInvitation']);
|
|
226
|
+
// Console de conta (login de sessão do IdP + gerência de PAT).
|
|
227
|
+
router.get('/account/login', [C.accountSession, 'show']);
|
|
228
|
+
// L6: throttle por IP no login/logout do console de conta (anti-brute-force),
|
|
229
|
+
// alinhado com as demais rotas de credencial (interaction, forgot, reset).
|
|
230
|
+
withLogin(router.post('/account/login', [C.accountSession, 'login']));
|
|
231
|
+
withLogin(router.post('/account/logout', [C.accountSession, 'logout']));
|
|
232
|
+
// Confirmação de troca de e-mail (standalone, GET-only — consome o token do link;
|
|
233
|
+
// pode ser aberta em outro dispositivo, então NÃO exige sessão).
|
|
234
|
+
router.get('/account/email/confirm', [C.accountSecurity, 'confirmEmail']);
|
|
235
|
+
// Rotas de tokens protegidas por AccountAuthMiddleware (redireciona para /account/login se não autenticado).
|
|
236
|
+
router
|
|
237
|
+
.group(() => {
|
|
238
|
+
router.get('/account/tokens', [C.accountTokens, 'index']);
|
|
239
|
+
router.post('/account/tokens', [C.accountTokens, 'store']);
|
|
240
|
+
router.post('/account/tokens/:id/revoke', [C.accountTokens, 'destroy']);
|
|
241
|
+
// Segurança da conta: trocar senha + solicitar troca de e-mail + perfil.
|
|
242
|
+
router.get('/account/security', [C.accountSecurity, 'index']);
|
|
243
|
+
router.post('/account/security/password', [C.accountSecurity, 'changePassword']);
|
|
244
|
+
router.post('/account/security/email', [C.accountSecurity, 'changeEmail']);
|
|
245
|
+
router.post('/account/security/email/cancel', [C.accountSecurity, 'cancelEmailChange']);
|
|
246
|
+
router.post('/account/security/profile', [C.accountSecurity, 'updateProfile']);
|
|
247
|
+
// LGPD/GDPR: export de dados (portabilidade) + deleção self-service (danger zone).
|
|
248
|
+
// O export carrega o throttle de login (anti-abuso) quando o rate-limit existe.
|
|
249
|
+
withLogin(router.get('/account/security/export', [C.accountSecurity, 'exportData']));
|
|
250
|
+
router.post('/account/security/delete', [C.accountSecurity, 'deleteAccount']);
|
|
251
|
+
// Trusted devices: limpa o cookie de confiança DESTE navegador.
|
|
252
|
+
router.post('/account/security/trusted-devices/revoke', [
|
|
253
|
+
C.accountSecurity,
|
|
254
|
+
'revokeTrustedDevices',
|
|
255
|
+
]);
|
|
256
|
+
// Apps com acesso (consentimento): lista os grants da conta + revogação por client.
|
|
257
|
+
router.get('/account/apps', [C.accountApps, 'index']);
|
|
258
|
+
router.post('/account/apps/:clientId/revoke', [C.accountApps, 'revoke']);
|
|
259
|
+
// MFA / TOTP (enrollment, confirmação, disable).
|
|
260
|
+
router.get('/account/mfa', [C.accountMfa, 'index']);
|
|
261
|
+
router.post('/account/mfa/enroll', [C.accountMfa, 'enroll']);
|
|
262
|
+
router.post('/account/mfa/confirm', [C.accountMfa, 'confirm']);
|
|
263
|
+
router.post('/account/mfa/disable', [C.accountMfa, 'disable']);
|
|
264
|
+
// MFA / WebAuthn (passkeys): registro (begin/finish) + remoção.
|
|
265
|
+
router.post('/account/mfa/passkeys/options', [C.accountMfa, 'passkeyRegisterOptions']);
|
|
266
|
+
router.post('/account/mfa/passkeys/verify', [C.accountMfa, 'passkeyRegisterVerify']);
|
|
267
|
+
router.post('/account/mfa/passkeys/:id/remove', [C.accountMfa, 'passkeyRemove']);
|
|
268
|
+
// Sudo mode (confirm identity): GET exibe o formulário; POST verifica a senha.
|
|
269
|
+
router.get('/account/confirm', [C.accountConfirm, 'show']);
|
|
270
|
+
router.post('/account/confirm', [C.accountConfirm, 'confirm']);
|
|
271
|
+
router.post('/account/confirm/passkey/options', [C.accountConfirm, 'passkeyOptions']);
|
|
272
|
+
router.post('/account/confirm/passkey', [C.accountConfirm, 'passkeyConfirm']);
|
|
273
|
+
// Organizations (multi-tenancy) — sempre montadas; controller retorna 404/403 sem tabelas.
|
|
274
|
+
router.get('/account/orgs', [C.accountOrgs, 'index']);
|
|
275
|
+
router.post('/account/orgs', [C.accountOrgs, 'store']);
|
|
276
|
+
router.post('/account/orgs/deactivate', [C.accountOrgs, 'deactivate']);
|
|
277
|
+
router.post('/account/orgs/:id/activate', [C.accountOrgs, 'activate']);
|
|
278
|
+
router.post('/account/orgs/:id/leave', [C.accountOrgs, 'leave']);
|
|
279
|
+
router.post('/account/orgs/:id/invite', [C.accountOrgs, 'invite']);
|
|
280
|
+
router.post('/account/orgs/:id/members/:accountId/remove', [C.accountOrgs, 'removeMember']);
|
|
281
|
+
router.post('/account/orgs/:id/invitations/:invId/revoke', [C.accountOrgs, 'revokeInvitation']);
|
|
282
|
+
// JSON endpoints for React hooks (authkit-react).
|
|
283
|
+
router.get('/account/orgs/json', [C.accountOrgs, 'listJson']);
|
|
284
|
+
router.get('/account/orgs/invitations/json', [C.accountOrgs, 'listInvitationsJson']);
|
|
285
|
+
router.get('/account/orgs/:id/json', [C.accountOrgs, 'showJson']);
|
|
286
|
+
// ─── Account self-service JSON API (authkit-react TanStack hooks) ─────
|
|
287
|
+
// ⚠️ ORDER MATTERS: fixed-segment routes before parameterised ones.
|
|
288
|
+
// Registered INSIDE the accountGuard group → same session-auth protection.
|
|
289
|
+
// Mutating routes use CSRF (shield middleware on the host app).
|
|
290
|
+
router.get('/account/api/me', [C.accountApi, 'me']);
|
|
291
|
+
router.get('/account/api/security', [C.accountApi, 'securityOverview']);
|
|
292
|
+
router.patch('/account/api/profile', [C.accountApi, 'updateProfile']);
|
|
293
|
+
router.post('/account/api/password', [C.accountApi, 'changePassword']);
|
|
294
|
+
// Email-change: cancel BEFORE the generic post to avoid pattern collision.
|
|
295
|
+
router.post('/account/api/email-change/cancel', [C.accountApi, 'cancelEmailChange']);
|
|
296
|
+
router.post('/account/api/email-change', [C.accountApi, 'requestEmailChange']);
|
|
297
|
+
// Sessions: fixed routes BEFORE :id.
|
|
298
|
+
router.get('/account/api/sessions', [C.accountApi, 'listSessions']);
|
|
299
|
+
router.post('/account/api/sessions/revoke-others', [C.accountApi, 'revokeOtherSessions']);
|
|
300
|
+
router.post('/account/api/sessions/revoke-all', [C.accountApi, 'revokeAllSessions']);
|
|
301
|
+
router.delete('/account/api/sessions/:id', [C.accountApi, 'revokeSession']);
|
|
302
|
+
// Apps (grants).
|
|
303
|
+
router.get('/account/api/apps', [C.accountApi, 'listApps']);
|
|
304
|
+
router.delete('/account/api/apps/:clientId', [C.accountApi, 'revokeApp']);
|
|
305
|
+
// MFA + passkeys.
|
|
306
|
+
router.get('/account/api/mfa', [C.accountApi, 'mfaStatus']);
|
|
307
|
+
router.get('/account/api/passkeys', [C.accountApi, 'listPasskeys']);
|
|
308
|
+
router.delete('/account/api/passkeys/:id', [C.accountApi, 'removePasskey']);
|
|
309
|
+
// PATs.
|
|
310
|
+
router.get('/account/api/tokens', [C.accountApi, 'listTokens']);
|
|
311
|
+
router.post('/account/api/tokens', [C.accountApi, 'createToken']);
|
|
312
|
+
router.delete('/account/api/tokens/:id', [C.accountApi, 'revokeToken']);
|
|
313
|
+
// Orgs: invitations BEFORE :id (fixed segment before parameterised).
|
|
314
|
+
router.get('/account/api/orgs', [C.accountApi, 'listOrgs']);
|
|
315
|
+
router.get('/account/api/orgs/invitations', [C.accountApi, 'listOrgInvitations']);
|
|
316
|
+
router.get('/account/api/orgs/:id', [C.accountApi, 'showOrg']);
|
|
317
|
+
})
|
|
318
|
+
.use([accountGuard]);
|
|
319
|
+
// Console admin (do config.admin.enabled ou opts). Protegido pelo adminGuard (sessão + role global).
|
|
320
|
+
if (adminOpt) {
|
|
321
|
+
// Resolve o prefixo: `true` → '/admin' (default); objeto → usa prefix fornecido.
|
|
322
|
+
const rawPrefix = typeof adminOpt === 'object' && adminOpt.prefix ? adminOpt.prefix : '/admin';
|
|
323
|
+
const ap = normalizeAdminPrefix(rawPrefix);
|
|
324
|
+
// Persiste no singleton de processo para que controllers e views usem o mesmo prefixo.
|
|
325
|
+
setAdminPrefix(ap);
|
|
326
|
+
router
|
|
327
|
+
.group(() => {
|
|
328
|
+
// Console admin (SPA React self-contained): todas as rotas GET servem o
|
|
329
|
+
// shell HTML; os endpoints JSON sob {prefix}/api/* são a fonte de dados da SPA.
|
|
330
|
+
// ⚠️ ORDEM IMPORTA: o AdonisJS casa rotas wildcard por ORDEM DE REGISTRO.
|
|
331
|
+
// Os assets e TODA a JSON API `/api/*` precisam ser registrados ANTES do
|
|
332
|
+
// catch-all `${ap}/*` (que serve o shell HTML), senão o catch-all engole
|
|
333
|
+
// `/api/*` e devolve HTML onde a SPA espera JSON ("Unexpected token '<'").
|
|
334
|
+
// ─── Assets estáticos do Vite build ───────────────────────────────────
|
|
335
|
+
router.get(`${ap}/assets/*`, [C.consoleShell, 'serveAsset']).as('authkit_console_assets');
|
|
336
|
+
// ─── JSON API do console (session-authed via adminGuard upstream) ─────
|
|
337
|
+
// GET {ap}/api/overview
|
|
338
|
+
router.get(`${ap}/api/overview`, [C.consoleOverview, 'handle']);
|
|
339
|
+
// Usuários.
|
|
340
|
+
router.get(`${ap}/api/users`, [C.consoleUsers, 'index']);
|
|
341
|
+
router.get(`${ap}/api/users/:id`, [C.consoleUsers, 'show']);
|
|
342
|
+
router.post(`${ap}/api/users`, [C.consoleUsers, 'store']);
|
|
343
|
+
router.patch(`${ap}/api/users/:id/roles`, [C.consoleUsers, 'updateRoles']);
|
|
344
|
+
router.post(`${ap}/api/users/:id/disable`, [C.consoleUsers, 'disable']);
|
|
345
|
+
router.post(`${ap}/api/users/:id/enable`, [C.consoleUsers, 'enable']);
|
|
346
|
+
router.post(`${ap}/api/users/:id/reset-password`, [C.consoleUsers, 'resetPassword']);
|
|
347
|
+
router.delete(`${ap}/api/users/:id`, [C.consoleUsers, 'destroy']);
|
|
348
|
+
// Sessões.
|
|
349
|
+
router.get(`${ap}/api/sessions`, [C.consoleSessions, 'index']);
|
|
350
|
+
router.post(`${ap}/api/sessions/revoke-all`, [C.consoleSessions, 'revokeAll']);
|
|
351
|
+
// Sessões por usuário (drawer do user — ANTES do catch-all para não receber HTML).
|
|
352
|
+
router.get(`${ap}/api/users/:id/sessions`, [C.consoleSessions, 'userSessions']);
|
|
353
|
+
router.post(`${ap}/api/users/:id/revoke-sessions`, [C.consoleSessions, 'userRevokeSessions']);
|
|
354
|
+
// Clients OIDC.
|
|
355
|
+
router.get(`${ap}/api/clients`, [C.consoleClients, 'index']);
|
|
356
|
+
router.post(`${ap}/api/clients`, [C.consoleClients, 'store']);
|
|
357
|
+
router.patch(`${ap}/api/clients/:id`, [C.consoleClients, 'update']);
|
|
358
|
+
router.delete(`${ap}/api/clients/:id`, [C.consoleClients, 'destroy']);
|
|
359
|
+
router.post(`${ap}/api/clients/:id/regenerate-secret`, [C.consoleClients, 'regenerateSecret']);
|
|
360
|
+
// Roles.
|
|
361
|
+
router.get(`${ap}/api/roles`, [C.consoleRoles, 'index']);
|
|
362
|
+
router.post(`${ap}/api/roles`, [C.consoleRoles, 'store']);
|
|
363
|
+
router.patch(`${ap}/api/roles/:name`, [C.consoleRoles, 'update']);
|
|
364
|
+
router.delete(`${ap}/api/roles/:name`, [C.consoleRoles, 'destroy']);
|
|
365
|
+
// Organizações (capability-gated: 404 quando store não suporta).
|
|
366
|
+
// ⚠️ Rotas fixas ANTES de parametrizadas para evitar shadowing.
|
|
367
|
+
router.get(`${ap}/api/orgs`, [C.consoleOrgs, 'index']);
|
|
368
|
+
router.post(`${ap}/api/orgs`, [C.consoleOrgs, 'store']);
|
|
369
|
+
router.get(`${ap}/api/orgs/:id`, [C.consoleOrgs, 'show']);
|
|
370
|
+
router.patch(`${ap}/api/orgs/:id`, [C.consoleOrgs, 'update']);
|
|
371
|
+
router.delete(`${ap}/api/orgs/:id`, [C.consoleOrgs, 'destroy']);
|
|
372
|
+
// Membros: PATCH (role) ANTES de DELETE para não colidir, ambos antes do catch-all.
|
|
373
|
+
router.post(`${ap}/api/orgs/:id/members`, [C.consoleOrgs, 'addMember']);
|
|
374
|
+
router.patch(`${ap}/api/orgs/:id/members/:accountId`, [C.consoleOrgs, 'updateMemberRole']);
|
|
375
|
+
router.delete(`${ap}/api/orgs/:id/members/:accountId`, [C.consoleOrgs, 'removeMember']);
|
|
376
|
+
// Convites.
|
|
377
|
+
router.post(`${ap}/api/orgs/:id/invitations`, [C.consoleOrgs, 'createInvitation']);
|
|
378
|
+
router.delete(`${ap}/api/orgs/:id/invitations/:invitationId`, [C.consoleOrgs, 'revokeInvitation']);
|
|
379
|
+
// Auditoria (capability-gated: 404 quando sink não suporta consulta).
|
|
380
|
+
router.get(`${ap}/api/audit`, [C.consoleAudit, 'index']);
|
|
381
|
+
// Settings.
|
|
382
|
+
router.get(`${ap}/api/settings`, [C.consoleSettings, 'index']);
|
|
383
|
+
router.put(`${ap}/api/settings/:key`, [C.consoleSettings, 'upsert']);
|
|
384
|
+
router.delete(`${ap}/api/settings/:key`, [C.consoleSettings, 'destroy']);
|
|
385
|
+
// Chave de assinatura managed (status + rotação ao vivo).
|
|
386
|
+
router.get(`${ap}/api/keys`, [C.consoleKeys, 'status']);
|
|
387
|
+
router.post(`${ap}/api/keys/rotate`, [C.consoleKeys, 'rotate']);
|
|
388
|
+
// Impersonation (capability-gated: 404 quando desabilitado ou sem client).
|
|
389
|
+
router.get(`${ap}/api/impersonation/:userId`, [C.consoleImpersonation, 'handle']);
|
|
390
|
+
// ─── Shell HTML — POR ÚLTIMO (catch-all) ──────────────────────────────
|
|
391
|
+
// Serve a SPA para todas as demais rotas GET do console; o roteamento
|
|
392
|
+
// client-side (hash) é tratado pela SPA. Nomes explícitos: o mesmo par
|
|
393
|
+
// controller.método em duas rotas colide no auto-naming do AdonisJS.
|
|
394
|
+
router.get(ap, [C.consoleShell, 'serve']).as('authkit_console_root');
|
|
395
|
+
router.get(`${ap}/*`, [C.consoleShell, 'serve']).as('authkit_console_shell');
|
|
396
|
+
})
|
|
397
|
+
.use([adminGuard]);
|
|
398
|
+
}
|
|
399
|
+
// Admin REST API (opt-in — R6). Superfície machine-to-machine atrás do
|
|
400
|
+
// adminApiGuard (API key). Todas as rotas levam o throttle de introspecção.
|
|
401
|
+
if (adminApiOpt) {
|
|
402
|
+
// Resolve o prefixo: `true` → '/api/authkit/v1' (default); objeto → usa prefix fornecido.
|
|
403
|
+
const rawApiPrefix = typeof adminApiOpt === 'object' && adminApiOpt.prefix
|
|
404
|
+
? adminApiOpt.prefix
|
|
405
|
+
: '/api/authkit/v1';
|
|
406
|
+
const aap = normalizeAdminApiPrefix(rawApiPrefix);
|
|
407
|
+
// Persiste no singleton de processo para que o SDK remoto e outros consumidores
|
|
408
|
+
// usem o mesmo prefixo sem precisar receber a opção.
|
|
409
|
+
setAdminApiPrefix(aap);
|
|
410
|
+
// Aplica o throttle de introspecção a uma rota qualquer (GET ou escrita).
|
|
411
|
+
const withApiThrottle = (route) => {
|
|
412
|
+
if (throttles)
|
|
413
|
+
route.use([throttles.introspection]);
|
|
414
|
+
return route;
|
|
415
|
+
};
|
|
416
|
+
router
|
|
417
|
+
.group(() => {
|
|
418
|
+
// Usuários.
|
|
419
|
+
withApiThrottle(router.get('/users', [C.apiUsers, 'index']));
|
|
420
|
+
withApiThrottle(router.post('/users', [C.apiUsers, 'store']));
|
|
421
|
+
withApiThrottle(router.get('/users/:id', [C.apiUsers, 'show']));
|
|
422
|
+
withApiThrottle(router.patch('/users/:id', [C.apiUsers, 'update']));
|
|
423
|
+
withApiThrottle(router.delete('/users/:id', [C.apiUsers, 'destroy']));
|
|
424
|
+
withApiThrottle(router.post('/users/:id/disable', [C.apiUsers, 'disable']));
|
|
425
|
+
withApiThrottle(router.post('/users/:id/enable', [C.apiUsers, 'enable']));
|
|
426
|
+
withApiThrottle(router.post('/users/:id/reset-password', [C.apiUsers, 'resetPassword']));
|
|
427
|
+
withApiThrottle(router.get('/users/:id/sessions', [C.apiUsers, 'sessions']));
|
|
428
|
+
withApiThrottle(router.post('/users/:id/revoke-sessions', [C.apiUsers, 'revokeSessions']));
|
|
429
|
+
// Clients OIDC.
|
|
430
|
+
withApiThrottle(router.get('/clients', [C.apiClients, 'index']));
|
|
431
|
+
withApiThrottle(router.post('/clients', [C.apiClients, 'store']));
|
|
432
|
+
withApiThrottle(router.get('/clients/:id', [C.apiClients, 'show']));
|
|
433
|
+
withApiThrottle(router.patch('/clients/:id', [C.apiClients, 'update']));
|
|
434
|
+
withApiThrottle(router.post('/clients/:id/regenerate-secret', [C.apiClients, 'regenerateSecret']));
|
|
435
|
+
withApiThrottle(router.delete('/clients/:id', [C.apiClients, 'destroy']));
|
|
436
|
+
// Organizações.
|
|
437
|
+
withApiThrottle(router.get('/organizations', [C.apiOrgs, 'index']));
|
|
438
|
+
withApiThrottle(router.post('/organizations', [C.apiOrgs, 'store']));
|
|
439
|
+
withApiThrottle(router.get('/organizations/:id', [C.apiOrgs, 'show']));
|
|
440
|
+
withApiThrottle(router.patch('/organizations/:id', [C.apiOrgs, 'update']));
|
|
441
|
+
withApiThrottle(router.delete('/organizations/:id', [C.apiOrgs, 'destroy']));
|
|
442
|
+
withApiThrottle(router.post('/organizations/:id/members', [C.apiOrgs, 'addMember']));
|
|
443
|
+
withApiThrottle(router.delete('/organizations/:id/members/:accountId', [C.apiOrgs, 'removeMember']));
|
|
444
|
+
withApiThrottle(router.patch('/organizations/:id/members/:accountId', [C.apiOrgs, 'updateMemberRole']));
|
|
445
|
+
withApiThrottle(router.post('/organizations/:id/invitations', [C.apiOrgs, 'createInvitation']));
|
|
446
|
+
withApiThrottle(router.delete('/organizations/:id/invitations/:invitationId', [C.apiOrgs, 'revokeInvitation']));
|
|
447
|
+
// Auditoria + métricas + verificação de token.
|
|
448
|
+
withApiThrottle(router.get('/audit', [C.apiMisc, 'audit']));
|
|
449
|
+
withApiThrottle(router.get('/stats', [C.apiMisc, 'stats']));
|
|
450
|
+
withApiThrottle(router.post('/tokens/verify', [C.apiMisc, 'verify']));
|
|
451
|
+
// Runtime settings CRUD.
|
|
452
|
+
withApiThrottle(router.get('/settings', [C.apiSettings, 'index']));
|
|
453
|
+
withApiThrottle(router.get('/settings/:key', [C.apiSettings, 'show']));
|
|
454
|
+
withApiThrottle(router.put('/settings/:key', [C.apiSettings, 'upsert']));
|
|
455
|
+
withApiThrottle(router.delete('/settings/:key', [C.apiSettings, 'destroy']));
|
|
456
|
+
// Chave de assinatura managed (status + rotação ao vivo).
|
|
457
|
+
withApiThrottle(router.get('/keys', [C.apiKeys, 'status']));
|
|
458
|
+
withApiThrottle(router.post('/keys/rotate', [C.apiKeys, 'rotate']));
|
|
459
|
+
})
|
|
460
|
+
.prefix(aap)
|
|
461
|
+
// Throttle por IP do grupo inteiro (M8): roda ANTES da guard, então tentativas
|
|
462
|
+
// de Bearer key inválida do mesmo IP são limitadas mesmo quando a auth falha.
|
|
463
|
+
// O `withApiThrottle` (introspection, por token) continua como camada adicional.
|
|
464
|
+
.use(throttles ? [throttles.adminIp, adminApiGuard] : [adminApiGuard]);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* Função low-level que renderiza uma view Edge built-in da lib sem criar um
|
|
4
|
+
* closure. Usada internamente pelo `edgeRenderer()` e pelo `inertiaRenderer()`
|
|
5
|
+
* como fallback silencioso para views não listadas no allowlist (incluindo todas
|
|
6
|
+
* as telas `admin/*`).
|
|
7
|
+
*
|
|
8
|
+
* @internal Exportada para reuso — não faz parte da API pública do seam.
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderEdgeView(ctx: HttpContext, view: string, props: Record<string, unknown>): Promise<unknown>;
|
|
11
|
+
/** Renderer do seam para hosts Edge. As views são donas-da-lib (disco `authkit::`). */
|
|
12
|
+
export declare function edgeRenderer(): (ctx: HttpContext, view: string, props: Record<string, unknown>) => Promise<unknown>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DEFAULT_MESSAGES, translate } from '../i18n.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve o catálogo de mensagens ativo a partir do `authkit.server` (config
|
|
4
|
+
* resolvida com o locale do host). Defensivo: se o container/serviço não estiver
|
|
5
|
+
* disponível (ex.: teste unitário do renderer com ctx mockado), cai no default
|
|
6
|
+
* pt-BR embutido — as views continuam renderizando.
|
|
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
|
+
* Função low-level que renderiza uma view Edge built-in da lib sem criar um
|
|
22
|
+
* closure. Usada internamente pelo `edgeRenderer()` e pelo `inertiaRenderer()`
|
|
23
|
+
* como fallback silencioso para views não listadas no allowlist (incluindo todas
|
|
24
|
+
* as telas `admin/*`).
|
|
25
|
+
*
|
|
26
|
+
* @internal Exportada para reuso — não faz parte da API pública do seam.
|
|
27
|
+
*/
|
|
28
|
+
export async function renderEdgeView(ctx, view, props) {
|
|
29
|
+
const messages = await resolveMessagesFromCtx(ctx);
|
|
30
|
+
const t = (key, params) => translate(messages, key, params);
|
|
31
|
+
return ctx.view.render(`authkit::${view}`, { ...props, t, messages });
|
|
32
|
+
}
|
|
33
|
+
/** Renderer do seam para hosts Edge. As views são donas-da-lib (disco `authkit::`). */
|
|
34
|
+
export function edgeRenderer() {
|
|
35
|
+
return async (ctx, view, props) => {
|
|
36
|
+
return renderEdgeView(ctx, view, props);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* Opções do renderer Inertia/React.
|
|
4
|
+
*/
|
|
5
|
+
export interface InertiaRendererOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Prefixo das páginas no diretório `inertia/pages/` do host.
|
|
8
|
+
* Ex.: `'authkit'` → a view `login` mapeia para `inertia/pages/authkit/login.tsx`.
|
|
9
|
+
*/
|
|
10
|
+
prefix: string;
|
|
11
|
+
/**
|
|
12
|
+
* Lista de nomes de view que o host criou como páginas React (allowlist).
|
|
13
|
+
*
|
|
14
|
+
* Quando fornecida, **somente** as views listadas passam pelo Inertia; qualquer
|
|
15
|
+
* outra view (não listada, ou prefixada com `admin/`) recai silenciosamente no
|
|
16
|
+
* renderer Edge built-in da lib — sem erro 500.
|
|
17
|
+
*
|
|
18
|
+
* ### ⚠️ Atenção: sem `views`, qualquer tela nova da lib quebra hosts SSR
|
|
19
|
+
*
|
|
20
|
+
* Se `views` for omitido, o comportamento legado é preservado (todas as views
|
|
21
|
+
* são enviadas ao Inertia) para compatibilidade retroativa. Nesse modo, qualquer
|
|
22
|
+
* tela nova adicionada pela lib gerará um erro SSR no host ("Cannot read
|
|
23
|
+
* properties of undefined (reading 'default')") porque o host não terá criado a
|
|
24
|
+
* página React correspondente. **Recomenda-se sempre fornecer `views`** com
|
|
25
|
+
* exatamente as páginas que o scaffold (`node ace configure`) gerou.
|
|
26
|
+
*
|
|
27
|
+
* A ordem do array é irrelevante — `views` é tratado como um *conjunto*
|
|
28
|
+
* (allowlist). Os nomes têm autocomplete via {@link AuthkitScreen}.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Gera `inertia/pages/authkit/<view>.tsx` para cada nome listado.
|
|
32
|
+
* render: inertiaRenderer({
|
|
33
|
+
* prefix: 'authkit',
|
|
34
|
+
* views: [
|
|
35
|
+
* 'login', 'consent', 'signup', 'forgot', 'reset',
|
|
36
|
+
* 'verify-email', 'mfa-challenge',
|
|
37
|
+
* 'account/login', 'account/tokens', 'account/mfa',
|
|
38
|
+
* ],
|
|
39
|
+
* })
|
|
40
|
+
*/
|
|
41
|
+
views?: AuthkitScreen[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Nomes das telas conhecidas da lib — dá autocomplete no array `views`.
|
|
45
|
+
* O `(string & {})` mantém o tipo aberto: telas custom (ou de versões mais
|
|
46
|
+
* novas da lib) continuam aceitas sem erro de compilação.
|
|
47
|
+
*/
|
|
48
|
+
export type AuthkitScreen = 'login' | 'signup' | 'consent' | 'forgot' | 'reset' | 'verify-email' | 'mfa-challenge' | 'otp-unlock' | 'maintenance' | 'account/login' | 'account/tokens' | 'account/mfa' | 'account/security' | 'account/apps' | 'account/orgs' | 'account/confirm' | 'account/email-confirmed' | (string & {});
|
|
49
|
+
/**
|
|
50
|
+
* Renderer do seam para hosts Inertia/React.
|
|
51
|
+
*
|
|
52
|
+
* As páginas React vivem no host em `inertia/pages/<prefix>/<view>`.
|
|
53
|
+
* (O console admin não passa por aqui: é a SPA self-contained da lib,
|
|
54
|
+
* servida pelo shell controller.)
|
|
55
|
+
*
|
|
56
|
+
* Quando `views` é fornecido (allowlist), apenas as views listadas vão ao Inertia;
|
|
57
|
+
* qualquer outra view recai no Edge renderer built-in sem erro.
|
|
58
|
+
*
|
|
59
|
+
* ---
|
|
60
|
+
*
|
|
61
|
+
* ### Props da tela `account/login`
|
|
62
|
+
*
|
|
63
|
+
* | Prop | Tipo | Descrição |
|
|
64
|
+
* |-------------|---------------------|-----------|
|
|
65
|
+
* | `csrfToken` | `string` | Token CSRF para o campo `_csrf` do formulário. |
|
|
66
|
+
* | `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. |
|
|
67
|
+
* | `error` | `string \| undefined` | Mensagem de erro de autenticação localizada (credenciais inválidas, conta bloqueada, etc.). |
|
|
68
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
69
|
+
*/
|
|
70
|
+
export declare function inertiaRenderer(opts: InertiaRendererOptions): (ctx: HttpContext, view: string, props: Record<string, unknown>) => Promise<any>;
|