@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,163 @@
1
+ import { type PasswordPolicyViolation, type ResolvedPasswordConfig } from './policy.js';
2
+ import { type PwnedLogger, type FetchLike } from './pwned.js';
3
+ /**
4
+ * Verificador de hashes legados (de OUTROS sistemas). Chamado quando a
5
+ * verificação nativa do hasher do Adonis falha OU não reconhece o formato do
6
+ * hash (ex.: bcrypt PHP `$2y$`, Django `pbkdf2_sha256$`, MD5, etc.).
7
+ *
8
+ * Retorno:
9
+ * - `true` → a senha confere (o store então re-hasheia com o hasher atual);
10
+ * - `false` → a senha NÃO confere;
11
+ * - `null` → este verifier não trata esse formato (deixa o login falhar).
12
+ *
13
+ * @example
14
+ * // bcrypt vindo do PHP usa o prefixo `$2y$`; o hasher bcrypt do Node entende
15
+ * // `$2b$`. A conversão é só trocar o prefixo (mesmo algoritmo):
16
+ * const legacyVerifier = async (hashed, plain) => {
17
+ * if (!hashed.startsWith('$2y$')) return null // não é meu formato
18
+ * const normalized = '$2b$' + hashed.slice(4)
19
+ * return bcrypt.compare(plain, normalized) // true | false
20
+ * }
21
+ */
22
+ export type LegacyPasswordVerifier = (hashedPassword: string, plainPassword: string) => Promise<boolean | null>;
23
+ /**
24
+ * Config de senha aceita pelo store (entrada do host).
25
+ *
26
+ * Política de complexidade e checagem de vazamento são gerenciadas em runtime
27
+ * via setting `password_policy` no admin console ou Admin API.
28
+ * Aqui ficam apenas os parâmetros de infra/código.
29
+ */
30
+ export interface PasswordConfigInput {
31
+ /**
32
+ * Verificador de hashes legados de outros sistemas. Acionado quando a
33
+ * verificação nativa falha. Veja {@link LegacyPasswordVerifier}.
34
+ */
35
+ legacyVerifier?: LegacyPasswordVerifier;
36
+ /**
37
+ * Pepper de infra (segredo de boot). HMAC-SHA256 da senha ANTES do hasher
38
+ * seguindo OWASP (defense-in-depth: DB comprometido sem o pepper = hashes
39
+ * inúteis).
40
+ *
41
+ * - `string` → pepper corrente.
42
+ * - `string[]` → rotação: o PRIMEIRO é o corrente (hash); TODOS são tentados
43
+ * no verify. Se confere com um pepper antigo → lazy re-hash com o corrente.
44
+ * - Ausente → comportamento original (sem HMAC, back-compat total).
45
+ *
46
+ * IMPORTANTE: Contas existentes podem ter hash SEM pepper — o verify tenta
47
+ * com cada pepper E sem pepper (legacy); em sucesso re-hasheia com o corrente.
48
+ *
49
+ * @example
50
+ * // config/authkit.ts
51
+ * password: { pepper: env.get('PASSWORD_PEPPER') }
52
+ *
53
+ * @example
54
+ * // Rotação: novo pepper primeiro, antigos no array.
55
+ * password: { pepper: [env.get('PEPPER_V2'), env.get('PEPPER_V1')] }
56
+ */
57
+ pepper?: string | string[];
58
+ /**
59
+ * Timeout em ms para a checagem de vazamento HIBP (HaveIBeenPwned). Infra.
60
+ * Default: 2000 ms. A checagem é habilitada/desabilitada via runtime setting
61
+ * `password_policy.checkPwned` no admin console.
62
+ */
63
+ pwnedTimeoutMs?: number;
64
+ }
65
+ /** Erro de política/vazamento de senha — carrega a chave i18n + params. */
66
+ export declare class PasswordPolicyError extends Error {
67
+ readonly key: PasswordPolicyViolation | 'password.pwned' | 'password.reused' | 'password.common';
68
+ readonly params?: Record<string, string | number> | undefined;
69
+ constructor(key: PasswordPolicyViolation | 'password.pwned' | 'password.reused' | 'password.common', params?: Record<string, string | number> | undefined);
70
+ }
71
+ /**
72
+ * Aplica o pepper à senha em claro via HMAC-SHA256, retornando um hex-digest
73
+ * que será entregue ao hasher como se fosse a senha. Sem pepper → retorna a
74
+ * senha inalterada (back-compat total).
75
+ */
76
+ export declare function applyPepper(plain: string, pepper: string): string;
77
+ /**
78
+ * Resolve o array de peppers a tentar no verify, incluindo o sentinel "sem
79
+ * pepper" (cadeia vazia) para back-compat com hashes antigos sem pepper.
80
+ *
81
+ * @returns [corrente, ...antigos, ''] — string vazia = tentar sem HMAC (legacy).
82
+ */
83
+ export declare function resolvePeppers(pepper: string | string[] | undefined): string[];
84
+ /**
85
+ * Aplica o pepper corrente à senha em claro. O pepper corrente é SEMPRE o
86
+ * primeiro do array (ou a string direta). Sem pepper → retorna a senha.
87
+ */
88
+ export declare function applyCurrentPepper(plain: string, pepper: string | string[] | undefined): string;
89
+ /**
90
+ * Resultado de uma verificação de senha pelo manager. `rehash` indica que a
91
+ * senha confere mas o hash armazenado deve ser re-gerado (formato legado OU
92
+ * parâmetros do hasher desatualizados) — o chamador (store) persiste o novo hash
93
+ * best-effort.
94
+ */
95
+ export interface PasswordVerifyResult {
96
+ ok: boolean;
97
+ rehash: boolean;
98
+ }
99
+ /**
100
+ * Concentra a lógica de senha do store: validação de política + vazamento (ao
101
+ * DEFINIR uma senha) e verificação com lazy rehash + legacy verifier (ao
102
+ * AUTENTICAR). A política usa lib defaults — a runtime setting `password_policy`
103
+ * é a única fonte de customização (via `assertAcceptable` com override).
104
+ */
105
+ export declare class PasswordManager {
106
+ readonly config: ResolvedPasswordConfig;
107
+ private readonly legacyVerifier?;
108
+ private readonly logger?;
109
+ private readonly fetchImpl?;
110
+ /** Pepper configurado (secret de boot). Pode ser string ou array para rotação. */
111
+ readonly pepper: string | string[] | undefined;
112
+ /** Timeout em ms para a checagem de vazamento HIBP. */
113
+ readonly pwnedTimeoutMs: number;
114
+ constructor(input?: PasswordConfigInput, deps?: {
115
+ logger?: PwnedLogger;
116
+ fetchImpl?: FetchLike;
117
+ });
118
+ /** Há um verificador de hash legado configurado? */
119
+ hasLegacyVerifier(): boolean;
120
+ /**
121
+ * Aplica o pepper corrente à senha em claro antes do hash. Sem pepper →
122
+ * retorna a senha inalterada (back-compat total).
123
+ */
124
+ applyCurrentPepper(plain: string): string;
125
+ /**
126
+ * Valida uma senha NOVA: política primeiro (barata, local), depois vazamento
127
+ * (rede, opcional, fail-safe). Lança {@link PasswordPolicyError} na 1ª falha.
128
+ *
129
+ * @param policyOverride - Política resolvida em runtime (via setting `password_policy`).
130
+ * Quando fornecida, sobrescreve os defaults da lib para esta chamada.
131
+ */
132
+ assertAcceptable(plainPassword: string, policyOverride?: {
133
+ minLength?: number;
134
+ requireUppercase?: boolean;
135
+ requireLowercase?: boolean;
136
+ requireNumbers?: boolean;
137
+ requireSymbols?: boolean;
138
+ checkPwned?: boolean;
139
+ blockCommon?: boolean;
140
+ }): Promise<void>;
141
+ /**
142
+ * Verifica `plainPassword` contra o `hashedPassword` armazenado, com suporte
143
+ * a pepper.
144
+ *
145
+ * Sequência:
146
+ * 1. Para cada pepper possível (corrente + antigos + sem pepper para legacy):
147
+ * a. `nativeVerify(hashed, peppered(plain))`. Se OK → checa `needsRehash`
148
+ * e devolve `{ ok: true, rehash }`. rehash=true quando pepper não é o
149
+ * corrente (re-hash com o corrente transparente).
150
+ * 2. Se nenhum pepper funcionou com native, tenta o `legacyVerifier` com
151
+ * `applyCurrentPepper(plain)` (e também sem pepper, para import de sistemas
152
+ * legados antes de pepperar).
153
+ * `true` → `{ ok: true, rehash: true }`;
154
+ * `false`/`null` → `{ ok: false, rehash: false }`.
155
+ *
156
+ * `nativeVerify`/`needsRehash` são injetados pelo store (vêm do model Lucid),
157
+ * mantendo este manager desacoplado do Lucid.
158
+ */
159
+ verify(hashedPassword: string, plainPassword: string, hooks: {
160
+ nativeVerify: (hashed: string, plain: string) => Promise<boolean>;
161
+ needsRehash: (hashed: string) => boolean;
162
+ }): Promise<PasswordVerifyResult>;
163
+ }
@@ -0,0 +1,191 @@
1
+ import { createHmac } from 'node:crypto';
2
+ import { checkPasswordPolicy, policyViolationParams, resolvePasswordConfig, DEFAULT_PWNED_TIMEOUT_MS, } from './policy.js';
3
+ import { isPasswordPwned } from './pwned.js';
4
+ import { isCommonPassword } from './common_passwords.js';
5
+ /** Erro de política/vazamento de senha — carrega a chave i18n + params. */
6
+ export class PasswordPolicyError extends Error {
7
+ key;
8
+ params;
9
+ constructor(key, params) {
10
+ super(key);
11
+ this.key = key;
12
+ this.params = params;
13
+ this.name = 'PasswordPolicyError';
14
+ }
15
+ }
16
+ // ---------------------------------------------------------------------------
17
+ // Pepper helpers (OWASP pattern: HMAC-SHA256 before hashing)
18
+ // ---------------------------------------------------------------------------
19
+ /**
20
+ * Aplica o pepper à senha em claro via HMAC-SHA256, retornando um hex-digest
21
+ * que será entregue ao hasher como se fosse a senha. Sem pepper → retorna a
22
+ * senha inalterada (back-compat total).
23
+ */
24
+ export function applyPepper(plain, pepper) {
25
+ return createHmac('sha256', pepper).update(plain).digest('hex');
26
+ }
27
+ /**
28
+ * Resolve o array de peppers a tentar no verify, incluindo o sentinel "sem
29
+ * pepper" (cadeia vazia) para back-compat com hashes antigos sem pepper.
30
+ *
31
+ * @returns [corrente, ...antigos, ''] — string vazia = tentar sem HMAC (legacy).
32
+ */
33
+ export function resolvePeppers(pepper) {
34
+ if (!pepper)
35
+ return [''];
36
+ const arr = Array.isArray(pepper) ? pepper : [pepper];
37
+ // Inclui string vazia no final para tentar sem pepper (legacy back-compat).
38
+ return [...arr, ''];
39
+ }
40
+ /**
41
+ * Aplica o pepper corrente à senha em claro. O pepper corrente é SEMPRE o
42
+ * primeiro do array (ou a string direta). Sem pepper → retorna a senha.
43
+ */
44
+ export function applyCurrentPepper(plain, pepper) {
45
+ if (!pepper)
46
+ return plain;
47
+ const current = Array.isArray(pepper) ? pepper[0] : pepper;
48
+ if (!current)
49
+ return plain;
50
+ return applyPepper(plain, current);
51
+ }
52
+ /**
53
+ * Concentra a lógica de senha do store: validação de política + vazamento (ao
54
+ * DEFINIR uma senha) e verificação com lazy rehash + legacy verifier (ao
55
+ * AUTENTICAR). A política usa lib defaults — a runtime setting `password_policy`
56
+ * é a única fonte de customização (via `assertAcceptable` com override).
57
+ */
58
+ export class PasswordManager {
59
+ config;
60
+ legacyVerifier;
61
+ logger;
62
+ fetchImpl;
63
+ /** Pepper configurado (secret de boot). Pode ser string ou array para rotação. */
64
+ pepper;
65
+ /** Timeout em ms para a checagem de vazamento HIBP. */
66
+ pwnedTimeoutMs;
67
+ constructor(input = {}, deps = {}) {
68
+ // Lib defaults: minLength=8, sem complexidade, sem checkPwned (setting-driven).
69
+ this.config = resolvePasswordConfig({});
70
+ this.legacyVerifier = input.legacyVerifier;
71
+ this.logger = deps.logger;
72
+ this.fetchImpl = deps.fetchImpl;
73
+ this.pepper = input.pepper;
74
+ this.pwnedTimeoutMs = input.pwnedTimeoutMs ?? DEFAULT_PWNED_TIMEOUT_MS;
75
+ }
76
+ /** Há um verificador de hash legado configurado? */
77
+ hasLegacyVerifier() {
78
+ return typeof this.legacyVerifier === 'function';
79
+ }
80
+ /**
81
+ * Aplica o pepper corrente à senha em claro antes do hash. Sem pepper →
82
+ * retorna a senha inalterada (back-compat total).
83
+ */
84
+ applyCurrentPepper(plain) {
85
+ return applyCurrentPepper(plain, this.pepper);
86
+ }
87
+ /**
88
+ * Valida uma senha NOVA: política primeiro (barata, local), depois vazamento
89
+ * (rede, opcional, fail-safe). Lança {@link PasswordPolicyError} na 1ª falha.
90
+ *
91
+ * @param policyOverride - Política resolvida em runtime (via setting `password_policy`).
92
+ * Quando fornecida, sobrescreve os defaults da lib para esta chamada.
93
+ */
94
+ async assertAcceptable(plainPassword, policyOverride) {
95
+ const effectivePolicy = policyOverride
96
+ ? {
97
+ minLength: policyOverride.minLength ?? this.config.policy.minLength,
98
+ requireUppercase: policyOverride.requireUppercase ?? this.config.policy.requireUppercase,
99
+ requireLowercase: policyOverride.requireLowercase ?? this.config.policy.requireLowercase,
100
+ requireNumbers: policyOverride.requireNumbers ?? this.config.policy.requireNumbers,
101
+ requireSymbols: policyOverride.requireSymbols ?? this.config.policy.requireSymbols,
102
+ }
103
+ : this.config.policy;
104
+ const violation = checkPasswordPolicy(plainPassword, effectivePolicy);
105
+ if (violation) {
106
+ throw new PasswordPolicyError(violation, policyViolationParams(violation, effectivePolicy));
107
+ }
108
+ // Checagem offline de senhas comuns (case-insensitive, ANTES do HIBP).
109
+ // Default: blockCommon=true. Somente pula se explicitamente desligado.
110
+ const blockCommon = policyOverride?.blockCommon !== false;
111
+ if (blockCommon && isCommonPassword(plainPassword)) {
112
+ throw new PasswordPolicyError('password.common');
113
+ }
114
+ if (policyOverride?.checkPwned) {
115
+ const pwned = await isPasswordPwned(plainPassword, {
116
+ timeoutMs: this.pwnedTimeoutMs,
117
+ logger: this.logger,
118
+ fetchImpl: this.fetchImpl,
119
+ });
120
+ if (pwned)
121
+ throw new PasswordPolicyError('password.pwned');
122
+ }
123
+ }
124
+ /**
125
+ * Verifica `plainPassword` contra o `hashedPassword` armazenado, com suporte
126
+ * a pepper.
127
+ *
128
+ * Sequência:
129
+ * 1. Para cada pepper possível (corrente + antigos + sem pepper para legacy):
130
+ * a. `nativeVerify(hashed, peppered(plain))`. Se OK → checa `needsRehash`
131
+ * e devolve `{ ok: true, rehash }`. rehash=true quando pepper não é o
132
+ * corrente (re-hash com o corrente transparente).
133
+ * 2. Se nenhum pepper funcionou com native, tenta o `legacyVerifier` com
134
+ * `applyCurrentPepper(plain)` (e também sem pepper, para import de sistemas
135
+ * legados antes de pepperar).
136
+ * `true` → `{ ok: true, rehash: true }`;
137
+ * `false`/`null` → `{ ok: false, rehash: false }`.
138
+ *
139
+ * `nativeVerify`/`needsRehash` são injetados pelo store (vêm do model Lucid),
140
+ * mantendo este manager desacoplado do Lucid.
141
+ */
142
+ async verify(hashedPassword, plainPassword, hooks) {
143
+ const peppers = resolvePeppers(this.pepper);
144
+ const currentPepper = Array.isArray(this.pepper) ? this.pepper[0] : (this.pepper ?? '');
145
+ for (let i = 0; i < peppers.length; i++) {
146
+ const p = peppers[i];
147
+ const peppered = p ? applyPepper(plainPassword, p) : plainPassword;
148
+ let nativeOk = false;
149
+ try {
150
+ nativeOk = await hooks.nativeVerify(hashedPassword, peppered);
151
+ }
152
+ catch {
153
+ nativeOk = false;
154
+ }
155
+ if (nativeOk) {
156
+ // Se este não é o pepper corrente → re-hash obrigatório com o corrente.
157
+ const isCurrentPepper = (p === currentPepper) || (!p && !this.pepper);
158
+ let rehash = isCurrentPepper ? false : true;
159
+ if (!rehash) {
160
+ try {
161
+ rehash = hooks.needsRehash(hashedPassword);
162
+ }
163
+ catch {
164
+ rehash = false;
165
+ }
166
+ }
167
+ return { ok: true, rehash };
168
+ }
169
+ }
170
+ // Nenhum pepper funcionou com nativeVerify → tenta legacyVerifier.
171
+ if (this.legacyVerifier) {
172
+ // Tenta com o pepper corrente E sem pepper (para hashes de sistemas legados
173
+ // que ainda não tinham pepper).
174
+ const tryCandidates = this.pepper
175
+ ? [applyCurrentPepper(plainPassword, this.pepper), plainPassword]
176
+ : [plainPassword];
177
+ for (const candidate of tryCandidates) {
178
+ let legacy = null;
179
+ try {
180
+ legacy = await this.legacyVerifier(hashedPassword, candidate);
181
+ }
182
+ catch {
183
+ legacy = null;
184
+ }
185
+ if (legacy === true)
186
+ return { ok: true, rehash: true };
187
+ }
188
+ }
189
+ return { ok: false, rehash: false };
190
+ }
191
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Política de senha (shapes + checagens puras). Testável em isolamento.
3
+ * A política ativa é gerenciada via runtime setting `password_policy` em
4
+ * `auth_settings` (admin console / Admin API). Os defaults da lib ficam aqui.
5
+ */
6
+ /**
7
+ * Regras de complexidade de senha (shape interno — alinhado com o shape
8
+ * da runtime setting `password_policy` em `auth_settings`).
9
+ */
10
+ export interface PasswordPolicyInput {
11
+ /** Comprimento mínimo. Default: 8. */
12
+ minLength?: number;
13
+ /** Exige ao menos uma letra maiúscula. Default: false. */
14
+ requireUppercase?: boolean;
15
+ /** Exige ao menos uma letra minúscula. Default: false. */
16
+ requireLowercase?: boolean;
17
+ /** Exige ao menos um dígito. Default: false. */
18
+ requireNumbers?: boolean;
19
+ /** Exige ao menos um símbolo (não alfanumérico). Default: false. */
20
+ requireSymbols?: boolean;
21
+ }
22
+ /** Política resolvida (todos os campos presentes). */
23
+ export interface ResolvedPasswordPolicy {
24
+ minLength: number;
25
+ requireUppercase: boolean;
26
+ requireLowercase: boolean;
27
+ requireNumbers: boolean;
28
+ requireSymbols: boolean;
29
+ }
30
+ /**
31
+ * Checagem contra vazamentos (HaveIBeenPwned Range API, k-anonymity). Quando
32
+ * `true`, usa os defaults; um objeto permite ajustar o timeout. FAIL-SAFE: erro
33
+ * de rede/timeout/5xx NÃO bloqueia a senha (loga warning e permite).
34
+ */
35
+ export type CheckPwnedInput = boolean | {
36
+ timeoutMs?: number;
37
+ };
38
+ /** Config de senha resolvida, carregada pelo store/controllers. */
39
+ export interface ResolvedPasswordConfig {
40
+ policy: ResolvedPasswordPolicy;
41
+ checkPwned: {
42
+ enabled: boolean;
43
+ timeoutMs: number;
44
+ };
45
+ }
46
+ export declare const DEFAULT_PWNED_TIMEOUT_MS = 2000;
47
+ /**
48
+ * Chave i18n da regra de política violada (estável — os catálogos en/pt-BR
49
+ * carregam todas). `password.pwned` é a mensagem do vazamento.
50
+ */
51
+ export type PasswordPolicyViolation = 'password.policy.min_length' | 'password.policy.uppercase' | 'password.policy.lowercase' | 'password.policy.numbers' | 'password.policy.symbols';
52
+ export declare function resolvePasswordPolicy(input?: PasswordPolicyInput): ResolvedPasswordPolicy;
53
+ export declare function resolveCheckPwned(input?: CheckPwnedInput): {
54
+ enabled: boolean;
55
+ timeoutMs: number;
56
+ };
57
+ export declare function resolvePasswordConfig(input?: {
58
+ policy?: PasswordPolicyInput;
59
+ checkPwned?: CheckPwnedInput;
60
+ }): ResolvedPasswordConfig;
61
+ /**
62
+ * Aplica a política a uma senha em claro. Devolve a PRIMEIRA violação (chave
63
+ * i18n) ou `null` se a senha passa. Ordem estável: comprimento → maiúscula →
64
+ * minúscula → dígito → símbolo.
65
+ */
66
+ export declare function checkPasswordPolicy(password: string, policy: ResolvedPasswordPolicy): PasswordPolicyViolation | null;
67
+ /**
68
+ * Parâmetros para interpolar a mensagem i18n da violação (ex.: `{min}` no
69
+ * comprimento mínimo). Devolve `undefined` para regras sem parâmetro.
70
+ */
71
+ export declare function policyViolationParams(violation: PasswordPolicyViolation, policy: ResolvedPasswordPolicy): Record<string, string | number> | undefined;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Política de senha (shapes + checagens puras). Testável em isolamento.
3
+ * A política ativa é gerenciada via runtime setting `password_policy` em
4
+ * `auth_settings` (admin console / Admin API). Os defaults da lib ficam aqui.
5
+ */
6
+ export const DEFAULT_PWNED_TIMEOUT_MS = 2000;
7
+ export function resolvePasswordPolicy(input) {
8
+ return {
9
+ minLength: input?.minLength ?? 8,
10
+ requireUppercase: input?.requireUppercase ?? false,
11
+ requireLowercase: input?.requireLowercase ?? false,
12
+ requireNumbers: input?.requireNumbers ?? false,
13
+ requireSymbols: input?.requireSymbols ?? false,
14
+ };
15
+ }
16
+ export function resolveCheckPwned(input) {
17
+ if (!input)
18
+ return { enabled: false, timeoutMs: DEFAULT_PWNED_TIMEOUT_MS };
19
+ if (input === true)
20
+ return { enabled: true, timeoutMs: DEFAULT_PWNED_TIMEOUT_MS };
21
+ return { enabled: true, timeoutMs: input.timeoutMs ?? DEFAULT_PWNED_TIMEOUT_MS };
22
+ }
23
+ export function resolvePasswordConfig(input) {
24
+ return {
25
+ policy: resolvePasswordPolicy(input?.policy),
26
+ checkPwned: resolveCheckPwned(input?.checkPwned),
27
+ };
28
+ }
29
+ /**
30
+ * Aplica a política a uma senha em claro. Devolve a PRIMEIRA violação (chave
31
+ * i18n) ou `null` se a senha passa. Ordem estável: comprimento → maiúscula →
32
+ * minúscula → dígito → símbolo.
33
+ */
34
+ export function checkPasswordPolicy(password, policy) {
35
+ if (password.length < policy.minLength)
36
+ return 'password.policy.min_length';
37
+ if (policy.requireUppercase && !/[A-Z]/.test(password))
38
+ return 'password.policy.uppercase';
39
+ if (policy.requireLowercase && !/[a-z]/.test(password))
40
+ return 'password.policy.lowercase';
41
+ if (policy.requireNumbers && !/[0-9]/.test(password))
42
+ return 'password.policy.numbers';
43
+ if (policy.requireSymbols && !/[^A-Za-z0-9]/.test(password))
44
+ return 'password.policy.symbols';
45
+ return null;
46
+ }
47
+ /**
48
+ * Parâmetros para interpolar a mensagem i18n da violação (ex.: `{min}` no
49
+ * comprimento mínimo). Devolve `undefined` para regras sem parâmetro.
50
+ */
51
+ export function policyViolationParams(violation, policy) {
52
+ if (violation === 'password.policy.min_length')
53
+ return { min: policy.minLength };
54
+ return undefined;
55
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Checagem de senha vazada via HaveIBeenPwned Pwned Passwords (Range API), com
3
+ * k-anonymity: NUNCA enviamos a senha nem o hash completo — só os 5 primeiros
4
+ * hex chars do SHA-1, e procuramos o sufixo localmente na resposta.
5
+ *
6
+ * FAIL-SAFE por design: qualquer erro (rede, timeout, 5xx, parsing) resulta em
7
+ * "não vazada" (permite a senha) e loga um warning. A indisponibilidade do
8
+ * serviço externo NUNCA deve bloquear o usuário de definir uma senha.
9
+ */
10
+ /** Logger mínimo (subconjunto do logger do AdonisJS). */
11
+ export interface PwnedLogger {
12
+ warn(obj: unknown, msg?: string): void;
13
+ }
14
+ /**
15
+ * Cliente HTTP injetável (fetch nativo por default). Existe para testes: permite
16
+ * simular hit/miss/erro/timeout SEM rede. A assinatura espelha o `fetch` global.
17
+ */
18
+ export type FetchLike = (url: string, init?: {
19
+ signal?: AbortSignal;
20
+ headers?: Record<string, string>;
21
+ }) => Promise<{
22
+ ok: boolean;
23
+ status: number;
24
+ text(): Promise<string>;
25
+ }>;
26
+ /** Injeta um fetch fake para testes. `undefined` restaura o fetch nativo. */
27
+ export declare function __setFetchForTests(impl: FetchLike | undefined): void;
28
+ /**
29
+ * Retorna `true` se a senha aparece na base do HIBP, `false` caso contrário OU
30
+ * em qualquer falha (fail-safe). `timeoutMs` aborta a request.
31
+ */
32
+ export declare function isPasswordPwned(password: string, options?: {
33
+ timeoutMs: number;
34
+ logger?: PwnedLogger;
35
+ fetchImpl?: FetchLike;
36
+ }): Promise<boolean>;
@@ -0,0 +1,52 @@
1
+ import { createHash } from 'node:crypto';
2
+ let fetchImpl;
3
+ /** Injeta um fetch fake para testes. `undefined` restaura o fetch nativo. */
4
+ export function __setFetchForTests(impl) {
5
+ fetchImpl = impl;
6
+ }
7
+ function getFetch() {
8
+ if (fetchImpl)
9
+ return fetchImpl;
10
+ return globalThis.fetch;
11
+ }
12
+ const HIBP_RANGE_URL = 'https://api.pwnedpasswords.com/range/';
13
+ /**
14
+ * Retorna `true` se a senha aparece na base do HIBP, `false` caso contrário OU
15
+ * em qualquer falha (fail-safe). `timeoutMs` aborta a request.
16
+ */
17
+ export async function isPasswordPwned(password, options = {
18
+ timeoutMs: 2000,
19
+ }) {
20
+ const sha1 = createHash('sha1').update(password, 'utf8').digest('hex').toUpperCase();
21
+ const prefix = sha1.slice(0, 5);
22
+ const suffix = sha1.slice(5);
23
+ const doFetch = options.fetchImpl ?? getFetch();
24
+ const controller = new AbortController();
25
+ const timer = setTimeout(() => controller.abort(), options.timeoutMs);
26
+ try {
27
+ const res = await doFetch(`${HIBP_RANGE_URL}${prefix}`, {
28
+ signal: controller.signal,
29
+ // Add-Padding obscurece o tamanho da resposta (k-anonymity reforçado).
30
+ headers: { 'Add-Padding': 'true' },
31
+ });
32
+ if (!res.ok) {
33
+ options.logger?.warn({ status: res.status }, 'authkit: HIBP range API returned a non-OK status — skipping pwned check (fail-safe).');
34
+ return false;
35
+ }
36
+ const body = await res.text();
37
+ // Cada linha: "<SUFIXO>:<count>". Linhas de padding têm count 0 — ignoradas.
38
+ for (const line of body.split('\n')) {
39
+ const [candidate, countStr] = line.trim().split(':');
40
+ if (candidate === suffix && Number(countStr) > 0)
41
+ return true;
42
+ }
43
+ return false;
44
+ }
45
+ catch (error) {
46
+ options.logger?.warn({ err: error }, 'authkit: HIBP range API request failed (network/timeout) — skipping pwned check (fail-safe).');
47
+ return false;
48
+ }
49
+ finally {
50
+ clearTimeout(timer);
51
+ }
52
+ }
@@ -0,0 +1,6 @@
1
+ import type { PatStore } from './pat_store.js';
2
+ /**
3
+ * Implementação default do {@link PatStore} sobre um model Lucid composto de
4
+ * `withPersonalAccessToken()`. A coluna DB `user_id` é mapeada de `accountId`.
5
+ */
6
+ export declare function lucidPatStore(Model: any): PatStore;
@@ -0,0 +1,62 @@
1
+ import { DateTime } from 'luxon';
2
+ import { generatePatToken, hashPatToken } from './pat_tokens.js';
3
+ /**
4
+ * Implementação default do {@link PatStore} sobre um model Lucid composto de
5
+ * `withPersonalAccessToken()`. A coluna DB `user_id` é mapeada de `accountId`.
6
+ */
7
+ export function lucidPatStore(Model) {
8
+ const toRecord = (row) => ({
9
+ id: row.id,
10
+ name: row.name,
11
+ scopes: row.scopes ?? [],
12
+ audience: row.audience ?? null,
13
+ createdAt: row.createdAt ? row.createdAt.toISO() : '',
14
+ lastUsedAt: row.lastUsedAt ? row.lastUsedAt.toISO() : null,
15
+ expiresAt: row.expiresAt ? row.expiresAt.toISO() : null,
16
+ });
17
+ return {
18
+ async issue(input) {
19
+ const token = generatePatToken();
20
+ const row = await Model.create({
21
+ userId: input.accountId,
22
+ name: input.name,
23
+ tokenHash: hashPatToken(token),
24
+ scopes: input.scopes ?? [],
25
+ audience: input.audience ?? null,
26
+ expiresAt: input.expiresInDays
27
+ ? DateTime.now().plus({ days: input.expiresInDays })
28
+ : null,
29
+ });
30
+ return { token, pat: toRecord(row) };
31
+ },
32
+ async listForAccount(accountId) {
33
+ const rows = await Model.query()
34
+ .where('user_id', accountId)
35
+ .orderBy('created_at', 'desc');
36
+ return rows.map(toRecord);
37
+ },
38
+ async revoke(accountId, id) {
39
+ const row = await Model.query().where('id', id).where('user_id', accountId).first();
40
+ if (!row)
41
+ return false;
42
+ await row.delete();
43
+ return true;
44
+ },
45
+ async findActiveByToken(token) {
46
+ const hash = hashPatToken(token);
47
+ const row = await Model.query().where('token_hash', hash).first();
48
+ if (!row)
49
+ return null;
50
+ if (row.expiresAt && row.expiresAt < DateTime.now())
51
+ return null;
52
+ row.lastUsedAt = DateTime.now();
53
+ await row.save();
54
+ return {
55
+ accountId: row.userId,
56
+ scopes: row.scopes ?? [],
57
+ audience: row.audience ?? null,
58
+ exp: row.expiresAt ? Math.floor(row.expiresAt.toSeconds()) : null,
59
+ };
60
+ },
61
+ };
62
+ }
@@ -0,0 +1,31 @@
1
+ /** DTO seguro do PAT — sem o hash do token. */
2
+ export interface PatRecord {
3
+ id: string;
4
+ name: string;
5
+ scopes: string[];
6
+ audience: string | null;
7
+ createdAt: string;
8
+ lastUsedAt: string | null;
9
+ expiresAt: string | null;
10
+ }
11
+ export interface IssuePatInput {
12
+ accountId: string;
13
+ name: string;
14
+ scopes?: string[];
15
+ audience?: string | null;
16
+ expiresInDays?: number | null;
17
+ }
18
+ export interface PatStore {
19
+ issue(input: IssuePatInput): Promise<{
20
+ token: string;
21
+ pat: PatRecord;
22
+ }>;
23
+ listForAccount(accountId: string): Promise<PatRecord[]>;
24
+ revoke(accountId: string, id: string): Promise<boolean>;
25
+ findActiveByToken(token: string): Promise<{
26
+ accountId: string;
27
+ scopes: string[];
28
+ audience: string | null;
29
+ exp: number | null;
30
+ } | null>;
31
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ /** Gera um Personal Access Token opaco no formato `pat_<base64url>`. */
2
+ export declare function generatePatToken(): string;
3
+ /** SHA-256 (hex) do token — é o que se persiste; o token cru nunca é guardado. */
4
+ export declare function hashPatToken(token: string): string;