@adonis-agora/authkit-server 0.46.0 → 0.48.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/build/commands/clients_create.js +4 -4
- package/build/commands/configure.js +3 -2
- package/build/commands/doctor.js +8 -5
- package/build/commands/eject.js +1 -1
- package/build/commands/expire_scan.js +7 -5
- package/build/commands/import_users.js +1 -1
- package/build/commands/keys_rotate.js +7 -4
- package/build/host/views/account/apps.edge +5 -5
- package/build/host/views/account/login.edge +1 -1
- package/build/host/views/account/mfa.edge +7 -7
- package/build/host/views/account/orgs.edge +5 -5
- package/build/host/views/account/security.edge +10 -10
- package/build/host/views/account/tokens.edge +5 -5
- package/build/host/views/otp-unlock.edge +2 -2
- package/build/index.d.ts +7 -7
- package/build/index.js +5 -5
- package/build/providers/authkit_server_provider.d.ts +2 -2
- package/build/providers/authkit_server_provider.js +26 -10
- package/build/services/booted_app.d.ts +8 -0
- package/build/services/booted_app.js +27 -0
- package/build/services/main.d.ts +8 -1
- package/build/services/main.js +10 -2
- package/build/src/accounts/lucid_account_store.d.ts +3 -3
- package/build/src/accounts/lucid_account_store.js +6 -8
- package/build/src/accounts/lucid_store/core.js +1 -1
- package/build/src/accounts/lucid_store/mfa.js +1 -1
- package/build/src/accounts/lucid_store/organizations.js +2 -4
- package/build/src/accounts/lucid_store/password_hygiene.js +1 -4
- package/build/src/accounts/lucid_store/shared.d.ts +1 -1
- package/build/src/accounts/lucid_stores.d.ts +3 -3
- package/build/src/accounts/lucid_stores.js +2 -2
- package/build/src/adapters/database_adapter.js +3 -1
- package/build/src/adapters/factory.js +1 -1
- package/build/src/adapters/redis_adapter.js +2 -1
- package/build/src/commands/expire_scan_command.js +19 -5
- package/build/src/commands/settings_commands.js +22 -5
- package/build/src/define_config.d.ts +20 -20
- package/build/src/define_config.js +62 -67
- package/build/src/doctor/checks.js +45 -20
- package/build/src/events/dispatcher.d.ts +1 -1
- package/build/src/events/dispatcher.js +10 -10
- package/build/src/host/account_api/account_api_controller.js +95 -39
- package/build/src/host/account_deletion_ops.d.ts +4 -4
- package/build/src/host/account_deletion_ops.js +5 -5
- package/build/src/host/account_deletion_service.d.ts +2 -2
- package/build/src/host/account_deletion_service.js +2 -2
- package/build/src/host/account_export_service.d.ts +1 -1
- package/build/src/host/account_export_service.js +4 -6
- package/build/src/host/account_home.d.ts +0 -8
- package/build/src/host/account_home.js +6 -4
- package/build/src/host/account_login_url.d.ts +44 -0
- package/build/src/host/account_login_url.js +58 -0
- package/build/src/host/account_paths.d.ts +120 -0
- package/build/src/host/account_paths.js +161 -0
- package/build/src/host/admin_api/admin_orgs_service.d.ts +2 -2
- package/build/src/host/admin_api/admin_orgs_service.js +3 -2
- package/build/src/host/admin_api/admin_users_service.d.ts +12 -12
- package/build/src/host/admin_api/admin_users_service.js +20 -20
- package/build/src/host/admin_api/api_clients_controller.js +2 -2
- package/build/src/host/admin_api/api_misc_controller.js +2 -2
- package/build/src/host/admin_api/api_orgs_controller.js +3 -3
- package/build/src/host/admin_api/api_settings_controller.js +11 -5
- package/build/src/host/admin_api/api_users_controller.d.ts +2 -2
- package/build/src/host/admin_api/api_users_controller.js +37 -38
- package/build/src/host/admin_api/dto.d.ts +4 -4
- package/build/src/host/admin_clients_service.js +5 -4
- package/build/src/host/admin_console/admin_shell_controller.js +4 -2
- package/build/src/host/admin_console/console_audit_controller.js +1 -1
- package/build/src/host/admin_console/console_clients_controller.js +5 -3
- package/build/src/host/admin_console/console_impersonation_controller.js +1 -1
- package/build/src/host/admin_console/console_keys_controller.js +2 -4
- package/build/src/host/admin_console/console_orgs_controller.js +3 -3
- package/build/src/host/admin_console/console_roles_controller.js +30 -12
- package/build/src/host/admin_console/console_sessions_controller.js +3 -3
- package/build/src/host/admin_console/console_settings_controller.js +11 -5
- package/build/src/host/admin_console/console_users_controller.d.ts +2 -2
- package/build/src/host/admin_console/console_users_controller.js +46 -47
- package/build/src/host/admin_prefix.js +2 -2
- package/build/src/host/admin_sessions_service.d.ts +3 -1
- package/build/src/host/admin_sessions_service.js +36 -6
- package/build/src/host/adonis_auth_sync.d.ts +1 -1
- package/build/src/host/adonis_auth_user_provider.d.ts +1 -1
- package/build/src/host/app_key.js +1 -1
- package/build/src/host/avatar_storage.js +1 -3
- package/build/src/host/config_locks.js +1 -3
- package/build/src/host/console_session.d.ts +4 -0
- package/build/src/host/console_session.js +9 -2
- package/build/src/host/controllers/account_apps_controller.js +3 -2
- package/build/src/host/controllers/account_confirm_controller.js +2 -6
- package/build/src/host/controllers/account_mfa_controller.js +63 -12
- package/build/src/host/controllers/account_orgs_controller.js +53 -30
- package/build/src/host/controllers/account_security_controller.d.ts +2 -2
- package/build/src/host/controllers/account_security_controller.js +116 -116
- package/build/src/host/controllers/account_session_controller.js +7 -5
- package/build/src/host/controllers/account_tokens_controller.js +14 -2
- package/build/src/host/controllers/interaction_controller.js +59 -22
- package/build/src/host/controllers/pat_introspection_controller.js +10 -0
- package/build/src/host/controllers/registration_controller.js +28 -13
- package/build/src/host/default_mailer.js +11 -7
- package/build/src/host/durable/account_deletion_workflow.d.ts +2 -2
- package/build/src/host/durable/account_deletion_workflow.js +14 -14
- package/build/src/host/durable/account_export_workflow.d.ts +2 -2
- package/build/src/host/durable/account_export_workflow.js +12 -12
- package/build/src/host/durable/index.d.ts +5 -5
- package/build/src/host/durable/index.js +6 -6
- package/build/src/host/i18n.d.ts +1376 -1376
- package/build/src/host/i18n.js +1380 -1380
- package/build/src/host/impersonation.js +1 -7
- package/build/src/host/key_rotation_actions.d.ts +1 -1
- package/build/src/host/login_attempt.js +35 -6
- package/build/src/host/login_notify.js +1 -1
- package/build/src/host/middleware/account_auth.js +3 -1
- package/build/src/host/otp_lockout.js +1 -3
- package/build/src/host/rate_limit.js +1 -1
- package/build/src/host/register_auth_host.d.ts +96 -2
- package/build/src/host/register_auth_host.js +196 -91
- package/build/src/host/renderers/edge_renderer.js +19 -1
- package/build/src/host/renderers/inertia_renderer.d.ts +63 -0
- package/build/src/host/renderers/inertia_renderer.js +63 -0
- package/build/src/host/runtime_settings.js +1 -1
- package/build/src/host/runtime_toggles.d.ts +3 -3
- package/build/src/host/runtime_toggles.js +69 -24
- package/build/src/host/security_notice_service.d.ts +1 -1
- package/build/src/host/security_notice_service.js +1 -1
- package/build/src/host/session_context.js +1 -1
- package/build/src/host/sudo/index.d.ts +3 -3
- package/build/src/host/sudo/index.js +3 -3
- package/build/src/host/sudo/methods/magic_link.js +6 -5
- package/build/src/host/sudo/methods/passkey.js +7 -4
- package/build/src/host/sudo/methods/password.js +8 -3
- package/build/src/host/sudo/runtime.js +6 -13
- package/build/src/host/sudo_mode.js +3 -2
- package/build/src/host/ui-dist/assets/index-BQoTDiLV.js +137 -0
- package/build/src/host/ui-dist/index.html +1 -1
- package/build/src/keys/jwks_manager.js +1 -1
- package/build/src/keys/keystore.js +1 -1
- package/build/src/keys/keystore_manager.d.ts +2 -2
- package/build/src/keys/keystore_manager.js +2 -2
- package/build/src/keys/keystore_vault.js +8 -4
- package/build/src/mixins/with_audit_log.d.ts +1 -1
- package/build/src/mixins/with_auth_user.d.ts +1 -1
- package/build/src/mixins/with_auth_user.js +1 -1
- package/build/src/mixins/with_credentials.d.ts +1 -1
- package/build/src/mixins/with_mfa.d.ts +1 -1
- package/build/src/mixins/with_personal_access_token.d.ts +1 -1
- package/build/src/mixins/with_provider_identity.d.ts +1 -1
- package/build/src/mixins/with_webauthn_credential.d.ts +1 -1
- package/build/src/observability/diagnostics_bridge.js +2 -2
- package/build/src/observability/metrics_service.js +1 -1
- package/build/src/observability/telescope/data_providers.d.ts +1 -1
- package/build/src/observability/telescope/data_providers.js +29 -43
- package/build/src/observability/telescope/extension.d.ts +1 -1
- package/build/src/observability/telescope/extension.js +58 -58
- package/build/src/observability/telescope/index.d.ts +2 -2
- package/build/src/observability/telescope/index.js +2 -2
- package/build/src/observability/wire_provider_events.d.ts +1 -1
- package/build/src/observability/wire_provider_events.js +11 -11
- package/build/src/password/common_passwords.js +1 -1
- package/build/src/password/password_manager.d.ts +1 -1
- package/build/src/password/password_manager.js +4 -4
- package/build/src/pat/lucid_pat_store.js +2 -6
- package/build/src/pat/pat_tokens.js +1 -1
- package/build/src/provider/interaction_actions.js +1 -1
- package/build/src/provider/key_rotation_scheduler.js +3 -1
- package/build/src/provider/logout_sources.js +2 -8
- package/build/src/provider/oidc_service.d.ts +2 -2
- package/build/src/provider/oidc_service.js +22 -14
- package/build/src/provider/single_flight_lock.js +1 -3
- package/build/src/provider/token_exchange.d.ts +1 -1
- package/build/src/schema/ensure.js +3 -1
- package/build/stubs/ui/react/components/auth_shell.tsx +19 -19
- package/build/stubs/ui/react/pages/account/login.tsx +6 -7
- package/build/stubs/ui/react/pages/account/mfa.tsx +16 -15
- package/build/stubs/ui/react/pages/account/tokens.tsx +27 -17
- package/build/stubs/ui/react/pages/consent.tsx +12 -12
- package/build/stubs/ui/react/pages/forgot.tsx +7 -7
- package/build/stubs/ui/react/pages/login.tsx +22 -24
- package/build/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
- package/build/stubs/ui/react/pages/reset.tsx +10 -10
- package/build/stubs/ui/react/pages/signup.tsx +30 -16
- package/build/stubs/ui/react/pages/verify-email.tsx +6 -6
- package/package.json +1 -1
- package/stubs/main.ts +2 -2
- package/stubs/ui/react/components/auth_shell.tsx +19 -19
- package/stubs/ui/react/pages/account/login.tsx +6 -7
- package/stubs/ui/react/pages/account/mfa.tsx +16 -15
- package/stubs/ui/react/pages/account/tokens.tsx +27 -17
- package/stubs/ui/react/pages/consent.tsx +12 -12
- package/stubs/ui/react/pages/forgot.tsx +7 -7
- package/stubs/ui/react/pages/login.tsx +22 -24
- package/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
- package/stubs/ui/react/pages/reset.tsx +10 -10
- package/stubs/ui/react/pages/signup.tsx +30 -16
- package/stubs/ui/react/pages/verify-email.tsx +6 -6
- package/build/src/host/ui-dist/assets/index-BmI_J87g.js +0 -137
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ApplicationService } from '@adonisjs/core/types';
|
|
2
|
+
/** Registra o app bootado. Chamado uma vez pelo {@link AuthkitServerProvider} no `register()`. */
|
|
3
|
+
export declare function setBootedApp(app: ApplicationService): void;
|
|
4
|
+
/**
|
|
5
|
+
* O app bootado capturado pelo provider. Lança se lido antes do provider registrar — um sinal claro
|
|
6
|
+
* de que `@adonis-agora/authkit-server/authkit_server_provider` está ausente dos providers do app.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getBootedApp(): ApplicationService;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A {@link ApplicationService} BOOTADA, capturada por `AuthkitServerProvider.register()` — que o app
|
|
3
|
+
* instancia com a SUA própria cópia bootada do app.
|
|
4
|
+
*
|
|
5
|
+
* Por que capturar aqui em vez de `import app from '@adonisjs/core/services/app'`: num install pnpm
|
|
6
|
+
* (workspace / hoisted), este pacote pode resolver uma cópia FÍSICA de `@adonisjs/core` DIFERENTE da
|
|
7
|
+
* que o `bin/server` bootou. `services/app` expõe o app por um binding de nível de módulo definido no
|
|
8
|
+
* boot (`setApp`); numa cópia NÃO-bootada esse binding fica `undefined` — importar de lá devolve um
|
|
9
|
+
* app indefinido (`Cannot read properties of undefined (reading 'booted')`). A instância que o
|
|
10
|
+
* provider recebe é SEMPRE a bootada, então lê-la aqui é imune a splits de cópia / variantes de peer
|
|
11
|
+
* do core — o mesmo hazard de dual-package que já corrigimos no `'lucid.db'`.
|
|
12
|
+
*/
|
|
13
|
+
let bootedApp;
|
|
14
|
+
/** Registra o app bootado. Chamado uma vez pelo {@link AuthkitServerProvider} no `register()`. */
|
|
15
|
+
export function setBootedApp(app) {
|
|
16
|
+
bootedApp = app;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* O app bootado capturado pelo provider. Lança se lido antes do provider registrar — um sinal claro
|
|
20
|
+
* de que `@adonis-agora/authkit-server/authkit_server_provider` está ausente dos providers do app.
|
|
21
|
+
*/
|
|
22
|
+
export function getBootedApp() {
|
|
23
|
+
if (!bootedApp) {
|
|
24
|
+
throw new Error('@adonis-agora/authkit-server: app acessado antes de AuthkitServerProvider registrar. Adicione "@adonis-agora/authkit-server/authkit_server_provider" aos providers do adonisrc.ts.');
|
|
25
|
+
}
|
|
26
|
+
return bootedApp;
|
|
27
|
+
}
|
package/build/services/main.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OidcService } from
|
|
1
|
+
import type { OidcService } from '../src/provider/oidc_service.js';
|
|
2
2
|
/**
|
|
3
3
|
* Acessor singleton do {@link OidcService}, seguindo a convenção `services/main` do
|
|
4
4
|
* AdonisJS (igual `@adonisjs/lucid/services/db`, `@adonisjs/drive/services/main` e
|
|
@@ -10,6 +10,13 @@ import type { OidcService } from "../src/provider/oidc_service.js";
|
|
|
10
10
|
* Roda `await app.booted()` no top-level, então SÓ funciona dentro de um app
|
|
11
11
|
* booted — por isso `scripts/import-smoke.mjs` pula o diretório `services`.
|
|
12
12
|
*
|
|
13
|
+
* O `app` vem do {@link getBootedApp} (capturado pelo provider no `register()`), NÃO de
|
|
14
|
+
* `import app from "@adonisjs/core/services/app"`: sob pnpm este pacote pode resolver uma cópia
|
|
15
|
+
* FÍSICA de `@adonisjs/core` diferente da que o `bin/server` bootou, cujo binding de `services/app`
|
|
16
|
+
* fica `undefined` — mesmo dual-package hazard do `'lucid.db'`, aqui para o singleton do core. Ver
|
|
17
|
+
* {@link ./booted_app.js}. A instância que o provider recebe é sempre a bootada. Back-compat total:
|
|
18
|
+
* o `default` continua sendo o {@link OidcService} resolvido.
|
|
19
|
+
*
|
|
13
20
|
* Dentro da própria lib continuamos resolvendo via `ctx.containerResolver.make("authkit.server")`,
|
|
14
21
|
* que é o idioma das libs first-party (ver `@adonisjs/auth`, `initialize_auth_middleware`).
|
|
15
22
|
*/
|
package/build/services/main.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { getBootedApp } from './booted_app.js';
|
|
2
2
|
/**
|
|
3
3
|
* Acessor singleton do {@link OidcService}, seguindo a convenção `services/main` do
|
|
4
4
|
* AdonisJS (igual `@adonisjs/lucid/services/db`, `@adonisjs/drive/services/main` e
|
|
@@ -10,11 +10,19 @@ import app from "@adonisjs/core/services/app";
|
|
|
10
10
|
* Roda `await app.booted()` no top-level, então SÓ funciona dentro de um app
|
|
11
11
|
* booted — por isso `scripts/import-smoke.mjs` pula o diretório `services`.
|
|
12
12
|
*
|
|
13
|
+
* O `app` vem do {@link getBootedApp} (capturado pelo provider no `register()`), NÃO de
|
|
14
|
+
* `import app from "@adonisjs/core/services/app"`: sob pnpm este pacote pode resolver uma cópia
|
|
15
|
+
* FÍSICA de `@adonisjs/core` diferente da que o `bin/server` bootou, cujo binding de `services/app`
|
|
16
|
+
* fica `undefined` — mesmo dual-package hazard do `'lucid.db'`, aqui para o singleton do core. Ver
|
|
17
|
+
* {@link ./booted_app.js}. A instância que o provider recebe é sempre a bootada. Back-compat total:
|
|
18
|
+
* o `default` continua sendo o {@link OidcService} resolvido.
|
|
19
|
+
*
|
|
13
20
|
* Dentro da própria lib continuamos resolvendo via `ctx.containerResolver.make("authkit.server")`,
|
|
14
21
|
* que é o idioma das libs first-party (ver `@adonisjs/auth`, `initialize_auth_middleware`).
|
|
15
22
|
*/
|
|
16
23
|
let service;
|
|
24
|
+
const app = getBootedApp();
|
|
17
25
|
await app.booted(async () => {
|
|
18
|
-
service = await app.container.make(
|
|
26
|
+
service = await app.container.make('authkit.server');
|
|
19
27
|
});
|
|
20
28
|
export { service as default };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { AuditSink } from '../audit/audit_sink.js';
|
|
2
|
+
import { type PasswordConfigInput } from '../password/password_manager.js';
|
|
3
|
+
import type { FetchLike, PwnedLogger } from '../password/pwned.js';
|
|
1
4
|
import type { AccountStore } from './account_store.js';
|
|
2
5
|
import { type AccountSecretEncrypter, type WebauthnCeremonies } from './lucid_store/shared.js';
|
|
3
|
-
import { type PasswordConfigInput } from '../password/password_manager.js';
|
|
4
|
-
import type { AuditSink } from '../audit/audit_sink.js';
|
|
5
|
-
import type { PwnedLogger, FetchLike } from '../password/pwned.js';
|
|
6
6
|
export type { AccountSecretEncrypter, WebauthnCeremonies };
|
|
7
7
|
/**
|
|
8
8
|
* Serviço de encryption do app (APP_KEY), carregado LAZY via import dinâmico.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { generateAuthenticationOptions, generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse, } from '@simplewebauthn/server';
|
|
2
|
-
import {
|
|
2
|
+
import { PasswordManager } from '../password/password_manager.js';
|
|
3
3
|
import { buildCore } from './lucid_store/core.js';
|
|
4
4
|
import { buildMfa } from './lucid_store/mfa.js';
|
|
5
|
+
import { buildOrganizations } from './lucid_store/organizations.js';
|
|
6
|
+
import { buildPasswordExpiration, buildPasswordHistory } from './lucid_store/password_hygiene.js';
|
|
5
7
|
import { buildProviderIdentity } from './lucid_store/provider_identity.js';
|
|
8
|
+
import { hasTable, } from './lucid_store/shared.js';
|
|
9
|
+
import { buildDeletion, buildEmailVerificationStatus, buildProfile, buildStatus, hasColumn, } from './lucid_store/status_profile.js';
|
|
6
10
|
import { buildWebauthn } from './lucid_store/webauthn.js';
|
|
7
|
-
import { buildStatus, buildProfile, buildEmailVerificationStatus, buildDeletion, hasColumn, } from './lucid_store/status_profile.js';
|
|
8
|
-
import { buildOrganizations } from './lucid_store/organizations.js';
|
|
9
|
-
import { buildPasswordHistory, buildPasswordExpiration } from './lucid_store/password_hygiene.js';
|
|
10
|
-
import { PasswordManager } from '../password/password_manager.js';
|
|
11
11
|
let encSvc;
|
|
12
12
|
let encLoading;
|
|
13
13
|
/** Resolve quando o `loadEncryption()` corrente terminar (sucesso OU falha). */
|
|
@@ -192,9 +192,7 @@ export function lucidAccountStore(Model, options = {}) {
|
|
|
192
192
|
// Status (disable/enable) só quando o model tem a coluna `disabled_at`.
|
|
193
193
|
...(hasColumn(Model, 'disabledAt') ? buildStatus(ctx) : {}),
|
|
194
194
|
// Perfil (nome/avatar) só quando o model tem ao menos uma das colunas.
|
|
195
|
-
...(hasColumn(Model, 'fullName') || hasColumn(Model, 'avatarUrl')
|
|
196
|
-
? buildProfile(ctx)
|
|
197
|
-
: {}),
|
|
195
|
+
...(hasColumn(Model, 'fullName') || hasColumn(Model, 'avatarUrl') ? buildProfile(ctx) : {}),
|
|
198
196
|
// Estado de verificação de e-mail (leitura) só quando o model tem a coluna.
|
|
199
197
|
...(hasColumn(Model, 'emailVerifiedAt') ? buildEmailVerificationStatus(ctx) : {}),
|
|
200
198
|
// Deleção da conta: sempre disponível (qualquer model Lucid pode deletar).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
|
-
import { DateTime } from 'luxon';
|
|
3
2
|
import { Scrypt } from '@adonisjs/core/hash/drivers/scrypt';
|
|
3
|
+
import { DateTime } from 'luxon';
|
|
4
4
|
import { hasColumn } from './status_profile.js';
|
|
5
5
|
/** Prefixo do token de troca de e-mail (reaproveita a coluna emailVerificationToken). */
|
|
6
6
|
const EMAIL_CHANGE_PREFIX = 'ec:';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { authenticator } from 'otplib';
|
|
2
|
-
import { generateRecoveryCode, hashesEqual, sha256,
|
|
2
|
+
import { buildMfaStateRepo, generateRecoveryCode, hashesEqual, sha256, } from './shared.js';
|
|
3
3
|
/**
|
|
4
4
|
* Capacidade de MFA / TOTP — LIB-OWNED.
|
|
5
5
|
*
|
|
@@ -201,9 +201,7 @@ export function buildOrganizations(ctx) {
|
|
|
201
201
|
return rows.map(toOrgInvitation);
|
|
202
202
|
},
|
|
203
203
|
async listPendingInvitationsForEmail(email) {
|
|
204
|
-
const rows = await InvitationModel.query()
|
|
205
|
-
.where('email', email)
|
|
206
|
-
.whereNull('accepted_at');
|
|
204
|
+
const rows = await InvitationModel.query().where('email', email).whereNull('accepted_at');
|
|
207
205
|
return rows.map(toOrgInvitation);
|
|
208
206
|
},
|
|
209
207
|
async acceptInvitation(invitationId, accountId) {
|
|
@@ -227,7 +225,7 @@ export function buildOrganizations(ctx) {
|
|
|
227
225
|
else {
|
|
228
226
|
expiresMs = 0;
|
|
229
227
|
}
|
|
230
|
-
if (isNaN(expiresMs) || expiresMs < Date.now())
|
|
228
|
+
if (Number.isNaN(expiresMs) || expiresMs < Date.now())
|
|
231
229
|
return { ok: false, reason: 'expired' };
|
|
232
230
|
// Verifica e-mail
|
|
233
231
|
const accountEmail = await findAccountEmail(accountId);
|
|
@@ -74,10 +74,7 @@ export function buildPasswordHistory(ctx, db) {
|
|
|
74
74
|
return; // menos registros que o limite → nada a podar
|
|
75
75
|
// Apaga os mais antigos (todos exceto os últimos `count`).
|
|
76
76
|
const keepIds = rows.map((r) => r.id);
|
|
77
|
-
await qFrom()
|
|
78
|
-
.where('account_id', accountId)
|
|
79
|
-
.whereNotIn('id', keepIds)
|
|
80
|
-
.delete();
|
|
77
|
+
await qFrom().where('account_id', accountId).whereNotIn('id', keepIds).delete();
|
|
81
78
|
}
|
|
82
79
|
catch {
|
|
83
80
|
// Best-effort.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { generateAuthenticationOptions, generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse } from '@simplewebauthn/server';
|
|
2
|
-
import type { AuthAccount } from '../account_store.js';
|
|
3
2
|
import type { AuditSink } from '../../audit/audit_sink.js';
|
|
4
3
|
import type { PasswordManager } from '../../password/password_manager.js';
|
|
4
|
+
import type { AuthAccount } from '../account_store.js';
|
|
5
5
|
/**
|
|
6
6
|
* Encripta/decripta um valor (ex.: o segredo TOTP) em repouso. Mantém a lib
|
|
7
7
|
* desacoplada do serviço de encryption do app — qualquer implementação que
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type LucidAccountStoreOptions } from './lucid_account_store.js';
|
|
2
|
-
import type { AccountStore } from './account_store.js';
|
|
3
|
-
import type { PatStore } from '../pat/pat_store.js';
|
|
4
1
|
import type { AuditSink } from '../audit/audit_sink.js';
|
|
2
|
+
import type { PatStore } from '../pat/pat_store.js';
|
|
3
|
+
import type { AccountStore } from './account_store.js';
|
|
4
|
+
import { type LucidAccountStoreOptions } from './lucid_account_store.js';
|
|
5
5
|
/** Models Lucid (compostos dos mixins do authkit) para montar os stores de uma vez. */
|
|
6
6
|
export interface LucidStoresModels {
|
|
7
7
|
/** Model de `withAuthUser()` (+withCredentials/+withMfa). Obrigatório. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { lucidAccountStore } from './lucid_account_store.js';
|
|
2
|
-
import { lucidPatStore } from '../pat/lucid_pat_store.js';
|
|
3
1
|
import { lucidAuditSink } from '../audit/lucid_audit_sink.js';
|
|
2
|
+
import { lucidPatStore } from '../pat/lucid_pat_store.js';
|
|
3
|
+
import { lucidAccountStore } from './lucid_account_store.js';
|
|
4
4
|
/**
|
|
5
5
|
* Conveniência que monta `accountStore` (+ `patStore` + `audit`) a partir dos models,
|
|
6
6
|
* declarando `mfaIssuer`/`webauthn`/`encrypter` UMA vez. Substitui o wiring repetido
|
|
@@ -52,7 +52,9 @@ export class DatabaseAdapter {
|
|
|
52
52
|
if (!found)
|
|
53
53
|
return;
|
|
54
54
|
found.consumed = Math.floor(Date.now() / 1000);
|
|
55
|
-
await this.#query()
|
|
55
|
+
await this.#query()
|
|
56
|
+
.where('id', id)
|
|
57
|
+
.update({ payload: JSON.stringify(found) });
|
|
56
58
|
}
|
|
57
59
|
async destroy(id) {
|
|
58
60
|
await this.#query().where('id', id).delete();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RedisAdapter } from './redis_adapter.js';
|
|
2
1
|
import { DatabaseAdapter } from './database_adapter.js';
|
|
2
|
+
import { RedisAdapter } from './redis_adapter.js';
|
|
3
3
|
export const adapters = {
|
|
4
4
|
/**
|
|
5
5
|
* Factory para o adapter Redis. O consumidor precisa ter o @adonisjs/redis
|
|
@@ -88,7 +88,8 @@ export class RedisAdapter {
|
|
|
88
88
|
const gk = this.#grantKey(grantId);
|
|
89
89
|
const keys = await this.redis.lrange(gk, 0, -1);
|
|
90
90
|
const multi = this.redis.multi();
|
|
91
|
-
|
|
91
|
+
for (const k of keys)
|
|
92
|
+
multi.del(k);
|
|
92
93
|
multi.del(gk);
|
|
93
94
|
await multi.exec();
|
|
94
95
|
}
|
|
@@ -27,9 +27,9 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
27
27
|
}
|
|
28
28
|
return path;
|
|
29
29
|
};
|
|
30
|
-
import { resolveAuthkitConfig } from './resolve_config.js';
|
|
31
30
|
import { RuntimeSettings } from '../host/runtime_settings.js';
|
|
32
31
|
import { resolveEffectiveAccountExpiration } from '../host/runtime_toggles.js';
|
|
32
|
+
import { resolveAuthkitConfig } from './resolve_config.js';
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
34
34
|
// Core logic (pura, testável sem Ace)
|
|
35
35
|
// ---------------------------------------------------------------------------
|
|
@@ -101,7 +101,11 @@ export async function runExpireScan(app, opts) {
|
|
|
101
101
|
else if (warnDays > 0 && lastMs < warnCutoffMs) {
|
|
102
102
|
// A expirar em breve.
|
|
103
103
|
const daysUntilExpiry = Math.ceil((lastMs + inactiveDays * 24 * 60 * 60 * 1000 - nowMs) / (24 * 60 * 60 * 1000));
|
|
104
|
-
warnSoon.push({
|
|
104
|
+
warnSoon.push({
|
|
105
|
+
accountId: account.id,
|
|
106
|
+
email: account.email,
|
|
107
|
+
expiresInDays: daysUntilExpiry,
|
|
108
|
+
});
|
|
105
109
|
if (warn && !dryRun) {
|
|
106
110
|
// Verifica se já foi avisado dentro da janela de warnDays dias.
|
|
107
111
|
const alreadyWarned = await wasWarnedRecently(audit, account.id, warnDays);
|
|
@@ -150,7 +154,12 @@ export async function runExpireScan(app, opts) {
|
|
|
150
154
|
/** Retorna o timestamp em ms do último login.success da conta, ou null se nunca logou. */
|
|
151
155
|
async function getLastLoginMs(audit, accountId) {
|
|
152
156
|
try {
|
|
153
|
-
const result = await audit.list({
|
|
157
|
+
const result = await audit.list({
|
|
158
|
+
type: 'login.success',
|
|
159
|
+
subject: accountId,
|
|
160
|
+
page: 1,
|
|
161
|
+
limit: 1,
|
|
162
|
+
});
|
|
154
163
|
if (result.data.length === 0)
|
|
155
164
|
return null;
|
|
156
165
|
const createdAt = result.data[0].createdAt;
|
|
@@ -169,7 +178,12 @@ async function getLastLoginMs(audit, accountId) {
|
|
|
169
178
|
*/
|
|
170
179
|
async function wasWarnedRecently(audit, accountId, warnDays) {
|
|
171
180
|
try {
|
|
172
|
-
const result = await audit.list({
|
|
181
|
+
const result = await audit.list({
|
|
182
|
+
type: 'account.expiration_warned',
|
|
183
|
+
subject: accountId,
|
|
184
|
+
page: 1,
|
|
185
|
+
limit: 1,
|
|
186
|
+
});
|
|
173
187
|
if (result.data.length === 0)
|
|
174
188
|
return false;
|
|
175
189
|
const lastWarned = result.data[0].createdAt;
|
|
@@ -201,7 +215,7 @@ async function sendWarnEmail(cfg, account, expiresInDays) {
|
|
|
201
215
|
await mail.send((message) => {
|
|
202
216
|
message
|
|
203
217
|
.to(account.email)
|
|
204
|
-
.subject(
|
|
218
|
+
.subject('Your account will be deactivated due to inactivity')
|
|
205
219
|
.html(`<p>Your account will be deactivated in <strong>${expiresInDays} day(s)</strong> due to inactivity. Sign in to keep your account active.</p>`)
|
|
206
220
|
.text(`Your account will be deactivated in ${expiresInDays} day(s) due to inactivity. Sign in to keep your account active.`);
|
|
207
221
|
});
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* Todas suportam --json para output machine-readable.
|
|
16
16
|
*/
|
|
17
17
|
import { RuntimeSettings } from '../host/runtime_settings.js';
|
|
18
|
-
import { resolveAuthkitConfig } from './resolve_config.js';
|
|
19
18
|
import { SETTING_KEYS } from '../host/runtime_toggles.js';
|
|
19
|
+
import { resolveAuthkitConfig } from './resolve_config.js';
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
21
|
// Known-key shape validators (best-effort — warn only, não rejeita)
|
|
22
22
|
// ---------------------------------------------------------------------------
|
|
@@ -31,7 +31,13 @@ function validateKnownKey(key, value) {
|
|
|
31
31
|
const obj = value;
|
|
32
32
|
switch (key) {
|
|
33
33
|
case SETTING_KEYS.LOCKOUT: {
|
|
34
|
-
const fields = [
|
|
34
|
+
const fields = [
|
|
35
|
+
'enabled',
|
|
36
|
+
'maxAttempts',
|
|
37
|
+
'windowSec',
|
|
38
|
+
'baseLockoutSec',
|
|
39
|
+
'maxLockoutSec',
|
|
40
|
+
];
|
|
35
41
|
for (const f of fields) {
|
|
36
42
|
if (f in obj && f === 'enabled' && typeof obj[f] !== 'boolean')
|
|
37
43
|
return `lockout.${f} must be boolean`;
|
|
@@ -55,13 +61,19 @@ function validateKnownKey(key, value) {
|
|
|
55
61
|
return null;
|
|
56
62
|
}
|
|
57
63
|
case SETTING_KEYS.PASSWORD_POLICY: {
|
|
58
|
-
const boolFields = [
|
|
64
|
+
const boolFields = [
|
|
65
|
+
'requireUppercase',
|
|
66
|
+
'requireLowercase',
|
|
67
|
+
'requireNumbers',
|
|
68
|
+
'requireSymbols',
|
|
69
|
+
'checkPwned',
|
|
70
|
+
];
|
|
59
71
|
for (const f of boolFields) {
|
|
60
72
|
if (f in obj && typeof obj[f] !== 'boolean')
|
|
61
73
|
return `password_policy.${f} must be boolean`;
|
|
62
74
|
}
|
|
63
75
|
if ('minLength' in obj && typeof obj.minLength !== 'number')
|
|
64
|
-
return
|
|
76
|
+
return 'password_policy.minLength must be number';
|
|
65
77
|
return null;
|
|
66
78
|
}
|
|
67
79
|
case SETTING_KEYS.NOTIFICATIONS: {
|
|
@@ -145,7 +157,12 @@ export async function settingsList(app, opts) {
|
|
|
145
157
|
}
|
|
146
158
|
const rows = await svc.listSettings();
|
|
147
159
|
if (opts.json) {
|
|
148
|
-
opts.logger.info(JSON.stringify(rows.map((r) => ({
|
|
160
|
+
opts.logger.info(JSON.stringify(rows.map((r) => ({
|
|
161
|
+
key: r.key,
|
|
162
|
+
value: r.value,
|
|
163
|
+
updatedAt: r.updatedAt,
|
|
164
|
+
updatedBy: r.updatedBy,
|
|
165
|
+
}))));
|
|
149
166
|
return;
|
|
150
167
|
}
|
|
151
168
|
if (rows.length === 0) {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
4
|
-
import type
|
|
5
|
-
import type {
|
|
6
|
-
import type
|
|
7
|
-
import type
|
|
8
|
-
import {
|
|
9
|
-
import type {
|
|
10
|
-
import { type AuthMessages, type I18nConfig } from
|
|
11
|
-
import
|
|
12
|
-
import { type
|
|
13
|
-
import type {
|
|
1
|
+
import type { AccessTokenFormat, AccessTokensConfig, ClientConfig, JwksConfig, KeystoreStoreConfig, ObservabilityConfig, TtlConfig } from '@adonis-agora/authkit-core';
|
|
2
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
3
|
+
import type { AccountStore, AuthAccount } from './accounts/account_store.js';
|
|
4
|
+
import { type AdapterFactory, type OidcAdapterClass, adapters } from './adapters/factory.js';
|
|
5
|
+
import type { AuditSink } from './audit/audit_sink.js';
|
|
6
|
+
import { type EventsConfigInput } from './events/dispatcher.js';
|
|
7
|
+
import { type BotProtectionConfigInput, type ResolvedBotProtectionConfig } from './host/bot_protection.js';
|
|
8
|
+
import type { BrandingConfig } from './host/branding.js';
|
|
9
|
+
import type { ResolveGeo } from './host/geo.js';
|
|
10
|
+
import { type AuthMessages, type I18nConfig } from './host/i18n.js';
|
|
11
|
+
import type { SudoMethod } from './host/sudo/types.js';
|
|
12
|
+
import { type ResolvedTrustedDevicesConfig, type TrustedDevicesConfigInput } from './host/trusted_device.js';
|
|
13
|
+
import type { PatStore } from './pat/pat_store.js';
|
|
14
14
|
export { adapters };
|
|
15
15
|
export type { AuthAccount };
|
|
16
16
|
export type AuthHostRenderer = (ctx: HttpContext, view: string, props: Record<string, unknown>) => unknown;
|
|
@@ -120,7 +120,7 @@ export interface MailHooks {
|
|
|
120
120
|
id: string;
|
|
121
121
|
email: string;
|
|
122
122
|
};
|
|
123
|
-
kind:
|
|
123
|
+
kind: 'password_changed' | 'mfa_enabled' | 'mfa_disabled' | 'passkey_added' | 'passkey_removed' | 'email_changed';
|
|
124
124
|
ip?: string | null;
|
|
125
125
|
userAgent?: string | null;
|
|
126
126
|
timestamp: string;
|
|
@@ -282,7 +282,7 @@ export interface UploadsConfigInput {
|
|
|
282
282
|
* `'builtin'` força o `@adonisjs/drive`; `'media'` força o media (degrada para
|
|
283
283
|
* o input de URL se indisponível).
|
|
284
284
|
*/
|
|
285
|
-
storage?:
|
|
285
|
+
storage?: 'auto' | 'builtin' | 'media';
|
|
286
286
|
/** Disk do `@adonisjs/drive` a usar (backend builtin). Default: o disk DEFAULT do app. */
|
|
287
287
|
disk?: string;
|
|
288
288
|
/** Diretório/prefixo das chaves (backend builtin). Default: 'authkit/avatars'. */
|
|
@@ -298,7 +298,7 @@ export interface UploadsConfigInput {
|
|
|
298
298
|
export interface ResolvedUploadsConfig {
|
|
299
299
|
avatars: {
|
|
300
300
|
/** Backend ativo (default 'auto'). */
|
|
301
|
-
storage:
|
|
301
|
+
storage: 'auto' | 'builtin' | 'media';
|
|
302
302
|
/** Disk explícito; `undefined` = disk DEFAULT do app (backend builtin). */
|
|
303
303
|
disk?: string;
|
|
304
304
|
directory: string;
|
|
@@ -524,7 +524,7 @@ export interface AdminApiConfigInput {
|
|
|
524
524
|
* `AUTHKIT_ADMIN_API_KEY` (uma ou várias, separadas por vírgula). Elimina o
|
|
525
525
|
* spread condicional `...(env.get('AUTHKIT_ADMIN_API_KEY') ? {...} : {})`.
|
|
526
526
|
*/
|
|
527
|
-
apiKeys?: string[] |
|
|
527
|
+
apiKeys?: string[] | 'env';
|
|
528
528
|
}
|
|
529
529
|
export interface ResolvedAdminApiConfig {
|
|
530
530
|
enabled: boolean;
|
|
@@ -550,7 +550,7 @@ export interface OrganizationsConfigInput {
|
|
|
550
550
|
* emite org_id/org_slug/org_role da org ativa da sessão via cookie assinado.
|
|
551
551
|
* Default: 'active'.
|
|
552
552
|
*/
|
|
553
|
-
claimStrategy?:
|
|
553
|
+
claimStrategy?: 'active';
|
|
554
554
|
}
|
|
555
555
|
export interface ResolvedOrganizationsConfig {
|
|
556
556
|
/** `undefined` = auto (decide em runtime pelo capability-probing do store). */
|
|
@@ -558,7 +558,7 @@ export interface ResolvedOrganizationsConfig {
|
|
|
558
558
|
roles: string[];
|
|
559
559
|
allowSelfCreate: boolean;
|
|
560
560
|
invitationTtlHours: number;
|
|
561
|
-
claimStrategy:
|
|
561
|
+
claimStrategy: 'active';
|
|
562
562
|
}
|
|
563
563
|
export declare function resolveOrganizations(input?: OrganizationsConfigInput): ResolvedOrganizationsConfig;
|
|
564
564
|
/**
|
|
@@ -601,7 +601,7 @@ export interface AuthServerConfigInput {
|
|
|
601
601
|
* persistido em arquivo (`tmp/authkit_jwks.json`) p/ dev. Elimina o ternário
|
|
602
602
|
* env-aware que todo app escrevia.
|
|
603
603
|
*/
|
|
604
|
-
jwks: JwksConfig |
|
|
604
|
+
jwks: JwksConfig | 'auto';
|
|
605
605
|
ttl?: TtlConfig;
|
|
606
606
|
/** Nome da CLAIM (não do scope) onde os papéis globais são emitidos. Default: 'roles'. */
|
|
607
607
|
globalRolesClaim?: string;
|