@adonis-agora/authkit-server 0.47.0 → 0.49.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.
Files changed (190) hide show
  1. package/build/commands/clients_create.js +4 -4
  2. package/build/commands/configure.js +3 -2
  3. package/build/commands/doctor.js +8 -5
  4. package/build/commands/eject.js +1 -1
  5. package/build/commands/expire_scan.js +7 -5
  6. package/build/commands/import_users.js +1 -1
  7. package/build/commands/keys_rotate.js +7 -4
  8. package/build/host/views/account/apps.edge +5 -5
  9. package/build/host/views/account/login.edge +1 -1
  10. package/build/host/views/account/mfa.edge +7 -7
  11. package/build/host/views/account/orgs.edge +5 -5
  12. package/build/host/views/account/security.edge +10 -10
  13. package/build/host/views/account/tokens.edge +5 -5
  14. package/build/index.d.ts +22 -7
  15. package/build/index.js +18 -5
  16. package/build/providers/authkit_server_provider.d.ts +2 -2
  17. package/build/providers/authkit_server_provider.js +20 -11
  18. package/build/services/main.d.ts +1 -1
  19. package/build/services/main.js +2 -2
  20. package/build/src/accounts/lucid_account_store.d.ts +3 -3
  21. package/build/src/accounts/lucid_account_store.js +6 -8
  22. package/build/src/accounts/lucid_store/core.js +1 -1
  23. package/build/src/accounts/lucid_store/mfa.js +1 -1
  24. package/build/src/accounts/lucid_store/organizations.js +2 -4
  25. package/build/src/accounts/lucid_store/password_hygiene.js +1 -4
  26. package/build/src/accounts/lucid_store/shared.d.ts +1 -1
  27. package/build/src/accounts/lucid_stores.d.ts +3 -3
  28. package/build/src/accounts/lucid_stores.js +2 -2
  29. package/build/src/adapters/database_adapter.js +3 -1
  30. package/build/src/adapters/factory.js +1 -1
  31. package/build/src/adapters/redis_adapter.js +2 -1
  32. package/build/src/commands/expire_scan_command.js +19 -5
  33. package/build/src/commands/settings_commands.js +22 -5
  34. package/build/src/define_config.d.ts +20 -20
  35. package/build/src/define_config.js +62 -67
  36. package/build/src/doctor/checks.js +45 -20
  37. package/build/src/events/dispatcher.d.ts +1 -1
  38. package/build/src/events/dispatcher.js +10 -10
  39. package/build/src/host/account_api/account_api_controller.js +95 -39
  40. package/build/src/host/account_deletion_ops.d.ts +4 -4
  41. package/build/src/host/account_deletion_ops.js +5 -5
  42. package/build/src/host/account_deletion_service.d.ts +2 -2
  43. package/build/src/host/account_deletion_service.js +2 -2
  44. package/build/src/host/account_export_service.d.ts +1 -1
  45. package/build/src/host/account_export_service.js +4 -6
  46. package/build/src/host/account_home.d.ts +0 -8
  47. package/build/src/host/account_home.js +6 -4
  48. package/build/src/host/account_login_url.d.ts +6 -3
  49. package/build/src/host/account_login_url.js +16 -8
  50. package/build/src/host/account_paths.d.ts +120 -0
  51. package/build/src/host/account_paths.js +161 -0
  52. package/build/src/host/account_screen_props.d.ts +163 -0
  53. package/build/src/host/account_screen_props.js +23 -0
  54. package/build/src/host/admin_api/admin_orgs_service.d.ts +2 -2
  55. package/build/src/host/admin_api/admin_orgs_service.js +3 -2
  56. package/build/src/host/admin_api/admin_users_service.d.ts +12 -12
  57. package/build/src/host/admin_api/admin_users_service.js +20 -20
  58. package/build/src/host/admin_api/api_clients_controller.js +2 -2
  59. package/build/src/host/admin_api/api_misc_controller.js +2 -2
  60. package/build/src/host/admin_api/api_orgs_controller.js +3 -3
  61. package/build/src/host/admin_api/api_settings_controller.js +11 -5
  62. package/build/src/host/admin_api/api_users_controller.d.ts +2 -2
  63. package/build/src/host/admin_api/api_users_controller.js +37 -38
  64. package/build/src/host/admin_api/dto.d.ts +4 -4
  65. package/build/src/host/admin_clients_service.js +5 -4
  66. package/build/src/host/admin_console/admin_shell_controller.js +4 -2
  67. package/build/src/host/admin_console/console_audit_controller.js +1 -1
  68. package/build/src/host/admin_console/console_clients_controller.js +5 -3
  69. package/build/src/host/admin_console/console_impersonation_controller.js +1 -1
  70. package/build/src/host/admin_console/console_keys_controller.js +2 -4
  71. package/build/src/host/admin_console/console_orgs_controller.js +3 -3
  72. package/build/src/host/admin_console/console_roles_controller.js +30 -12
  73. package/build/src/host/admin_console/console_sessions_controller.js +3 -3
  74. package/build/src/host/admin_console/console_settings_controller.js +11 -5
  75. package/build/src/host/admin_console/console_users_controller.d.ts +2 -2
  76. package/build/src/host/admin_console/console_users_controller.js +46 -47
  77. package/build/src/host/admin_prefix.js +2 -2
  78. package/build/src/host/admin_sessions_service.js +1 -3
  79. package/build/src/host/adonis_auth_sync.d.ts +1 -1
  80. package/build/src/host/adonis_auth_user_provider.d.ts +1 -1
  81. package/build/src/host/app_key.js +1 -1
  82. package/build/src/host/avatar_storage.js +1 -3
  83. package/build/src/host/config_locks.js +1 -3
  84. package/build/src/host/console_session.js +1 -1
  85. package/build/src/host/controllers/account_apps_controller.js +3 -2
  86. package/build/src/host/controllers/account_confirm_controller.js +5 -8
  87. package/build/src/host/controllers/account_mfa_controller.js +72 -18
  88. package/build/src/host/controllers/account_orgs_controller.js +47 -27
  89. package/build/src/host/controllers/account_security_controller.d.ts +2 -2
  90. package/build/src/host/controllers/account_security_controller.js +116 -116
  91. package/build/src/host/controllers/account_session_controller.js +13 -8
  92. package/build/src/host/controllers/account_tokens_controller.js +3 -2
  93. package/build/src/host/controllers/interaction_controller.js +59 -22
  94. package/build/src/host/controllers/registration_controller.js +28 -13
  95. package/build/src/host/default_mailer.js +11 -7
  96. package/build/src/host/durable/account_deletion_workflow.d.ts +2 -2
  97. package/build/src/host/durable/account_deletion_workflow.js +14 -14
  98. package/build/src/host/durable/account_export_workflow.d.ts +2 -2
  99. package/build/src/host/durable/account_export_workflow.js +12 -12
  100. package/build/src/host/durable/index.d.ts +5 -5
  101. package/build/src/host/durable/index.js +6 -6
  102. package/build/src/host/i18n.d.ts +1376 -1376
  103. package/build/src/host/i18n.js +1380 -1380
  104. package/build/src/host/impersonation.js +1 -7
  105. package/build/src/host/key_rotation_actions.d.ts +1 -1
  106. package/build/src/host/login_attempt.js +35 -6
  107. package/build/src/host/login_notify.js +1 -1
  108. package/build/src/host/otp_lockout.js +1 -3
  109. package/build/src/host/rate_limit.js +1 -1
  110. package/build/src/host/register_auth_host.d.ts +30 -0
  111. package/build/src/host/register_auth_host.js +120 -74
  112. package/build/src/host/renderers/edge_renderer.js +15 -2
  113. package/build/src/host/renderers/inertia_renderer.d.ts +23 -58
  114. package/build/src/host/renderers/inertia_renderer.js +23 -58
  115. package/build/src/host/runtime_settings.js +1 -1
  116. package/build/src/host/runtime_toggles.d.ts +3 -3
  117. package/build/src/host/runtime_toggles.js +69 -24
  118. package/build/src/host/security_notice_service.d.ts +1 -1
  119. package/build/src/host/security_notice_service.js +1 -1
  120. package/build/src/host/session_context.js +1 -1
  121. package/build/src/host/sudo/index.d.ts +3 -3
  122. package/build/src/host/sudo/index.js +3 -3
  123. package/build/src/host/sudo/methods/magic_link.js +6 -5
  124. package/build/src/host/sudo/methods/passkey.js +7 -4
  125. package/build/src/host/sudo/methods/password.js +8 -3
  126. package/build/src/host/sudo/runtime.js +6 -13
  127. package/build/src/host/sudo_mode.js +3 -2
  128. package/build/src/host/ui-dist/assets/index-BQoTDiLV.js +137 -0
  129. package/build/src/host/ui-dist/index.html +1 -1
  130. package/build/src/keys/jwks_manager.js +1 -1
  131. package/build/src/keys/keystore.js +1 -1
  132. package/build/src/keys/keystore_manager.d.ts +2 -2
  133. package/build/src/keys/keystore_manager.js +2 -2
  134. package/build/src/keys/keystore_vault.js +8 -4
  135. package/build/src/mixins/with_audit_log.d.ts +1 -1
  136. package/build/src/mixins/with_auth_user.d.ts +1 -1
  137. package/build/src/mixins/with_auth_user.js +1 -1
  138. package/build/src/mixins/with_credentials.d.ts +1 -1
  139. package/build/src/mixins/with_mfa.d.ts +1 -1
  140. package/build/src/mixins/with_personal_access_token.d.ts +1 -1
  141. package/build/src/mixins/with_provider_identity.d.ts +1 -1
  142. package/build/src/mixins/with_webauthn_credential.d.ts +1 -1
  143. package/build/src/observability/diagnostics_bridge.js +2 -2
  144. package/build/src/observability/metrics_service.js +1 -1
  145. package/build/src/observability/telescope/data_providers.d.ts +1 -1
  146. package/build/src/observability/telescope/data_providers.js +29 -43
  147. package/build/src/observability/telescope/extension.d.ts +1 -1
  148. package/build/src/observability/telescope/extension.js +58 -58
  149. package/build/src/observability/telescope/index.d.ts +2 -2
  150. package/build/src/observability/telescope/index.js +2 -2
  151. package/build/src/observability/wire_provider_events.d.ts +1 -1
  152. package/build/src/observability/wire_provider_events.js +11 -11
  153. package/build/src/password/common_passwords.js +1 -1
  154. package/build/src/password/password_manager.d.ts +1 -1
  155. package/build/src/password/password_manager.js +4 -4
  156. package/build/src/pat/lucid_pat_store.js +2 -6
  157. package/build/src/pat/pat_tokens.js +1 -1
  158. package/build/src/provider/interaction_actions.js +1 -1
  159. package/build/src/provider/key_rotation_scheduler.js +3 -1
  160. package/build/src/provider/logout_sources.js +2 -8
  161. package/build/src/provider/oidc_service.d.ts +2 -2
  162. package/build/src/provider/oidc_service.js +22 -14
  163. package/build/src/provider/single_flight_lock.js +1 -3
  164. package/build/src/provider/token_exchange.d.ts +1 -1
  165. package/build/src/schema/ensure.js +3 -1
  166. package/build/stubs/ui/react/components/auth_shell.tsx +19 -19
  167. package/build/stubs/ui/react/pages/account/login.tsx +6 -7
  168. package/build/stubs/ui/react/pages/account/mfa.tsx +16 -15
  169. package/build/stubs/ui/react/pages/account/tokens.tsx +27 -17
  170. package/build/stubs/ui/react/pages/consent.tsx +12 -12
  171. package/build/stubs/ui/react/pages/forgot.tsx +7 -7
  172. package/build/stubs/ui/react/pages/login.tsx +22 -24
  173. package/build/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
  174. package/build/stubs/ui/react/pages/reset.tsx +10 -10
  175. package/build/stubs/ui/react/pages/signup.tsx +30 -16
  176. package/build/stubs/ui/react/pages/verify-email.tsx +6 -6
  177. package/package.json +2 -2
  178. package/stubs/main.ts +2 -2
  179. package/stubs/ui/react/components/auth_shell.tsx +19 -19
  180. package/stubs/ui/react/pages/account/login.tsx +6 -7
  181. package/stubs/ui/react/pages/account/mfa.tsx +16 -15
  182. package/stubs/ui/react/pages/account/tokens.tsx +27 -17
  183. package/stubs/ui/react/pages/consent.tsx +12 -12
  184. package/stubs/ui/react/pages/forgot.tsx +7 -7
  185. package/stubs/ui/react/pages/login.tsx +22 -24
  186. package/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
  187. package/stubs/ui/react/pages/reset.tsx +10 -10
  188. package/stubs/ui/react/pages/signup.tsx +30 -16
  189. package/stubs/ui/react/pages/verify-email.tsx +6 -6
  190. package/build/src/host/ui-dist/assets/index-BmI_J87g.js +0 -137
