@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,306 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { DateTime } from 'luxon';
3
+ import { Scrypt } from '@adonisjs/core/hash/drivers/scrypt';
4
+ import { hasColumn } from './status_profile.js';
5
+ /** Prefixo do token de troca de e-mail (reaproveita a coluna emailVerificationToken). */
6
+ const EMAIL_CHANGE_PREFIX = 'ec:';
7
+ /** Prefixo do magic link (reaproveita as colunas de reset de senha). */
8
+ const MAGIC_LINK_PREFIX = 'ml:';
9
+ /**
10
+ * Hasher usado SOMENTE para a verificação "dummy" anti-enumeração (mesma
11
+ * instância/parâmetros do mixin withAuthUser). Não toca em hashes reais.
12
+ */
13
+ const dummyHasher = new Scrypt({});
14
+ /**
15
+ * Hash dummy pré-computado de uma senha aleatória (descartada). É um scrypt
16
+ * REAL com os mesmos parâmetros de custo dos hashes de conta — verificar contra
17
+ * ele gasta ~o mesmo tempo de CPU que verificar um hash legítimo.
18
+ *
19
+ * Promise resolvida UMA vez no boot do módulo; o caminho sem-row aguarda-a e
20
+ * roda `dummyHasher.verify` para igualar o timing do caminho com-row, mitigando
21
+ * account enumeration por timing no login (OWASP).
22
+ */
23
+ const dummyHashPromise = dummyHasher.make(randomBytes(32).toString('hex'));
24
+ /**
25
+ * Núcleo SEMPRE presente do {@link CoreAccountStore} sobre um model Lucid:
26
+ * identidade, cadastro, reset de senha, verificação de e-mail, administração
27
+ * (listagem paginada + roles globais) e o self-service de segurança
28
+ * ({@link AccountSecurityCapability}: trocar senha/e-mail).
29
+ */
30
+ export function buildCore(ctx) {
31
+ const { Model, toAccount } = ctx;
32
+ return {
33
+ async findById(id) {
34
+ const row = await Model.find(id);
35
+ return row ? toAccount(row) : null;
36
+ },
37
+ async findByEmail(email) {
38
+ const row = await Model.query().where('email', email).first();
39
+ return row ? toAccount(row) : null;
40
+ },
41
+ async verifyCredentials(email, password) {
42
+ const row = await Model.query().where('email', email).first();
43
+ if (!row) {
44
+ // Anti-enumeração por timing: e-mail inexistente roda uma verificação
45
+ // scrypt DUMMY (mesmo custo do caminho real) e descarta o resultado, de
46
+ // modo que com-row e sem-row gastem ~o mesmo tempo de CPU. Best-effort:
47
+ // qualquer erro aqui NÃO altera o retorno (segue null).
48
+ try {
49
+ const dummyHash = await dummyHashPromise;
50
+ await ctx.passwords.verify(dummyHash, password, {
51
+ nativeVerify: (hashed, plain) => dummyHasher.verify(hashed, plain),
52
+ needsRehash: () => false,
53
+ });
54
+ }
55
+ catch {
56
+ // ignora — o objetivo é só gastar o tempo equivalente.
57
+ }
58
+ return null;
59
+ }
60
+ const result = await ctx.passwords.verify(row.password, password, {
61
+ nativeVerify: (_hashed, plain) => row.verifyPassword(plain),
62
+ needsRehash: () => row.passwordNeedsRehash(),
63
+ });
64
+ if (!result.ok)
65
+ return null;
66
+ // Lazy rehash transparente (padrão Auth0/Clerk): senha confere mas o hash
67
+ // está em formato legado OU com parâmetros desatualizados → re-hasheia com o
68
+ // hasher atual e persiste. Best-effort: uma falha no rehash NÃO falha o login.
69
+ if (result.rehash) {
70
+ try {
71
+ row.password = password; // o @beforeSave do mixin re-hasheia
72
+ await row.save();
73
+ await ctx.audit?.record({ type: 'password.rehashed', accountId: row.id });
74
+ }
75
+ catch {
76
+ // ignora — o usuário já está autenticado; o rehash tentará de novo no próximo login.
77
+ }
78
+ }
79
+ return toAccount(row);
80
+ },
81
+ async create(input) {
82
+ // Aplica a política de senha (comprimento/complexidade + vazamento) à senha
83
+ // nova. Lança PasswordPolicyError quando viola — o controller traduz a chave.
84
+ await ctx.passwords.assertAcceptable(input.password);
85
+ // Aplica o pepper antes do hash (o @beforeSave do mixin hasheia o que receber).
86
+ const pepperedPassword = ctx.passwords.applyCurrentPepper(input.password);
87
+ const now = DateTime.now();
88
+ const row = await Model.create({
89
+ email: input.email,
90
+ password: pepperedPassword,
91
+ fullName: input.fullName ?? null,
92
+ globalRoles: input.globalRoles ?? [],
93
+ emailVerifiedAt: input.emailVerified ? now : null,
94
+ // Registra quando a senha foi definida (se a coluna existe).
95
+ ...(hasColumn(Model, 'passwordChangedAt') ? { passwordChangedAt: now } : {}),
96
+ });
97
+ return toAccount(row);
98
+ },
99
+ async importAccount(input) {
100
+ // Skip se o e-mail já existe (idempotência do import).
101
+ const existing = await Model.query().where('email', input.email).first();
102
+ if (existing)
103
+ return null;
104
+ // Cria com uma senha aleatória (que o @beforeSave hasheia) só para satisfazer
105
+ // a coluna NOT NULL; em seguida sobrescreve com o hash de ORIGEM via query
106
+ // builder (bypassa o @beforeSave, então o hash entra COMO ESTÁ — o lazy rehash
107
+ // no 1º login migra para o hasher atual). NÃO aplica a política de senha.
108
+ const row = await Model.create({
109
+ email: input.email,
110
+ password: randomBytes(24).toString('hex'),
111
+ fullName: input.fullName ?? null,
112
+ globalRoles: input.globalRoles ?? [],
113
+ emailVerifiedAt: input.emailVerified ? DateTime.now() : null,
114
+ });
115
+ if (input.passwordHash) {
116
+ await Model.query().where('id', row.id).update({ password: input.passwordHash });
117
+ row.password = input.passwordHash;
118
+ // Limpa o dirty para que um save futuro não re-hasheie este hash de origem.
119
+ row.$attributes.password = input.passwordHash;
120
+ }
121
+ return toAccount(row);
122
+ },
123
+ async issuePasswordResetToken(email) {
124
+ const row = await Model.query().where('email', email).first();
125
+ if (!row)
126
+ return null;
127
+ const token = randomBytes(32).toString('hex');
128
+ row.passwordResetToken = token;
129
+ row.passwordResetExpiresAt = DateTime.now().plus({ hours: 1 });
130
+ await row.save();
131
+ return { token, account: toAccount(row) };
132
+ },
133
+ async consumePasswordResetToken(token, newPassword) {
134
+ // Magic links (`ml:`) NÃO são tokens de reset de senha — só o fluxo de
135
+ // consumeMagicLinkToken pode consumi-los (não trocam senha).
136
+ if (token.startsWith(MAGIC_LINK_PREFIX))
137
+ return false;
138
+ const row = await Model.query().where('passwordResetToken', token).first();
139
+ if (!row)
140
+ return false;
141
+ if (!row.passwordResetExpiresAt || row.passwordResetExpiresAt < DateTime.now())
142
+ return false;
143
+ // Política de senha aplicada também no reset (lança PasswordPolicyError).
144
+ await ctx.passwords.assertAcceptable(newPassword);
145
+ // Aplica o pepper antes do hash.
146
+ row.password = ctx.passwords.applyCurrentPepper(newPassword);
147
+ row.passwordResetToken = null;
148
+ row.passwordResetExpiresAt = null;
149
+ // Atualiza o timestamp da última troca (se a coluna existe).
150
+ if (hasColumn(Model, 'passwordChangedAt')) {
151
+ row.passwordChangedAt = DateTime.now();
152
+ }
153
+ await row.save();
154
+ return true;
155
+ },
156
+ // ----- Magic link (login passwordless) -----
157
+ async issueMagicLinkToken(email) {
158
+ const row = await Model.query().where('email', email).first();
159
+ if (!row)
160
+ return null;
161
+ // Token `ml:<random>` nas colunas de reset (sem migração); o prefixo o
162
+ // distingue de um token de reset de senha. Curta duração (15 min).
163
+ const token = `${MAGIC_LINK_PREFIX}${randomBytes(32).toString('hex')}`;
164
+ row.passwordResetToken = token;
165
+ row.passwordResetExpiresAt = DateTime.now().plus({ minutes: 15 });
166
+ await row.save();
167
+ return { token, account: toAccount(row) };
168
+ },
169
+ async consumeMagicLinkToken(token) {
170
+ if (!token || !token.startsWith(MAGIC_LINK_PREFIX))
171
+ return null;
172
+ const row = await Model.query().where('passwordResetToken', token).first();
173
+ if (!row)
174
+ return null;
175
+ if (!row.passwordResetExpiresAt || row.passwordResetExpiresAt < DateTime.now())
176
+ return null;
177
+ // Single-use: limpa o token (NÃO altera a senha).
178
+ row.passwordResetToken = null;
179
+ row.passwordResetExpiresAt = null;
180
+ await row.save();
181
+ return toAccount(row);
182
+ },
183
+ async issueEmailVerificationToken(email) {
184
+ const row = await Model.query().where('email', email).first();
185
+ if (!row)
186
+ return null;
187
+ const token = randomBytes(32).toString('hex');
188
+ row.emailVerificationToken = token;
189
+ await row.save();
190
+ return { token, account: toAccount(row) };
191
+ },
192
+ async consumeEmailVerificationToken(token) {
193
+ if (!token)
194
+ return false;
195
+ // Tokens de troca de e-mail (`ec:`) NÃO são verificações de cadastro — só o
196
+ // fluxo de confirmEmailChange pode consumi-los.
197
+ if (token.startsWith(EMAIL_CHANGE_PREFIX))
198
+ return false;
199
+ const row = await Model.query().where('emailVerificationToken', token).first();
200
+ if (!row)
201
+ return false;
202
+ row.emailVerifiedAt = DateTime.now();
203
+ row.emailVerificationToken = null;
204
+ await row.save();
205
+ return true;
206
+ },
207
+ // ----- Administração (console admin) -----
208
+ async listAccounts(params) {
209
+ const page = Math.max(1, params.page ?? 1);
210
+ const limit = Math.max(1, params.limit ?? 20);
211
+ const search = params.search?.trim();
212
+ const base = () => {
213
+ const q = Model.query();
214
+ // Filtro por e-mail (substring, case-insensitive). `whereILike` cai no LIKE
215
+ // no sqlite (case-insensitive por default p/ ASCII), e em ILIKE no Postgres.
216
+ if (search)
217
+ q.whereILike('email', `%${search}%`);
218
+ return q;
219
+ };
220
+ const countResult = await base().count('* as total');
221
+ // O shape do count varia por dialeto; lê de $extras.total (Lucid).
222
+ const total = Number(countResult[0]?.$extras?.total ?? 0);
223
+ const rows = await base()
224
+ .orderBy('email', 'asc')
225
+ .offset((page - 1) * limit)
226
+ .limit(limit);
227
+ return { data: rows.map(toAccount), total };
228
+ },
229
+ async setGlobalRoles(accountId, roles) {
230
+ const row = await Model.find(accountId);
231
+ if (!row)
232
+ return;
233
+ // A coluna `globalRoles` é serializada como JSON pelo mixin withAuthUser.
234
+ row.globalRoles = roles;
235
+ await row.save();
236
+ },
237
+ // ----- Self-service de segurança (console de conta) -----
238
+ async changePassword(accountId, newPassword) {
239
+ const row = await Model.find(accountId);
240
+ if (!row)
241
+ return false;
242
+ // Política de senha aplicada na troca (lança PasswordPolicyError).
243
+ await ctx.passwords.assertAcceptable(newPassword);
244
+ // O hash acontece no @beforeSave do mixin withAuthUser ao detectar $dirty.password.
245
+ // Aplica o pepper antes do hash.
246
+ const pepperedNew = ctx.passwords.applyCurrentPepper(newPassword);
247
+ row.password = pepperedNew;
248
+ // Atualiza o timestamp da última troca (se a coluna existe).
249
+ if (hasColumn(Model, 'passwordChangedAt')) {
250
+ row.passwordChangedAt = DateTime.now();
251
+ }
252
+ await row.save();
253
+ return true;
254
+ },
255
+ async requestEmailChange(accountId, newEmail) {
256
+ const row = await Model.find(accountId);
257
+ if (!row)
258
+ return null;
259
+ // Não permite tomar um e-mail já usado por OUTRA conta.
260
+ const taken = await Model.query().where('email', newEmail).first();
261
+ if (taken && taken.id !== row.id)
262
+ return null;
263
+ // Token = `ec:<base64url(newEmail)>:<random>`. Reaproveita a coluna
264
+ // emailVerificationToken (sem migração nova); o prefixo `ec:` distingue do
265
+ // token de verificação de cadastro. O e-mail viaja codificado no próprio
266
+ // token, então não precisamos de coluna extra para o "pending email".
267
+ const encodedEmail = Buffer.from(newEmail, 'utf8').toString('base64url');
268
+ const token = `${EMAIL_CHANGE_PREFIX}${encodedEmail}:${randomBytes(24).toString('hex')}`;
269
+ row.emailVerificationToken = token;
270
+ await row.save();
271
+ return { token, account: toAccount(row), newEmail };
272
+ },
273
+ async confirmEmailChange(token) {
274
+ if (!token || !token.startsWith(EMAIL_CHANGE_PREFIX))
275
+ return { ok: false };
276
+ const parts = token.split(':');
277
+ // Forma esperada: ['ec', '<b64email>', '<random>']
278
+ if (parts.length !== 3)
279
+ return { ok: false };
280
+ let newEmail;
281
+ try {
282
+ newEmail = Buffer.from(parts[1], 'base64url').toString('utf8');
283
+ }
284
+ catch {
285
+ return { ok: false };
286
+ }
287
+ if (!newEmail)
288
+ return { ok: false };
289
+ const row = await Model.query().where('emailVerificationToken', token).first();
290
+ if (!row)
291
+ return { ok: false };
292
+ // Defesa contra corrida: o e-mail pode ter sido tomado entre o pedido e a
293
+ // confirmação por outra conta.
294
+ const taken = await Model.query().where('email', newEmail).first();
295
+ if (taken && taken.id !== row.id)
296
+ return { ok: false };
297
+ // Captura o e-mail antigo ANTES de sobrescrever (para notificações de segurança).
298
+ const oldEmail = row.email;
299
+ row.email = newEmail;
300
+ row.emailVerifiedAt = DateTime.now();
301
+ row.emailVerificationToken = null;
302
+ await row.save();
303
+ return { ok: true, account: toAccount(row), oldEmail, newEmail };
304
+ },
305
+ };
306
+ }
@@ -0,0 +1,15 @@
1
+ import type { MfaCapability } from '../account_store.js';
2
+ import { type LucidStoreContext } from './shared.js';
3
+ /**
4
+ * Capacidade de MFA / TOTP — LIB-OWNED.
5
+ *
6
+ * O estado de MFA (`totp_secret`, `mfa_enabled_at`, `recovery_codes`,
7
+ * `last_totp_step`) vive numa tabela PRÓPRIA auto-gerida `auth_mfa` (criada pelo
8
+ * {@link ensureAuthkitSchema}), keyed por `account_id`. O host NÃO precisa migrar
9
+ * nada — `withMfa()` continua componível no model mas não declara mais colunas.
10
+ *
11
+ * Acesso ao banco via a CONEXÃO do próprio model (`Model.query().client`), a mesma
12
+ * usada pelo restante do store. O `email` (para o keyuri/QR) continua vindo do
13
+ * model principal — só o ESTADO de MFA migrou para `auth_mfa`.
14
+ */
15
+ export declare function buildMfa(ctx: LucidStoreContext): MfaCapability;
@@ -0,0 +1,108 @@
1
+ import { authenticator } from 'otplib';
2
+ import { generateRecoveryCode, hashesEqual, sha256, buildMfaStateRepo, } from './shared.js';
3
+ /**
4
+ * Capacidade de MFA / TOTP — LIB-OWNED.
5
+ *
6
+ * O estado de MFA (`totp_secret`, `mfa_enabled_at`, `recovery_codes`,
7
+ * `last_totp_step`) vive numa tabela PRÓPRIA auto-gerida `auth_mfa` (criada pelo
8
+ * {@link ensureAuthkitSchema}), keyed por `account_id`. O host NÃO precisa migrar
9
+ * nada — `withMfa()` continua componível no model mas não declara mais colunas.
10
+ *
11
+ * Acesso ao banco via a CONEXÃO do próprio model (`Model.query().client`), a mesma
12
+ * usada pelo restante do store. O `email` (para o keyuri/QR) continua vindo do
13
+ * model principal — só o ESTADO de MFA migrou para `auth_mfa`.
14
+ */
15
+ export function buildMfa(ctx) {
16
+ const { Model, mfaIssuer, recoveryCodeCount, sealSecret, openSecret } = ctx;
17
+ const repo = buildMfaStateRepo(Model);
18
+ return {
19
+ async getMfaState(accountId) {
20
+ const state = await repo.read(accountId);
21
+ // `enabledAt` (epoch ms) habilita o trusted-device check: um cookie de
22
+ // confiança emitido ANTES deste instante é inválido (re-enrolar revoga).
23
+ return { enabled: !!state?.mfaEnabledAt, enabledAt: state?.mfaEnabledAt ?? null };
24
+ },
25
+ async startTotpEnrollment(accountId) {
26
+ // O email/QR vem do model principal; só o ESTADO de MFA vive em auth_mfa.
27
+ const row = await Model.find(accountId);
28
+ if (!row)
29
+ return null;
30
+ const secret = authenticator.generateSecret();
31
+ // Segredo PENDENTE: armazenado (encriptado em repouso) mas mfaEnabledAt continua null.
32
+ // Re-enrollment: zera o anti-replay para o NOVO segredo (o histórico de steps
33
+ // do segredo antigo não se aplica ao novo) e limpa recovery codes pendentes.
34
+ await repo.upsert(accountId, {
35
+ totpSecret: sealSecret(secret),
36
+ mfaEnabledAt: null,
37
+ recoveryCodes: null,
38
+ lastTotpStep: null,
39
+ });
40
+ const otpauthUri = authenticator.keyuri(row.email, mfaIssuer, secret);
41
+ return { secret, otpauthUri };
42
+ },
43
+ async confirmTotpEnrollment(accountId, code) {
44
+ const state = await repo.read(accountId);
45
+ if (!state || !state.totpSecret)
46
+ return { ok: false };
47
+ const secret = openSecret(state.totpSecret);
48
+ if (!secret)
49
+ return { ok: false };
50
+ // Só confirma a partir de um segredo pendente (não re-confirma um já ativo).
51
+ const valid = authenticator.verify({ token: String(code ?? ''), secret });
52
+ if (!valid)
53
+ return { ok: false };
54
+ const codes = Array.from({ length: recoveryCodeCount }, () => generateRecoveryCode());
55
+ await repo.upsert(accountId, {
56
+ mfaEnabledAt: Date.now(),
57
+ recoveryCodes: codes.map(sha256),
58
+ });
59
+ return { ok: true, recoveryCodes: codes };
60
+ },
61
+ async verifyTotp(accountId, code) {
62
+ const state = await repo.read(accountId);
63
+ if (!state || !state.mfaEnabledAt || !state.totpSecret)
64
+ return false;
65
+ const secret = openSecret(state.totpSecret);
66
+ if (!secret)
67
+ return false;
68
+ const token = String(code ?? '');
69
+ // M3 (anti-replay): `checkDelta` retorna o offset (delta) da janela onde o
70
+ // token bate, ou null se inválido. Convertemos o delta no índice ABSOLUTO
71
+ // da janela (`step`) usando o epoch/period correntes do otplib:
72
+ // stepAtual = floor(epochSegundos / period)
73
+ // stepDoToken = stepAtual + delta
74
+ const delta = authenticator.checkDelta(token, secret);
75
+ if (delta === null)
76
+ return false;
77
+ const opts = authenticator.allOptions();
78
+ // `epoch` vem em ms; `step` (period) em segundos. Default do otplib: epoch=now, step=30.
79
+ const period = opts.step || 30;
80
+ const currentStep = Math.floor(opts.epoch / 1000 / period);
81
+ const tokenStep = currentStep + delta;
82
+ // Rejeita replay: se este step já foi aceito (ou um posterior), nega. Isso
83
+ // impede reusar o MESMO código dentro da janela de validade (~30s) e também
84
+ // qualquer código de um step já consumido.
85
+ const last = typeof state.lastTotpStep === 'number' ? state.lastTotpStep : null;
86
+ if (last !== null && tokenStep <= last)
87
+ return false;
88
+ // Sucesso: persiste o step aceito para barrar o próximo replay.
89
+ await repo.upsert(accountId, { lastTotpStep: tokenStep });
90
+ return true;
91
+ },
92
+ async consumeRecoveryCode(accountId, code) {
93
+ const state = await repo.read(accountId);
94
+ if (!state || !state.mfaEnabledAt || !Array.isArray(state.recoveryCodes))
95
+ return false;
96
+ const target = sha256(String(code ?? '').trim());
97
+ const remaining = state.recoveryCodes.filter((h) => !hashesEqual(h, target));
98
+ if (remaining.length === state.recoveryCodes.length)
99
+ return false; // nada casou
100
+ await repo.upsert(accountId, { recoveryCodes: remaining });
101
+ return true;
102
+ },
103
+ async disableMfa(accountId) {
104
+ // Limpa todo o estado de MFA. Inclui o anti-replay: um futuro re-enroll começa do zero.
105
+ await repo.clear(accountId);
106
+ },
107
+ };
108
+ }
@@ -0,0 +1,13 @@
1
+ import type { OrganizationsCapability } from '../account_store.js';
2
+ /**
3
+ * Contexto mínimo para o builder de organizations. Recebe os três models direto
4
+ * (já construídos pelo lucidAccountStore após o hasTable probing).
5
+ */
6
+ export interface OrgStoreContext {
7
+ OrgModel: any;
8
+ MemberModel: any;
9
+ InvitationModel: any;
10
+ /** Mapa accountId → email, para validar aceitação de convite. */
11
+ findAccountEmail: (accountId: string) => Promise<string | null>;
12
+ }
13
+ export declare function buildOrganizations(ctx: OrgStoreContext): OrganizationsCapability;