@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
@@ -1,22 +1,22 @@
1
- import { configProvider } from "@adonisjs/core";
2
- import { generateJwks } from "./keys/jwks_manager.js";
3
- import { KeystoreManager, resolveKeystoreVault, } from "./keys/keystore_manager.js";
4
- import { KeystoreCodec } from "./keys/keystore_codec.js";
5
- import { loadEncryptionService } from "./keys/keystore_crypto.js";
6
- import { adapters, } from "./adapters/factory.js";
7
- import { composeAuditSink, resolveEvents, } from "./events/dispatcher.js";
8
- import { resolveMessages, } from "./host/i18n.js";
9
- import { resolveTrustedDevices, } from "./host/trusted_device.js";
10
- import { resolveBotProtection, } from "./host/bot_protection.js";
11
- import { deriveLockedSettingKeys } from "./host/config_locks.js";
12
- import { edgeRenderer } from "./host/renderers/edge_renderer.js";
1
+ import { configProvider } from '@adonisjs/core';
2
+ import { adapters } from './adapters/factory.js';
3
+ import { composeAuditSink, resolveEvents } from './events/dispatcher.js';
4
+ import { resolveBotProtection, } from './host/bot_protection.js';
5
+ import { deriveLockedSettingKeys } from './host/config_locks.js';
6
+ import { resolveMessages } from './host/i18n.js';
7
+ import { edgeRenderer } from './host/renderers/edge_renderer.js';
8
+ import { resolveTrustedDevices, } from './host/trusted_device.js';
9
+ import { generateJwks } from './keys/jwks_manager.js';
10
+ import { KeystoreCodec } from './keys/keystore_codec.js';
11
+ import { loadEncryptionService } from './keys/keystore_crypto.js';
12
+ import { KeystoreManager, resolveKeystoreVault } from './keys/keystore_manager.js';
13
13
  export { adapters };
14
14
  const RATE_LIMIT_DEFAULTS = {
15
- login: { points: 10, duration: "1 min" },
16
- introspection: { points: 60, duration: "1 min" },
17
- adminIp: { points: 30, duration: "1 min" },
15
+ login: { points: 10, duration: '1 min' },
16
+ introspection: { points: 60, duration: '1 min' },
17
+ adminIp: { points: 30, duration: '1 min' },
18
18
  // Mesmos limites do login, bucket separado — ver `ResolvedRateLimitConfig.sudo`.
19
- sudo: { points: 10, duration: "1 min" },
19
+ sudo: { points: 10, duration: '1 min' },
20
20
  };
