@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,131 @@
|
|
|
1
|
+
import type { AuthAccount } from '../../accounts/account_store.js';
|
|
2
|
+
import type { OrgSummary, OrgMember, OrgInvitation } from '../../accounts/account_store.js';
|
|
3
|
+
import type { OrgDetail } from './admin_orgs_service.js';
|
|
4
|
+
import type { AdminClient, CreatedClient } from '../admin_clients_service.js';
|
|
5
|
+
import type { AdminSession, AdminGrant } from '../admin_sessions_service.js';
|
|
6
|
+
import type { StoredAuditEvent } from '../../audit/audit_sink.js';
|
|
7
|
+
/** Projeta uma conta para a forma JSON (camelCase) da Admin REST API. */
|
|
8
|
+
export declare function userDto(account: AuthAccount, disabled?: boolean): {
|
|
9
|
+
id: string;
|
|
10
|
+
email: string;
|
|
11
|
+
name: string | null;
|
|
12
|
+
avatarUrl: string | null;
|
|
13
|
+
globalRoles: string[];
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare function clientDto(client: AdminClient): {
|
|
17
|
+
clientId: string;
|
|
18
|
+
confidential: boolean;
|
|
19
|
+
grants: string[];
|
|
20
|
+
redirectUris: string[];
|
|
21
|
+
postLogoutRedirectUris: string[];
|
|
22
|
+
tokenEndpointAuthMethod: string;
|
|
23
|
+
backchannelLogoutUri: string | null;
|
|
24
|
+
backchannelLogoutSessionRequired: boolean;
|
|
25
|
+
};
|
|
26
|
+
/** Inclui o secret (mostrado UMA vez) em create/regenerate. */
|
|
27
|
+
export declare function createdClientDto(created: CreatedClient): {
|
|
28
|
+
clientId: string;
|
|
29
|
+
clientSecret: string | null;
|
|
30
|
+
};
|
|
31
|
+
export declare function sessionDto(session: AdminSession): {
|
|
32
|
+
id: string;
|
|
33
|
+
accountId: string;
|
|
34
|
+
email: string | null;
|
|
35
|
+
loginTs: number | null;
|
|
36
|
+
amr: string[];
|
|
37
|
+
userAgent: string | null;
|
|
38
|
+
browser: string | null;
|
|
39
|
+
os: string | null;
|
|
40
|
+
ip: string | null;
|
|
41
|
+
location: string | null;
|
|
42
|
+
};
|
|
43
|
+
export declare function grantDto(grant: AdminGrant): {
|
|
44
|
+
id: string;
|
|
45
|
+
accountId: string;
|
|
46
|
+
clientId: string | null;
|
|
47
|
+
accessTokens: number;
|
|
48
|
+
refreshTokens: number;
|
|
49
|
+
};
|
|
50
|
+
export declare function auditDto(event: StoredAuditEvent): {
|
|
51
|
+
id: string;
|
|
52
|
+
type: import("../../audit/audit_sink.js").AuditEventType;
|
|
53
|
+
accountId: string | null;
|
|
54
|
+
email: string | null;
|
|
55
|
+
clientId: string | null;
|
|
56
|
+
actorId: string | null;
|
|
57
|
+
ip: string | null;
|
|
58
|
+
metadata: Record<string, unknown> | null;
|
|
59
|
+
createdAt: string | null;
|
|
60
|
+
};
|
|
61
|
+
export declare function orgDto(org: OrgSummary & {
|
|
62
|
+
memberCount?: number;
|
|
63
|
+
}): {
|
|
64
|
+
memberCount?: number | undefined;
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
slug: string;
|
|
68
|
+
logoUrl: string | null;
|
|
69
|
+
metadata: Record<string, unknown> | null;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
};
|
|
72
|
+
export declare function orgMemberDto(member: OrgMember): {
|
|
73
|
+
accountId: string;
|
|
74
|
+
email: string | null;
|
|
75
|
+
role: string;
|
|
76
|
+
joinedAt: string;
|
|
77
|
+
};
|
|
78
|
+
export declare function orgInvitationDto(inv: OrgInvitation): {
|
|
79
|
+
id: string;
|
|
80
|
+
organizationId: string;
|
|
81
|
+
email: string;
|
|
82
|
+
role: string;
|
|
83
|
+
invitedBy: string;
|
|
84
|
+
expiresAt: string;
|
|
85
|
+
acceptedAt: string | null;
|
|
86
|
+
createdAt: string;
|
|
87
|
+
};
|
|
88
|
+
export declare function orgDetailDto(detail: OrgDetail): {
|
|
89
|
+
members: {
|
|
90
|
+
accountId: string;
|
|
91
|
+
email: string | null;
|
|
92
|
+
role: string;
|
|
93
|
+
joinedAt: string;
|
|
94
|
+
}[];
|
|
95
|
+
pendingInvitations: {
|
|
96
|
+
id: string;
|
|
97
|
+
organizationId: string;
|
|
98
|
+
email: string;
|
|
99
|
+
role: string;
|
|
100
|
+
invitedBy: string;
|
|
101
|
+
expiresAt: string;
|
|
102
|
+
acceptedAt: string | null;
|
|
103
|
+
createdAt: string;
|
|
104
|
+
}[];
|
|
105
|
+
memberCount?: number | undefined;
|
|
106
|
+
id: string;
|
|
107
|
+
name: string;
|
|
108
|
+
slug: string;
|
|
109
|
+
logoUrl: string | null;
|
|
110
|
+
metadata: Record<string, unknown> | null;
|
|
111
|
+
createdAt: string;
|
|
112
|
+
};
|
|
113
|
+
/** Envelope de erro padrão da Admin REST API. */
|
|
114
|
+
export declare function apiError(code: string, message: string, details?: Record<string, unknown>): {
|
|
115
|
+
error: {
|
|
116
|
+
details?: Record<string, unknown> | undefined;
|
|
117
|
+
code: string;
|
|
118
|
+
message: string;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
import type { SettingRow } from '../runtime_settings.js';
|
|
122
|
+
export declare function settingDto(row: SettingRow): {
|
|
123
|
+
lockedBy?: "config" | undefined;
|
|
124
|
+
key: string;
|
|
125
|
+
organizationId: string | null;
|
|
126
|
+
value: unknown;
|
|
127
|
+
updatedAt: string | null;
|
|
128
|
+
updatedBy: string | null;
|
|
129
|
+
/** Travada via defineConfig → UI deve desabilitar a edição e mostrar aviso. */
|
|
130
|
+
locked: boolean;
|
|
131
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/** Projeta uma conta para a forma JSON (camelCase) da Admin REST API. */
|
|
2
|
+
export function userDto(account, disabled = false) {
|
|
3
|
+
return {
|
|
4
|
+
id: account.id,
|
|
5
|
+
email: account.email,
|
|
6
|
+
name: account.name ?? null,
|
|
7
|
+
avatarUrl: account.avatarUrl ?? null,
|
|
8
|
+
globalRoles: account.globalRoles ?? [],
|
|
9
|
+
disabled,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function clientDto(client) {
|
|
13
|
+
return {
|
|
14
|
+
clientId: client.clientId,
|
|
15
|
+
confidential: client.confidential,
|
|
16
|
+
grants: client.grants,
|
|
17
|
+
redirectUris: client.redirectUris,
|
|
18
|
+
postLogoutRedirectUris: client.postLogoutRedirectUris,
|
|
19
|
+
tokenEndpointAuthMethod: client.tokenEndpointAuthMethod,
|
|
20
|
+
backchannelLogoutUri: client.backchannelLogoutUri ?? null,
|
|
21
|
+
backchannelLogoutSessionRequired: client.backchannelLogoutSessionRequired ?? false,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Inclui o secret (mostrado UMA vez) em create/regenerate. */
|
|
25
|
+
export function createdClientDto(created) {
|
|
26
|
+
return {
|
|
27
|
+
clientId: created.clientId,
|
|
28
|
+
clientSecret: created.clientSecret ?? null,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function sessionDto(session) {
|
|
32
|
+
return {
|
|
33
|
+
id: session.id,
|
|
34
|
+
accountId: session.accountId,
|
|
35
|
+
email: session.email ?? null,
|
|
36
|
+
loginTs: session.loginTs ?? null,
|
|
37
|
+
amr: session.amr ?? [],
|
|
38
|
+
userAgent: session.userAgent ?? null,
|
|
39
|
+
browser: session.browser ?? null,
|
|
40
|
+
os: session.os ?? null,
|
|
41
|
+
ip: session.ip ?? null,
|
|
42
|
+
location: session.location ?? null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function grantDto(grant) {
|
|
46
|
+
return {
|
|
47
|
+
id: grant.id,
|
|
48
|
+
accountId: grant.accountId,
|
|
49
|
+
clientId: grant.clientId ?? null,
|
|
50
|
+
accessTokens: grant.accessTokens,
|
|
51
|
+
refreshTokens: grant.refreshTokens,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function auditDto(event) {
|
|
55
|
+
return {
|
|
56
|
+
id: event.id,
|
|
57
|
+
type: event.type,
|
|
58
|
+
accountId: event.accountId ?? null,
|
|
59
|
+
email: event.email ?? null,
|
|
60
|
+
clientId: event.clientId ?? null,
|
|
61
|
+
actorId: event.actorId ?? null,
|
|
62
|
+
ip: event.ip ?? null,
|
|
63
|
+
metadata: event.metadata ?? null,
|
|
64
|
+
createdAt: event.createdAt instanceof Date ? event.createdAt.toISOString() : event.createdAt,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function orgDto(org) {
|
|
68
|
+
return {
|
|
69
|
+
id: org.id,
|
|
70
|
+
name: org.name,
|
|
71
|
+
slug: org.slug,
|
|
72
|
+
logoUrl: org.logoUrl ?? null,
|
|
73
|
+
metadata: org.metadata ?? null,
|
|
74
|
+
createdAt: org.createdAt,
|
|
75
|
+
...(org.memberCount !== undefined ? { memberCount: org.memberCount } : {}),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function orgMemberDto(member) {
|
|
79
|
+
return {
|
|
80
|
+
accountId: member.accountId,
|
|
81
|
+
email: member.email ?? null,
|
|
82
|
+
role: member.role,
|
|
83
|
+
joinedAt: member.joinedAt,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export function orgInvitationDto(inv) {
|
|
87
|
+
return {
|
|
88
|
+
id: inv.id,
|
|
89
|
+
organizationId: inv.organizationId,
|
|
90
|
+
email: inv.email,
|
|
91
|
+
role: inv.role,
|
|
92
|
+
invitedBy: inv.invitedBy,
|
|
93
|
+
expiresAt: inv.expiresAt,
|
|
94
|
+
acceptedAt: inv.acceptedAt ?? null,
|
|
95
|
+
createdAt: inv.createdAt,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export function orgDetailDto(detail) {
|
|
99
|
+
return {
|
|
100
|
+
...orgDto(detail),
|
|
101
|
+
members: detail.members.map(orgMemberDto),
|
|
102
|
+
pendingInvitations: detail.pendingInvitations.map(orgInvitationDto),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/** Envelope de erro padrão da Admin REST API. */
|
|
106
|
+
export function apiError(code, message, details) {
|
|
107
|
+
return { error: { code, message, ...(details ? { details } : {}) } };
|
|
108
|
+
}
|
|
109
|
+
import { isSettingLocked } from '../config_locks.js';
|
|
110
|
+
export function settingDto(row) {
|
|
111
|
+
const locked = isSettingLocked(row.key);
|
|
112
|
+
return {
|
|
113
|
+
key: row.key,
|
|
114
|
+
organizationId: row.organizationId ?? null,
|
|
115
|
+
value: row.value,
|
|
116
|
+
updatedAt: row.updatedAt instanceof Date ? row.updatedAt.toISOString() : (row.updatedAt ?? null),
|
|
117
|
+
updatedBy: row.updatedBy ?? null,
|
|
118
|
+
/** Travada via defineConfig → UI deve desabilitar a edição e mostrar aviso. */
|
|
119
|
+
locked,
|
|
120
|
+
...(locked ? { lockedBy: 'config' } : {}),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ResolvedServerConfig } from '../../define_config.js';
|
|
2
|
+
/** Resultado de introspecção genérica (PAT ou opaque access token). */
|
|
3
|
+
export type VerifyResult = {
|
|
4
|
+
active: false;
|
|
5
|
+
} | {
|
|
6
|
+
active: true;
|
|
7
|
+
/** 'pat' (Personal Access Token) ou 'access_token' (opaque AT do provider). */
|
|
8
|
+
tokenType: 'pat' | 'access_token';
|
|
9
|
+
sub: string;
|
|
10
|
+
email?: string | null;
|
|
11
|
+
name?: string | null;
|
|
12
|
+
roles?: string[];
|
|
13
|
+
scopes?: string[];
|
|
14
|
+
audience?: string | string[] | null;
|
|
15
|
+
clientId?: string | null;
|
|
16
|
+
exp?: number | null;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Introspecção genérica de token usada pela Admin REST API (`POST /tokens/verify`).
|
|
20
|
+
* Roteia por prefixo: tokens `pat_...` vão pelo {@link PatStore} (mesma rota do
|
|
21
|
+
* `/authkit/pat/introspect`); os demais são tratados como opaque access tokens e
|
|
22
|
+
* resolvidos pelo `AccessToken.find` do oidc-provider. Sempre best-effort: token
|
|
23
|
+
* desconhecido/expirado → `{ active: false }`.
|
|
24
|
+
*/
|
|
25
|
+
export declare class TokenVerifyService {
|
|
26
|
+
#private;
|
|
27
|
+
private cfg;
|
|
28
|
+
/** Provider do oidc-provider (service.provider) — para opaque AT. */
|
|
29
|
+
private provider;
|
|
30
|
+
constructor(cfg: ResolvedServerConfig,
|
|
31
|
+
/** Provider do oidc-provider (service.provider) — para opaque AT. */
|
|
32
|
+
provider: any);
|
|
33
|
+
verify(token: string): Promise<VerifyResult>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Introspecção genérica de token usada pela Admin REST API (`POST /tokens/verify`).
|
|
3
|
+
* Roteia por prefixo: tokens `pat_...` vão pelo {@link PatStore} (mesma rota do
|
|
4
|
+
* `/authkit/pat/introspect`); os demais são tratados como opaque access tokens e
|
|
5
|
+
* resolvidos pelo `AccessToken.find` do oidc-provider. Sempre best-effort: token
|
|
6
|
+
* desconhecido/expirado → `{ active: false }`.
|
|
7
|
+
*/
|
|
8
|
+
export class TokenVerifyService {
|
|
9
|
+
cfg;
|
|
10
|
+
provider;
|
|
11
|
+
constructor(cfg,
|
|
12
|
+
/** Provider do oidc-provider (service.provider) — para opaque AT. */
|
|
13
|
+
provider) {
|
|
14
|
+
this.cfg = cfg;
|
|
15
|
+
this.provider = provider;
|
|
16
|
+
}
|
|
17
|
+
async verify(token) {
|
|
18
|
+
if (!token || typeof token !== 'string')
|
|
19
|
+
return { active: false };
|
|
20
|
+
if (token.startsWith('pat_'))
|
|
21
|
+
return this.#verifyPat(token);
|
|
22
|
+
return this.#verifyAccessToken(token);
|
|
23
|
+
}
|
|
24
|
+
async #verifyPat(token) {
|
|
25
|
+
if (!this.cfg.patStore)
|
|
26
|
+
return { active: false };
|
|
27
|
+
const meta = await this.cfg.patStore.findActiveByToken(token);
|
|
28
|
+
if (!meta)
|
|
29
|
+
return { active: false };
|
|
30
|
+
const account = await this.cfg.accountStore.findById(meta.accountId);
|
|
31
|
+
if (!account)
|
|
32
|
+
return { active: false };
|
|
33
|
+
return {
|
|
34
|
+
active: true,
|
|
35
|
+
tokenType: 'pat',
|
|
36
|
+
sub: account.id,
|
|
37
|
+
email: account.email,
|
|
38
|
+
name: account.name ?? null,
|
|
39
|
+
roles: account.globalRoles ?? [],
|
|
40
|
+
scopes: meta.scopes,
|
|
41
|
+
audience: meta.audience,
|
|
42
|
+
exp: meta.exp,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async #verifyAccessToken(token) {
|
|
46
|
+
let at;
|
|
47
|
+
try {
|
|
48
|
+
at = await this.provider?.AccessToken?.find(token);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return { active: false };
|
|
52
|
+
}
|
|
53
|
+
if (!at)
|
|
54
|
+
return { active: false };
|
|
55
|
+
// O oidc-provider expira artefatos sozinho; isExpired/exp como guarda extra.
|
|
56
|
+
if (typeof at.isExpired === 'boolean' && at.isExpired)
|
|
57
|
+
return { active: false };
|
|
58
|
+
const sub = at.accountId ?? '';
|
|
59
|
+
const account = sub ? await this.cfg.accountStore.findById(sub) : null;
|
|
60
|
+
const scopes = typeof at.scope === 'string' ? at.scope.split(' ').filter(Boolean) : [];
|
|
61
|
+
return {
|
|
62
|
+
active: true,
|
|
63
|
+
tokenType: 'access_token',
|
|
64
|
+
sub,
|
|
65
|
+
email: account?.email ?? null,
|
|
66
|
+
name: account?.name ?? null,
|
|
67
|
+
roles: account?.globalRoles ?? [],
|
|
68
|
+
scopes,
|
|
69
|
+
audience: at.aud ?? null,
|
|
70
|
+
clientId: at.clientId ?? null,
|
|
71
|
+
exp: typeof at.exp === 'number' ? at.exp : null,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { OidcService } from '../provider/oidc_service.js';
|
|
2
|
+
/** Métodos de autenticação no token endpoint suportados pelo formulário admin. */
|
|
3
|
+
export type TokenEndpointAuthMethod = 'client_secret_basic' | 'client_secret_post' | 'none';
|
|
4
|
+
/** Entrada normalizada de um client gerenciável (vinda do formulário admin). */
|
|
5
|
+
export interface ClientInput {
|
|
6
|
+
clientId?: string;
|
|
7
|
+
redirectUris: string[];
|
|
8
|
+
postLogoutRedirectUris: string[];
|
|
9
|
+
grantTypes: string[];
|
|
10
|
+
tokenEndpointAuthMethod: TokenEndpointAuthMethod;
|
|
11
|
+
/**
|
|
12
|
+
* Endpoint de OIDC Back-Channel Logout do RP. Quando definido, o IdP envia um
|
|
13
|
+
* `logout_token` para esta URI ao encerrar a sessão/grant do usuário (RFC 7644).
|
|
14
|
+
*/
|
|
15
|
+
backchannelLogoutUri?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Quando `true`, exige que o `logout_token` inclua a claim `sid`. Ignorado quando
|
|
18
|
+
* `backchannelLogoutUri` não está definido.
|
|
19
|
+
*/
|
|
20
|
+
backchannelLogoutSessionRequired?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** Client persistido, apresentado ao console admin. */
|
|
23
|
+
export interface AdminClient {
|
|
24
|
+
clientId: string;
|
|
25
|
+
confidential: boolean;
|
|
26
|
+
grants: string[];
|
|
27
|
+
redirectUris: string[];
|
|
28
|
+
postLogoutRedirectUris: string[];
|
|
29
|
+
tokenEndpointAuthMethod: string;
|
|
30
|
+
/** Endpoint de OIDC Back-Channel Logout (opcional). */
|
|
31
|
+
backchannelLogoutUri?: string;
|
|
32
|
+
/** Exige sid no logout_token (opcional). */
|
|
33
|
+
backchannelLogoutSessionRequired?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Resultado de uma criação: o client + o secret em claro (mostrado UMA vez). */
|
|
36
|
+
export interface CreatedClient {
|
|
37
|
+
clientId: string;
|
|
38
|
+
/** undefined para public clients (sem secret). */
|
|
39
|
+
clientSecret?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Serviço de CRUD de clients OIDC persistidos no adapter (model `Client`),
|
|
43
|
+
* usado pelo console admin. Encapsula:
|
|
44
|
+
* - a montagem do payload NA FORMA EXATA que o oidc-provider espera (snake_case,
|
|
45
|
+
* igual ao que o registro dinâmico — RFC 7591 — grava);
|
|
46
|
+
* - a invalidação do cache de clients dinâmicos do provider após cada escrita
|
|
47
|
+
* (ver {@link OidcService.evictDynamicClientCache});
|
|
48
|
+
* - a enumeração via a capacidade opcional `list` do adapter.
|
|
49
|
+
*/
|
|
50
|
+
export declare class AdminClientsService {
|
|
51
|
+
#private;
|
|
52
|
+
private oidc;
|
|
53
|
+
constructor(oidc: OidcService);
|
|
54
|
+
/** Indica se o adapter suporta enumeração (capacidade opcional). */
|
|
55
|
+
get canList(): boolean;
|
|
56
|
+
/** Lista os clients persistidos (vazio quando o adapter não enumera; cheque canList). */
|
|
57
|
+
list(): Promise<AdminClient[]>;
|
|
58
|
+
/** Lê um client persistido pelo client_id (undefined quando não existe). */
|
|
59
|
+
find(clientId: string): Promise<AdminClient | undefined>;
|
|
60
|
+
/**
|
|
61
|
+
* Cria um client. Gera client_id quando não informado; gera client_secret
|
|
62
|
+
* para clients confidenciais (auth method != 'none'). Retorna o secret em
|
|
63
|
+
* claro UMA vez (não é recuperável depois — o payload guarda o mesmo valor).
|
|
64
|
+
*/
|
|
65
|
+
create(input: ClientInput): Promise<CreatedClient>;
|
|
66
|
+
/**
|
|
67
|
+
* Cria um client PRESERVANDO um `clientSecret` fornecido externamente (em vez de
|
|
68
|
+
* gerar um aleatório). Útil para migração de clients estáticos do config, onde o
|
|
69
|
+
* secret original deve ser preservado para não quebrar apps já configurados.
|
|
70
|
+
*
|
|
71
|
+
* Para clients públicos (auth method `none`), `providedSecret` é ignorado.
|
|
72
|
+
* Lança se o `clientId` já existir no adapter — chame `find` antes.
|
|
73
|
+
*/
|
|
74
|
+
createWithSecret(input: ClientInput, providedSecret: string | undefined): Promise<CreatedClient>;
|
|
75
|
+
/**
|
|
76
|
+
* Atualiza metadata editável (redirect/post-logout URIs, grants, auth method)
|
|
77
|
+
* PRESERVANDO o client_secret existente. Lança se o client não existe.
|
|
78
|
+
*/
|
|
79
|
+
update(clientId: string, input: Partial<ClientInput>): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Regenera o client_secret de um client confidencial, preservando o resto da
|
|
82
|
+
* metadata. Retorna o novo secret em claro (mostrado UMA vez). Lança se o
|
|
83
|
+
* client não existe ou é public (auth method 'none').
|
|
84
|
+
*/
|
|
85
|
+
regenerateSecret(clientId: string): Promise<string>;
|
|
86
|
+
/** Remove um client persistido e invalida o cache. */
|
|
87
|
+
delete(clientId: string): Promise<void>;
|
|
88
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
/** Métodos públicos (sem segredo) — espelham os "non-secret" do oidc-provider. */
|
|
3
|
+
const PUBLIC_AUTH_METHODS = new Set(['none']);
|
|
4
|
+
/** Gera um identificador opaco no estilo do oidc-provider (~43 chars base64url). */
|
|
5
|
+
function randomId() {
|
|
6
|
+
return randomBytes(32).toString('base64url');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Serviço de CRUD de clients OIDC persistidos no adapter (model `Client`),
|
|
10
|
+
* usado pelo console admin. Encapsula:
|
|
11
|
+
* - a montagem do payload NA FORMA EXATA que o oidc-provider espera (snake_case,
|
|
12
|
+
* igual ao que o registro dinâmico — RFC 7591 — grava);
|
|
13
|
+
* - a invalidação do cache de clients dinâmicos do provider após cada escrita
|
|
14
|
+
* (ver {@link OidcService.evictDynamicClientCache});
|
|
15
|
+
* - a enumeração via a capacidade opcional `list` do adapter.
|
|
16
|
+
*/
|
|
17
|
+
export class AdminClientsService {
|
|
18
|
+
oidc;
|
|
19
|
+
#adapter;
|
|
20
|
+
constructor(oidc) {
|
|
21
|
+
this.oidc = oidc;
|
|
22
|
+
// O AdapterClass é o MESMO que o provider usa; instanciamos o model 'Client'
|
|
23
|
+
// para ler/gravar os mesmos artefatos que o oidc-provider persiste.
|
|
24
|
+
this.#adapter = new oidc.config.AdapterClass('Client');
|
|
25
|
+
}
|
|
26
|
+
/** Indica se o adapter suporta enumeração (capacidade opcional). */
|
|
27
|
+
get canList() {
|
|
28
|
+
return typeof this.#adapter.list === 'function';
|
|
29
|
+
}
|
|
30
|
+
/** Lista os clients persistidos (vazio quando o adapter não enumera; cheque canList). */
|
|
31
|
+
async list() {
|
|
32
|
+
if (this.#adapter.list) {
|
|
33
|
+
const rows = await this.#adapter.list();
|
|
34
|
+
return rows.map((r) => this.#present({ clientId: r.id, payload: r.payload }));
|
|
35
|
+
}
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
/** Lê um client persistido pelo client_id (undefined quando não existe). */
|
|
39
|
+
async find(clientId) {
|
|
40
|
+
const payload = await this.#adapter.find(clientId);
|
|
41
|
+
if (!payload)
|
|
42
|
+
return undefined;
|
|
43
|
+
return this.#present({ clientId, payload: payload });
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Cria um client. Gera client_id quando não informado; gera client_secret
|
|
47
|
+
* para clients confidenciais (auth method != 'none'). Retorna o secret em
|
|
48
|
+
* claro UMA vez (não é recuperável depois — o payload guarda o mesmo valor).
|
|
49
|
+
*/
|
|
50
|
+
async create(input) {
|
|
51
|
+
const clientId = (input.clientId ?? '').trim() || randomId();
|
|
52
|
+
const confidential = !PUBLIC_AUTH_METHODS.has(input.tokenEndpointAuthMethod);
|
|
53
|
+
const clientSecret = confidential ? randomId() : undefined;
|
|
54
|
+
const payload = this.#buildPayload(clientId, input, clientSecret);
|
|
55
|
+
// expiresIn 0 => sem TTL (clients são permanentes, como no registro dinâmico).
|
|
56
|
+
await this.#adapter.upsert(clientId, payload, 0);
|
|
57
|
+
await this.oidc.evictDynamicClientCache();
|
|
58
|
+
return { clientId, clientSecret };
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Cria um client PRESERVANDO um `clientSecret` fornecido externamente (em vez de
|
|
62
|
+
* gerar um aleatório). Útil para migração de clients estáticos do config, onde o
|
|
63
|
+
* secret original deve ser preservado para não quebrar apps já configurados.
|
|
64
|
+
*
|
|
65
|
+
* Para clients públicos (auth method `none`), `providedSecret` é ignorado.
|
|
66
|
+
* Lança se o `clientId` já existir no adapter — chame `find` antes.
|
|
67
|
+
*/
|
|
68
|
+
async createWithSecret(input, providedSecret) {
|
|
69
|
+
const clientId = (input.clientId ?? '').trim() || randomId();
|
|
70
|
+
const confidential = !PUBLIC_AUTH_METHODS.has(input.tokenEndpointAuthMethod);
|
|
71
|
+
const clientSecret = confidential ? (providedSecret ?? randomId()) : undefined;
|
|
72
|
+
const payload = this.#buildPayload(clientId, input, clientSecret);
|
|
73
|
+
await this.#adapter.upsert(clientId, payload, 0);
|
|
74
|
+
await this.oidc.evictDynamicClientCache();
|
|
75
|
+
return { clientId, clientSecret };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Atualiza metadata editável (redirect/post-logout URIs, grants, auth method)
|
|
79
|
+
* PRESERVANDO o client_secret existente. Lança se o client não existe.
|
|
80
|
+
*/
|
|
81
|
+
async update(clientId, input) {
|
|
82
|
+
const existing = await this.#adapter.find(clientId);
|
|
83
|
+
if (!existing)
|
|
84
|
+
throw new Error(`client ${clientId} não encontrado`);
|
|
85
|
+
const previousSecret = existing.client_secret;
|
|
86
|
+
// MERGE (PATCH de verdade): campos não enviados (undefined) preservam o valor
|
|
87
|
+
// atual do client. Sem isto, um update parcial reseta tudo que não veio no body
|
|
88
|
+
// (ex.: não mandar tokenEndpointAuthMethod virava confidential; não mandar
|
|
89
|
+
// grantTypes derrubava token-exchange).
|
|
90
|
+
const merged = {
|
|
91
|
+
clientId,
|
|
92
|
+
redirectUris: input.redirectUris ?? (existing.redirect_uris ?? []),
|
|
93
|
+
postLogoutRedirectUris: input.postLogoutRedirectUris ?? (existing.post_logout_redirect_uris ?? []),
|
|
94
|
+
grantTypes: input.grantTypes ?? (existing.grant_types ?? []),
|
|
95
|
+
tokenEndpointAuthMethod: input.tokenEndpointAuthMethod ??
|
|
96
|
+
(existing.token_endpoint_auth_method ?? 'client_secret_basic'),
|
|
97
|
+
backchannelLogoutUri: input.backchannelLogoutUri ?? existing.backchannel_logout_uri,
|
|
98
|
+
backchannelLogoutSessionRequired: input.backchannelLogoutSessionRequired ??
|
|
99
|
+
existing.backchannel_logout_session_required,
|
|
100
|
+
};
|
|
101
|
+
const confidential = !PUBLIC_AUTH_METHODS.has(merged.tokenEndpointAuthMethod);
|
|
102
|
+
// Mantém o secret atual se continua confidencial; se virou public, remove-o.
|
|
103
|
+
const clientSecret = confidential ? (previousSecret ?? randomId()) : undefined;
|
|
104
|
+
const payload = this.#buildPayload(clientId, merged, clientSecret);
|
|
105
|
+
await this.#adapter.upsert(clientId, payload, 0);
|
|
106
|
+
await this.oidc.evictDynamicClientCache();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Regenera o client_secret de um client confidencial, preservando o resto da
|
|
110
|
+
* metadata. Retorna o novo secret em claro (mostrado UMA vez). Lança se o
|
|
111
|
+
* client não existe ou é public (auth method 'none').
|
|
112
|
+
*/
|
|
113
|
+
async regenerateSecret(clientId) {
|
|
114
|
+
const existing = await this.#adapter.find(clientId);
|
|
115
|
+
if (!existing)
|
|
116
|
+
throw new Error(`client ${clientId} não encontrado`);
|
|
117
|
+
const authMethod = existing.token_endpoint_auth_method ?? 'client_secret_basic';
|
|
118
|
+
if (PUBLIC_AUTH_METHODS.has(authMethod)) {
|
|
119
|
+
throw new Error(`client ${clientId} é public — não possui secret`);
|
|
120
|
+
}
|
|
121
|
+
const clientSecret = randomId();
|
|
122
|
+
const payload = { ...existing, client_secret: clientSecret };
|
|
123
|
+
await this.#adapter.upsert(clientId, payload, 0);
|
|
124
|
+
await this.oidc.evictDynamicClientCache();
|
|
125
|
+
return clientSecret;
|
|
126
|
+
}
|
|
127
|
+
/** Remove um client persistido e invalida o cache. */
|
|
128
|
+
async delete(clientId) {
|
|
129
|
+
await this.#adapter.destroy(clientId);
|
|
130
|
+
await this.oidc.evictDynamicClientCache();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Monta o payload na forma snake_case que o oidc-provider espera/persiste —
|
|
134
|
+
* verificada contra o que o registro dinâmico (RFC 7591) grava. As chaves de
|
|
135
|
+
* metadata não enviadas (subject_type, id_token_signed_response_alg, etc.) são
|
|
136
|
+
* preenchidas pelo Schema do provider ao construir o Client em `find`.
|
|
137
|
+
*/
|
|
138
|
+
#buildPayload(clientId, input, clientSecret) {
|
|
139
|
+
const grantTypes = input.grantTypes.length
|
|
140
|
+
? input.grantTypes
|
|
141
|
+
: ['authorization_code', 'refresh_token'];
|
|
142
|
+
// response_types: 'code' quando o fluxo de authorization_code está presente.
|
|
143
|
+
const responseTypes = grantTypes.includes('authorization_code') ? ['code'] : [];
|
|
144
|
+
const payload = {
|
|
145
|
+
client_id: clientId,
|
|
146
|
+
redirect_uris: input.redirectUris,
|
|
147
|
+
post_logout_redirect_uris: input.postLogoutRedirectUris,
|
|
148
|
+
grant_types: grantTypes,
|
|
149
|
+
response_types: responseTypes,
|
|
150
|
+
token_endpoint_auth_method: input.tokenEndpointAuthMethod,
|
|
151
|
+
};
|
|
152
|
+
if (clientSecret)
|
|
153
|
+
payload.client_secret = clientSecret;
|
|
154
|
+
if (input.backchannelLogoutUri) {
|
|
155
|
+
payload.backchannel_logout_uri = input.backchannelLogoutUri;
|
|
156
|
+
if (input.backchannelLogoutSessionRequired !== undefined) {
|
|
157
|
+
payload.backchannel_logout_session_required = input.backchannelLogoutSessionRequired;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return payload;
|
|
161
|
+
}
|
|
162
|
+
/** Projeta um payload persistido para a forma exibida no console admin. */
|
|
163
|
+
#present(row) {
|
|
164
|
+
const p = row.payload;
|
|
165
|
+
const authMethod = p.token_endpoint_auth_method ?? 'client_secret_basic';
|
|
166
|
+
const result = {
|
|
167
|
+
clientId: row.clientId,
|
|
168
|
+
confidential: !!p.client_secret,
|
|
169
|
+
grants: p.grant_types ?? ['authorization_code', 'refresh_token'],
|
|
170
|
+
redirectUris: p.redirect_uris ?? [],
|
|
171
|
+
postLogoutRedirectUris: p.post_logout_redirect_uris ?? [],
|
|
172
|
+
tokenEndpointAuthMethod: authMethod,
|
|
173
|
+
};
|
|
174
|
+
if (p.backchannel_logout_uri) {
|
|
175
|
+
result.backchannelLogoutUri = p.backchannel_logout_uri;
|
|
176
|
+
result.backchannelLogoutSessionRequired =
|
|
177
|
+
p.backchannel_logout_session_required ?? false;
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* Controla o serving do console admin React (Missão B).
|
|
4
|
+
*
|
|
5
|
+
* `serve` — serve o shell HTML (SPA) para TODAS as rotas de página do console.
|
|
6
|
+
* `serveAsset` — serve arquivos estáticos do build (JS/CSS/fonts/images) com cache.
|
|
7
|
+
*
|
|
8
|
+
* O shell HTML é o index.html produzido pelo Vite build em `build/host/ui-dist/`.
|
|
9
|
+
* O servidor injeta `window.__AUTHKIT__` e reescreve o placeholder de base dinâmica
|
|
10
|
+
* `/__AUTHKIT_BASE__/` → `${adminBase}/assets/` para que todos os imports de assets
|
|
11
|
+
* Vite resolvam corretamente independente do prefixo admin configurado.
|
|
12
|
+
*
|
|
13
|
+
* Se o dist não existir (ambiente de dev sem build prévia), serve o placeholder HTML
|
|
14
|
+
* legado de `src/host/ui/admin.html` com uma mensagem de instrução.
|
|
15
|
+
*/
|
|
16
|
+
export default class AdminShellController {
|
|
17
|
+
/**
|
|
18
|
+
* GET {prefix} — serve o shell HTML da SPA.
|
|
19
|
+
* GET {prefix}/* — idem (qualquer rota de página é tratada pela SPA via hash-routing).
|
|
20
|
+
*/
|
|
21
|
+
serve(ctx: HttpContext): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* GET {prefix}/assets/:file(*) — serve assets estáticos do Vite build.
|
|
24
|
+
* Os assets do Vite têm hash no nome → cache agressivo (1 ano).
|
|
25
|
+
*/
|
|
26
|
+
serveAsset(ctx: HttpContext): Promise<void>;
|
|
27
|
+
}
|