@@ -8,7 +8,7 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
10
  <link href="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700&family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;1,400&display=swap" rel="stylesheet">
11
- <script type="module" crossorigin src="/__AUTHKIT_BASE__/assets/index-BmI_J87g.js"></script>
11
+ <script type="module" crossorigin src="/__AUTHKIT_BASE__/assets/index-BQoTDiLV.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/__AUTHKIT_BASE__/assets/index-DTSmD4RU.css">
13
13
  </head>
14
14
  <body>
@@ -1,5 +1,5 @@
1
- import { generateKeyPair, exportJWK } from 'jose';
2
1
  import { randomUUID } from 'node:crypto';
2
+ import { exportJWK, generateKeyPair } from 'jose';
3
3
  /** Gera um JWKS privado (1 chave) pronto para `oidc-provider`. */
4
4
  export async function generateJwks(alg) {
5
5
  const { privateKey } = await generateKeyPair(alg, { extractable: true });
@@ -1,5 +1,5 @@
1
- import { generateKeyPair, exportJWK } from 'jose';
2
1
  import { randomUUID } from 'node:crypto';
2
+ import { exportJWK, generateKeyPair } from 'jose';
3
3
  /** Gera uma chave de assinatura privada como JWK (com use/alg/kid + carimbo de criação). */
4
4
  export async function generateSigningJwk(alg) {
5
5
  const { privateKey } = await generateKeyPair(alg, { extractable: true });
@@ -1,8 +1,8 @@
1
+ import type { KeystoreStoreConfig } from '@adonis-agora/authkit-core';
2
+ import type { SigningAlg } from './jwks_manager.js';
1
3
  import { type PersistedKeystore, type RotationPlan } from './keystore.js';
2
4
  import type { KeystoreCodec } from './keystore_codec.js';
3
5
  import { type KeystoreVault } from './keystore_vault.js';
4
- import type { SigningAlg } from './jwks_manager.js';
5
- import type { KeystoreStoreConfig } from '@adonis-agora/authkit-core';
6
6
  /**
7
7
  * Único caminho de I/O do keystore managed: compõe um {@link KeystoreVault} (onde
8
8
  * o blob mora) com um {@link KeystoreCodec} (serialização + encryption). As helpers
@@ -1,5 +1,5 @@
1
- import { generateSigningJwk, planRotation } from './keystore.js';
2
- import { FileKeystoreVault, DriveKeystoreVault, LucidKeystoreVault, RedisKeystoreVault, HashicorpVaultKeystoreVault, LazyExternalVault } from './keystore_vault.js';
1
+ import { generateSigningJwk, planRotation, } from './keystore.js';
2
+ import { DriveKeystoreVault, FileKeystoreVault, HashicorpVaultKeystoreVault, LazyExternalVault, LucidKeystoreVault, RedisKeystoreVault, } from './keystore_vault.js';
3
3
  /**
4
4
  * Único caminho de I/O do keystore managed: compõe um {@link KeystoreVault} (onde
5
5
  * o blob mora) com um {@link KeystoreCodec} (serialização + encryption). As helpers
@@ -19,7 +19,7 @@ export class FileKeystoreVault {
19
19
  }
20
20
  async write(blob) {
21
21
  mkdirSync(dirname(this.path), { recursive: true });
22
- writeFileSync(this.path, blob.endsWith('\n') ? blob : blob + '\n', { mode: 0o600 });
22
+ writeFileSync(this.path, blob.endsWith('\n') ? blob : `${blob}\n`, { mode: 0o600 });
23
23
  }
24
24
  async head() {
25
25
  return existsSync(this.path) ? String(statSync(this.path).mtimeMs) : null;
@@ -148,8 +148,12 @@ export class HashicorpVaultKeystoreVault {
148
148
  h['x-vault-token'] = this.#token;
149
149
  return h;
150
150
  }
151
- #dataUrl() { return `${this.#endpoint}/v1/${this.#mount}/data/${this.#path}`; }
152
- #metaUrl() { return `${this.#endpoint}/v1/${this.#mount}/metadata/${this.#path}`; }
151
+ #dataUrl() {
152
+ return `${this.#endpoint}/v1/${this.#mount}/data/${this.#path}`;
153
+ }
154
+ #metaUrl() {
155
+ return `${this.#endpoint}/v1/${this.#mount}/metadata/${this.#path}`;
156
+ }
153
157
  async read() {
154
158
  const res = await this.#fetch(this.#dataUrl(), { method: 'GET', headers: this.#headers() });
155
159
  if (res.status === 404)
@@ -256,7 +260,7 @@ export class DriveKeystoreVault {
256
260
  const disk = await this.disk();
257
261
  try {
258
262
  const meta = await disk.getMetaData(this.key);
259
- return meta?.etag ?? (meta?.lastModified ? String(new Date(meta.lastModified).getTime()) : null);
263
+ return (meta?.etag ?? (meta?.lastModified ? String(new Date(meta.lastModified).getTime()) : null));
260
264
  }
261
265
  catch {
262
266
  return null;
@@ -1,5 +1,5 @@
1
- import { BaseModel } from '@adonisjs/lucid/orm';
2
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
+ import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  import { DateTime } from 'luxon';
4
4
  import type { AuditEventType } from '../audit/audit_sink.js';
5
5
  /** Instância composta pelo mixin {@link withAuditLog}. */
@@ -1,5 +1,5 @@
1
- import { BaseModel } from '@adonisjs/lucid/orm';
2
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
+ import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  /**
4
4
  * Instância composta pelo mixin {@link withAuthUser}.
5
5
  */
@@ -4,8 +4,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
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
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { column, beforeSave } from '@adonisjs/lucid/orm';
8
7
  import { Scrypt } from '@adonisjs/core/hash/drivers/scrypt';
8
+ import { beforeSave, column } from '@adonisjs/lucid/orm';
9
9
  import { jsonColumn } from './json_column.js';
10
10
  const hasher = new Scrypt({});
11
11
  export function withAuthUser() {
@@ -1,5 +1,5 @@
1
- import { BaseModel } from '@adonisjs/lucid/orm';
2
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
+ import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  import { DateTime } from 'luxon';
4
4
  /**
5
5
  * Instância composta pelo mixin {@link withCredentials}.
@@ -1,5 +1,5 @@
1
- import { BaseModel } from '@adonisjs/lucid/orm';
2
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
+ import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  import { DateTime } from 'luxon';
4
4
  /**
5
5
  * @deprecated O estado de MFA deixou de viver no model do host. Estas propriedades
@@ -1,5 +1,5 @@
1
- import { BaseModel } from '@adonisjs/lucid/orm';
2
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
+ import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  import { DateTime } from 'luxon';
4
4
  /** Instância composta pelo mixin {@link withPersonalAccessToken}. */
5
5
  export interface PersonalAccessTokenRow {
@@ -1,5 +1,5 @@
1
- import { BaseModel } from '@adonisjs/lucid/orm';
2
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
+ import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  import { DateTime } from 'luxon';
4
4
  /**
5
5
  * Instância composta pelo mixin {@link withProviderIdentity}. Liga uma conta
@@ -1,5 +1,5 @@
1
- import { BaseModel } from '@adonisjs/lucid/orm';
2
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
+ import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  import { DateTime } from 'luxon';
4
4
  /**
5
5
  * Instância composta pelo mixin {@link withWebauthnCredential}. Representa uma
@@ -10,7 +10,7 @@
10
10
  * `onDiagnostic('authkit', …)`) registra quando presente. Nada aqui pode lançar
11
11
  * para dentro do caminho de auth.
12
12
  */
13
- const EMIT_SLOT = Symbol.for("@agora/diagnostics:emit");
13
+ const EMIT_SLOT = Symbol.for('@agora/diagnostics:emit');
14
14
  /**
15
15
  * Republica `event` no barramento de diagnostics como `agora:authkit:<event>`
16
16
  * (o canal/diagnostics suffix É o nome do evento — sem tabela de mapeamento).
@@ -19,7 +19,7 @@ const EMIT_SLOT = Symbol.for("@agora/diagnostics:emit");
19
19
  export function emitDiagnostic(event, payload) {
20
20
  try {
21
21
  const emit = globalThis[EMIT_SLOT];
22
- emit?.("authkit", event, payload);
22
+ emit?.('authkit', event, payload);
23
23
  }
24
24
  catch {
25
25
  // best-effort: a ponte de diagnostics nunca quebra o caminho de auth.
@@ -1,4 +1,4 @@
1
- import { NoopRecorder } from '@adonis-agora/authkit-core';
1
+ import { NoopRecorder, } from '@adonis-agora/authkit-core';
2
2
  import { OtelRecorder } from './otel_recorder.js';
3
3
  export async function createMetricsRecorder(observability, meterName) {
4
4
  if (!observability.metrics)
@@ -1,4 +1,4 @@
1
- import type { DataProvider } from "@adonis-agora/telescope";
1
+ import type { DataProvider } from '@adonis-agora/telescope';
2
2
  /**
3
3
  * A stat (`{ value, delta?, spark? }`) over a window for a set of event types.
4
4
  * `query.metric` chooses the grouping; `query.windowMs` the window (default 24h).
@@ -1,7 +1,7 @@
1
1
  /** The Telescope entry `type` the generic diagnostics watcher records under. */
2
- const DIAGNOSTIC_TYPE = "diagnostic";
2
+ const DIAGNOSTIC_TYPE = 'diagnostic';
3
3
  /** The tag the diagnostics watcher stamps for authkit-emitted events. */
4
- const AUTHKIT_TAG = "lib:authkit";
4
+ const AUTHKIT_TAG = 'lib:authkit';
5
5
  /** Default rolling window for the entry-backed providers (24h). */
6
6
  const DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000;
7
7
  /** Fetch captured `agora:authkit:*` audit entries from Telescope (newest-first). */
@@ -14,7 +14,7 @@ async function fetchEntries(ctx, limit = 5_000) {
14
14
  }
15
15
  /** The `AuditEventType` an entry carries (under `content.event`), or `''`. */
16
16
  function eventOf(e) {
17
- return e.content?.event ?? "";
17
+ return e.content?.event ?? '';
18
18
  }
19
19
  /** Epoch millis the entry was recorded at, or `0` when absent/unparsable. */
20
20
  function timeOf(e) {
@@ -39,32 +39,19 @@ function splitWindows(entries, windowMs, now) {
39
39
  };
40
40
  }
41
41
  // The audit event groupings the dashboard rolls up.
42
- const LOGIN_SUCCESS = ["login.success"];
43
- const LOGIN_FAILURE = [
44
- "login.failure",
45
- "bot_protection.rejected",
46
- ];
47
- const MFA_ENROLLMENTS = [
48
- "mfa.enabled",
49
- "passkey.registered",
50
- ];
51
- const LOCKOUTS = ["account.locked", "otp.locked"];
52
- const PAT_EVENTS = [
53
- "pat.issued",
54
- "pat.revoked",
55
- "pat.used",
56
- ];
57
- const IMPERSONATION_EVENTS = [
58
- "impersonation",
59
- "impersonation.started",
60
- ];
42
+ const LOGIN_SUCCESS = ['login.success'];
43
+ const LOGIN_FAILURE = ['login.failure', 'bot_protection.rejected'];
44
+ const MFA_ENROLLMENTS = ['mfa.enabled', 'passkey.registered'];
45
+ const LOCKOUTS = ['account.locked', 'otp.locked'];
46
+ const PAT_EVENTS = ['pat.issued', 'pat.revoked', 'pat.used'];
47
+ const IMPERSONATION_EVENTS = ['impersonation', 'impersonation.started'];
61
48
  /**
62
49
  * A stat (`{ value, delta?, spark? }`) over a window for a set of event types.
63
50
  * `query.metric` chooses the grouping; `query.windowMs` the window (default 24h).
64
51
  */
65
52
  export function authkitEventCountProvider() {
66
53
  return {
67
- name: "authkit.eventCount",
54
+ name: 'authkit.eventCount',
68
55
  async resolve(query, ctx) {
69
56
  const entries = await fetchEntries(ctx);
70
57
  const windowMs = Number(query?.windowMs ?? DEFAULT_WINDOW_MS);
@@ -91,17 +78,16 @@ export function authkitEventCountProvider() {
91
78
  /** Map a panel `metric` to the set of `AuditEventType`s it aggregates. */
92
79
  function typesForMetric(metric) {
93
80
  switch (metric) {
94
- case "loginFailure":
81
+ case 'loginFailure':
95
82
  return LOGIN_FAILURE;
96
- case "mfaEnrollments":
83
+ case 'mfaEnrollments':
97
84
  return MFA_ENROLLMENTS;
98
- case "lockouts":
85
+ case 'lockouts':
99
86
  return LOCKOUTS;
100
- case "pat":
87
+ case 'pat':
101
88
  return PAT_EVENTS;
102
- case "impersonation":
89
+ case 'impersonation':
103
90
  return IMPERSONATION_EVENTS;
104
- case "loginSuccess":
105
91
  default:
106
92
  return LOGIN_SUCCESS;
107
93
  }
@@ -112,7 +98,7 @@ function typesForMetric(metric) {
112
98
  */
113
99
  export function authkitLoginSuccessRateProvider() {
114
100
  return {
115
- name: "authkit.loginSuccessRate",
101
+ name: 'authkit.loginSuccessRate',
116
102
  async resolve(query, ctx) {
117
103
  const entries = await fetchEntries(ctx);
118
104
  const windowMs = Number(query?.windowMs ?? DEFAULT_WINDOW_MS);
@@ -130,7 +116,7 @@ export function authkitLoginSuccessRateProvider() {
130
116
  */
131
117
  export function authkitLoginsOverTimeProvider() {
132
118
  return {
133
- name: "authkit.loginsOverTime",
119
+ name: 'authkit.loginsOverTime',
134
120
  async resolve(query, ctx) {
135
121
  const entries = await fetchEntries(ctx);
136
122
  const n = Math.max(1, Number(query?.buckets ?? 24));
@@ -170,16 +156,16 @@ export function authkitLoginsOverTimeProvider() {
170
156
  }
171
157
  /** Donut/bar `breakdown` segments — a count per top-level audit event family. */
172
158
  const BREAKDOWN_GROUPS = [
173
- { label: "Login OK", types: LOGIN_SUCCESS, color: "#34d399" },
174
- { label: "Login fail", types: LOGIN_FAILURE, color: "#f87171" },
175
- { label: "MFA", types: MFA_ENROLLMENTS, color: "#38bdf8" },
176
- { label: "Lockouts", types: LOCKOUTS, color: "#fbbf24" },
177
- { label: "PAT", types: PAT_EVENTS, color: "#a78bfa" },
178
- { label: "Impersonation", types: IMPERSONATION_EVENTS, color: "#fb923c" },
159
+ { label: 'Login OK', types: LOGIN_SUCCESS, color: '#34d399' },
160
+ { label: 'Login fail', types: LOGIN_FAILURE, color: '#f87171' },
161
+ { label: 'MFA', types: MFA_ENROLLMENTS, color: '#38bdf8' },
162
+ { label: 'Lockouts', types: LOCKOUTS, color: '#fbbf24' },
163
+ { label: 'PAT', types: PAT_EVENTS, color: '#a78bfa' },
164
+ { label: 'Impersonation', types: IMPERSONATION_EVENTS, color: '#fb923c' },
179
165
  ];
180
166
  export function authkitEventBreakdownProvider() {
181
167
  return {
182
- name: "authkit.eventBreakdown",
168
+ name: 'authkit.eventBreakdown',
183
169
  async resolve(query, ctx) {
184
170
  const entries = await fetchEntries(ctx);
185
171
  const windowMs = Number(query?.windowMs ?? DEFAULT_WINDOW_MS);
@@ -199,7 +185,7 @@ export function authkitEventBreakdownProvider() {
199
185
  */
200
186
  export function authkitTokenActivityProvider() {
201
187
  return {
202
- name: "authkit.tokenActivity",
188
+ name: 'authkit.tokenActivity',
203
189
  async resolve(query, ctx) {
204
190
  const entries = await fetchEntries(ctx);
205
191
  const limit = Math.min(200, Math.max(10, Number(query?.limit ?? 50)));
@@ -211,11 +197,11 @@ export function authkitTokenActivityProvider() {
211
197
  const p = e.content?.payload;
212
198
  return {
213
199
  at: e.createdAt
214
- ? `${new Date(e.createdAt).toISOString().replace("T", " ").slice(0, 16)}Z`
215
- : "",
200
+ ? `${new Date(e.createdAt).toISOString().replace('T', ' ').slice(0, 16)}Z`
201
+ : '',
216
202
  event: eventOf(e),
217
- subject: p?.accountId ?? "",
218
- actor: p?.actorId ?? "",
203
+ subject: p?.accountId ?? '',
204
+ actor: p?.actorId ?? '',
219
205
  // `ip` is intentionally NOT surfaced: the diagnostics bridge emits a
220
206
  // PII-free projection of each audit event (no `email`/`ip`/`metadata`)
221
207
  // so a deleted account's PII never lands in Telescope's store. See
@@ -1,4 +1,4 @@
1
- import type { TelescopeExtension } from "@adonis-agora/telescope";
1
+ import type { TelescopeExtension } from '@adonis-agora/telescope';
2
2
  /** Options for {@link defineAuthkitTelescopeExtension}. */
3
3
  export interface AuthkitTelescopeOptions {
4
4
  /**
@@ -1,11 +1,11 @@
1
- import { authkitDataProviders } from "./data_providers.js";
1
+ import { authkitDataProviders } from './data_providers.js';
2
2
  /**
3
3
  * The navigable entry type the extension contributes: it scopes Telescope's
4
4
  * entry-type nav to authkit's audit events (recorded as `diagnostic` entries
5
5
  * tagged `lib:authkit`).
6
6
  */
7
7
  function authkitEntryType() {
8
- return { id: "authkit", label: "Auth", dot: "bg-emerald-400" };
8
+ return { id: 'authkit', label: 'Auth', dot: 'bg-emerald-400' };
9
9
  }
10
10
  /**
11
11
  * The authkit "Security" dashboard — a golden-signals layout for auth: login
@@ -16,123 +16,123 @@ function authkitEntryType() {
16
16
  function authkitSecurityDashboard(opts) {
17
17
  const windowMs = opts.windowMs ?? 24 * 60 * 60 * 1000;
18
18
  return {
19
- id: "authkit.security",
20
- label: "Security",
21
- navGroup: "Auth",
19
+ id: 'authkit.security',
20
+ label: 'Security',
21
+ navGroup: 'Auth',
22
22
  panels: [],
23
23
  sections: [
24
24
  {
25
- title: "Logins",
25
+ title: 'Logins',
26
26
  cols: 4,
27
27
  panels: [
28
28
  {
29
- kind: "gauge",
30
- title: "Login success rate",
31
- data: { provider: "authkit.loginSuccessRate", query: { windowMs } },
29
+ kind: 'gauge',
30
+ title: 'Login success rate',
31
+ data: { provider: 'authkit.loginSuccessRate', query: { windowMs } },
32
32
  max: 1,
33
- format: "percent",
34
- thresholds: { warn: 0.9, bad: 0.75, direction: "down-bad" },
33
+ format: 'percent',
34
+ thresholds: { warn: 0.9, bad: 0.75, direction: 'down-bad' },
35
35
  },
36
36
  {
37
- kind: "stat",
38
- title: "Successful logins",
37
+ kind: 'stat',
38
+ title: 'Successful logins',
39
39
  data: {
40
- provider: "authkit.eventCount",
41
- query: { metric: "loginSuccess", windowMs },
40
+ provider: 'authkit.eventCount',
41
+ query: { metric: 'loginSuccess', windowMs },
42
42
  },
43
43
  spark: true,
44
44
  },
45
45
  {
46
- kind: "stat",
47
- title: "Failed logins",
46
+ kind: 'stat',
47
+ title: 'Failed logins',
48
48
  data: {
49
- provider: "authkit.eventCount",
50
- query: { metric: "loginFailure", windowMs },
49
+ provider: 'authkit.eventCount',
50
+ query: { metric: 'loginFailure', windowMs },
51
51
  },
52
52
  spark: true,
53
- thresholds: { warn: 25, bad: 100, direction: "up-bad" },
53
+ thresholds: { warn: 25, bad: 100, direction: 'up-bad' },
54
54
  },
55
55
  {
56
- kind: "stat",
57
- title: "Account lockouts",
56
+ kind: 'stat',
57
+ title: 'Account lockouts',
58
58
  data: {
59
- provider: "authkit.eventCount",
60
- query: { metric: "lockouts", windowMs },
59
+ provider: 'authkit.eventCount',
60
+ query: { metric: 'lockouts', windowMs },
61
61
  },
62
62
  spark: true,
63
- thresholds: { warn: 5, bad: 25, direction: "up-bad" },
63
+ thresholds: { warn: 5, bad: 25, direction: 'up-bad' },
64
64
  },
65
65
  ],
66
66
  },
67
67
  {
68
- title: "MFA & tokens",
68
+ title: 'MFA & tokens',
69
69
  cols: 3,
70
70
  panels: [
71
71
  {
72
- kind: "stat",
73
- title: "MFA / passkey enrollments",
72
+ kind: 'stat',
73
+ title: 'MFA / passkey enrollments',
74
74
  data: {
75
- provider: "authkit.eventCount",
76
- query: { metric: "mfaEnrollments", windowMs },
75
+ provider: 'authkit.eventCount',
76
+ query: { metric: 'mfaEnrollments', windowMs },
77
77
  },
78
78
  spark: true,
79
79
  },
80
80
  {
81
- kind: "stat",
82
- title: "Impersonation events",
81
+ kind: 'stat',
82
+ title: 'Impersonation events',
83
83
  data: {
84
- provider: "authkit.eventCount",
85
- query: { metric: "impersonation", windowMs },
84
+ provider: 'authkit.eventCount',
85
+ query: { metric: 'impersonation', windowMs },
86
86
  },
87
87
  spark: true,
88
- thresholds: { warn: 1, bad: 10, direction: "up-bad" },
88
+ thresholds: { warn: 1, bad: 10, direction: 'up-bad' },
89
89
  },
90
90
  {
91
- kind: "stat",
92
- title: "PAT activity",
91
+ kind: 'stat',
92
+ title: 'PAT activity',
93
93
  data: {
94
- provider: "authkit.eventCount",
95
- query: { metric: "pat", windowMs },
94
+ provider: 'authkit.eventCount',
95
+ query: { metric: 'pat', windowMs },
96
96
  },
97
97
  spark: true,
98
98
  },
99
99
  ],
100
100
  },
101
101
  {
102
- title: "Trends",
102
+ title: 'Trends',
103
103
  cols: 2,
104
104
  panels: [
105
105
  {
106
- kind: "timeseries",
107
- title: "Logins over time",
108
- data: { provider: "authkit.loginsOverTime" },
109
- series: ["success", "failure"],
110
- style: "stacked",
106
+ kind: 'timeseries',
107
+ title: 'Logins over time',
108
+ data: { provider: 'authkit.loginsOverTime' },
109
+ series: ['success', 'failure'],
110
+ style: 'stacked',
111
111
  },
112
112
  {
113
- kind: "breakdown",
114
- title: "Events by family",
115
- data: { provider: "authkit.eventBreakdown", query: { windowMs } },
116
- style: "donut",
113
+ kind: 'breakdown',
114
+ title: 'Events by family',
115
+ data: { provider: 'authkit.eventBreakdown', query: { windowMs } },
116
+ style: 'donut',
117
117
  },
118
118
  ],
119
119
  },
120
120
  {
121
- title: "PAT & impersonation activity",
121
+ title: 'PAT & impersonation activity',
122
122
  cols: 2,
123
123
  panels: [
124
124
  {
125
- kind: "table",
126
- title: "Recent token & impersonation events",
127
- data: { provider: "authkit.tokenActivity" },
125
+ kind: 'table',
126
+ title: 'Recent token & impersonation events',
127
+ data: { provider: 'authkit.tokenActivity' },
128
128
  // No "IP" column: the diagnostics bridge emits a PII-free projection
129
129
  // (no `email`/`ip`/`metadata`), so a deleted account's PII never lands
130
130
  // in Telescope's store. See `redactAuditEventForDiagnostics`.
131
131
  columns: [
132
- { key: "at", label: "When" },
133
- { key: "event", label: "Event" },
134
- { key: "subject", label: "Subject" },
135
- { key: "actor", label: "Actor" },
132
+ { key: 'at', label: 'When' },
133
+ { key: 'event', label: 'Event' },
134
+ { key: 'subject', label: 'Subject' },
135
+ { key: 'actor', label: 'Actor' },
136
136
  ],
137
137
  },
138
138
  ],
@@ -161,7 +161,7 @@ function authkitSecurityDashboard(opts) {
161
161
  */
162
162
  export function defineAuthkitTelescopeExtension(opts = {}) {
163
163
  return {
164
- name: "authkit",
164
+ name: 'authkit',
165
165
  entryTypes: () => [authkitEntryType()],
166
166
  dashboards: () => [authkitSecurityDashboard(opts)],
167
167
  dataProviders: () => authkitDataProviders(),
@@ -4,5 +4,5 @@
4
4
  * pulls in telescope. Import it ONLY from `config/telescope.ts`, where both
5
5
  * `@adonis-agora/telescope` and `@adonis-agora/authkit-server` are installed.
6
6
  */
7
- export { defineAuthkitTelescopeExtension, type AuthkitTelescopeOptions, } from "./extension.js";
8
- export { authkitDataProviders, authkitEventCountProvider, authkitLoginSuccessRateProvider, authkitLoginsOverTimeProvider, authkitEventBreakdownProvider, authkitTokenActivityProvider, } from "./data_providers.js";
7
+ export { defineAuthkitTelescopeExtension, type AuthkitTelescopeOptions, } from './extension.js';
8
+ export { authkitDataProviders, authkitEventCountProvider, authkitLoginSuccessRateProvider, authkitLoginsOverTimeProvider, authkitEventBreakdownProvider, authkitTokenActivityProvider, } from './data_providers.js';
@@ -4,5 +4,5 @@
4
4
  * pulls in telescope. Import it ONLY from `config/telescope.ts`, where both
5
5
  * `@adonis-agora/telescope` and `@adonis-agora/authkit-server` are installed.
6
6
  */
7
- export { defineAuthkitTelescopeExtension, } from "./extension.js";
8
- export { authkitDataProviders, authkitEventCountProvider, authkitLoginSuccessRateProvider, authkitLoginsOverTimeProvider, authkitEventBreakdownProvider, authkitTokenActivityProvider, } from "./data_providers.js";
7
+ export { defineAuthkitTelescopeExtension, } from './extension.js';
8
+ export { authkitDataProviders, authkitEventCountProvider, authkitLoginSuccessRateProvider, authkitLoginsOverTimeProvider, authkitEventBreakdownProvider, authkitTokenActivityProvider, } from './data_providers.js';
@@ -1,4 +1,4 @@
1
- import { type MetricsRecorder } from "@adonis-agora/authkit-core";
1
+ import { type MetricsRecorder } from '@adonis-agora/authkit-core';
2
2
  /**
3
3
  * Liga eventos do oidc-provider aos counters do recorder. Usa só eventos reais
4
4
  * do v9 (verificados em node_modules/oidc-provider/lib):
@@ -1,5 +1,5 @@
1
- import { AUTHKIT_METRICS, } from "@adonis-agora/authkit-core";
2
- import { emitDiagnostic } from "./diagnostics_bridge.js";
1
+ import { AUTHKIT_METRICS } from '@adonis-agora/authkit-core';
2
+ import { emitDiagnostic } from './diagnostics_bridge.js';
3
3
  /**
4
4
  * Liga eventos do oidc-provider aos counters do recorder. Usa só eventos reais
5
5
  * do v9 (verificados em node_modules/oidc-provider/lib):
@@ -11,20 +11,20 @@ import { emitDiagnostic } from "./diagnostics_bridge.js";
11
11
  * - `grant.revoked` (helpers/revoke.js) -> grantRevoked
12
12
  */
13
13
  export function wireProviderEvents(provider, recorder) {
14
- provider.on("grant.success", () => recorder.increment(AUTHKIT_METRICS.loginSuccess));
15
- provider.on("server_error", () => recorder.increment(AUTHKIT_METRICS.loginFailure));
16
- provider.on("access_token.saved", () => {
14
+ provider.on('grant.success', () => recorder.increment(AUTHKIT_METRICS.loginSuccess));
15
+ provider.on('server_error', () => recorder.increment(AUTHKIT_METRICS.loginFailure));
16
+ provider.on('access_token.saved', () => {
17
17
  recorder.increment(AUTHKIT_METRICS.tokenIssued);
18
18
  // Emit estrutural irmão (best-effort, no-op sem o slot de diagnostics).
19
- emitDiagnostic("token.issued", { kind: "access_token" });
19
+ emitDiagnostic('token.issued', { kind: 'access_token' });
20
20
  });
21
- provider.on("access_token.issued", () => {
21
+ provider.on('access_token.issued', () => {
22
22
  recorder.increment(AUTHKIT_METRICS.tokenIssued);
23
- emitDiagnostic("token.issued", { kind: "access_token" });
23
+ emitDiagnostic('token.issued', { kind: 'access_token' });
24
24
  });
25
- provider.on("refresh_token.saved", () => {
25
+ provider.on('refresh_token.saved', () => {
26
26
  recorder.increment(AUTHKIT_METRICS.refreshRotated);
27
- emitDiagnostic("token.refreshed", { kind: "refresh_token" });
27
+ emitDiagnostic('token.refreshed', { kind: 'refresh_token' });
28
28
  });
29
- provider.on("grant.revoked", () => recorder.increment(AUTHKIT_METRICS.grantRevoked));
29
+ provider.on('grant.revoked', () => recorder.increment(AUTHKIT_METRICS.grantRevoked));
30
30
  }
@@ -12,8 +12,8 @@
12
12
  * Licença do arquivo de dados: CC0 / Public Domain.
13
13
  */
14
14
  import { readFileSync } from 'node:fs';
15
+ import { dirname, join } from 'node:path';
15
16
  import { fileURLToPath } from 'node:url';
16
- import { join, dirname } from 'node:path';
17
17
  /**
18
18
  * Set em memória das senhas comuns (minúsculas). Inicializado na primeira
19
19
  * chamada a `isCommonPassword`. O módulo garante que o carregamento ocorre
@@ -1,5 +1,5 @@
1
1
  import { type PasswordPolicyViolation, type ResolvedPasswordConfig } from './policy.js';
2
- import { type PwnedLogger, type FetchLike } from './pwned.js';
2
+ import { type FetchLike, type PwnedLogger } from './pwned.js';
3
3
  /**
4
4
  * Verificador de hashes legados (de OUTROS sistemas). Chamado quando a
5
5
  * verificação nativa do hasher do Adonis falha OU não reconhece o formato do