21
21
  export function resolveRateLimit(input) {
22
22
  const enabled = input?.enabled ?? true;
@@ -54,9 +54,9 @@ export function resolveDynamicRegistration(input) {
54
54
  const enabled = input?.enabled ?? false;
55
55
  const management = input?.management ?? false;
56
56
  if (management && !enabled) {
57
- throw new Error("authkit: dynamicRegistration.management (RFC 7592) requer " +
58
- "dynamicRegistration.enabled: true (RFC 7591). Habilite o registro dinâmico " +
59
- "ou desligue o management.");
57
+ throw new Error('authkit: dynamicRegistration.management (RFC 7592) requer ' +
58
+ 'dynamicRegistration.enabled: true (RFC 7591). Habilite o registro dinâmico ' +
59
+ 'ou desligue o management.');
60
60
  }
61
61
  return {
62
62
  enabled,
@@ -70,11 +70,11 @@ export function resolveDeviceFlow(input) {
70
70
  export function resolveUploads(input) {
71
71
  return {
72
72
  avatars: {
73
- storage: input?.avatars?.storage ?? "auto",
73
+ storage: input?.avatars?.storage ?? 'auto',
74
74
  disk: input?.avatars?.disk,
75
- directory: input?.avatars?.directory ?? "authkit/avatars",
76
- collection: input?.avatars?.collection ?? "avatar",
77
- ownerType: input?.avatars?.ownerType ?? "AuthAccount",
75
+ directory: input?.avatars?.directory ?? 'authkit/avatars',
76
+ collection: input?.avatars?.collection ?? 'avatar',
77
+ ownerType: input?.avatars?.ownerType ?? 'AuthAccount',
78
78
  maxSizeMb: input?.avatars?.maxSizeMb ?? 5,
79
79
  },
80
80
  };
@@ -89,7 +89,7 @@ export function resolvePar(input) {
89
89
  };
90
90
  }
91
91
  export function resolveStepUp(input) {
92
- const mfaAcr = input?.mfaAcr ?? "urn:authkit:mfa";
92
+ const mfaAcr = input?.mfaAcr ?? 'urn:authkit:mfa';
93
93
  // Garante que o mfaAcr esteja sempre na lista anunciada como suportada.
94
94
  const acrValues = Array.from(new Set([...(input?.acrValues ?? []), mfaAcr]));
95
95
  return { acrValues, mfaAcr };
@@ -106,13 +106,13 @@ export function resolveAuthMethodsConfig(input) {
106
106
  if (!input)
107
107
  return {};
108
108
  const out = {};
109
- if (typeof input.password === "boolean")
109
+ if (typeof input.password === 'boolean')
110
110
  out.password = input.password;
111
- if (typeof input.magicLink === "boolean")
111
+ if (typeof input.magicLink === 'boolean')
112
112
  out.magicLink = input.magicLink;
113
- if (typeof input.passkey === "boolean")
113
+ if (typeof input.passkey === 'boolean')
114
114
  out.passkey = input.passkey;
115
- if (typeof input.forgotPassword === "boolean")
115
+ if (typeof input.forgotPassword === 'boolean')
116
116
  out.forgotPassword = input.forgotPassword;
117
117
  return out;
118
118
  }
@@ -134,7 +134,7 @@ export function resolveRegistration(input) {
134
134
  * herda o `format` raiz quando não especifica o seu.
135
135
  */
136
136
  export function resolveAccessTokens(issuer, input) {
137
- const format = input?.format ?? "opaque";
137
+ const format = input?.format ?? 'opaque';
138
138
  const audience = input?.audience ?? issuer;
139
139
  const resources = {};
140
140
  for (const [indicator, rc] of Object.entries(input?.resources ?? {})) {
@@ -145,26 +145,26 @@ export function resolveAccessTokens(issuer, input) {
145
145
  expiresIn: rc.expiresIn,
146
146
  };
147
147
  }
148
- const anyResourceJwt = Object.values(resources).some((r) => r.format === "jwt");
149
- const anyJwt = format === "jwt" || anyResourceJwt;
148
+ const anyResourceJwt = Object.values(resources).some((r) => r.format === 'jwt');
149
+ const anyJwt = format === 'jwt' || anyResourceJwt;
150
150
  return { format, audience, anyJwt, resources };
151
151
  }
152
152
  export function resolveAdmin(input) {
153
153
  return {
154
154
  enabled: input?.enabled ?? false,
155
- roles: input?.roles && input.roles.length > 0 ? input.roles : ["ADMIN"],
155
+ roles: input?.roles && input.roles.length > 0 ? input.roles : ['ADMIN'],
156
156
  impersonation: false,
157
157
  };
158
158
  }
159
159
  /** Lê API keys de `AUTHKIT_ADMIN_API_KEY` (uma ou várias, separadas por vírgula). */
160
160
  function adminApiKeysFromEnv() {
161
- return (process.env.AUTHKIT_ADMIN_API_KEY ?? "")
162
- .split(",")
161
+ return (process.env.AUTHKIT_ADMIN_API_KEY ?? '')
162
+ .split(',')
163
163
  .map((key) => key.trim())
164
164
  .filter(Boolean);
165
165
  }
166
166
  export function resolveAdminApi(input) {
167
- const apiKeys = input?.apiKeys === "env" ? adminApiKeysFromEnv() : (input?.apiKeys ?? []);
167
+ const apiKeys = input?.apiKeys === 'env' ? adminApiKeysFromEnv() : (input?.apiKeys ?? []);
168
168
  return {
169
169
  // Default inteligente: liga quando há key resolvida (a menos que enabled:false explícito).
170
170
  enabled: input?.enabled ?? apiKeys.length > 0,
@@ -174,10 +174,10 @@ export function resolveAdminApi(input) {
174
174
  export function resolveOrganizations(input) {
175
175
  return {
176
176
  enabled: input?.enabled,
177
- roles: ["owner", "admin", "member"],
177
+ roles: ['owner', 'admin', 'member'],
178
178
  allowSelfCreate: false,
179
179
  invitationTtlHours: 168,
180
- claimStrategy: input?.claimStrategy ?? "active",
180
+ claimStrategy: input?.claimStrategy ?? 'active',
181
181
  };
182
182
  }
183
183
  /**
@@ -185,8 +185,8 @@ export function resolveOrganizations(input) {
185
185
  * `rpName` cai no `fallbackName` (branding/mfaIssuer) quando ausente.
186
186
  */
187
187
  export function resolveWebauthn(issuer, fallbackName, input) {
188
- let host = "localhost";
189
- let origin = "http://localhost";
188
+ let host = 'localhost';
189
+ let origin = 'http://localhost';
190
190
  try {
191
191
  const url = new URL(issuer);
192
192
  host = url.hostname;
@@ -205,7 +205,7 @@ const UNITS = { s: 1, m: 60, h: 3600, d: 86400 };
205
205
  export function toSeconds(value, fallback) {
206
206
  if (value === undefined)
207
207
  return fallback;
208
- if (typeof value === "number")
208
+ if (typeof value === 'number')
209
209
  return value;
210
210
  const m = /^(\d+)\s*([smhd])$/.exec(value.trim());
211
211
  if (!m)
@@ -219,9 +219,9 @@ export function toSeconds(value, fallback) {
219
219
  * internamente — encrypt OFF para não duplo-encriptar.
220
220
  */
221
221
  export function defaultEncryptForStore(store) {
222
- if (typeof store === "string")
222
+ if (typeof store === 'string')
223
223
  return true;
224
- return ["file", "drive", "lucid", "redis"].includes(store.driver);
224
+ return ['file', 'drive', 'lucid', 'redis'].includes(store.driver);
225
225
  }
226
226
  /**
227
227
  * Mensagem de aviso quando `jwks: 'auto'` cai no fallback de disco (sem
@@ -230,55 +230,52 @@ export function defaultEncryptForStore(store) {
230
230
  export function jwksAutoFallbackWarning(storePath) {
231
231
  if (!storePath)
232
232
  return null;
233
- return (`AuthKit: jwks 'auto' caiu no fallback de disco (${storePath}) — a chave privada de ` +
234
- `assinatura será persistida em arquivo. Para produção, defina AUTHKIT_JWKS ` +
235
- `(secret manager) ou configure jwks.store explicitamente.`);
233
+ return `AuthKit: jwks 'auto' caiu no fallback de disco (${storePath}) — a chave privada de assinatura será persistida em arquivo. Para produção, defina AUTHKIT_JWKS (secret manager) ou configure jwks.store explicitamente.`;
236
234
  }
237
235
  export function defineConfig(config) {
238
236
  return configProvider.create(async (app) => {
239
237
  const AdapterClass = await config.adapter.resolver(app);
240
238
  // `jwks: 'auto'` → resolve env-aware: AUTHKIT_JWKS inline, senão managed em arquivo.
241
- const jwksConfig = config.jwks === "auto"
239
+ const jwksConfig = config.jwks === 'auto'
242
240
  ? process.env.AUTHKIT_JWKS
243
241
  ? {
244
- source: "jwks",
242
+ source: 'jwks',
245
243
  keys: JSON.parse(process.env.AUTHKIT_JWKS).keys,
246
244
  }
247
245
  : {
248
- source: "managed",
249
- algorithm: "RS256",
250
- store: "tmp/authkit_jwks.json",
246
+ source: 'managed',
247
+ algorithm: 'RS256',
248
+ store: 'tmp/authkit_jwks.json',
251
249
  }
252
250
  : config.jwks;
253
- if (config.jwks === "auto" && !process.env.AUTHKIT_JWKS) {
251
+ if (config.jwks === 'auto' && !process.env.AUTHKIT_JWKS) {
254
252
  const warning = jwksAutoFallbackWarning(jwksConfig.store ?? null);
255
253
  if (warning) {
256
254
  await app.container
257
- .make("logger")
255
+ .make('logger')
258
256
  .then((l) => l?.warn(warning))
259
257
  .catch(() => { });
260
258
  }
261
259
  }
262
260
  const storeCfg = jwksConfig.store;
263
- if (jwksConfig.source === "managed" &&
261
+ if (jwksConfig.source === 'managed' &&
264
262
  storeCfg &&
265
- typeof storeCfg === "object" &&
266
- storeCfg.driver === "redis") {
263
+ typeof storeCfg === 'object' &&
264
+ storeCfg.driver === 'redis') {
267
265
  await app.container
268
- .make("logger")
266
+ .make('logger')
269
267
  .then((l) => l?.warn('AuthKit: keystore no driver "redis" — garanta PERSISTÊNCIA (RDB/AOF). Num Redis cache-only, um flush apaga o keystore e invalida todos os tokens.'))
270
268
  .catch(() => { });
271
269
  }
272
270
  let jwks;
273
- if (jwksConfig.source === "managed") {
274
- const alg = jwksConfig.algorithm ?? "RS256";
271
+ if (jwksConfig.source === 'managed') {
272
+ const alg = jwksConfig.algorithm ?? 'RS256';
275
273
  if (jwksConfig.store) {
276
274
  const vault = resolveKeystoreVault(jwksConfig.store, {
277
275
  makePath: (p) => app.makePath(p),
278
276
  container: app.container,
279
277
  });
280
- const encrypt = jwksConfig.encrypt ??
281
- defaultEncryptForStore(jwksConfig.store);
278
+ const encrypt = jwksConfig.encrypt ?? defaultEncryptForStore(jwksConfig.store);
282
279
  const enc = encrypt ? await loadEncryptionService() : undefined;
283
280
  const manager = new KeystoreManager(vault, new KeystoreCodec({ encrypt, enc }), alg);
284
281
  const store = await manager.ensure();
@@ -295,7 +292,7 @@ export function defineConfig(config) {
295
292
  // #9: mfaIssuer efetivo — top-level do defineConfig vence; senão o do lucidAccountStore; senão default.
296
293
  const effectiveMfaIssuer = config.mfaIssuer ??
297
294
  config.accountStore?.__mfaIssuer ??
298
- "AuthKit";
295
+ 'AuthKit';
299
296
  return {
300
297
  issuer: config.issuer,
301
298
  AdapterClass,
@@ -308,7 +305,7 @@ export function defineConfig(config) {
308
305
  idToken: toSeconds(config.ttl?.idToken, 900),
309
306
  session: toSeconds(config.ttl?.session, 604800),
310
307
  },
311
- globalRolesClaim: config.globalRolesClaim ?? "roles",
308
+ globalRolesClaim: config.globalRolesClaim ?? 'roles',
312
309
  resolveTokenRoles: config.resolveTokenRoles,
313
310
  cookieKeys: config.cookieKeys ?? [],
314
311
  observability: config.observability ?? {},
@@ -319,7 +316,7 @@ export function defineConfig(config) {
319
316
  },
320
317
  accountStore: config.accountStore,
321
318
  patStore: config.patStore,
322
- mountPath: config.mountPath ?? "/oidc",
319
+ mountPath: config.mountPath ?? '/oidc',
323
320
  accountHome: config.accountHome,
324
321
  // Default de runtime: sem isso, `render` ficava `undefined` e TODA
325
322
  // request a `/account/*`/`/auth/interaction/*` estourava um 500 sem
@@ -350,9 +347,7 @@ export function defineConfig(config) {
350
347
  // #9: reusa mfaIssuer/webauthn declarados no lucidAccountStore quando o
351
348
  // top-level não os fornece — consumidor declara UMA vez. Top-level ainda vence.
352
349
  mfaIssuer: effectiveMfaIssuer,
353
- webauthn: resolveWebauthn(config.issuer, effectiveMfaIssuer, config.webauthn ??
354
- config.accountStore
355
- ?.__webauthn),
350
+ webauthn: resolveWebauthn(config.issuer, effectiveMfaIssuer, config.webauthn ?? config.accountStore?.__webauthn),
356
351
  dynamicRegistration: resolveDynamicRegistration(config.dynamicRegistration),
357
352
  deviceFlow: resolveDeviceFlow(config.deviceFlow),
358
353
  uploads: resolveUploads(config.uploads),
@@ -371,7 +366,7 @@ export function defineConfig(config) {
371
366
  organizations: resolveOrganizations(config.organizations),
372
367
  resolveGeo: config.resolveGeo,
373
368
  messages: resolveMessages(config.i18n),
374
- locale: config.i18n?.locale ?? "pt-BR",
369
+ locale: config.i18n?.locale ?? 'pt-BR',
375
370
  schema: {
376
371
  autoManage: config.schema?.autoManage !== false,
377
372
  connection: config.schema?.connection,
@@ -35,7 +35,9 @@ export function checkIssuer(input) {
35
35
  catch {
36
36
  return [{ level: 'error', message: `issuer is not a valid URL: "${issuer}".` }];
37
37
  }
38
- const findings = [{ level: 'ok', message: `valid issuer: ${url.origin}${url.pathname}` }];
38
+ const findings = [
39
+ { level: 'ok', message: `valid issuer: ${url.origin}${url.pathname}` },
40
+ ];
39
41
  const normalize = (p) => (p.endsWith('/') ? p.slice(0, -1) : p) || '/';
40
42
  if (normalize(url.pathname) !== normalize(mountPath)) {
41
43
  findings.push({
@@ -143,7 +145,12 @@ export function checkSession(input) {
143
145
  ];
144
146
  }
145
147
  if (!input.sessionConfig) {
146
- return [{ level: 'warn', message: "config('session') missing — the session provider may not be configured." }];
148
+ return [
149
+ {
150
+ level: 'warn',
151
+ message: "config('session') missing — the session provider may not be configured.",
152
+ },
153
+ ];
147
154
  }
148
155
  const findings = [{ level: 'ok', message: 'session provider configured.' }];
149
156
  const driver = input.sessionConfig.store ?? input.sessionConfig.driver;
@@ -158,7 +165,10 @@ export function checkSession(input) {
158
165
  /** Hint de exceções de CSRF do shield para o mountPath. */
159
166
  export function checkShield(input) {
160
167
  if (!input.peers.shield) {
161
- return { level: 'error', message: '@adonisjs/shield is not importable — install it (required peer).' };
168
+ return {
169
+ level: 'error',
170
+ message: '@adonisjs/shield is not importable — install it (required peer).',
171
+ };
162
172
  }
163
173
  const mountPath = input.authkitConfig?.mountPath ?? '/oidc';
164
174
  return {
@@ -169,12 +179,18 @@ export function checkShield(input) {
169
179
  /** ally só é necessário quando social está configurado. */
170
180
  export function checkAlly(input) {
171
181
  const social = input.authkitConfig?.social;
172
- const usesSocial = !!social && (Array.isArray(social.providers) ? social.providers.length > 0 : Object.keys(social).length > 0);
182
+ const usesSocial = !!social &&
183
+ (Array.isArray(social.providers)
184
+ ? social.providers.length > 0
185
+ : Object.keys(social).length > 0);
173
186
  if (!usesSocial) {
174
187
  return { level: 'ok', message: 'social login not configured — @adonisjs/ally is optional.' };
175
188
  }
176
189
  if (!input.peers.ally) {
177
- return { level: 'error', message: 'social login configured, but @adonisjs/ally is not importable.' };
190
+ return {
191
+ level: 'error',
192
+ message: 'social login configured, but @adonisjs/ally is not importable.',
193
+ };
178
194
  }
179
195
  return { level: 'ok', message: 'social login configured and @adonisjs/ally available.' };
180
196
  }
@@ -198,7 +214,10 @@ export function checkOtpLockout(input) {
198
214
  * no console de conta). Apenas informa o estado.
199
215
  */
200
216
  export function checkSudoMode(_input) {
201
- return { level: 'ok', message: 'sudo_mode: enabled by default (15 min grace). Configure via admin settings or sudo_mode runtime setting.' };
217
+ return {
218
+ level: 'ok',
219
+ message: 'sudo_mode: enabled by default (15 min grace). Configure via admin settings or sudo_mode runtime setting.',
220
+ };
202
221
  }
203
222
  /** rateLimit ligado mas @adonisjs/limiter ausente → warn. */
204
223
  export function checkRateLimit(input) {
@@ -246,7 +265,10 @@ export function checkRequireVerifiedEmail(input) {
246
265
  message: 'login.requireVerifiedEmail is on, but the accountStore has no `isEmailVerified` capability — the check is a no-op (nobody is blocked). Add an `email_verified_at` column (or a store that tracks it).',
247
266
  };
248
267
  }
249
- return { level: 'ok', message: 'login.requireVerifiedEmail on and the accountStore can check it.' };
268
+ return {
269
+ level: 'ok',
270
+ message: 'login.requireVerifiedEmail on and the accountStore can check it.',
271
+ };
250
272
  }
251
273
  /**
252
274
  * Bot protection (informativo): ativo quando `botProtection.verify` é uma função.
@@ -362,9 +384,13 @@ export function checkAccessTokens(input) {
362
384
  return null;
363
385
  const resources = at.resources ?? {};
364
386
  const resourceCount = Object.keys(resources).length;
365
- const anyJwt = at.anyJwt ?? (at.format === 'jwt' || Object.values(resources).some((r) => r?.format === 'jwt'));
387
+ const anyJwt = at.anyJwt ??
388
+ (at.format === 'jwt' || Object.values(resources).some((r) => r?.format === 'jwt'));
366
389
  if (!anyJwt) {
367
- return { level: 'ok', message: 'access tokens are opaque (default) — introspect them at the introspection endpoint.' };
390
+ return {
391
+ level: 'ok',
392
+ message: 'access tokens are opaque (default) — introspect them at the introspection endpoint.',
393
+ };
368
394
  }
369
395
  const detail = resourceCount
370
396
  ? `format=${at.format}, ${resourceCount} resource(s) configured`
@@ -474,7 +500,8 @@ export function checkAuthMethodsSetting(input) {
474
500
  const allOff = s.password === false &&
475
501
  s.magicLink === false &&
476
502
  s.passkey === false &&
477
- Array.isArray(s.social) && s.social.length === 0;
503
+ Array.isArray(s.social) &&
504
+ s.social.length === 0;
478
505
  if (allOff) {
479
506
  return {
480
507
  level: 'warn',
@@ -489,9 +516,7 @@ export function checkAuthMethodsSetting(input) {
489
516
  if (unknown.length > 0) {
490
517
  return {
491
518
  level: 'warn',
492
- message: `auth_methods setting references social provider(s) not in config.social.providers: [${unknown.join(', ')}]. ` +
493
- 'These providers will be silently filtered out (intersection rule). ' +
494
- 'Remove them from the setting or add them to config.social.providers.',
519
+ message: `auth_methods setting references social provider(s) not in config.social.providers: [${unknown.join(', ')}]. These providers will be silently filtered out (intersection rule). Remove them from the setting or add them to config.social.providers.`,
495
520
  };
496
521
  }
497
522
  }
@@ -567,8 +592,7 @@ export function checkPasswordPepper(input) {
567
592
  if (Array.isArray(pepper)) {
568
593
  return {
569
594
  level: 'ok',
570
- message: `password.pepper rotation configured (${pepper.length} pepper(s)). ` +
571
- 'First pepper is current; subsequent peppers are tried on verify (lazy re-hash).',
595
+ message: `password.pepper rotation configured (${pepper.length} pepper(s)). First pepper is current; subsequent peppers are tried on verify (lazy re-hash).`,
572
596
  };
573
597
  }
574
598
  return null;
@@ -654,8 +678,7 @@ export function checkSessionPolicy(input) {
654
678
  if (idleMin > 0 && defaultHours > 0 && idleMin > defaultHours * 60) {
655
679
  return {
656
680
  level: 'warn',
657
- message: `session_policy: idleTimeoutMinutes (${idleMin}) exceeds defaultSessionHours*60 (${defaultHours * 60}). ` +
658
- 'The idle timeout will never trigger — increase defaultSessionHours or reduce idleTimeoutMinutes.',
681
+ message: `session_policy: idleTimeoutMinutes (${idleMin}) exceeds defaultSessionHours*60 (${defaultHours * 60}). The idle timeout will never trigger — increase defaultSessionHours or reduce idleTimeoutMinutes.`,
659
682
  };
660
683
  }
661
684
  if (rememberDays > 365) {
@@ -701,8 +724,7 @@ export function checkRolesCatalog(input) {
701
724
  if (outOfCatalog.length > 0) {
702
725
  return {
703
726
  level: 'warn',
704
- message: `roles_catalog: ${catalogRoles.length} role(s) in catalog, but cfg.admin.roles references [${outOfCatalog.join(', ')}] which are not in the catalog. ` +
705
- 'Admin access depends on these roles — add them to the catalog at /admin/roles.',
727
+ message: `roles_catalog: ${catalogRoles.length} role(s) in catalog, but cfg.admin.roles references [${outOfCatalog.join(', ')}] which are not in the catalog. Admin access depends on these roles — add them to the catalog at /admin/roles.`,
706
728
  };
707
729
  }
708
730
  return {
@@ -764,7 +786,10 @@ export function checkPasskeyAutofill(input) {
764
786
  */
765
787
  export function signingKeyAgeFinding(ageDays, maxAgeDays) {
766
788
  if (ageDays === null)
767
- return { level: 'ok', message: 'jwks: idade da chave não aplicável (sem keystore persistido).' };
789
+ return {
790
+ level: 'ok',
791
+ message: 'jwks: idade da chave não aplicável (sem keystore persistido).',
792
+ };
768
793
  if (ageDays > maxAgeDays) {
769
794
  return {
770
795
  level: 'warn',
@@ -1,4 +1,4 @@
1
- import type { AuditEvent, AuditSink } from "../audit/audit_sink.js";
1
+ import type { AuditEvent, AuditSink } from '../audit/audit_sink.js';
2
2
  /**
3
3
  * Configuração de eventos/webhooks para o host observar tudo que o IdP audita.
4
4
  *
@@ -1,5 +1,5 @@
1
- import { createHmac } from "node:crypto";
2
- import { emitDiagnostic } from "../observability/diagnostics_bridge.js";
1
+ import { createHmac } from 'node:crypto';
2
+ import { emitDiagnostic } from '../observability/diagnostics_bridge.js';
3
3
  export function resolveEvents(input) {
4
4
  if (!input || (!input.onEvent && !input.webhook))
5
5
  return undefined;
@@ -27,7 +27,7 @@ export function buildWebhookBody(event) {
27
27
  }
28
28
  /** Calcula o header de assinatura `sha256=<hmac>` para um corpo + segredo. */
29
29
  export function signWebhookBody(body, secret) {
30
- return "sha256=" + createHmac("sha256", secret).update(body).digest("hex");
30
+ return `sha256=${createHmac('sha256', secret).update(body).digest('hex')}`;
31
31
  }
32
32
  /**
33
33
  * Projeta um {@link AuditEvent} para o barramento `@agora/diagnostics` SEM PII
@@ -75,13 +75,13 @@ async function dispatchWebhook(webhook, event) {
75
75
  try {
76
76
  const body = buildWebhookBody(event);
77
77
  const headers = {
78
- "content-type": "application/json",
78
+ 'content-type': 'application/json',
79
79
  };
80
80
  if (webhook.secret) {
81
- headers["x-authkit-signature"] = signWebhookBody(body, webhook.secret);
81
+ headers['x-authkit-signature'] = signWebhookBody(body, webhook.secret);
82
82
  }
83
83
  await fetch(webhook.url, {
84
- method: "POST",
84
+ method: 'POST',
85
85
  headers,
86
86
  body,
87
87
  signal: AbortSignal.timeout(WEBHOOK_TIMEOUT_MS),
@@ -131,11 +131,11 @@ export function composeAuditSink(original, events = {}) {
131
131
  },
132
132
  };
133
133
  // Preserva a capacidade de consulta do sink original (console admin).
134
- if (original && typeof original.list === "function") {
134
+ if (original && typeof original.list === 'function') {
135
135
  composed.list = original.list.bind(original);
136
136
  }
137
137
  // Preserva a anonimização (LGPD) do sink original (deleção de conta).
138
- if (original && typeof original.anonymizeAccount === "function") {
138
+ if (original && typeof original.anonymizeAccount === 'function') {
139
139
  composed.anonymizeAccount = original.anonymizeAccount.bind(original);
140
140
  }
141
141
  // Preserva quaisquer propriedades extras do sink original (ex.: campos de
@@ -147,10 +147,10 @@ export function composeAuditSink(original, events = {}) {
147
147
  const src = original;
148
148
  const dst = composed;
149
149
  for (const key of Object.keys(src)) {
150
- if (key === "record" || key === "list" || key === "anonymizeAccount")
150
+ if (key === 'record' || key === 'list' || key === 'anonymizeAccount')
151
151
  continue;
152
152
  const value = src[key];
153
- dst[key] = typeof value === "function" ? value.bind(original) : value;
153
+ dst[key] = typeof value === 'function' ? value.bind(original) : value;
154
154
  }
155
155
  }
156
156
  return composed;