@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,104 @@
|
|
|
1
|
+
import { generateSigningJwk, planRotation } from './keystore.js';
|
|
2
|
+
import { FileKeystoreVault, DriveKeystoreVault, LucidKeystoreVault, RedisKeystoreVault, HashicorpVaultKeystoreVault, LazyExternalVault } from './keystore_vault.js';
|
|
3
|
+
/**
|
|
4
|
+
* Único caminho de I/O do keystore managed: compõe um {@link KeystoreVault} (onde
|
|
5
|
+
* o blob mora) com um {@link KeystoreCodec} (serialização + encryption). As helpers
|
|
6
|
+
* puras (gerar chave, planejar rotação) continuam em `keystore.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export class KeystoreManager {
|
|
9
|
+
vault;
|
|
10
|
+
codec;
|
|
11
|
+
alg;
|
|
12
|
+
constructor(vault, codec, alg) {
|
|
13
|
+
this.vault = vault;
|
|
14
|
+
this.codec = codec;
|
|
15
|
+
this.alg = alg;
|
|
16
|
+
}
|
|
17
|
+
/** Lê o keystore (privado) ou null se ausente. */
|
|
18
|
+
async read() {
|
|
19
|
+
const blob = await this.vault.read();
|
|
20
|
+
if (blob == null)
|
|
21
|
+
return null;
|
|
22
|
+
return this.codec.decode(blob);
|
|
23
|
+
}
|
|
24
|
+
/** Garante que exista: gera+persiste se ausente; senão decodifica e retorna. */
|
|
25
|
+
async ensure() {
|
|
26
|
+
const blob = await this.vault.read();
|
|
27
|
+
if (blob == null) {
|
|
28
|
+
const store = { keys: [await generateSigningJwk(this.alg)] };
|
|
29
|
+
await this.vault.write(await this.codec.encode(store));
|
|
30
|
+
return store;
|
|
31
|
+
}
|
|
32
|
+
return this.codec.decode(blob);
|
|
33
|
+
}
|
|
34
|
+
/** Rotaciona: chave nova na frente, mantém as `keep` mais recentes. Persiste. */
|
|
35
|
+
async rotate(keep = 2, retire = false) {
|
|
36
|
+
const current = (await this.read()) ?? { keys: [] };
|
|
37
|
+
const fresh = await generateSigningJwk(this.alg);
|
|
38
|
+
const next = [fresh, ...current.keys];
|
|
39
|
+
const effectiveKeep = retire ? 1 : Math.max(1, keep);
|
|
40
|
+
const kept = next.slice(0, effectiveKeep);
|
|
41
|
+
const retiredKids = next.slice(effectiveKeep).map((k) => k.kid);
|
|
42
|
+
const store = { keys: kept };
|
|
43
|
+
await this.vault.write(await this.codec.encode(store));
|
|
44
|
+
return { store, newKid: fresh.kid, retiredKids };
|
|
45
|
+
}
|
|
46
|
+
/** Plano de rotação (puro, sem I/O de escrita). */
|
|
47
|
+
async plan(keep, retire) {
|
|
48
|
+
return planRotation(await this.read(), keep, retire);
|
|
49
|
+
}
|
|
50
|
+
/** Token barato de mudança (delegado ao vault; fallback p/ read completo). */
|
|
51
|
+
async head() {
|
|
52
|
+
if (this.vault.head)
|
|
53
|
+
return this.vault.head();
|
|
54
|
+
return this.vault.read();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Packages-irmãos que entregam os cofres de cloud (planos futuros). */
|
|
58
|
+
const CLOUD_DRIVER_PACKAGE = {
|
|
59
|
+
'aws-secrets-manager': '@adonis-agora/authkit-vault-aws',
|
|
60
|
+
'gcp-secret-manager': '@adonis-agora/authkit-vault-gcp',
|
|
61
|
+
'azure-key-vault': '@adonis-agora/authkit-vault-azure',
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Resolve a config `store` num {@link KeystoreVault}. `ctx.makePath` = `app.makePath`
|
|
65
|
+
* (resolve paths relativos à raiz do app). Instância custom (com `read`/`write`)
|
|
66
|
+
* passa direto. Drivers de cloud lançam nesta fatia (chegam nos packages-irmãos).
|
|
67
|
+
*/
|
|
68
|
+
export function resolveKeystoreVault(store, ctx) {
|
|
69
|
+
if (typeof store === 'string')
|
|
70
|
+
return new FileKeystoreVault(ctx.makePath(store));
|
|
71
|
+
if (typeof store.read === 'function')
|
|
72
|
+
return store;
|
|
73
|
+
const cfg = store;
|
|
74
|
+
switch (cfg.driver) {
|
|
75
|
+
case 'file':
|
|
76
|
+
return new FileKeystoreVault(ctx.makePath(cfg.path));
|
|
77
|
+
case 'drive':
|
|
78
|
+
return new DriveKeystoreVault(cfg.key, cfg.disk);
|
|
79
|
+
case 'lucid':
|
|
80
|
+
return new LucidKeystoreVault(async () => {
|
|
81
|
+
const db = await ctx.container.make('lucid.db');
|
|
82
|
+
return cfg.connection ? db.connection(cfg.connection) : db.connection();
|
|
83
|
+
}, cfg.table, cfg.key);
|
|
84
|
+
case 'redis':
|
|
85
|
+
return new RedisKeystoreVault(async () => {
|
|
86
|
+
const rm = await ctx.container.make('redis');
|
|
87
|
+
return cfg.connection ? rm.connection(cfg.connection) : rm.connection();
|
|
88
|
+
}, cfg.key);
|
|
89
|
+
case 'hashicorp-vault':
|
|
90
|
+
return new HashicorpVaultKeystoreVault({
|
|
91
|
+
endpoint: cfg.endpoint,
|
|
92
|
+
path: cfg.path,
|
|
93
|
+
token: cfg.token,
|
|
94
|
+
mount: cfg.mount,
|
|
95
|
+
field: cfg.field,
|
|
96
|
+
});
|
|
97
|
+
default: {
|
|
98
|
+
const pkg = CLOUD_DRIVER_PACKAGE[cfg.driver];
|
|
99
|
+
if (!pkg)
|
|
100
|
+
throw new Error(`AuthKit keystore: driver "${cfg.driver}" desconhecido.`);
|
|
101
|
+
return new LazyExternalVault(pkg, cfg);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cofre onde o keystore (blob, possivelmente encriptado) é persistido. Ponto de
|
|
3
|
+
* extensão: cofres custom implementam esta interface. `head` é um token barato de
|
|
4
|
+
* detecção de mudança (mtime/etag/versão) p/ o poll de reload (Fatia C).
|
|
5
|
+
*/
|
|
6
|
+
export interface KeystoreVault {
|
|
7
|
+
read(): Promise<string | null>;
|
|
8
|
+
write(blob: string): Promise<void>;
|
|
9
|
+
head?(): Promise<string | null>;
|
|
10
|
+
}
|
|
11
|
+
/** Cofre em arquivo local (default; mode 0600). */
|
|
12
|
+
export declare class FileKeystoreVault implements KeystoreVault {
|
|
13
|
+
private path;
|
|
14
|
+
constructor(path: string);
|
|
15
|
+
read(): Promise<string | null>;
|
|
16
|
+
write(blob: string): Promise<void>;
|
|
17
|
+
head(): Promise<string | null>;
|
|
18
|
+
}
|
|
19
|
+
/** Service do `@adonisjs/drive` resolvido lazy (peer opt-in; mesmo padrão do avatar). */
|
|
20
|
+
type DriveService = any;
|
|
21
|
+
/** Reaponta o loader do drive (testes). @internal */
|
|
22
|
+
export declare function __setKeystoreDriveLoaderForTests(fn: (() => Promise<DriveService | null>) | undefined): void;
|
|
23
|
+
/**
|
|
24
|
+
* Cofre numa tabela Lucid dedicada (`authkit_keystore`, KV de uma linha). Compartilhado
|
|
25
|
+
* entre instâncias (multi-instância nativo). Auto-cria a tabela no primeiro write — o
|
|
26
|
+
* keystore carrega na resolução do config, ANTES do `start()` (onde o schema auto-manage
|
|
27
|
+
* roda), então o vault não pode depender dela existir. `getConn` é lazy. `head()` = updated_at.
|
|
28
|
+
*/
|
|
29
|
+
export declare class LucidKeystoreVault implements KeystoreVault {
|
|
30
|
+
private getConn;
|
|
31
|
+
private table;
|
|
32
|
+
private key;
|
|
33
|
+
constructor(getConn: () => Promise<any>, table?: string, key?: string);
|
|
34
|
+
private ensureTable;
|
|
35
|
+
read(): Promise<string | null>;
|
|
36
|
+
write(blob: string): Promise<void>;
|
|
37
|
+
head(): Promise<string | null>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Cofre numa key do Redis. Compartilhado entre instâncias (multi-instância nativo).
|
|
41
|
+
* `getClient` é lazy. `head()` devolve o próprio blob (redis get é barato).
|
|
42
|
+
*
|
|
43
|
+
* ⚠️ Requer Redis com PERSISTÊNCIA (RDB/AOF): num Redis cache-only, um flush apaga o
|
|
44
|
+
* keystore → todos os tokens invalidam. (Há um warning no boot quando o driver é redis.)
|
|
45
|
+
*/
|
|
46
|
+
export declare class RedisKeystoreVault implements KeystoreVault {
|
|
47
|
+
private getClient;
|
|
48
|
+
private key;
|
|
49
|
+
constructor(getClient: () => Promise<any>, key?: string);
|
|
50
|
+
read(): Promise<string | null>;
|
|
51
|
+
write(blob: string): Promise<void>;
|
|
52
|
+
head(): Promise<string | null>;
|
|
53
|
+
}
|
|
54
|
+
/** fetch mínimo que o vault HTTP usa (injetável p/ testes). */
|
|
55
|
+
type VaultFetch = (url: string, init?: {
|
|
56
|
+
method?: string;
|
|
57
|
+
headers?: Record<string, string>;
|
|
58
|
+
body?: string;
|
|
59
|
+
}) => Promise<{
|
|
60
|
+
ok: boolean;
|
|
61
|
+
status: number;
|
|
62
|
+
json(): Promise<any>;
|
|
63
|
+
}>;
|
|
64
|
+
export interface HashicorpVaultConfig {
|
|
65
|
+
endpoint: string;
|
|
66
|
+
path: string;
|
|
67
|
+
token?: string;
|
|
68
|
+
mount?: string;
|
|
69
|
+
field?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Cofre no HashiCorp Vault (KV v2, via API HTTP — sem SDK). Compartilhado entre
|
|
73
|
+
* instâncias e com encryption/ACL próprios do Vault (por isso `encrypt` default OFF).
|
|
74
|
+
* Crítico: erro HTTP não-404 lança (não degrada). `head()` = versão atual (metadata).
|
|
75
|
+
*/
|
|
76
|
+
export declare class HashicorpVaultKeystoreVault implements KeystoreVault {
|
|
77
|
+
#private;
|
|
78
|
+
constructor(cfg: HashicorpVaultConfig, fetchImpl?: VaultFetch);
|
|
79
|
+
read(): Promise<string | null>;
|
|
80
|
+
write(blob: string): Promise<void>;
|
|
81
|
+
head(): Promise<string | null>;
|
|
82
|
+
}
|
|
83
|
+
type ExternalImport = (spec: string) => Promise<any>;
|
|
84
|
+
/**
|
|
85
|
+
* Proxy que lazy-importa um package de cofre externo (aws/gcp/azure secrets managers)
|
|
86
|
+
* no PRIMEIRO I/O e delega. Mantém `resolveKeystoreVault` síncrono. O package precisa
|
|
87
|
+
* exportar `createKeystoreVault(cfg): KeystoreVault`. Se não estiver instalado → erro
|
|
88
|
+
* claro pedindo pra instalar (chave é crítica, não degrada).
|
|
89
|
+
*/
|
|
90
|
+
export declare class LazyExternalVault implements KeystoreVault {
|
|
91
|
+
#private;
|
|
92
|
+
private pkg;
|
|
93
|
+
private cfg;
|
|
94
|
+
private importFn;
|
|
95
|
+
constructor(pkg: string, cfg: any, importFn?: ExternalImport);
|
|
96
|
+
read(): Promise<string | null>;
|
|
97
|
+
write(blob: string): Promise<void>;
|
|
98
|
+
head(): Promise<string | null>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Cofre num disk do `@adonisjs/drive` (S3/GCS/local). Diferente do avatar, chave é
|
|
102
|
+
* crítica: se o drive não está instalado mas foi selecionado → ERRO (não degrada).
|
|
103
|
+
*/
|
|
104
|
+
export declare class DriveKeystoreVault implements KeystoreVault {
|
|
105
|
+
private key;
|
|
106
|
+
private diskName?;
|
|
107
|
+
constructor(key: string, diskName?: string | undefined);
|
|
108
|
+
private disk;
|
|
109
|
+
read(): Promise<string | null>;
|
|
110
|
+
write(blob: string): Promise<void>;
|
|
111
|
+
head(): Promise<string | null>;
|
|
112
|
+
}
|
|
113
|
+
export {};
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { dirname } from 'node:path';
|
|
11
|
+
/** Cofre em arquivo local (default; mode 0600). */
|
|
12
|
+
export class FileKeystoreVault {
|
|
13
|
+
path;
|
|
14
|
+
constructor(path) {
|
|
15
|
+
this.path = path;
|
|
16
|
+
}
|
|
17
|
+
async read() {
|
|
18
|
+
return existsSync(this.path) ? readFileSync(this.path, 'utf-8') : null;
|
|
19
|
+
}
|
|
20
|
+
async write(blob) {
|
|
21
|
+
mkdirSync(dirname(this.path), { recursive: true });
|
|
22
|
+
writeFileSync(this.path, blob.endsWith('\n') ? blob : blob + '\n', { mode: 0o600 });
|
|
23
|
+
}
|
|
24
|
+
async head() {
|
|
25
|
+
return existsSync(this.path) ? String(statSync(this.path).mtimeMs) : null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
let driveServicePromise;
|
|
29
|
+
async function loadDrive() {
|
|
30
|
+
if (!driveServicePromise) {
|
|
31
|
+
const specifier = '@adonisjs/drive/services/main';
|
|
32
|
+
driveServicePromise = import(__rewriteRelativeImportExtension(specifier))
|
|
33
|
+
.then((m) => m.default ?? null)
|
|
34
|
+
.catch(() => null);
|
|
35
|
+
}
|
|
36
|
+
return driveServicePromise;
|
|
37
|
+
}
|
|
38
|
+
/** Reaponta o loader do drive (testes). @internal */
|
|
39
|
+
export function __setKeystoreDriveLoaderForTests(fn) {
|
|
40
|
+
driveServicePromise = fn ? fn() : undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Cofre numa tabela Lucid dedicada (`authkit_keystore`, KV de uma linha). Compartilhado
|
|
44
|
+
* entre instâncias (multi-instância nativo). Auto-cria a tabela no primeiro write — o
|
|
45
|
+
* keystore carrega na resolução do config, ANTES do `start()` (onde o schema auto-manage
|
|
46
|
+
* roda), então o vault não pode depender dela existir. `getConn` é lazy. `head()` = updated_at.
|
|
47
|
+
*/
|
|
48
|
+
export class LucidKeystoreVault {
|
|
49
|
+
getConn;
|
|
50
|
+
table;
|
|
51
|
+
key;
|
|
52
|
+
constructor(getConn, table = 'authkit_keystore', key = 'jwks') {
|
|
53
|
+
this.getConn = getConn;
|
|
54
|
+
this.table = table;
|
|
55
|
+
this.key = key;
|
|
56
|
+
}
|
|
57
|
+
async ensureTable(conn) {
|
|
58
|
+
if (await conn.schema.hasTable(this.table))
|
|
59
|
+
return;
|
|
60
|
+
try {
|
|
61
|
+
await conn.schema.createTable(this.table, (t) => {
|
|
62
|
+
t.string('key').notNullable().primary();
|
|
63
|
+
t.text('blob').notNullable();
|
|
64
|
+
t.bigInteger('updated_at').notNullable();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
// Outra instância criou a tabela entre o hasTable e o createTable (race no boot
|
|
69
|
+
// multi-instância). Se já existe agora, OK; senão propaga.
|
|
70
|
+
if (!(await conn.schema.hasTable(this.table)))
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async read() {
|
|
75
|
+
const conn = await this.getConn();
|
|
76
|
+
if (!(await conn.schema.hasTable(this.table)))
|
|
77
|
+
return null;
|
|
78
|
+
const row = await conn.from(this.table).where('key', this.key).first();
|
|
79
|
+
return row ? row.blob : null;
|
|
80
|
+
}
|
|
81
|
+
async write(blob) {
|
|
82
|
+
const conn = await this.getConn();
|
|
83
|
+
await this.ensureTable(conn);
|
|
84
|
+
await conn
|
|
85
|
+
.table(this.table)
|
|
86
|
+
.insert({ key: this.key, blob, updated_at: Date.now() })
|
|
87
|
+
.onConflict('key')
|
|
88
|
+
.merge();
|
|
89
|
+
}
|
|
90
|
+
async head() {
|
|
91
|
+
const conn = await this.getConn();
|
|
92
|
+
if (!(await conn.schema.hasTable(this.table)))
|
|
93
|
+
return null;
|
|
94
|
+
const row = await conn.from(this.table).where('key', this.key).first();
|
|
95
|
+
return row ? String(row.updated_at) : null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Cofre numa key do Redis. Compartilhado entre instâncias (multi-instância nativo).
|
|
100
|
+
* `getClient` é lazy. `head()` devolve o próprio blob (redis get é barato).
|
|
101
|
+
*
|
|
102
|
+
* ⚠️ Requer Redis com PERSISTÊNCIA (RDB/AOF): num Redis cache-only, um flush apaga o
|
|
103
|
+
* keystore → todos os tokens invalidam. (Há um warning no boot quando o driver é redis.)
|
|
104
|
+
*/
|
|
105
|
+
export class RedisKeystoreVault {
|
|
106
|
+
getClient;
|
|
107
|
+
key;
|
|
108
|
+
constructor(getClient, key = 'authkit:jwks') {
|
|
109
|
+
this.getClient = getClient;
|
|
110
|
+
this.key = key;
|
|
111
|
+
}
|
|
112
|
+
async read() {
|
|
113
|
+
const client = await this.getClient();
|
|
114
|
+
return (await client.get(this.key)) ?? null;
|
|
115
|
+
}
|
|
116
|
+
async write(blob) {
|
|
117
|
+
const client = await this.getClient();
|
|
118
|
+
await client.set(this.key, blob);
|
|
119
|
+
}
|
|
120
|
+
async head() {
|
|
121
|
+
const client = await this.getClient();
|
|
122
|
+
return (await client.get(this.key)) ?? null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Cofre no HashiCorp Vault (KV v2, via API HTTP — sem SDK). Compartilhado entre
|
|
127
|
+
* instâncias e com encryption/ACL próprios do Vault (por isso `encrypt` default OFF).
|
|
128
|
+
* Crítico: erro HTTP não-404 lança (não degrada). `head()` = versão atual (metadata).
|
|
129
|
+
*/
|
|
130
|
+
export class HashicorpVaultKeystoreVault {
|
|
131
|
+
#endpoint;
|
|
132
|
+
#mount;
|
|
133
|
+
#path;
|
|
134
|
+
#field;
|
|
135
|
+
#token;
|
|
136
|
+
#fetch;
|
|
137
|
+
constructor(cfg, fetchImpl) {
|
|
138
|
+
this.#endpoint = cfg.endpoint.replace(/\/+$/, '');
|
|
139
|
+
this.#mount = (cfg.mount ?? 'secret').replace(/^\/+|\/+$/g, '');
|
|
140
|
+
this.#path = cfg.path.replace(/^\/+/, '');
|
|
141
|
+
this.#field = cfg.field ?? 'value';
|
|
142
|
+
this.#token = cfg.token;
|
|
143
|
+
this.#fetch = fetchImpl ?? globalThis.fetch;
|
|
144
|
+
}
|
|
145
|
+
#headers() {
|
|
146
|
+
const h = { 'content-type': 'application/json' };
|
|
147
|
+
if (this.#token)
|
|
148
|
+
h['x-vault-token'] = this.#token;
|
|
149
|
+
return h;
|
|
150
|
+
}
|
|
151
|
+
#dataUrl() { return `${this.#endpoint}/v1/${this.#mount}/data/${this.#path}`; }
|
|
152
|
+
#metaUrl() { return `${this.#endpoint}/v1/${this.#mount}/metadata/${this.#path}`; }
|
|
153
|
+
async read() {
|
|
154
|
+
const res = await this.#fetch(this.#dataUrl(), { method: 'GET', headers: this.#headers() });
|
|
155
|
+
if (res.status === 404)
|
|
156
|
+
return null;
|
|
157
|
+
if (!res.ok)
|
|
158
|
+
throw new Error(`AuthKit keystore (hashicorp-vault): read falhou (HTTP ${res.status}).`);
|
|
159
|
+
const body = await res.json();
|
|
160
|
+
const value = body?.data?.data?.[this.#field];
|
|
161
|
+
return typeof value === 'string' ? value : null;
|
|
162
|
+
}
|
|
163
|
+
async write(blob) {
|
|
164
|
+
const res = await this.#fetch(this.#dataUrl(), {
|
|
165
|
+
method: 'POST',
|
|
166
|
+
headers: this.#headers(),
|
|
167
|
+
body: JSON.stringify({ data: { [this.#field]: blob } }),
|
|
168
|
+
});
|
|
169
|
+
if (!res.ok)
|
|
170
|
+
throw new Error(`AuthKit keystore (hashicorp-vault): write falhou (HTTP ${res.status}).`);
|
|
171
|
+
}
|
|
172
|
+
async head() {
|
|
173
|
+
const res = await this.#fetch(this.#metaUrl(), { method: 'GET', headers: this.#headers() });
|
|
174
|
+
if (res.status === 404)
|
|
175
|
+
return null;
|
|
176
|
+
if (!res.ok)
|
|
177
|
+
return null; // head é best-effort p/ o poll
|
|
178
|
+
const body = await res.json();
|
|
179
|
+
const v = body?.data?.current_version;
|
|
180
|
+
return v === undefined || v === null ? null : String(v);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Proxy que lazy-importa um package de cofre externo (aws/gcp/azure secrets managers)
|
|
185
|
+
* no PRIMEIRO I/O e delega. Mantém `resolveKeystoreVault` síncrono. O package precisa
|
|
186
|
+
* exportar `createKeystoreVault(cfg): KeystoreVault`. Se não estiver instalado → erro
|
|
187
|
+
* claro pedindo pra instalar (chave é crítica, não degrada).
|
|
188
|
+
*/
|
|
189
|
+
export class LazyExternalVault {
|
|
190
|
+
pkg;
|
|
191
|
+
cfg;
|
|
192
|
+
importFn;
|
|
193
|
+
#inner;
|
|
194
|
+
constructor(pkg, cfg, importFn = (spec) => import(__rewriteRelativeImportExtension(spec))) {
|
|
195
|
+
this.pkg = pkg;
|
|
196
|
+
this.cfg = cfg;
|
|
197
|
+
this.importFn = importFn;
|
|
198
|
+
}
|
|
199
|
+
async #resolve() {
|
|
200
|
+
if (this.#inner)
|
|
201
|
+
return this.#inner;
|
|
202
|
+
let mod;
|
|
203
|
+
try {
|
|
204
|
+
mod = await this.importFn(this.pkg);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
throw new Error(`AuthKit keystore: instale o package ${this.pkg} para usar este driver.`);
|
|
208
|
+
}
|
|
209
|
+
const factory = mod?.createKeystoreVault ?? mod?.default?.createKeystoreVault;
|
|
210
|
+
if (typeof factory !== 'function') {
|
|
211
|
+
throw new Error(`AuthKit keystore: ${this.pkg} não exporta createKeystoreVault.`);
|
|
212
|
+
}
|
|
213
|
+
this.#inner = factory(this.cfg);
|
|
214
|
+
return this.#inner;
|
|
215
|
+
}
|
|
216
|
+
async read() {
|
|
217
|
+
return (await this.#resolve()).read();
|
|
218
|
+
}
|
|
219
|
+
async write(blob) {
|
|
220
|
+
return (await this.#resolve()).write(blob);
|
|
221
|
+
}
|
|
222
|
+
async head() {
|
|
223
|
+
const v = await this.#resolve();
|
|
224
|
+
return v.head ? v.head() : null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Cofre num disk do `@adonisjs/drive` (S3/GCS/local). Diferente do avatar, chave é
|
|
229
|
+
* crítica: se o drive não está instalado mas foi selecionado → ERRO (não degrada).
|
|
230
|
+
*/
|
|
231
|
+
export class DriveKeystoreVault {
|
|
232
|
+
key;
|
|
233
|
+
diskName;
|
|
234
|
+
constructor(key, diskName) {
|
|
235
|
+
this.key = key;
|
|
236
|
+
this.diskName = diskName;
|
|
237
|
+
}
|
|
238
|
+
async disk() {
|
|
239
|
+
const drive = await loadDrive();
|
|
240
|
+
if (!drive) {
|
|
241
|
+
throw new Error('AuthKit keystore: driver "drive" selecionado mas @adonisjs/drive não está instalado.');
|
|
242
|
+
}
|
|
243
|
+
return this.diskName ? drive.use(this.diskName) : drive;
|
|
244
|
+
}
|
|
245
|
+
async read() {
|
|
246
|
+
const disk = await this.disk();
|
|
247
|
+
if (!(await disk.exists(this.key)))
|
|
248
|
+
return null;
|
|
249
|
+
return disk.get(this.key);
|
|
250
|
+
}
|
|
251
|
+
async write(blob) {
|
|
252
|
+
const disk = await this.disk();
|
|
253
|
+
await disk.put(this.key, blob);
|
|
254
|
+
}
|
|
255
|
+
async head() {
|
|
256
|
+
const disk = await this.disk();
|
|
257
|
+
try {
|
|
258
|
+
const meta = await disk.getMetaData(this.key);
|
|
259
|
+
return meta?.etag ?? (meta?.lastModified ? String(new Date(meta.lastModified).getTime()) : null);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializer canônico de coluna JSON para os mixins. Centraliza o par
|
|
3
|
+
* `prepare`/`consume` (`JSON.stringify`/`JSON.parse`) que cada mixin escrevia à
|
|
4
|
+
* mão com tratamentos de null/default ligeiramente diferentes.
|
|
5
|
+
*
|
|
6
|
+
* As opções parametrizam exatamente as variações observadas entre os mixins, de
|
|
7
|
+
* modo que o comportamento por coluna fica IDÊNTICO ao código original:
|
|
8
|
+
*
|
|
9
|
+
* - `fallback`: valor devolvido por `consume` quando a coluna é null/undefined
|
|
10
|
+
* (ex.: `[]` para `globalRoles`/`scopes`; `null` para `recoveryCodes`/`metadata`).
|
|
11
|
+
* - `emptyOnWrite`: o que `prepare` grava quando o valor é "vazio" (null/undefined,
|
|
12
|
+
* ou — quando `treatEmptyArrayAsEmpty` — um array de length 0). `'null'` grava
|
|
13
|
+
* `null` na coluna; `'serialize'` ainda serializa (ex.: `globalRoles` grava
|
|
14
|
+
* `"[]"`). Default: `'null'`.
|
|
15
|
+
* - `treatEmptyArrayAsEmpty`: quando true, um array vazio também conta como "vazio"
|
|
16
|
+
* no write (caso do `transports`, que grava null em `[]`). Default: false.
|
|
17
|
+
*/
|
|
18
|
+
export interface JsonColumnOptions<T> {
|
|
19
|
+
/** Valor devolvido por `consume` quando a coluna está null/undefined. */
|
|
20
|
+
fallback: T;
|
|
21
|
+
/** O que `prepare` grava para valores vazios. Default: 'null'. */
|
|
22
|
+
emptyOnWrite?: 'null' | 'serialize';
|
|
23
|
+
/** Trata array vazio como "vazio" no write (grava null). Default: false. */
|
|
24
|
+
treatEmptyArrayAsEmpty?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Devolve o par `{ prepare, consume }` para usar num `@column({...})`.
|
|
28
|
+
* `T` é o tipo lógico da coluna (ex.: `string[]` ou `Record<string, unknown>`).
|
|
29
|
+
*/
|
|
30
|
+
export declare function jsonColumn<T>(opts: JsonColumnOptions<T>): {
|
|
31
|
+
prepare: (value: T | null | undefined) => string | null;
|
|
32
|
+
consume: (value: unknown) => T;
|
|
33
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Devolve o par `{ prepare, consume }` para usar num `@column({...})`.
|
|
3
|
+
* `T` é o tipo lógico da coluna (ex.: `string[]` ou `Record<string, unknown>`).
|
|
4
|
+
*/
|
|
5
|
+
export function jsonColumn(opts) {
|
|
6
|
+
const emptyOnWrite = opts.emptyOnWrite ?? 'null';
|
|
7
|
+
const treatEmptyArrayAsEmpty = opts.treatEmptyArrayAsEmpty ?? false;
|
|
8
|
+
const isEmpty = (value) => {
|
|
9
|
+
if (value === null || value === undefined)
|
|
10
|
+
return true;
|
|
11
|
+
if (treatEmptyArrayAsEmpty && Array.isArray(value) && value.length === 0)
|
|
12
|
+
return true;
|
|
13
|
+
return false;
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
prepare: (value) => {
|
|
17
|
+
if (isEmpty(value)) {
|
|
18
|
+
return emptyOnWrite === 'serialize' ? JSON.stringify(opts.fallback) : null;
|
|
19
|
+
}
|
|
20
|
+
return JSON.stringify(value);
|
|
21
|
+
},
|
|
22
|
+
consume: (value) => {
|
|
23
|
+
if (value === null || value === undefined)
|
|
24
|
+
return opts.fallback;
|
|
25
|
+
// Drivers de Postgres entregam colunas json/jsonb JÁ desserializadas
|
|
26
|
+
// (objeto/array); SQLite entrega TEXT. Só strings precisam de JSON.parse —
|
|
27
|
+
// parsear um objeto vira JSON.parse("[object Object]") e explode.
|
|
28
|
+
if (typeof value !== 'string')
|
|
29
|
+
return value;
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse(value);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return opts.fallback;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseModel } from '@adonisjs/lucid/orm';
|
|
2
|
+
import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
|
|
3
|
+
import { DateTime } from 'luxon';
|
|
4
|
+
import type { AuditEventType } from '../audit/audit_sink.js';
|
|
5
|
+
/** Instância composta pelo mixin {@link withAuditLog}. */
|
|
6
|
+
export interface AuditLogRow {
|
|
7
|
+
type: AuditEventType;
|
|
8
|
+
accountId: string | null;
|
|
9
|
+
email: string | null;
|
|
10
|
+
clientId: string | null;
|
|
11
|
+
actorId: string | null;
|
|
12
|
+
ip: string | null;
|
|
13
|
+
metadata: Record<string, unknown> | null;
|
|
14
|
+
createdAt: DateTime;
|
|
15
|
+
}
|
|
16
|
+
export type AuditLogClass<Model extends NormalizeConstructor<typeof BaseModel>> = Model & {
|
|
17
|
+
new (...args: any[]): AuditLogRow;
|
|
18
|
+
};
|
|
19
|
+
export declare function withAuditLog(): <Model extends NormalizeConstructor<typeof BaseModel>>(superclass: Model) => AuditLogClass<Model>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { column } from '@adonisjs/lucid/orm';
|
|
8
|
+
import { jsonColumn } from './json_column.js';
|
|
9
|
+
export function withAuditLog() {
|
|
10
|
+
return (superclass) => {
|
|
11
|
+
class AuditLogMixin extends superclass {
|
|
12
|
+
}
|
|
13
|
+
__decorate([
|
|
14
|
+
column()
|
|
15
|
+
], AuditLogMixin.prototype, "type", void 0);
|
|
16
|
+
__decorate([
|
|
17
|
+
column()
|
|
18
|
+
], AuditLogMixin.prototype, "accountId", void 0);
|
|
19
|
+
__decorate([
|
|
20
|
+
column()
|
|
21
|
+
], AuditLogMixin.prototype, "email", void 0);
|
|
22
|
+
__decorate([
|
|
23
|
+
column()
|
|
24
|
+
], AuditLogMixin.prototype, "clientId", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
column()
|
|
27
|
+
], AuditLogMixin.prototype, "actorId", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
column()
|
|
30
|
+
], AuditLogMixin.prototype, "ip", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
column(jsonColumn({ fallback: null }))
|
|
33
|
+
], AuditLogMixin.prototype, "metadata", void 0);
|
|
34
|
+
__decorate([
|
|
35
|
+
column.dateTime({ autoCreate: true })
|
|
36
|
+
], AuditLogMixin.prototype, "createdAt", void 0);
|
|
37
|
+
return AuditLogMixin;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseModel } from '@adonisjs/lucid/orm';
|
|
2
|
+
import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
|
|
3
|
+
/**
|
|
4
|
+
* Instância composta pelo mixin {@link withAuthUser}.
|
|
5
|
+
*/
|
|
6
|
+
export interface AuthUserRow {
|
|
7
|
+
email: string;
|
|
8
|
+
password: string;
|
|
9
|
+
globalRoles: string[];
|
|
10
|
+
verifyPassword(plain: string): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* O hash armazenado precisa ser re-gerado? `true` quando o hasher atual não
|
|
13
|
+
* reconhece o formato (hash legado de outro sistema) OU os parâmetros estão
|
|
14
|
+
* desatualizados. Usado pelo lazy rehash no login.
|
|
15
|
+
*/
|
|
16
|
+
passwordNeedsRehash(): boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Classe resultante da composição com o mixin {@link withAuthUser}.
|
|
20
|
+
*/
|
|
21
|
+
export type AuthUserClass<Model extends NormalizeConstructor<typeof BaseModel>> = Model & {
|
|
22
|
+
new (...args: any[]): AuthUserRow;
|
|
23
|
+
};
|
|
24
|
+
export declare function withAuthUser(): <Model extends NormalizeConstructor<typeof BaseModel>>(superclass: Model) => AuthUserClass<Model>;
|