@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,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema das tabelas que o PRÓPRIO authkit possui (nomes fixos). As tabelas
|
|
3
|
+
* do host (users, webauthn credentials, provider identities, PATs, audit)
|
|
4
|
+
* ficam de fora de propósito: nome e shape são decisão do host.
|
|
5
|
+
*
|
|
6
|
+
* `ensureAuthkitSchema()` é ADITIVO e idempotente:
|
|
7
|
+
* - cria as tabelas que faltam;
|
|
8
|
+
* - adiciona colunas novas em tabelas existentes (ALTER ADD);
|
|
9
|
+
* - nunca dropa nada nem altera tipo de coluna existente.
|
|
10
|
+
*
|
|
11
|
+
* Roda automaticamente no boot quando `schema.autoManage` está ligado
|
|
12
|
+
* (default), ou manualmente dentro de uma migration do host:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* // database/migrations/xxxx_authkit_schema.ts
|
|
16
|
+
* import { BaseSchema } from '@adonisjs/lucid/schema'
|
|
17
|
+
* import { ensureAuthkitSchema } from '@adonis-agora/authkit-server'
|
|
18
|
+
*
|
|
19
|
+
* export default class extends BaseSchema {
|
|
20
|
+
* async up() {
|
|
21
|
+
* await ensureAuthkitSchema(this.db)
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
const TABLES = [
|
|
27
|
+
{
|
|
28
|
+
name: 'authkit_oidc_payloads',
|
|
29
|
+
create: (t) => {
|
|
30
|
+
t.string('id', 255).notNullable();
|
|
31
|
+
t.string('model_name', 100).notNullable();
|
|
32
|
+
t.text('payload').notNullable();
|
|
33
|
+
t.string('grant_id', 255).nullable().index();
|
|
34
|
+
t.string('user_code', 255).nullable().index();
|
|
35
|
+
t.string('uid', 255).nullable().index();
|
|
36
|
+
t.timestamp('expires_at', { useTz: true }).nullable();
|
|
37
|
+
t.primary(['model_name', 'id']);
|
|
38
|
+
},
|
|
39
|
+
columns: {
|
|
40
|
+
id: (t) => t.string('id', 255),
|
|
41
|
+
model_name: (t) => t.string('model_name', 100),
|
|
42
|
+
payload: (t) => t.text('payload'),
|
|
43
|
+
grant_id: (t) => t.string('grant_id', 255).nullable().index(),
|
|
44
|
+
user_code: (t) => t.string('user_code', 255).nullable().index(),
|
|
45
|
+
uid: (t) => t.string('uid', 255).nullable().index(),
|
|
46
|
+
expires_at: (t) => t.timestamp('expires_at', { useTz: true }).nullable(),
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'auth_settings',
|
|
51
|
+
create: (t) => {
|
|
52
|
+
t.string('key').notNullable();
|
|
53
|
+
t.string('organization_id').nullable();
|
|
54
|
+
t.text('value').notNullable();
|
|
55
|
+
t.timestamp('updated_at', { useTz: true }).nullable();
|
|
56
|
+
t.string('updated_by').nullable();
|
|
57
|
+
t.unique(['key', 'organization_id']);
|
|
58
|
+
},
|
|
59
|
+
columns: {
|
|
60
|
+
key: (t) => t.string('key'),
|
|
61
|
+
organization_id: (t) => t.string('organization_id').nullable(),
|
|
62
|
+
value: (t) => t.text('value'),
|
|
63
|
+
updated_at: (t) => t.timestamp('updated_at', { useTz: true }).nullable(),
|
|
64
|
+
updated_by: (t) => t.string('updated_by').nullable(),
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'auth_password_history',
|
|
69
|
+
create: (t) => {
|
|
70
|
+
t.increments('id').primary();
|
|
71
|
+
t.string('account_id').notNullable();
|
|
72
|
+
t.text('password_hash').notNullable();
|
|
73
|
+
/* o código sempre envia created_at no INSERT — default de banco desnecessário */
|
|
74
|
+
t.timestamp('created_at', { useTz: true }).notNullable();
|
|
75
|
+
t.index(['account_id', 'created_at']);
|
|
76
|
+
},
|
|
77
|
+
columns: {
|
|
78
|
+
account_id: (t) => t.string('account_id'),
|
|
79
|
+
password_hash: (t) => t.text('password_hash'),
|
|
80
|
+
created_at: (t) => t.timestamp('created_at', { useTz: true }).nullable(),
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'auth_mfa',
|
|
85
|
+
/**
|
|
86
|
+
* Estado de MFA/TOTP por conta — LIB-OWNED (substitui as colunas
|
|
87
|
+
* `totp_secret`/`mfa_enabled_at`/`recovery_codes`/`last_totp_step` que viviam
|
|
88
|
+
* na tabela `users` do host). Keyed por `account_id` (1:1 com a conta).
|
|
89
|
+
*
|
|
90
|
+
* - `totp_secret` — segredo TOTP encriptado em repouso (text, null = sem enrollment).
|
|
91
|
+
* - `mfa_enabled_at`— instante do (re)enrollment confirmado (null = MFA desligado).
|
|
92
|
+
* - `recovery_codes`— hashes (sha256) dos recovery codes, single-use (json, null = nenhum).
|
|
93
|
+
* - `last_totp_step`— último step TOTP aceito (anti-replay M3; bigint, null = nenhum).
|
|
94
|
+
*/
|
|
95
|
+
create: (t) => {
|
|
96
|
+
t.string('account_id').notNullable().primary();
|
|
97
|
+
t.text('totp_secret').nullable();
|
|
98
|
+
t.timestamp('mfa_enabled_at', { useTz: true }).nullable();
|
|
99
|
+
t.json('recovery_codes').nullable();
|
|
100
|
+
t.bigInteger('last_totp_step').nullable();
|
|
101
|
+
},
|
|
102
|
+
columns: {
|
|
103
|
+
totp_secret: (t) => t.text('totp_secret').nullable(),
|
|
104
|
+
mfa_enabled_at: (t) => t.timestamp('mfa_enabled_at', { useTz: true }).nullable(),
|
|
105
|
+
recovery_codes: (t) => t.json('recovery_codes').nullable(),
|
|
106
|
+
last_totp_step: (t) => t.bigInteger('last_totp_step').nullable(),
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'auth_organizations',
|
|
111
|
+
create: (t) => {
|
|
112
|
+
t.string('id').primary();
|
|
113
|
+
t.string('name').notNullable();
|
|
114
|
+
t.string('slug').notNullable().unique();
|
|
115
|
+
t.string('logo_url').nullable();
|
|
116
|
+
t.json('metadata').nullable();
|
|
117
|
+
t.timestamp('created_at', { useTz: true }).nullable();
|
|
118
|
+
t.timestamp('updated_at', { useTz: true }).nullable();
|
|
119
|
+
},
|
|
120
|
+
columns: {
|
|
121
|
+
name: (t) => t.string('name'),
|
|
122
|
+
slug: (t) => t.string('slug'),
|
|
123
|
+
logo_url: (t) => t.string('logo_url').nullable(),
|
|
124
|
+
metadata: (t) => t.json('metadata').nullable(),
|
|
125
|
+
created_at: (t) => t.timestamp('created_at', { useTz: true }).nullable(),
|
|
126
|
+
updated_at: (t) => t.timestamp('updated_at', { useTz: true }).nullable(),
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'auth_organization_members',
|
|
131
|
+
create: (t) => {
|
|
132
|
+
t.string('id').primary();
|
|
133
|
+
t.string('organization_id')
|
|
134
|
+
.notNullable()
|
|
135
|
+
.references('id')
|
|
136
|
+
.inTable('auth_organizations')
|
|
137
|
+
.onDelete('CASCADE');
|
|
138
|
+
t.string('account_id').notNullable();
|
|
139
|
+
t.string('role').notNullable().defaultTo('member');
|
|
140
|
+
t.timestamp('created_at', { useTz: true }).nullable();
|
|
141
|
+
t.timestamp('updated_at', { useTz: true }).nullable();
|
|
142
|
+
t.unique(['organization_id', 'account_id']);
|
|
143
|
+
},
|
|
144
|
+
columns: {
|
|
145
|
+
organization_id: (t) => t.string('organization_id'),
|
|
146
|
+
account_id: (t) => t.string('account_id'),
|
|
147
|
+
role: (t) => t.string('role').defaultTo('member'),
|
|
148
|
+
created_at: (t) => t.timestamp('created_at', { useTz: true }).nullable(),
|
|
149
|
+
updated_at: (t) => t.timestamp('updated_at', { useTz: true }).nullable(),
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: 'auth_session_revocations',
|
|
154
|
+
/**
|
|
155
|
+
* Log de revogações de Back-Channel Logout para clients com sessão cookie-based.
|
|
156
|
+
* Escrito pelo handler de BCL de cada client (e pela revogação em massa do admin);
|
|
157
|
+
* lido pelo BackchannelRevocationMiddleware em toda request. Vive no schema `auth`
|
|
158
|
+
* para ser compartilhável entre todos os apps que apontam para o MESMO banco.
|
|
159
|
+
*/
|
|
160
|
+
create: (t) => {
|
|
161
|
+
t.increments('id').primary();
|
|
162
|
+
// sid do logout_token → revoga UMA sessão SSO específica (nullable: pode vir só sub).
|
|
163
|
+
t.string('sid').nullable().index();
|
|
164
|
+
// sub do logout_token → revoga TODAS as sessões do usuário antes de revoked_at.
|
|
165
|
+
t.string('sub').nullable().index();
|
|
166
|
+
t.timestamp('revoked_at', { useTz: true }).notNullable();
|
|
167
|
+
// Prune por idade (revogações mais velhas que o TTL máximo de sessão viram lixo).
|
|
168
|
+
t.index(['revoked_at']);
|
|
169
|
+
},
|
|
170
|
+
columns: {
|
|
171
|
+
sid: (t) => t.string('sid').nullable().index(),
|
|
172
|
+
sub: (t) => t.string('sub').nullable().index(),
|
|
173
|
+
revoked_at: (t) => t.timestamp('revoked_at', { useTz: true }).nullable(),
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'auth_organization_invitations',
|
|
178
|
+
create: (t) => {
|
|
179
|
+
t.string('id').primary();
|
|
180
|
+
t.string('organization_id')
|
|
181
|
+
.notNullable()
|
|
182
|
+
.references('id')
|
|
183
|
+
.inTable('auth_organizations')
|
|
184
|
+
.onDelete('CASCADE');
|
|
185
|
+
t.string('email').notNullable();
|
|
186
|
+
t.string('role').notNullable().defaultTo('member');
|
|
187
|
+
t.string('token_hash').notNullable().unique();
|
|
188
|
+
t.string('invited_by').notNullable();
|
|
189
|
+
t.timestamp('expires_at', { useTz: true }).notNullable();
|
|
190
|
+
t.timestamp('accepted_at', { useTz: true }).nullable();
|
|
191
|
+
t.timestamp('created_at', { useTz: true }).nullable();
|
|
192
|
+
t.timestamp('updated_at', { useTz: true }).nullable();
|
|
193
|
+
},
|
|
194
|
+
columns: {
|
|
195
|
+
organization_id: (t) => t.string('organization_id'),
|
|
196
|
+
email: (t) => t.string('email'),
|
|
197
|
+
role: (t) => t.string('role').defaultTo('member'),
|
|
198
|
+
token_hash: (t) => t.string('token_hash'),
|
|
199
|
+
invited_by: (t) => t.string('invited_by'),
|
|
200
|
+
expires_at: (t) => t.timestamp('expires_at', { useTz: true }).nullable(),
|
|
201
|
+
accepted_at: (t) => t.timestamp('accepted_at', { useTz: true }).nullable(),
|
|
202
|
+
created_at: (t) => t.timestamp('created_at', { useTz: true }).nullable(),
|
|
203
|
+
updated_at: (t) => t.timestamp('updated_at', { useTz: true }).nullable(),
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
/**
|
|
208
|
+
* Probe searchPath-aware: `schema.hasTable` no Postgres ignora o
|
|
209
|
+
* search_path, então testamos com um SELECT de verdade (mesma técnica do
|
|
210
|
+
* RuntimeSettings).
|
|
211
|
+
*/
|
|
212
|
+
async function tableExists(conn, table) {
|
|
213
|
+
try {
|
|
214
|
+
await conn.from(table).limit(1);
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async function columnExists(conn, table, column) {
|
|
222
|
+
try {
|
|
223
|
+
await conn.from(table).select(column).limit(1);
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Garante que as tabelas do authkit existem e têm todas as colunas que esta
|
|
232
|
+
* versão da lib espera. Aditivo e idempotente — seguro de rodar em todo boot
|
|
233
|
+
* e dentro de migrations.
|
|
234
|
+
*/
|
|
235
|
+
export async function ensureAuthkitSchema(db, options = {}) {
|
|
236
|
+
const conn = options.connection ? db.connection(options.connection) : db.connection();
|
|
237
|
+
const report = { created: [], altered: {} };
|
|
238
|
+
for (const def of TABLES) {
|
|
239
|
+
if (!(await tableExists(conn, def.name))) {
|
|
240
|
+
try {
|
|
241
|
+
await conn.schema.createTable(def.name, def.create);
|
|
242
|
+
report.created.push(def.name);
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
/**
|
|
247
|
+
* Corrida entre instâncias subindo juntas: se outra instância criou
|
|
248
|
+
* a tabela entre o probe e o CREATE, segue o jogo; senão, propaga.
|
|
249
|
+
*/
|
|
250
|
+
if (!(await tableExists(conn, def.name)))
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
for (const [column, add] of Object.entries(def.columns)) {
|
|
255
|
+
if (await columnExists(conn, def.name, column))
|
|
256
|
+
continue;
|
|
257
|
+
await conn.schema.alterTable(def.name, (t) => add(t));
|
|
258
|
+
(report.altered[def.name] ??= []).push(column);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return report;
|
|
262
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.configPath('authkit.ts') })
|
|
3
|
+
}}}
|
|
4
|
+
import env from '#start/env'
|
|
5
|
+
import AuthUser from '#models/auth_user'
|
|
6
|
+
import { defineConfig, adapters, lucidAccountStore } from '@adonis-agora/authkit-server'
|
|
7
|
+
|
|
8
|
+
const authServerConfig = defineConfig({
|
|
9
|
+
issuer: env.get('AUTHKIT_ISSUER'),
|
|
10
|
+
adapter: adapters.redis({ connection: 'main' }),
|
|
11
|
+
jwks: { source: 'managed', algorithm: 'RS256' },
|
|
12
|
+
ttl: { accessToken: '15m', refreshToken: '30d' },
|
|
13
|
+
globalRolesClaim: 'roles',
|
|
14
|
+
accountStore: lucidAccountStore(AuthUser),
|
|
15
|
+
// Clients são gerenciados em runtime via console admin (/admin/clients) ou
|
|
16
|
+
// Admin API, sem necessidade de redeploy.
|
|
17
|
+
// Use: node ace authkit:clients:create --redirect-uri=https://app/cb
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
export default authServerConfig
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.configPath('authkit.ts'), overwrite: true })
|
|
3
|
+
}}}
|
|
4
|
+
import env from '#start/env'
|
|
5
|
+
import AuthUser from '#models/auth_user'
|
|
6
|
+
import { defineConfig, adapters, inertiaRenderer } from '@adonis-agora/authkit-server'
|
|
7
|
+
|
|
8
|
+
const authServerConfig = defineConfig({
|
|
9
|
+
issuer: env.get('AUTHKIT_ISSUER'),
|
|
10
|
+
adapter: adapters.redis({ connection: 'main' }),
|
|
11
|
+
jwks: { source: 'managed', algorithm: 'RS256' },
|
|
12
|
+
clients: [
|
|
13
|
+
// registre seus clients OIDC aqui
|
|
14
|
+
],
|
|
15
|
+
ttl: { accessToken: '15m', refreshToken: '30d' },
|
|
16
|
+
globalRolesClaim: 'roles',
|
|
17
|
+
findAccount: async (sub) => {
|
|
18
|
+
const user = await AuthUser.find(sub)
|
|
19
|
+
if (!user) return null
|
|
20
|
+
return { id: user.id, email: user.email, globalRoles: user.globalRoles }
|
|
21
|
+
},
|
|
22
|
+
verifyCredentials: async (email, password) => {
|
|
23
|
+
const user = await AuthUser.query().where('email', email).first()
|
|
24
|
+
if (!user || !(await user.verifyPassword(password))) return null
|
|
25
|
+
return { id: user.id }
|
|
26
|
+
},
|
|
27
|
+
/**
|
|
28
|
+
* Renderer Inertia/React: apenas as views listadas em `views` vão ao Inertia;
|
|
29
|
+
* as demais (incluindo todas as telas admin/*) recaem silenciosamente no
|
|
30
|
+
* renderer Edge built-in da lib — evitando SSR crash por página inexistente.
|
|
31
|
+
*
|
|
32
|
+
* A lista abaixo corresponde exatamente às páginas que o scaffold gerou.
|
|
33
|
+
* Adicione entradas aqui somente se criar a página React correspondente.
|
|
34
|
+
*/
|
|
35
|
+
render: inertiaRenderer({
|
|
36
|
+
prefix: 'authkit',
|
|
37
|
+
views: [
|
|
38
|
+
'login',
|
|
39
|
+
'consent',
|
|
40
|
+
'signup',
|
|
41
|
+
'forgot',
|
|
42
|
+
'reset',
|
|
43
|
+
'verify-email',
|
|
44
|
+
'mfa-challenge',
|
|
45
|
+
'account/login',
|
|
46
|
+
'account/tokens',
|
|
47
|
+
'account/mfa',
|
|
48
|
+
],
|
|
49
|
+
}),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
export default authServerConfig
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const stubsRoot: string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.makePath('app/models/auth_user.ts') })
|
|
3
|
+
}}}
|
|
4
|
+
import { BaseModel, column } from '@adonisjs/lucid/orm'
|
|
5
|
+
import { compose } from '@adonisjs/core/helpers'
|
|
6
|
+
import { withAuthUser, withCredentials } from '@adonis-agora/authkit-server'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Por padrão o AuthKit cria/usa as tabelas na conexão DEFAULT da aplicação
|
|
10
|
+
* (config/database.ts) — não força nenhum banco/schema próprio.
|
|
11
|
+
*
|
|
12
|
+
* Se você quiser isolar o AuthKit num schema ou banco dedicado, defina uma
|
|
13
|
+
* conexão no config/database.ts do app e referencie aqui, ex.:
|
|
14
|
+
*
|
|
15
|
+
* static connection = 'auth'
|
|
16
|
+
*
|
|
17
|
+
* (e aponte as migrations correspondentes para essa conexão).
|
|
18
|
+
*/
|
|
19
|
+
export default class AuthUser extends compose(BaseModel, withAuthUser(), withCredentials()) {
|
|
20
|
+
@column({ isPrimary: true })
|
|
21
|
+
declare id: string
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.makePath('resources/views/authkit/consent.edge') })
|
|
3
|
+
}}}
|
|
4
|
+
<!doctype html>
|
|
5
|
+
<html lang="pt-br"><head><meta charset="utf-8"><title>Autorizar</title>
|
|
6
|
+
<script src="https://cdn.tailwindcss.com"></script></head>
|
|
7
|
+
<body class="min-h-screen flex items-center justify-center bg-gray-50">
|
|
8
|
+
<form method="POST" action="/auth/interaction/{{ uid }}/consent" class="w-full max-w-sm bg-white p-6 rounded-lg shadow">
|
|
9
|
+
<h1 class="text-lg font-semibold mb-2">Autorizar acesso</h1>
|
|
10
|
+
<p class="text-sm text-gray-600 mb-4">O app <strong>{{ params.client_id }}</strong> quer acessar sua conta.</p>
|
|
11
|
+
<button class="w-full bg-black text-white rounded py-2">Autorizar</button>
|
|
12
|
+
</form>
|
|
13
|
+
</body></html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.makePath('resources/views/authkit/login.edge') })
|
|
3
|
+
}}}
|
|
4
|
+
<!doctype html>
|
|
5
|
+
<html lang="pt-br"><head><meta charset="utf-8"><title>Entrar</title>
|
|
6
|
+
<script src="https://cdn.tailwindcss.com"></script></head>
|
|
7
|
+
<body class="min-h-screen flex items-center justify-center bg-gray-50">
|
|
8
|
+
<form method="POST" action="/auth/interaction/{{ uid }}/login" class="w-full max-w-sm bg-white p-6 rounded-lg shadow">
|
|
9
|
+
<h1 class="text-lg font-semibold mb-4">Entrar</h1>
|
|
10
|
+
@if(error)
|
|
11
|
+
<p class="text-red-600 text-sm mb-3">{{ error }}</p>
|
|
12
|
+
@end
|
|
13
|
+
<label class="block text-sm mb-1">E-mail</label>
|
|
14
|
+
<input name="email" type="email" required class="w-full border rounded px-3 py-2 mb-3" />
|
|
15
|
+
<label class="block text-sm mb-1">Senha</label>
|
|
16
|
+
<input name="password" type="password" required class="w-full border rounded px-3 py-2 mb-4" />
|
|
17
|
+
<button class="w-full bg-black text-white rounded py-2">Entrar</button>
|
|
18
|
+
</form>
|
|
19
|
+
</body></html>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.makePath('inertia/components/auth_shell.tsx') })
|
|
3
|
+
}}}
|
|
4
|
+
import type { ReactNode } from 'react'
|
|
5
|
+
|
|
6
|
+
export interface AuthBrand {
|
|
7
|
+
appName: string
|
|
8
|
+
accent: string
|
|
9
|
+
accentSoft?: string
|
|
10
|
+
company?: string
|
|
11
|
+
tagline?: string
|
|
12
|
+
audienceLabel?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const COMPANY_FALLBACK = 'Acme'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Layout de duas colunas para as telas de autenticacao do IdP.
|
|
19
|
+
* Painel esquerdo: marca (empresa guarda-chuva + produto). Painel direito: formulario.
|
|
20
|
+
*/
|
|
21
|
+
export default function AuthShell({
|
|
22
|
+
brand,
|
|
23
|
+
children,
|
|
24
|
+
}: {
|
|
25
|
+
brand?: AuthBrand
|
|
26
|
+
children: ReactNode
|
|
27
|
+
}) {
|
|
28
|
+
const accent = brand?.accent ?? '#111827'
|
|
29
|
+
const accentSoft = brand?.accentSoft ?? accent
|
|
30
|
+
const company = brand?.company ?? COMPANY_FALLBACK
|
|
31
|
+
const appName = brand?.appName ?? 'Sua conta'
|
|
32
|
+
const tagline = brand?.tagline ?? 'Acesso unificado'
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div className="min-h-screen flex items-center justify-center bg-gray-100 p-4">
|
|
36
|
+
<div className="w-full max-w-4xl overflow-hidden rounded-2xl bg-white shadow-xl ring-1 ring-black/5 grid md:grid-cols-2">
|
|
37
|
+
{/* Painel da marca */}
|
|
38
|
+
<div
|
|
39
|
+
className="relative flex flex-col justify-between p-8 text-white md:p-10"
|
|
40
|
+
style={{ backgroundImage: `linear-gradient(135deg, ${accent} 0%, ${accentSoft} 100%)` }}
|
|
41
|
+
>
|
|
42
|
+
<div
|
|
43
|
+
className="text-xs font-semibold uppercase tracking-[0.2em] text-white/80"
|
|
44
|
+
aria-label="Empresa"
|
|
45
|
+
>
|
|
46
|
+
{company}
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div className="mt-10 md:mt-0">
|
|
50
|
+
<h2 className="text-2xl font-bold leading-tight md:text-3xl">{appName}</h2>
|
|
51
|
+
<p className="mt-2 text-sm text-white/85">{tagline}</p>
|
|
52
|
+
{brand?.audienceLabel && (
|
|
53
|
+
<span className="mt-4 inline-block rounded-full bg-white/20 px-3 py-1 text-xs font-medium uppercase tracking-wide text-white ring-1 ring-white/30">
|
|
54
|
+
{brand.audienceLabel}
|
|
55
|
+
</span>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div className="mt-10 text-xs text-white/60">© {company}</div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
{/* Painel do formulario */}
|
|
63
|
+
<div className="p-8 md:p-10">{children}</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.makePath('inertia/pages/authkit/account/login.tsx') })
|
|
3
|
+
}}}
|
|
4
|
+
interface Props {
|
|
5
|
+
csrfToken: string
|
|
6
|
+
error?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function AccountLogin({ csrfToken, error }: Props) {
|
|
10
|
+
return (
|
|
11
|
+
<div className="min-h-screen flex items-center justify-center bg-gray-100 p-4">
|
|
12
|
+
<form
|
|
13
|
+
method="POST"
|
|
14
|
+
action="/account/login"
|
|
15
|
+
className="w-full max-w-sm rounded-2xl bg-white p-8 shadow-xl ring-1 ring-black/5"
|
|
16
|
+
>
|
|
17
|
+
<input type="hidden" name="_csrf" value={csrfToken} />
|
|
18
|
+
<div className="text-xs font-semibold uppercase tracking-[0.2em] text-gray-400">Acme</div>
|
|
19
|
+
<h1 className="mt-2 text-xl font-semibold text-gray-900">Minha conta</h1>
|
|
20
|
+
<p className="mt-1 text-sm text-gray-500">Gerencie seus tokens de acesso.</p>
|
|
21
|
+
|
|
22
|
+
{error && <p className="mt-4 text-sm text-red-600">{error}</p>}
|
|
23
|
+
|
|
24
|
+
<label htmlFor="email" className="mt-6 mb-1 block text-sm font-medium text-gray-700">
|
|
25
|
+
E-mail
|
|
26
|
+
</label>
|
|
27
|
+
<input
|
|
28
|
+
id="email"
|
|
29
|
+
name="email"
|
|
30
|
+
type="email"
|
|
31
|
+
required
|
|
32
|
+
autoFocus
|
|
33
|
+
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm outline-none focus:border-gray-900"
|
|
34
|
+
/>
|
|
35
|
+
|
|
36
|
+
<label htmlFor="password" className="mt-4 mb-1 block text-sm font-medium text-gray-700">
|
|
37
|
+
Senha
|
|
38
|
+
</label>
|
|
39
|
+
<input
|
|
40
|
+
id="password"
|
|
41
|
+
name="password"
|
|
42
|
+
type="password"
|
|
43
|
+
required
|
|
44
|
+
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm outline-none focus:border-gray-900"
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
<button
|
|
48
|
+
type="submit"
|
|
49
|
+
className="mt-6 w-full rounded-lg bg-gray-900 py-2.5 text-sm font-semibold text-white transition hover:opacity-90"
|
|
50
|
+
>
|
|
51
|
+
Entrar
|
|
52
|
+
</button>
|
|
53
|
+
</form>
|
|
54
|
+
</div>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.makePath('inertia/pages/authkit/account/mfa.tsx') })
|
|
3
|
+
}}}
|
|
4
|
+
interface Props {
|
|
5
|
+
csrfToken: string
|
|
6
|
+
enabled: boolean
|
|
7
|
+
enrolling?: boolean
|
|
8
|
+
secret?: string | null
|
|
9
|
+
qrDataUrl?: string | null
|
|
10
|
+
error?: string
|
|
11
|
+
recoveryCodes?: string[] | null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function AccountMfa({
|
|
15
|
+
csrfToken,
|
|
16
|
+
enabled,
|
|
17
|
+
enrolling,
|
|
18
|
+
secret,
|
|
19
|
+
qrDataUrl,
|
|
20
|
+
error,
|
|
21
|
+
recoveryCodes,
|
|
22
|
+
}: Props) {
|
|
23
|
+
return (
|
|
24
|
+
<div className="min-h-screen bg-gray-100 p-4">
|
|
25
|
+
<div className="mx-auto max-w-2xl">
|
|
26
|
+
<div className="flex items-center justify-between py-6">
|
|
27
|
+
<div>
|
|
28
|
+
<div className="text-xs font-semibold uppercase tracking-[0.2em] text-gray-400">Acme</div>
|
|
29
|
+
<h1 className="text-xl font-semibold text-gray-900">Verificação em duas etapas</h1>
|
|
30
|
+
</div>
|
|
31
|
+
<form method="POST" action="/account/logout">
|
|
32
|
+
<input type="hidden" name="_csrf" value={csrfToken} />
|
|
33
|
+
<button type="submit" className="text-sm text-gray-500 hover:underline">
|
|
34
|
+
Sair
|
|
35
|
+
</button>
|
|
36
|
+
</form>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
{error && <p className="mb-4 text-sm text-red-600">{error}</p>}
|
|
40
|
+
|
|
41
|
+
{recoveryCodes && recoveryCodes.length > 0 && (
|
|
42
|
+
<div className="mb-6 rounded-lg border border-emerald-300 bg-emerald-50 p-4">
|
|
43
|
+
<p className="text-sm font-medium text-emerald-900">
|
|
44
|
+
Guarde seus códigos de recuperação — eles não serão mostrados de novo:
|
|
45
|
+
</p>
|
|
46
|
+
<ul className="mt-3 grid grid-cols-2 gap-2">
|
|
47
|
+
{recoveryCodes.map((rc) => (
|
|
48
|
+
<li key={rc}>
|
|
49
|
+
<code className="block rounded bg-white px-3 py-2 text-sm text-emerald-800 ring-1 ring-emerald-200">
|
|
50
|
+
{rc}
|
|
51
|
+
</code>
|
|
52
|
+
</li>
|
|
53
|
+
))}
|
|
54
|
+
</ul>
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
57
|
+
|
|
58
|
+
{enrolling ? (
|
|
59
|
+
<div className="rounded-xl bg-white p-6 shadow-sm ring-1 ring-black/5">
|
|
60
|
+
<p className="text-sm text-gray-600">
|
|
61
|
+
Escaneie o QR code com seu app autenticador (Google Authenticator, 1Password, etc.).
|
|
62
|
+
</p>
|
|
63
|
+
{qrDataUrl && (
|
|
64
|
+
<img src={qrDataUrl} alt="QR code TOTP" className="mx-auto my-4 h-48 w-48" />
|
|
65
|
+
)}
|
|
66
|
+
{secret && (
|
|
67
|
+
<>
|
|
68
|
+
<p className="text-center text-xs text-gray-500">Ou informe manualmente:</p>
|
|
69
|
+
<code className="mx-auto mt-1 block w-fit break-all rounded bg-gray-100 px-3 py-2 text-sm text-gray-800">
|
|
70
|
+
{secret}
|
|
71
|
+
</code>
|
|
72
|
+
</>
|
|
73
|
+
)}
|
|
74
|
+
<form method="POST" action="/account/mfa/confirm" className="mt-6">
|
|
75
|
+
<input type="hidden" name="_csrf" value={csrfToken} />
|
|
76
|
+
<label htmlFor="code" className="mb-1 block text-sm font-medium text-gray-700">
|
|
77
|
+
Código de confirmação
|
|
78
|
+
</label>
|
|
79
|
+
<input
|
|
80
|
+
id="code"
|
|
81
|
+
name="code"
|
|
82
|
+
inputMode="numeric"
|
|
83
|
+
pattern="[0-9]*"
|
|
84
|
+
maxLength={6}
|
|
85
|
+
autoFocus
|
|
86
|
+
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-center text-lg tracking-[0.4em] outline-none focus:border-gray-900"
|
|
87
|
+
/>
|
|
88
|
+
<button
|
|
89
|
+
type="submit"
|
|
90
|
+
className="mt-4 w-full rounded-lg bg-gray-900 py-2.5 text-sm font-semibold text-white"
|
|
91
|
+
>
|
|
92
|
+
Ativar verificação em duas etapas
|
|
93
|
+
</button>
|
|
94
|
+
</form>
|
|
95
|
+
</div>
|
|
96
|
+
) : enabled ? (
|
|
97
|
+
<div className="rounded-xl bg-white p-6 shadow-sm ring-1 ring-black/5">
|
|
98
|
+
<p className="text-sm text-gray-700">
|
|
99
|
+
A verificação em duas etapas está{' '}
|
|
100
|
+
<span className="font-semibold text-emerald-700">ativa</span> nesta conta.
|
|
101
|
+
</p>
|
|
102
|
+
<form method="POST" action="/account/mfa/disable" className="mt-4">
|
|
103
|
+
<input type="hidden" name="_csrf" value={csrfToken} />
|
|
104
|
+
<button
|
|
105
|
+
type="submit"
|
|
106
|
+
className="rounded-lg border border-red-300 px-4 py-2 text-sm font-semibold text-red-600 hover:bg-red-50"
|
|
107
|
+
>
|
|
108
|
+
Desativar
|
|
109
|
+
</button>
|
|
110
|
+
</form>
|
|
111
|
+
</div>
|
|
112
|
+
) : (
|
|
113
|
+
<div className="rounded-xl bg-white p-6 shadow-sm ring-1 ring-black/5">
|
|
114
|
+
<p className="text-sm text-gray-700">
|
|
115
|
+
A verificação em duas etapas está desativada. Ative-a para proteger sua conta com um app
|
|
116
|
+
autenticador.
|
|
117
|
+
</p>
|
|
118
|
+
<form method="POST" action="/account/mfa/enroll" className="mt-4">
|
|
119
|
+
<input type="hidden" name="_csrf" value={csrfToken} />
|
|
120
|
+
<button
|
|
121
|
+
type="submit"
|
|
122
|
+
className="rounded-lg bg-gray-900 px-4 py-2 text-sm font-semibold text-white"
|
|
123
|
+
>
|
|
124
|
+
Ativar verificação em duas etapas
|
|
125
|
+
</button>
|
|
126
|
+
</form>
|
|
127
|
+
</div>
|
|
128
|
+
)}
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
)
|
|
132
|
+
}
|