@adonis-agora/authkit-server 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +158 -0
  3. package/build/assets/grafana/authkit-dashboard.json +118 -0
  4. package/build/commands/clients_create.d.ts +27 -0
  5. package/build/commands/clients_create.js +121 -0
  6. package/build/commands/commands.json +292 -0
  7. package/build/commands/configure.d.ts +2 -0
  8. package/build/commands/configure.js +45 -0
  9. package/build/commands/doctor.d.ts +10 -0
  10. package/build/commands/doctor.js +113 -0
  11. package/build/commands/eject.d.ts +11 -0
  12. package/build/commands/eject.js +96 -0
  13. package/build/commands/expire_scan.d.ts +28 -0
  14. package/build/commands/expire_scan.js +92 -0
  15. package/build/commands/import_users.d.ts +17 -0
  16. package/build/commands/import_users.js +80 -0
  17. package/build/commands/keys_rotate.d.ts +21 -0
  18. package/build/commands/keys_rotate.js +126 -0
  19. package/build/commands/main.d.ts +12 -0
  20. package/build/commands/main.js +38 -0
  21. package/build/commands/settings_get.d.ts +18 -0
  22. package/build/commands/settings_get.js +43 -0
  23. package/build/commands/settings_list.d.ts +17 -0
  24. package/build/commands/settings_list.js +39 -0
  25. package/build/commands/settings_set.d.ts +20 -0
  26. package/build/commands/settings_set.js +55 -0
  27. package/build/commands/settings_unset.d.ts +18 -0
  28. package/build/commands/settings_unset.js +46 -0
  29. package/build/commands/ui_preset.d.ts +4 -0
  30. package/build/commands/ui_preset.js +32 -0
  31. package/build/database/migrations/make_authkit_oidc_table.d.ts +6 -0
  32. package/build/database/migrations/make_authkit_oidc_table.js +19 -0
  33. package/build/host/ui/admin.html +29 -0
  34. package/build/host/views/account/apps.edge +59 -0
  35. package/build/host/views/account/confirm.edge +70 -0
  36. package/build/host/views/account/email-confirmed.edge +16 -0
  37. package/build/host/views/account/login.edge +33 -0
  38. package/build/host/views/account/mfa.edge +152 -0
  39. package/build/host/views/account/orgs.edge +58 -0
  40. package/build/host/views/account/security.edge +215 -0
  41. package/build/host/views/account/tokens.edge +75 -0
  42. package/build/host/views/consent.edge +20 -0
  43. package/build/host/views/forgot.edge +43 -0
  44. package/build/host/views/login.edge +251 -0
  45. package/build/host/views/maintenance.edge +32 -0
  46. package/build/host/views/mfa-challenge.edge +107 -0
  47. package/build/host/views/otp-unlock.edge +40 -0
  48. package/build/host/views/partials/styles.edge +2 -0
  49. package/build/host/views/reset.edge +30 -0
  50. package/build/host/views/signup.edge +62 -0
  51. package/build/host/views/verify-email.edge +17 -0
  52. package/build/index.d.ts +115 -0
  53. package/build/index.js +76 -0
  54. package/build/password/common_passwords.txt +10000 -0
  55. package/build/providers/authkit_server_provider.d.ts +27 -0
  56. package/build/providers/authkit_server_provider.js +242 -0
  57. package/build/src/accounts/account_store.d.ts +578 -0
  58. package/build/src/accounts/account_store.js +60 -0
  59. package/build/src/accounts/lucid_account_store.d.ts +156 -0
  60. package/build/src/accounts/lucid_account_store.js +294 -0
  61. package/build/src/accounts/lucid_store/core.d.ts +9 -0
  62. package/build/src/accounts/lucid_store/core.js +306 -0
  63. package/build/src/accounts/lucid_store/mfa.d.ts +15 -0
  64. package/build/src/accounts/lucid_store/mfa.js +108 -0
  65. package/build/src/accounts/lucid_store/organizations.d.ts +13 -0
  66. package/build/src/accounts/lucid_store/organizations.js +294 -0
  67. package/build/src/accounts/lucid_store/password_hygiene.d.ts +20 -0
  68. package/build/src/accounts/lucid_store/password_hygiene.js +130 -0
  69. package/build/src/accounts/lucid_store/provider_identity.d.ts +8 -0
  70. package/build/src/accounts/lucid_store/provider_identity.js +59 -0
  71. package/build/src/accounts/lucid_store/shared.d.ts +113 -0
  72. package/build/src/accounts/lucid_store/shared.js +130 -0
  73. package/build/src/accounts/lucid_store/status_profile.d.ts +34 -0
  74. package/build/src/accounts/lucid_store/status_profile.js +100 -0
  75. package/build/src/accounts/lucid_store/webauthn.d.ts +8 -0
  76. package/build/src/accounts/lucid_store/webauthn.js +140 -0
  77. package/build/src/accounts/lucid_stores.d.ts +45 -0
  78. package/build/src/accounts/lucid_stores.js +30 -0
  79. package/build/src/adapters/adapter_contract.d.ts +37 -0
  80. package/build/src/adapters/adapter_contract.js +1 -0
  81. package/build/src/adapters/database_adapter.d.ts +21 -0
  82. package/build/src/adapters/database_adapter.js +79 -0
  83. package/build/src/adapters/factory.d.ts +30 -0
  84. package/build/src/adapters/factory.js +43 -0
  85. package/build/src/adapters/redis_adapter.d.ts +24 -0
  86. package/build/src/adapters/redis_adapter.js +122 -0
  87. package/build/src/audit/audit_sink.d.ts +63 -0
  88. package/build/src/audit/audit_sink.js +1 -0
  89. package/build/src/audit/lucid_audit_sink.d.ts +10 -0
  90. package/build/src/audit/lucid_audit_sink.js +99 -0
  91. package/build/src/commands/expire_scan_command.d.ts +60 -0
  92. package/build/src/commands/expire_scan_command.js +229 -0
  93. package/build/src/commands/import_clients.d.ts +40 -0
  94. package/build/src/commands/import_clients.js +79 -0
  95. package/build/src/commands/import_users.d.ts +51 -0
  96. package/build/src/commands/import_users.js +94 -0
  97. package/build/src/commands/resolve_config.d.ts +13 -0
  98. package/build/src/commands/resolve_config.js +18 -0
  99. package/build/src/commands/settings_commands.d.ts +47 -0
  100. package/build/src/commands/settings_commands.js +270 -0
  101. package/build/src/controllers/oidc_callback_controller.d.ts +22 -0
  102. package/build/src/controllers/oidc_callback_controller.js +33 -0
  103. package/build/src/define_config.d.ts +772 -0
  104. package/build/src/define_config.js +351 -0
  105. package/build/src/doctor/checks.d.ts +197 -0
  106. package/build/src/doctor/checks.js +858 -0
  107. package/build/src/events/dispatcher.d.ts +45 -0
  108. package/build/src/events/dispatcher.js +117 -0
  109. package/build/src/host/account_api/account_api_controller.d.ts +245 -0
  110. package/build/src/host/account_api/account_api_controller.js +827 -0
  111. package/build/src/host/account_deletion_ops.d.ts +80 -0
  112. package/build/src/host/account_deletion_ops.js +118 -0
  113. package/build/src/host/account_deletion_service.d.ts +63 -0
  114. package/build/src/host/account_deletion_service.js +133 -0
  115. package/build/src/host/account_export_service.d.ts +76 -0
  116. package/build/src/host/account_export_service.js +140 -0
  117. package/build/src/host/account_home.d.ts +11 -0
  118. package/build/src/host/account_home.js +11 -0
  119. package/build/src/host/account_lockout.d.ts +86 -0
  120. package/build/src/host/account_lockout.js +185 -0
  121. package/build/src/host/active_org_cookie.d.ts +28 -0
  122. package/build/src/host/active_org_cookie.js +47 -0
  123. package/build/src/host/admin_api/admin_api_guard.d.ts +16 -0
  124. package/build/src/host/admin_api/admin_api_guard.js +59 -0
  125. package/build/src/host/admin_api/admin_orgs_service.d.ts +125 -0
  126. package/build/src/host/admin_api/admin_orgs_service.js +324 -0
  127. package/build/src/host/admin_api/admin_users_service.d.ts +163 -0
  128. package/build/src/host/admin_api/admin_users_service.js +308 -0
  129. package/build/src/host/admin_api/api_clients_controller.d.ts +54 -0
  130. package/build/src/host/admin_api/api_clients_controller.js +89 -0
  131. package/build/src/host/admin_api/api_keys_controller.d.ts +19 -0
  132. package/build/src/host/admin_api/api_keys_controller.js +36 -0
  133. package/build/src/host/admin_api/api_misc_controller.d.ts +19 -0
  134. package/build/src/host/admin_api/api_misc_controller.js +44 -0
  135. package/build/src/host/admin_api/api_orgs_controller.d.ts +108 -0
  136. package/build/src/host/admin_api/api_orgs_controller.js +189 -0
  137. package/build/src/host/admin_api/api_settings_controller.d.ts +55 -0
  138. package/build/src/host/admin_api/api_settings_controller.js +134 -0
  139. package/build/src/host/admin_api/api_users_controller.d.ts +108 -0
  140. package/build/src/host/admin_api/api_users_controller.js +187 -0
  141. package/build/src/host/admin_api/dto.d.ts +131 -0
  142. package/build/src/host/admin_api/dto.js +122 -0
  143. package/build/src/host/admin_api/token_verify_service.d.ts +34 -0
  144. package/build/src/host/admin_api/token_verify_service.js +74 -0
  145. package/build/src/host/admin_clients_service.d.ts +88 -0
  146. package/build/src/host/admin_clients_service.js +181 -0
  147. package/build/src/host/admin_console/admin_shell_controller.d.ts +27 -0
  148. package/build/src/host/admin_console/admin_shell_controller.js +167 -0
  149. package/build/src/host/admin_console/console_audit_controller.d.ts +17 -0
  150. package/build/src/host/admin_console/console_audit_controller.js +25 -0
  151. package/build/src/host/admin_console/console_clients_controller.d.ts +53 -0
  152. package/build/src/host/admin_console/console_clients_controller.js +102 -0
  153. package/build/src/host/admin_console/console_impersonation_controller.d.ts +23 -0
  154. package/build/src/host/admin_console/console_impersonation_controller.js +45 -0
  155. package/build/src/host/admin_console/console_keys_controller.d.ts +24 -0
  156. package/build/src/host/admin_console/console_keys_controller.js +41 -0
  157. package/build/src/host/admin_console/console_orgs_controller.d.ts +96 -0
  158. package/build/src/host/admin_console/console_orgs_controller.js +238 -0
  159. package/build/src/host/admin_console/console_overview_controller.d.ts +27 -0
  160. package/build/src/host/admin_console/console_overview_controller.js +44 -0
  161. package/build/src/host/admin_console/console_roles_controller.d.ts +31 -0
  162. package/build/src/host/admin_console/console_roles_controller.js +108 -0
  163. package/build/src/host/admin_console/console_sessions_controller.d.ts +91 -0
  164. package/build/src/host/admin_console/console_sessions_controller.js +125 -0
  165. package/build/src/host/admin_console/console_settings_controller.d.ts +47 -0
  166. package/build/src/host/admin_console/console_settings_controller.js +115 -0
  167. package/build/src/host/admin_console/console_users_controller.d.ts +110 -0
  168. package/build/src/host/admin_console/console_users_controller.js +212 -0
  169. package/build/src/host/admin_prefix.d.ts +50 -0
  170. package/build/src/host/admin_prefix.js +77 -0
  171. package/build/src/host/admin_sessions_service.d.ts +119 -0
  172. package/build/src/host/admin_sessions_service.js +284 -0
  173. package/build/src/host/admin_stats_service.d.ts +44 -0
  174. package/build/src/host/admin_stats_service.js +130 -0
  175. package/build/src/host/admin_validators.d.ts +247 -0
  176. package/build/src/host/admin_validators.js +197 -0
  177. package/build/src/host/augmentations.d.ts +12 -0
  178. package/build/src/host/augmentations.js +1 -0
  179. package/build/src/host/auth_host_config.d.ts +22 -0
  180. package/build/src/host/auth_host_config.js +13 -0
  181. package/build/src/host/avatar_storage.d.ts +68 -0
  182. package/build/src/host/avatar_storage.js +166 -0
  183. package/build/src/host/bot_protection.d.ts +187 -0
  184. package/build/src/host/bot_protection.js +132 -0
  185. package/build/src/host/branding.d.ts +19 -0
  186. package/build/src/host/branding.js +8 -0
  187. package/build/src/host/config_locks.d.ts +38 -0
  188. package/build/src/host/config_locks.js +70 -0
  189. package/build/src/host/console_session.d.ts +27 -0
  190. package/build/src/host/console_session.js +36 -0
  191. package/build/src/host/controllers/account_apps_controller.d.ts +15 -0
  192. package/build/src/host/controllers/account_apps_controller.js +61 -0
  193. package/build/src/host/controllers/account_confirm_controller.d.ts +24 -0
  194. package/build/src/host/controllers/account_confirm_controller.js +144 -0
  195. package/build/src/host/controllers/account_mfa_controller.d.ts +28 -0
  196. package/build/src/host/controllers/account_mfa_controller.js +208 -0
  197. package/build/src/host/controllers/account_orgs_controller.d.ts +80 -0
  198. package/build/src/host/controllers/account_orgs_controller.js +401 -0
  199. package/build/src/host/controllers/account_security_controller.d.ts +43 -0
  200. package/build/src/host/controllers/account_security_controller.js +546 -0
  201. package/build/src/host/controllers/account_session_controller.d.ts +21 -0
  202. package/build/src/host/controllers/account_session_controller.js +113 -0
  203. package/build/src/host/controllers/account_tokens_controller.d.ts +7 -0
  204. package/build/src/host/controllers/account_tokens_controller.js +67 -0
  205. package/build/src/host/controllers/interaction_controller.d.ts +125 -0
  206. package/build/src/host/controllers/interaction_controller.js +981 -0
  207. package/build/src/host/controllers/pat_introspection_controller.d.ts +22 -0
  208. package/build/src/host/controllers/pat_introspection_controller.js +46 -0
  209. package/build/src/host/controllers/registration_controller.d.ts +18 -0
  210. package/build/src/host/controllers/registration_controller.js +382 -0
  211. package/build/src/host/controllers/social_controller.d.ts +8 -0
  212. package/build/src/host/controllers/social_controller.js +89 -0
  213. package/build/src/host/csrf.d.ts +29 -0
  214. package/build/src/host/csrf.js +14 -0
  215. package/build/src/host/default_mailer.d.ts +112 -0
  216. package/build/src/host/default_mailer.js +417 -0
  217. package/build/src/host/durable/account_deletion_workflow.d.ts +48 -0
  218. package/build/src/host/durable/account_deletion_workflow.js +86 -0
  219. package/build/src/host/durable/account_export_workflow.d.ts +68 -0
  220. package/build/src/host/durable/account_export_workflow.js +93 -0
  221. package/build/src/host/durable/index.d.ts +68 -0
  222. package/build/src/host/durable/index.js +77 -0
  223. package/build/src/host/email_templates.d.ts +39 -0
  224. package/build/src/host/email_templates.js +69 -0
  225. package/build/src/host/geo.d.ts +22 -0
  226. package/build/src/host/geo.js +39 -0
  227. package/build/src/host/i18n.d.ts +1416 -0
  228. package/build/src/host/i18n.js +1583 -0
  229. package/build/src/host/impersonation.d.ts +25 -0
  230. package/build/src/host/impersonation.js +31 -0
  231. package/build/src/host/key_rotation.d.ts +14 -0
  232. package/build/src/host/key_rotation.js +27 -0
  233. package/build/src/host/key_rotation_actions.d.ts +42 -0
  234. package/build/src/host/key_rotation_actions.js +27 -0
  235. package/build/src/host/login_attempt.d.ts +98 -0
  236. package/build/src/host/login_attempt.js +211 -0
  237. package/build/src/host/login_notify.d.ts +27 -0
  238. package/build/src/host/login_notify.js +142 -0
  239. package/build/src/host/middleware/account_auth.d.ts +7 -0
  240. package/build/src/host/middleware/account_auth.js +11 -0
  241. package/build/src/host/otp_lockout.d.ts +103 -0
  242. package/build/src/host/otp_lockout.js +221 -0
  243. package/build/src/host/rate_limit.d.ts +39 -0
  244. package/build/src/host/rate_limit.js +94 -0
  245. package/build/src/host/register_auth_host.d.ts +97 -0
  246. package/build/src/host/register_auth_host.js +466 -0
  247. package/build/src/host/renderers/edge_renderer.d.ts +12 -0
  248. package/build/src/host/renderers/edge_renderer.js +38 -0
  249. package/build/src/host/renderers/inertia_renderer.d.ts +70 -0
  250. package/build/src/host/renderers/inertia_renderer.js +54 -0
  251. package/build/src/host/runtime_settings.d.ts +181 -0
  252. package/build/src/host/runtime_settings.js +307 -0
  253. package/build/src/host/runtime_toggles.d.ts +807 -0
  254. package/build/src/host/runtime_toggles.js +784 -0
  255. package/build/src/host/security_notice_service.d.ts +36 -0
  256. package/build/src/host/security_notice_service.js +87 -0
  257. package/build/src/host/session_context.d.ts +23 -0
  258. package/build/src/host/session_context.js +89 -0
  259. package/build/src/host/sudo_mode.d.ts +56 -0
  260. package/build/src/host/sudo_mode.js +99 -0
  261. package/build/src/host/svg_chart.d.ts +15 -0
  262. package/build/src/host/svg_chart.js +45 -0
  263. package/build/src/host/trusted_device.d.ts +61 -0
  264. package/build/src/host/trusted_device.js +65 -0
  265. package/build/src/host/ui-dist/assets/index-CRWcmsex.js +137 -0
  266. package/build/src/host/ui-dist/assets/index-DTSmD4RU.css +1 -0
  267. package/build/src/host/ui-dist/index.html +17 -0
  268. package/build/src/host/user_agent.d.ts +18 -0
  269. package/build/src/host/user_agent.js +50 -0
  270. package/build/src/host/validators.d.ts +127 -0
  271. package/build/src/host/validators.js +53 -0
  272. package/build/src/keys/jwks_manager.d.ts +6 -0
  273. package/build/src/keys/jwks_manager.js +11 -0
  274. package/build/src/keys/keystore.d.ts +52 -0
  275. package/build/src/keys/keystore.js +68 -0
  276. package/build/src/keys/keystore_codec.d.ts +20 -0
  277. package/build/src/keys/keystore_codec.js +42 -0
  278. package/build/src/keys/keystore_crypto.d.ts +9 -0
  279. package/build/src/keys/keystore_crypto.js +27 -0
  280. package/build/src/keys/keystore_manager.d.ts +43 -0
  281. package/build/src/keys/keystore_manager.js +104 -0
  282. package/build/src/keys/keystore_vault.d.ts +113 -0
  283. package/build/src/keys/keystore_vault.js +265 -0
  284. package/build/src/mixins/json_column.d.ts +33 -0
  285. package/build/src/mixins/json_column.js +38 -0
  286. package/build/src/mixins/with_audit_log.d.ts +19 -0
  287. package/build/src/mixins/with_audit_log.js +39 -0
  288. package/build/src/mixins/with_auth_user.d.ts +24 -0
  289. package/build/src/mixins/with_auth_user.js +46 -0
  290. package/build/src/mixins/with_credentials.d.ts +20 -0
  291. package/build/src/mixins/with_credentials.js +29 -0
  292. package/build/src/mixins/with_mfa.d.ts +35 -0
  293. package/build/src/mixins/with_mfa.js +21 -0
  294. package/build/src/mixins/with_personal_access_token.d.ts +19 -0
  295. package/build/src/mixins/with_personal_access_token.js +42 -0
  296. package/build/src/mixins/with_provider_identity.d.ts +20 -0
  297. package/build/src/mixins/with_provider_identity.js +32 -0
  298. package/build/src/mixins/with_webauthn_credential.d.ts +37 -0
  299. package/build/src/mixins/with_webauthn_credential.js +46 -0
  300. package/build/src/observability/diagnostics_bridge.d.ts +6 -0
  301. package/build/src/observability/diagnostics_bridge.js +27 -0
  302. package/build/src/observability/metrics_controller.d.ts +5 -0
  303. package/build/src/observability/metrics_controller.js +24 -0
  304. package/build/src/observability/metrics_service.d.ts +2 -0
  305. package/build/src/observability/metrics_service.js +7 -0
  306. package/build/src/observability/otel_recorder.d.ts +10 -0
  307. package/build/src/observability/otel_recorder.js +59 -0
  308. package/build/src/observability/telescope/data_providers.d.ts +24 -0
  309. package/build/src/observability/telescope/data_providers.js +235 -0
  310. package/build/src/observability/telescope/extension.d.ts +29 -0
  311. package/build/src/observability/telescope/extension.js +167 -0
  312. package/build/src/observability/telescope/index.d.ts +8 -0
  313. package/build/src/observability/telescope/index.js +8 -0
  314. package/build/src/observability/wire_provider_events.d.ts +12 -0
  315. package/build/src/observability/wire_provider_events.js +30 -0
  316. package/build/src/password/common_passwords.d.ts +31 -0
  317. package/build/src/password/common_passwords.js +73 -0
  318. package/build/src/password/password_manager.d.ts +163 -0
  319. package/build/src/password/password_manager.js +191 -0
  320. package/build/src/password/policy.d.ts +71 -0
  321. package/build/src/password/policy.js +55 -0
  322. package/build/src/password/pwned.d.ts +36 -0
  323. package/build/src/password/pwned.js +52 -0
  324. package/build/src/pat/lucid_pat_store.d.ts +6 -0
  325. package/build/src/pat/lucid_pat_store.js +62 -0
  326. package/build/src/pat/pat_store.d.ts +31 -0
  327. package/build/src/pat/pat_store.js +1 -0
  328. package/build/src/pat/pat_tokens.d.ts +4 -0
  329. package/build/src/pat/pat_tokens.js +9 -0
  330. package/build/src/provider/build_provider.d.ts +45 -0
  331. package/build/src/provider/build_provider.js +219 -0
  332. package/build/src/provider/device_sources.d.ts +6 -0
  333. package/build/src/provider/device_sources.js +65 -0
  334. package/build/src/provider/interaction_actions.d.ts +36 -0
  335. package/build/src/provider/interaction_actions.js +55 -0
  336. package/build/src/provider/key_rotation_scheduler.d.ts +28 -0
  337. package/build/src/provider/key_rotation_scheduler.js +40 -0
  338. package/build/src/provider/keystore_reload.d.ts +21 -0
  339. package/build/src/provider/keystore_reload.js +39 -0
  340. package/build/src/provider/logout_sources.d.ts +13 -0
  341. package/build/src/provider/logout_sources.js +64 -0
  342. package/build/src/provider/oidc_service.d.ts +81 -0
  343. package/build/src/provider/oidc_service.js +254 -0
  344. package/build/src/provider/single_flight_lock.d.ts +18 -0
  345. package/build/src/provider/single_flight_lock.js +31 -0
  346. package/build/src/provider/token_exchange.d.ts +21 -0
  347. package/build/src/provider/token_exchange.js +124 -0
  348. package/build/src/register_routes.d.ts +16 -0
  349. package/build/src/register_routes.js +21 -0
  350. package/build/src/schema/ensure.d.ts +41 -0
  351. package/build/src/schema/ensure.js +262 -0
  352. package/build/stubs/config/authkit.stub +20 -0
  353. package/build/stubs/config/authkit_react.stub +52 -0
  354. package/build/stubs/main.d.ts +1 -0
  355. package/build/stubs/main.js +2 -0
  356. package/build/stubs/models/auth_user.stub +22 -0
  357. package/build/stubs/ui/edge/views/consent.edge +13 -0
  358. package/build/stubs/ui/edge/views/login.edge +19 -0
  359. package/build/stubs/ui/react/components/auth_shell.tsx +67 -0
  360. package/build/stubs/ui/react/pages/account/login.tsx +56 -0
  361. package/build/stubs/ui/react/pages/account/mfa.tsx +132 -0
  362. package/build/stubs/ui/react/pages/account/tokens.tsx +88 -0
  363. package/build/stubs/ui/react/pages/consent.tsx +39 -0
  364. package/build/stubs/ui/react/pages/forgot.tsx +44 -0
  365. package/build/stubs/ui/react/pages/login.tsx +171 -0
  366. package/build/stubs/ui/react/pages/mfa-challenge.tsx +72 -0
  367. package/build/stubs/ui/react/pages/reset.tsx +58 -0
  368. package/build/stubs/ui/react/pages/signup.tsx +78 -0
  369. package/build/stubs/ui/react/pages/verify-email.tsx +24 -0
  370. package/build/types.d.ts +7 -0
  371. package/build/types.js +1 -0
  372. package/package.json +147 -0
  373. package/stubs/config/authkit.stub +20 -0
  374. package/stubs/config/authkit_react.stub +52 -0
  375. package/stubs/main.ts +2 -0
  376. package/stubs/models/auth_user.stub +22 -0
  377. package/stubs/ui/edge/views/consent.edge +13 -0
  378. package/stubs/ui/edge/views/login.edge +19 -0
  379. package/stubs/ui/react/components/auth_shell.tsx +67 -0
  380. package/stubs/ui/react/pages/account/login.tsx +56 -0
  381. package/stubs/ui/react/pages/account/mfa.tsx +132 -0
  382. package/stubs/ui/react/pages/account/tokens.tsx +88 -0
  383. package/stubs/ui/react/pages/consent.tsx +39 -0
  384. package/stubs/ui/react/pages/forgot.tsx +44 -0
  385. package/stubs/ui/react/pages/login.tsx +171 -0
  386. package/stubs/ui/react/pages/mfa-challenge.tsx +72 -0
  387. package/stubs/ui/react/pages/reset.tsx +58 -0
  388. package/stubs/ui/react/pages/signup.tsx +78 -0
  389. package/stubs/ui/react/pages/verify-email.tsx +24 -0
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Serviço de notificações de segurança: envia e-mail quando eventos sensíveis
3
+ * ocorrem na conta (senha alterada, MFA ligado/desligado, passkey add/remove,
4
+ * e-mail alterado). Best-effort, fail-safe total — NUNCA lança na request.
5
+ *
6
+ * Respeita a setting `security_notifications` em `auth_settings` (enabled + kinds).
7
+ * O hook `mail.onSecurityNotice` do config tem prioridade sobre o mailer default.
8
+ */
9
+ import type { HttpContext } from '@adonisjs/core/http';
10
+ import type { MailHooks } from '../define_config.js';
11
+ import type { AuditSink } from '../audit/audit_sink.js';
12
+ import type { SecurityNotificationKind } from './runtime_toggles.js';
13
+ /**
14
+ * Contexto para disparo de uma notificação de segurança.
15
+ */
16
+ export interface SecurityNoticeContext {
17
+ account: {
18
+ id: string;
19
+ email: string;
20
+ };
21
+ kind: SecurityNotificationKind;
22
+ ip?: string | null;
23
+ userAgent?: string | null;
24
+ timestamp?: string;
25
+ metadata?: Record<string, string>;
26
+ }
27
+ /**
28
+ * Despacha uma notificação de segurança, se habilitada e o kind for um dos
29
+ * configurados. Best-effort: qualquer falha é ignorada silenciosamente (logged).
30
+ *
31
+ * @param ctx HttpContext para o mailer default
32
+ * @param notice Contexto da notificação
33
+ * @param mailHooks Hooks de mail do config (opcional)
34
+ * @param audit Sink de auditoria (opcional)
35
+ */
36
+ export declare function dispatchSecurityNotice(ctx: HttpContext, notice: SecurityNoticeContext, mailHooks: Pick<MailHooks, 'onSecurityNotice'> | undefined, audit: AuditSink | undefined): Promise<void>;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Serviço de notificações de segurança: envia e-mail quando eventos sensíveis
3
+ * ocorrem na conta (senha alterada, MFA ligado/desligado, passkey add/remove,
4
+ * e-mail alterado). Best-effort, fail-safe total — NUNCA lança na request.
5
+ *
6
+ * Respeita a setting `security_notifications` em `auth_settings` (enabled + kinds).
7
+ * O hook `mail.onSecurityNotice` do config tem prioridade sobre o mailer default.
8
+ */
9
+ import { resolveRuntimeSettings } from './runtime_settings.js';
10
+ import { resolveEffectiveSecurityNotifications } from './runtime_toggles.js';
11
+ import { sendSecurityNoticeEmail } from './default_mailer.js';
12
+ /**
13
+ * Despacha uma notificação de segurança, se habilitada e o kind for um dos
14
+ * configurados. Best-effort: qualquer falha é ignorada silenciosamente (logged).
15
+ *
16
+ * @param ctx HttpContext para o mailer default
17
+ * @param notice Contexto da notificação
18
+ * @param mailHooks Hooks de mail do config (opcional)
19
+ * @param audit Sink de auditoria (opcional)
20
+ */
21
+ export async function dispatchSecurityNotice(ctx, notice, mailHooks, audit) {
22
+ try {
23
+ // Resolve settings em runtime (fail-safe: sem tabela → defaults habilitados).
24
+ let enabled = true;
25
+ let enabledKinds = [
26
+ 'password_changed',
27
+ 'mfa_enabled',
28
+ 'mfa_disabled',
29
+ 'passkey_added',
30
+ 'passkey_removed',
31
+ 'email_changed',
32
+ ];
33
+ try {
34
+ const runtimeSettings = await resolveRuntimeSettings(ctx);
35
+ if (runtimeSettings && (await runtimeSettings.isTablePresent())) {
36
+ const resolved = await resolveEffectiveSecurityNotifications(runtimeSettings);
37
+ enabled = resolved.enabled;
38
+ enabledKinds = resolved.kinds;
39
+ }
40
+ }
41
+ catch {
42
+ // DB não disponível ou tabela ausente → usa defaults (habilitado, todos os kinds).
43
+ }
44
+ if (!enabled)
45
+ return;
46
+ if (!enabledKinds.includes(notice.kind))
47
+ return;
48
+ const timestamp = notice.timestamp ?? new Date().toISOString();
49
+ const noticeData = {
50
+ account: notice.account,
51
+ kind: notice.kind,
52
+ ip: notice.ip ?? null,
53
+ userAgent: notice.userAgent ?? null,
54
+ timestamp,
55
+ metadata: notice.metadata,
56
+ };
57
+ // Hook do config tem prioridade; senão usa o mailer default.
58
+ if (mailHooks?.onSecurityNotice) {
59
+ await mailHooks.onSecurityNotice(noticeData);
60
+ }
61
+ else {
62
+ await sendSecurityNoticeEmail(ctx, {
63
+ email: notice.account.email,
64
+ kind: notice.kind,
65
+ timestamp,
66
+ ip: notice.ip,
67
+ metadata: notice.metadata,
68
+ });
69
+ }
70
+ // Audita o envio da notificação (best-effort).
71
+ await audit?.record({
72
+ type: 'security_notice.sent',
73
+ accountId: notice.account.id,
74
+ ip: notice.ip ?? null,
75
+ metadata: { kind: notice.kind },
76
+ });
77
+ }
78
+ catch (error) {
79
+ // Fail-safe total: erro na notificação NUNCA quebra o fluxo principal.
80
+ try {
81
+ ctx.logger.error({ err: error, kind: notice.kind, accountId: notice.account.id }, 'authkit: falha ao enviar notificação de segurança');
82
+ }
83
+ catch {
84
+ // Logger também falhou — silencioso.
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,23 @@
1
+ import type { ResolvedServerConfig } from '../define_config.js';
2
+ import type { AdminSession } from './admin_sessions_service.js';
3
+ /**
4
+ * ENRIQUECE sessões ativas com contexto de dispositivo (user-agent → browser/SO),
5
+ * IP e localização, SEM tocar no payload da `Session` do oidc-provider (que não é
6
+ * extensível de forma portátil entre adapters).
7
+ *
8
+ * A FONTE do contexto é o próprio audit log: cada `login.success` carrega o `ip` e
9
+ * o `userAgent` (em `metadata.userAgent`, gravado por `notifyLoginSuccess`). Como a
10
+ * `Session` carrega o `loginTs` (epoch do login), correlacionamos cada sessão ao
11
+ * evento `login.success` da MESMA conta cujo timestamp é o mais próximo do `loginTs`
12
+ * — um join barato em memória sobre uma janela recente de eventos.
13
+ *
14
+ * CAPABILITY-PROBED + FAIL-SAFE: degrada para os campos vazios (sem quebrar a
15
+ * listagem) quando o sink de auditoria não suporta consulta (`list` ausente). A
16
+ * geolocalização usa o hook plugável `resolveGeo` (ausente = só IP, sem location),
17
+ * com timeout curto.
18
+ *
19
+ * LIMITAÇÃO: a correlação por timestamp é uma APROXIMAÇÃO — duas sessões da mesma
20
+ * conta criadas no mesmo segundo podem trocar de contexto entre si. É suficiente
21
+ * para exibição (não para decisões de segurança).
22
+ */
23
+ export declare function enrichSessionsWithContext(cfg: Pick<ResolvedServerConfig, 'audit' | 'resolveGeo'>, accountId: string, sessions: AdminSession[]): Promise<AdminSession[]>;
@@ -0,0 +1,89 @@
1
+ import { parseUserAgent } from './user_agent.js';
2
+ import { resolveGeoSafe } from './geo.js';
3
+ /**
4
+ * ENRIQUECE sessões ativas com contexto de dispositivo (user-agent → browser/SO),
5
+ * IP e localização, SEM tocar no payload da `Session` do oidc-provider (que não é
6
+ * extensível de forma portátil entre adapters).
7
+ *
8
+ * A FONTE do contexto é o próprio audit log: cada `login.success` carrega o `ip` e
9
+ * o `userAgent` (em `metadata.userAgent`, gravado por `notifyLoginSuccess`). Como a
10
+ * `Session` carrega o `loginTs` (epoch do login), correlacionamos cada sessão ao
11
+ * evento `login.success` da MESMA conta cujo timestamp é o mais próximo do `loginTs`
12
+ * — um join barato em memória sobre uma janela recente de eventos.
13
+ *
14
+ * CAPABILITY-PROBED + FAIL-SAFE: degrada para os campos vazios (sem quebrar a
15
+ * listagem) quando o sink de auditoria não suporta consulta (`list` ausente). A
16
+ * geolocalização usa o hook plugável `resolveGeo` (ausente = só IP, sem location),
17
+ * com timeout curto.
18
+ *
19
+ * LIMITAÇÃO: a correlação por timestamp é uma APROXIMAÇÃO — duas sessões da mesma
20
+ * conta criadas no mesmo segundo podem trocar de contexto entre si. É suficiente
21
+ * para exibição (não para decisões de segurança).
22
+ */
23
+ export async function enrichSessionsWithContext(cfg, accountId, sessions) {
24
+ if (sessions.length === 0)
25
+ return sessions;
26
+ // Sem consulta de audit não há de onde puxar o contexto → devolve como veio.
27
+ if (typeof cfg.audit?.list !== 'function')
28
+ return sessions;
29
+ // Janela recente de login.success da conta (limite são para não estourar memória).
30
+ const page = await cfg.audit.list({
31
+ type: 'login.success',
32
+ subject: accountId,
33
+ page: 1,
34
+ limit: 200,
35
+ });
36
+ const events = page.data.map((e) => ({
37
+ ts: toEpochSeconds(e.createdAt),
38
+ ip: e.ip ?? null,
39
+ userAgent: e.metadata?.userAgent ?? null,
40
+ }));
41
+ return Promise.all(sessions.map(async (s) => {
42
+ const match = closestEvent(events, s.loginTs);
43
+ if (!match)
44
+ return s;
45
+ const { browser, os } = parseUserAgent(match.userAgent);
46
+ const location = await resolveGeoSafe(cfg.resolveGeo, match.ip);
47
+ return {
48
+ ...s,
49
+ userAgent: match.userAgent,
50
+ browser: match.userAgent ? browser : null,
51
+ os: match.userAgent ? os : null,
52
+ ip: match.ip,
53
+ location,
54
+ };
55
+ }));
56
+ }
57
+ /**
58
+ * Escolhe o evento cujo timestamp é o MAIS PRÓXIMO do `loginTs` da sessão. Quando a
59
+ * sessão não tem `loginTs`, devolve o evento mais recente com algum contexto. `null`
60
+ * quando não há eventos úteis.
61
+ */
62
+ function closestEvent(events, loginTs) {
63
+ const usable = events.filter((e) => e.ip !== null || e.userAgent !== null);
64
+ if (usable.length === 0)
65
+ return null;
66
+ if (loginTs === undefined) {
67
+ // Sem loginTs: o primeiro (a listagem do sink vem desc por createdAt).
68
+ return usable[0];
69
+ }
70
+ let best = null;
71
+ let bestDelta = Number.POSITIVE_INFINITY;
72
+ for (const e of usable) {
73
+ if (e.ts === null)
74
+ continue;
75
+ const delta = Math.abs(e.ts - loginTs);
76
+ if (delta < bestDelta) {
77
+ bestDelta = delta;
78
+ best = e;
79
+ }
80
+ }
81
+ return best ?? usable[0];
82
+ }
83
+ /** Normaliza o createdAt do audit (Date | ISO string) para epoch-segundos. */
84
+ function toEpochSeconds(createdAt) {
85
+ if (!createdAt)
86
+ return null;
87
+ const ms = createdAt instanceof Date ? createdAt.getTime() : Date.parse(createdAt);
88
+ return Number.isFinite(ms) ? Math.floor(ms / 1000) : null;
89
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Sudo mode (confirm_password + grace period).
3
+ *
4
+ * Após confirmar a identidade (senha ou passkey), o helper `requireSudo` registra
5
+ * o timestamp na sessão Adonis. Dentro da janela de graça (`graceMinutes`) a
6
+ * confirmação é aceita; fora dela, o usuário é redirecionado para `/account/confirm`.
7
+ *
8
+ * Setting `sudo_mode`:
9
+ * - `enabled`: habilita/desabilita o sudo mode. Default: true.
10
+ * - `graceMinutes`: janela de graça em minutos. Default: 15.
11
+ *
12
+ * Chave de sessão: `authkit_sudo_at` (timestamp ms).
13
+ */
14
+ import type { HttpContext } from '@adonisjs/core/http';
15
+ import type { SettingsCapability } from './runtime_settings.js';
16
+ export interface SudoModeSetting {
17
+ enabled?: boolean;
18
+ graceMinutes?: number;
19
+ }
20
+ export interface ResolvedSudoModeSetting {
21
+ enabled: boolean;
22
+ graceMinutes: number;
23
+ }
24
+ export declare const SUDO_MODE_DEFAULTS: ResolvedSudoModeSetting;
25
+ /**
26
+ * Resolve a setting `sudo_mode` em runtime (fail-safe).
27
+ */
28
+ export declare function resolveEffectiveSudoMode(settings: SettingsCapability): Promise<ResolvedSudoModeSetting>;
29
+ /** Chave da sessão Adonis que registra quando o sudo foi confirmado. */
30
+ export declare const SUDO_SESSION_KEY = "authkit_sudo_at";
31
+ /**
32
+ * Registra o timestamp de confirmação de sudo na sessão (NOW).
33
+ * Chamar após o usuário confirmar sua identidade (senha ou passkey).
34
+ */
35
+ export declare function markSudo(ctx: HttpContext): void;
36
+ /**
37
+ * Verifica se o sudo está ativo (dentro da janela de graça).
38
+ *
39
+ * @returns `true` se o sudo está ativo (dentro da graça); `false` caso contrário.
40
+ */
41
+ export declare function isSudoActive(ctx: HttpContext, graceMinutes: number): boolean;
42
+ /**
43
+ * Guard de sudo mode. Verifica se a confirmação de identidade está ativa e
44
+ * dentro da janela de graça. Se estiver, retorna `true`. Se não, redireciona
45
+ * para `/account/confirm?return_to=<path atual>` e retorna a resposta.
46
+ *
47
+ * Uso:
48
+ * ```ts
49
+ * const result = await requireSudo(ctx, settings)
50
+ * if (result !== true) return result
51
+ * ```
52
+ *
53
+ * FAIL-SAFE: qualquer erro lê settings → retorna `true` (deixa passar).
54
+ * Quando `sudo_mode.enabled = false`, sempre retorna `true`.
55
+ */
56
+ export declare function requireSudo(ctx: HttpContext, settings: SettingsCapability | null): Promise<true | unknown>;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Sudo mode (confirm_password + grace period).
3
+ *
4
+ * Após confirmar a identidade (senha ou passkey), o helper `requireSudo` registra
5
+ * o timestamp na sessão Adonis. Dentro da janela de graça (`graceMinutes`) a
6
+ * confirmação é aceita; fora dela, o usuário é redirecionado para `/account/confirm`.
7
+ *
8
+ * Setting `sudo_mode`:
9
+ * - `enabled`: habilita/desabilita o sudo mode. Default: true.
10
+ * - `graceMinutes`: janela de graça em minutos. Default: 15.
11
+ *
12
+ * Chave de sessão: `authkit_sudo_at` (timestamp ms).
13
+ */
14
+ import { SETTING_KEYS } from './runtime_toggles.js';
15
+ export const SUDO_MODE_DEFAULTS = {
16
+ enabled: true,
17
+ graceMinutes: 15,
18
+ };
19
+ /**
20
+ * Resolve a setting `sudo_mode` em runtime (fail-safe).
21
+ */
22
+ export async function resolveEffectiveSudoMode(settings) {
23
+ try {
24
+ const raw = await settings.getSetting(SETTING_KEYS.SUDO_MODE);
25
+ if (raw === null || raw === undefined)
26
+ return SUDO_MODE_DEFAULTS;
27
+ if (typeof raw !== 'object' || Array.isArray(raw))
28
+ return SUDO_MODE_DEFAULTS;
29
+ const s = raw;
30
+ return {
31
+ enabled: typeof s.enabled === 'boolean' ? s.enabled : SUDO_MODE_DEFAULTS.enabled,
32
+ graceMinutes: typeof s.graceMinutes === 'number' && s.graceMinutes >= 0
33
+ ? Math.floor(s.graceMinutes)
34
+ : SUDO_MODE_DEFAULTS.graceMinutes,
35
+ };
36
+ }
37
+ catch {
38
+ return SUDO_MODE_DEFAULTS;
39
+ }
40
+ }
41
+ // ---------------------------------------------------------------------------
42
+ // Session key + helpers
43
+ // ---------------------------------------------------------------------------
44
+ /** Chave da sessão Adonis que registra quando o sudo foi confirmado. */
45
+ export const SUDO_SESSION_KEY = 'authkit_sudo_at';
46
+ /**
47
+ * Registra o timestamp de confirmação de sudo na sessão (NOW).
48
+ * Chamar após o usuário confirmar sua identidade (senha ou passkey).
49
+ */
50
+ export function markSudo(ctx) {
51
+ ctx.session.put(SUDO_SESSION_KEY, Date.now());
52
+ }
53
+ /**
54
+ * Verifica se o sudo está ativo (dentro da janela de graça).
55
+ *
56
+ * @returns `true` se o sudo está ativo (dentro da graça); `false` caso contrário.
57
+ */
58
+ export function isSudoActive(ctx, graceMinutes) {
59
+ const sudoAt = ctx.session.get(SUDO_SESSION_KEY);
60
+ if (!sudoAt)
61
+ return false;
62
+ const graceMs = graceMinutes * 60 * 1000;
63
+ return Date.now() - sudoAt <= graceMs;
64
+ }
65
+ /**
66
+ * Guard de sudo mode. Verifica se a confirmação de identidade está ativa e
67
+ * dentro da janela de graça. Se estiver, retorna `true`. Se não, redireciona
68
+ * para `/account/confirm?return_to=<path atual>` e retorna a resposta.
69
+ *
70
+ * Uso:
71
+ * ```ts
72
+ * const result = await requireSudo(ctx, settings)
73
+ * if (result !== true) return result
74
+ * ```
75
+ *
76
+ * FAIL-SAFE: qualquer erro lê settings → retorna `true` (deixa passar).
77
+ * Quando `sudo_mode.enabled = false`, sempre retorna `true`.
78
+ */
79
+ export async function requireSudo(ctx, settings) {
80
+ try {
81
+ const cfg = settings ? await resolveEffectiveSudoMode(settings) : SUDO_MODE_DEFAULTS;
82
+ if (!cfg.enabled)
83
+ return true;
84
+ if (isSudoActive(ctx, cfg.graceMinutes))
85
+ return true;
86
+ }
87
+ catch {
88
+ // FAIL-SAFE: erro ao resolver a setting → deixa passar.
89
+ return true;
90
+ }
91
+ // Fora da graça: redireciona para confirmação.
92
+ const rawUrl = ctx.request.url?.() ?? '';
93
+ const qs = ctx.request.parsedUrl?.search ?? '';
94
+ const dest = qs ? `${rawUrl}${qs}` : rawUrl;
95
+ const returnTo = dest && dest !== '/' && !dest.startsWith('/account/confirm')
96
+ ? `?return_to=${encodeURIComponent(dest)}`
97
+ : '';
98
+ return ctx.response.redirect(`/account/confirm${returnTo}`);
99
+ }
@@ -0,0 +1,15 @@
1
+ import type { DailyPoint } from './admin_stats_service.js';
2
+ /**
3
+ * Gera um gráfico de BARRAS em SVG inline (server-side, SEM nenhuma lib de chart e
4
+ * SEM JS no cliente) a partir de uma série diária. Estilo enxuto, consistente com o
5
+ * visual Tailwind do console (cor passável). Cada barra ganha um `<title>` para o
6
+ * tooltip nativo do browser (data + contagem) — acessível sem JS.
7
+ *
8
+ * A altura é normalizada pelo maior valor da série; séries todas-zero rendem barras
9
+ * de altura mínima (linha de base). O SVG é responsivo (`width: 100%`) via viewBox.
10
+ */
11
+ export declare function barChartSvg(series: DailyPoint[], opts?: {
12
+ width?: number;
13
+ height?: number;
14
+ color?: string;
15
+ }): string;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Gera um gráfico de BARRAS em SVG inline (server-side, SEM nenhuma lib de chart e
3
+ * SEM JS no cliente) a partir de uma série diária. Estilo enxuto, consistente com o
4
+ * visual Tailwind do console (cor passável). Cada barra ganha um `<title>` para o
5
+ * tooltip nativo do browser (data + contagem) — acessível sem JS.
6
+ *
7
+ * A altura é normalizada pelo maior valor da série; séries todas-zero rendem barras
8
+ * de altura mínima (linha de base). O SVG é responsivo (`width: 100%`) via viewBox.
9
+ */
10
+ export function barChartSvg(series, opts = {}) {
11
+ const width = opts.width ?? 600;
12
+ const height = opts.height ?? 80;
13
+ const color = opts.color ?? '#111827'; // gray-900
14
+ const n = series.length;
15
+ if (n === 0) {
16
+ return `<svg viewBox="0 0 ${width} ${height}" width="100%" role="img" aria-hidden="true"></svg>`;
17
+ }
18
+ const max = Math.max(1, ...series.map((p) => p.count));
19
+ const gap = 2;
20
+ const barWidth = Math.max(1, (width - gap * (n - 1)) / n);
21
+ const minBar = 1;
22
+ const bars = series
23
+ .map((p, i) => {
24
+ const x = i * (barWidth + gap);
25
+ const h = p.count > 0 ? Math.max(minBar, (p.count / max) * (height - 2)) : minBar;
26
+ const y = height - h;
27
+ const title = `${escapeXml(p.date)}: ${p.count}`;
28
+ return (`<rect x="${round(x)}" y="${round(y)}" width="${round(barWidth)}" height="${round(h)}" ` +
29
+ `rx="1" fill="${color}" opacity="${p.count > 0 ? 0.9 : 0.15}">` +
30
+ `<title>${title}</title></rect>`);
31
+ })
32
+ .join('');
33
+ return (`<svg viewBox="0 0 ${width} ${height}" width="100%" preserveAspectRatio="none" ` +
34
+ `role="img" aria-label="bar chart">${bars}</svg>`);
35
+ }
36
+ function round(n) {
37
+ return Math.round(n * 100) / 100;
38
+ }
39
+ function escapeXml(s) {
40
+ return s
41
+ .replace(/&/g, '&amp;')
42
+ .replace(/</g, '&lt;')
43
+ .replace(/>/g, '&gt;')
44
+ .replace(/"/g, '&quot;');
45
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * "Trusted devices" — pular o 2º fator (MFA) neste dispositivo por N dias.
3
+ *
4
+ * Mecanismo SEM novos requisitos de DB: um cookie httpOnly assinado/encriptado
5
+ * com a appKey do host (via `response.encryptedCookie` / `request.encryptedCookie`,
6
+ * que são appKey-backed). O cookie carrega `{ a: accountId, d: deviceId, iat, exp }`.
7
+ *
8
+ * Validação (ver {@link isTrustedDeviceValid}):
9
+ * - `exp` ainda no futuro;
10
+ * - `a` casa com a conta que acabou de passar pela senha;
11
+ * - `iat >= mfaEnabledAt` — re-enrolar o MFA invalida cookies antigos (revogação
12
+ * por re-enrollment, sem estado server-side).
13
+ *
14
+ * Step-up (acr_values pedindo o mfaAcr) SEMPRE ignora o cookie e força o MFA — a
15
+ * decisão fica no controller, antes de checar o cookie.
16
+ *
17
+ * Limitação conhecida (documentada): NÃO há uma lista de revogação por-dispositivo
18
+ * server-side; a revogação disponível é "revogar todos" via re-enrollment do MFA.
19
+ * Uma allowlist/denylist persistida fica como trabalho futuro.
20
+ */
21
+ /** Nome do cookie de dispositivo confiável. */
22
+ export declare const TRUSTED_DEVICE_COOKIE = "authkit_trusted_device";
23
+ /** Payload guardado (encriptado) no cookie de dispositivo confiável. */
24
+ export interface TrustedDevicePayload {
25
+ /** accountId ao qual a confiança pertence. */
26
+ a: string;
27
+ /** id opaco do dispositivo (para futura revogação por-dispositivo). */
28
+ d: string;
29
+ /** issued-at (epoch ms). */
30
+ iat: number;
31
+ /** expiry (epoch ms). */
32
+ exp: number;
33
+ }
34
+ /**
35
+ * Infra de trusted devices. Política (enabled, days) é gerenciada em runtime
36
+ * via setting `trusted_devices` no admin console ou Admin API.
37
+ */
38
+ export interface TrustedDevicesConfigInput {
39
+ }
40
+ export interface ResolvedTrustedDevicesConfig {
41
+ enabled: boolean;
42
+ days: number;
43
+ }
44
+ export declare function resolveTrustedDevices(_input?: TrustedDevicesConfigInput): ResolvedTrustedDevicesConfig;
45
+ /** Constrói o payload de um novo cookie de confiança para a conta. */
46
+ export declare function buildTrustedDevicePayload(accountId: string, cfg: ResolvedTrustedDevicesConfig, now?: number): TrustedDevicePayload;
47
+ /**
48
+ * `true` se o payload do cookie é uma confiança VÁLIDA para `accountId`:
49
+ * - estrutura íntegra;
50
+ * - pertence à conta certa;
51
+ * - não expirou;
52
+ * - foi emitido em/depois do último (re)enrollment de MFA (`mfaEnabledAt`).
53
+ *
54
+ * `mfaEnabledAt` em epoch ms (ou null quando o store não rastreia — nesse caso a
55
+ * checagem de re-enrollment é pulada, mantendo a validade por expiração apenas).
56
+ */
57
+ export declare function isTrustedDeviceValid(payload: unknown, opts: {
58
+ accountId: string;
59
+ mfaEnabledAt?: number | null;
60
+ now?: number;
61
+ }): boolean;
@@ -0,0 +1,65 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ /**
3
+ * "Trusted devices" — pular o 2º fator (MFA) neste dispositivo por N dias.
4
+ *
5
+ * Mecanismo SEM novos requisitos de DB: um cookie httpOnly assinado/encriptado
6
+ * com a appKey do host (via `response.encryptedCookie` / `request.encryptedCookie`,
7
+ * que são appKey-backed). O cookie carrega `{ a: accountId, d: deviceId, iat, exp }`.
8
+ *
9
+ * Validação (ver {@link isTrustedDeviceValid}):
10
+ * - `exp` ainda no futuro;
11
+ * - `a` casa com a conta que acabou de passar pela senha;
12
+ * - `iat >= mfaEnabledAt` — re-enrolar o MFA invalida cookies antigos (revogação
13
+ * por re-enrollment, sem estado server-side).
14
+ *
15
+ * Step-up (acr_values pedindo o mfaAcr) SEMPRE ignora o cookie e força o MFA — a
16
+ * decisão fica no controller, antes de checar o cookie.
17
+ *
18
+ * Limitação conhecida (documentada): NÃO há uma lista de revogação por-dispositivo
19
+ * server-side; a revogação disponível é "revogar todos" via re-enrollment do MFA.
20
+ * Uma allowlist/denylist persistida fica como trabalho futuro.
21
+ */
22
+ /** Nome do cookie de dispositivo confiável. */
23
+ export const TRUSTED_DEVICE_COOKIE = 'authkit_trusted_device';
24
+ export function resolveTrustedDevices(_input) {
25
+ return {
26
+ enabled: true,
27
+ days: 30,
28
+ };
29
+ }
30
+ /** Constrói o payload de um novo cookie de confiança para a conta. */
31
+ export function buildTrustedDevicePayload(accountId, cfg, now = Date.now()) {
32
+ return {
33
+ a: accountId,
34
+ d: randomBytes(16).toString('hex'),
35
+ iat: now,
36
+ exp: now + cfg.days * 24 * 60 * 60 * 1000,
37
+ };
38
+ }
39
+ /**
40
+ * `true` se o payload do cookie é uma confiança VÁLIDA para `accountId`:
41
+ * - estrutura íntegra;
42
+ * - pertence à conta certa;
43
+ * - não expirou;
44
+ * - foi emitido em/depois do último (re)enrollment de MFA (`mfaEnabledAt`).
45
+ *
46
+ * `mfaEnabledAt` em epoch ms (ou null quando o store não rastreia — nesse caso a
47
+ * checagem de re-enrollment é pulada, mantendo a validade por expiração apenas).
48
+ */
49
+ export function isTrustedDeviceValid(payload, opts) {
50
+ const now = opts.now ?? Date.now();
51
+ if (!payload || typeof payload !== 'object')
52
+ return false;
53
+ const p = payload;
54
+ if (typeof p.a !== 'string' || typeof p.iat !== 'number' || typeof p.exp !== 'number') {
55
+ return false;
56
+ }
57
+ if (p.a !== opts.accountId)
58
+ return false;
59
+ if (p.exp <= now)
60
+ return false;
61
+ // Re-enrollment do MFA revoga cookies emitidos antes dele.
62
+ if (typeof opts.mfaEnabledAt === 'number' && p.iat < opts.mfaEnabledAt)
63
+ return false;
64
+ return true;
65
+ }