@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,130 @@
1
+ import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
2
+ export const sha256 = (value) => createHash('sha256').update(value).digest('hex');
3
+ /** Recovery code legível: 10 chars hex em duas metades (ex.: a1b2c-3d4e5). */
4
+ export function generateRecoveryCode() {
5
+ const raw = randomBytes(5).toString('hex');
6
+ return `${raw.slice(0, 5)}-${raw.slice(5, 10)}`;
7
+ }
8
+ /** Comparação de hashes hex resistente a timing. */
9
+ export function hashesEqual(a, b) {
10
+ const ba = Buffer.from(a);
11
+ const bb = Buffer.from(b);
12
+ if (ba.length !== bb.length)
13
+ return false;
14
+ return timingSafeEqual(ba, bb);
15
+ }
16
+ /**
17
+ * Indica se o model Lucid tem sua tabela registrada no adapter do DB (runtime probe).
18
+ * Usado para detectar tabelas opcionais como auth_organizations/members/invitations.
19
+ * Mais robusto do que checar colunas: detecta a presença da tabela inteira.
20
+ * Em testes, as tabelas existem se foram criadas na migration do teste.
21
+ */
22
+ export async function hasTable(db, tableName) {
23
+ try {
24
+ return await db.connection().schema.hasTable(tableName);
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ /**
31
+ * Repositório do estado de MFA na tabela LIB-OWNED `auth_mfa`, keyed por
32
+ * `account_id`. Acessa o banco pela CONEXÃO do próprio model (`Model.query().client`),
33
+ * a mesma usada pelo restante do store — sem exigir migration no host.
34
+ *
35
+ * O `upsert` é portável (sqlite + pg sem UPSERT nativo): tenta UPDATE pela PK;
36
+ * se não afetou nenhuma linha, faz INSERT. `recovery_codes` é serializado como
37
+ * JSON (string) na escrita e desserializado na leitura (aceita tanto string —
38
+ * sqlite/text — quanto array já parseado — pg jsonb).
39
+ */
40
+ export function buildMfaStateRepo(Model) {
41
+ const TABLE = 'auth_mfa';
42
+ /** QueryClient ligado à conexão do model (equivale ao `db` do password_history). */
43
+ function client() {
44
+ return Model.query().client;
45
+ }
46
+ /** Normaliza `recovery_codes` vindo do banco (json string OU array já parseado). */
47
+ function parseRecoveryCodes(raw) {
48
+ if (raw === null || raw === undefined)
49
+ return null;
50
+ if (Array.isArray(raw))
51
+ return raw;
52
+ if (typeof raw === 'string') {
53
+ try {
54
+ const parsed = JSON.parse(raw);
55
+ return Array.isArray(parsed) ? parsed : null;
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+ /** Converte o valor de `mfa_enabled_at` do banco em epoch ms (ou null). */
64
+ function toEpochMs(raw) {
65
+ if (raw === null || raw === undefined)
66
+ return null;
67
+ if (raw instanceof Date)
68
+ return raw.getTime();
69
+ if (typeof raw === 'number')
70
+ return raw;
71
+ if (typeof raw === 'string') {
72
+ const t = new Date(raw).getTime();
73
+ return Number.isNaN(t) ? null : t;
74
+ }
75
+ // Luxon DateTime (defensivo) — alguns clients podem hidratar assim.
76
+ if (raw && typeof raw.toMillis === 'function')
77
+ return raw.toMillis();
78
+ return null;
79
+ }
80
+ return {
81
+ /** Lê o estado de MFA da conta; null se não há linha em `auth_mfa`. */
82
+ async read(accountId) {
83
+ const row = await client().from(TABLE).where('account_id', accountId).first();
84
+ if (!row)
85
+ return null;
86
+ return {
87
+ totpSecret: row.totp_secret ?? null,
88
+ mfaEnabledAt: toEpochMs(row.mfa_enabled_at),
89
+ recoveryCodes: parseRecoveryCodes(row.recovery_codes),
90
+ lastTotpStep: row.last_totp_step === null || row.last_totp_step === undefined
91
+ ? null
92
+ : Number(row.last_totp_step),
93
+ };
94
+ },
95
+ /**
96
+ * Upsert parcial: cria a linha se não existir, senão atualiza apenas os campos
97
+ * presentes no patch (campos ausentes preservados). Portável (sqlite + pg).
98
+ */
99
+ async upsert(accountId, patch) {
100
+ const update = {};
101
+ if ('totpSecret' in patch)
102
+ update.totp_secret = patch.totpSecret ?? null;
103
+ if ('mfaEnabledAt' in patch) {
104
+ update.mfa_enabled_at =
105
+ patch.mfaEnabledAt === null || patch.mfaEnabledAt === undefined
106
+ ? null
107
+ : new Date(patch.mfaEnabledAt);
108
+ }
109
+ if ('recoveryCodes' in patch) {
110
+ update.recovery_codes =
111
+ patch.recoveryCodes === null || patch.recoveryCodes === undefined
112
+ ? null
113
+ : JSON.stringify(patch.recoveryCodes);
114
+ }
115
+ if ('lastTotpStep' in patch)
116
+ update.last_totp_step = patch.lastTotpStep ?? null;
117
+ const affected = await client().from(TABLE).where('account_id', accountId).update(update);
118
+ // knex update retorna o nº de linhas afetadas (0 = linha ainda não existe).
119
+ if (!affected) {
120
+ await client()
121
+ .table(TABLE)
122
+ .insert({ account_id: accountId, ...update });
123
+ }
124
+ },
125
+ /** Remove o estado de MFA da conta (disable / reset total). No-op se ausente. */
126
+ async clear(accountId) {
127
+ await client().from(TABLE).where('account_id', accountId).delete();
128
+ },
129
+ };
130
+ }
@@ -0,0 +1,34 @@
1
+ import type { AccountDeletionCapability, AccountStatusCapability, EmailVerificationStatusCapability, ProfileCapability } from '../account_store.js';
2
+ import type { LucidStoreContext } from './shared.js';
3
+ /**
4
+ * Indica se o model declara uma coluna (pela propriedade do model, ex.: `disabledAt`).
5
+ * Lucid expõe as colunas em `$columnsDefinitions` (Map de propertyName → definição).
6
+ * Usado para montar as capacidades opcionais SÓ quando a coluna existe — assim o
7
+ * store degrada graciosamente (capacidade ausente) em models que não têm a coluna.
8
+ */
9
+ export declare function hasColumn(Model: any, property: string): boolean;
10
+ /**
11
+ * Status da conta (habilitar/desabilitar) sobre a coluna `disabled_at`
12
+ * (propriedade `disabledAt`) do model. Só deve ser montado quando a coluna existe
13
+ * ({@link hasColumn}).
14
+ */
15
+ export declare function buildStatus(ctx: LucidStoreContext): AccountStatusCapability;
16
+ /**
17
+ * Edição de perfil (nome/avatar) sobre as colunas `full_name`/`avatar_url` do
18
+ * model. Grava apenas as colunas que existirem. Só deve ser montado quando ao
19
+ * menos uma das colunas existe.
20
+ */
21
+ export declare function buildProfile(ctx: LucidStoreContext): ProfileCapability;
22
+ /**
23
+ * Estado de verificação de e-mail (leitura) sobre a coluna `email_verified_at`
24
+ * (propriedade `emailVerifiedAt`) do model. Só deve ser montado quando a coluna
25
+ * existe ({@link hasColumn}) — caso contrário a capacidade fica ausente e features
26
+ * como `requireVerifiedEmail` degradam (não bloqueiam).
27
+ */
28
+ export declare function buildEmailVerificationStatus(ctx: LucidStoreContext): EmailVerificationStatusCapability;
29
+ /**
30
+ * Deleção (hard delete) da linha da conta. Sempre disponível num model Lucid
31
+ * (qualquer model pode deletar). Apenas remove a própria conta — o cascade dos
32
+ * demais artefatos é orquestrado pelo `accountDeletionService` no host.
33
+ */
34
+ export declare function buildDeletion(ctx: LucidStoreContext): AccountDeletionCapability;
@@ -0,0 +1,100 @@
1
+ import { DateTime } from 'luxon';
2
+ /**
3
+ * Indica se o model declara uma coluna (pela propriedade do model, ex.: `disabledAt`).
4
+ * Lucid expõe as colunas em `$columnsDefinitions` (Map de propertyName → definição).
5
+ * Usado para montar as capacidades opcionais SÓ quando a coluna existe — assim o
6
+ * store degrada graciosamente (capacidade ausente) em models que não têm a coluna.
7
+ */
8
+ export function hasColumn(Model, property) {
9
+ const defs = Model?.$columnsDefinitions;
10
+ if (!defs || typeof defs.has !== 'function')
11
+ return false;
12
+ return defs.has(property);
13
+ }
14
+ /**
15
+ * Status da conta (habilitar/desabilitar) sobre a coluna `disabled_at`
16
+ * (propriedade `disabledAt`) do model. Só deve ser montado quando a coluna existe
17
+ * ({@link hasColumn}).
18
+ */
19
+ export function buildStatus(ctx) {
20
+ const { Model } = ctx;
21
+ return {
22
+ async disableAccount(accountId) {
23
+ const row = await Model.find(accountId);
24
+ if (!row)
25
+ return;
26
+ row.disabledAt = DateTime.now();
27
+ await row.save();
28
+ },
29
+ async enableAccount(accountId) {
30
+ const row = await Model.find(accountId);
31
+ if (!row)
32
+ return;
33
+ row.disabledAt = null;
34
+ await row.save();
35
+ },
36
+ async isDisabled(accountId) {
37
+ const row = await Model.find(accountId);
38
+ if (!row)
39
+ return false;
40
+ return row.disabledAt !== null && row.disabledAt !== undefined;
41
+ },
42
+ };
43
+ }
44
+ /**
45
+ * Edição de perfil (nome/avatar) sobre as colunas `full_name`/`avatar_url` do
46
+ * model. Grava apenas as colunas que existirem. Só deve ser montado quando ao
47
+ * menos uma das colunas existe.
48
+ */
49
+ export function buildProfile(ctx) {
50
+ const { Model, toAccount } = ctx;
51
+ const canName = hasColumn(Model, 'fullName');
52
+ const canAvatar = hasColumn(Model, 'avatarUrl');
53
+ return {
54
+ async updateProfile(accountId, patch) {
55
+ const row = await Model.find(accountId);
56
+ if (!row)
57
+ return null;
58
+ if (canName && patch.name !== undefined)
59
+ row.fullName = patch.name;
60
+ if (canAvatar && patch.avatarUrl !== undefined)
61
+ row.avatarUrl = patch.avatarUrl;
62
+ await row.save();
63
+ return toAccount(row);
64
+ },
65
+ };
66
+ }
67
+ /**
68
+ * Estado de verificação de e-mail (leitura) sobre a coluna `email_verified_at`
69
+ * (propriedade `emailVerifiedAt`) do model. Só deve ser montado quando a coluna
70
+ * existe ({@link hasColumn}) — caso contrário a capacidade fica ausente e features
71
+ * como `requireVerifiedEmail` degradam (não bloqueiam).
72
+ */
73
+ export function buildEmailVerificationStatus(ctx) {
74
+ const { Model } = ctx;
75
+ return {
76
+ async isEmailVerified(accountId) {
77
+ const row = await Model.find(accountId);
78
+ if (!row)
79
+ return false;
80
+ return row.emailVerifiedAt !== null && row.emailVerifiedAt !== undefined;
81
+ },
82
+ };
83
+ }
84
+ /**
85
+ * Deleção (hard delete) da linha da conta. Sempre disponível num model Lucid
86
+ * (qualquer model pode deletar). Apenas remove a própria conta — o cascade dos
87
+ * demais artefatos é orquestrado pelo `accountDeletionService` no host.
88
+ */
89
+ export function buildDeletion(ctx) {
90
+ const { Model } = ctx;
91
+ return {
92
+ async deleteAccount(accountId) {
93
+ const row = await Model.find(accountId);
94
+ if (!row)
95
+ return false;
96
+ await row.delete();
97
+ return true;
98
+ },
99
+ };
100
+ }
@@ -0,0 +1,8 @@
1
+ import type { WebauthnCapability } from '../account_store.js';
2
+ import { type LucidStoreContext, type ResolvedRp, type WebauthnCeremonies } from './shared.js';
3
+ /**
4
+ * Capacidade de passkeys / WebAuthn (2º fator alternativo ao TOTP). Só é montada
5
+ * quando o `webauthnCredentialModel` é fornecido — ausente, a capacidade inteira
6
+ * fica ABSENTE do store (a UI esconde a seção de passkeys).
7
+ */
8
+ export declare function buildWebauthn(ctx: LucidStoreContext, Credential: any, webauthn: ResolvedRp, ceremonies: WebauthnCeremonies): WebauthnCapability;
@@ -0,0 +1,140 @@
1
+ import { buildMfaStateRepo, } from './shared.js';
2
+ /**
3
+ * Capacidade de passkeys / WebAuthn (2º fator alternativo ao TOTP). Só é montada
4
+ * quando o `webauthnCredentialModel` é fornecido — ausente, a capacidade inteira
5
+ * fica ABSENTE do store (a UI esconde a seção de passkeys).
6
+ */
7
+ export function buildWebauthn(ctx, Credential, webauthn, ceremonies) {
8
+ const { Model } = ctx;
9
+ // Estado de MFA é LIB-OWNED (tabela `auth_mfa`): registrar uma passkey habilita
10
+ // o MFA gravando `mfa_enabled_at` em `auth_mfa`, não numa coluna do model.
11
+ const mfaState = buildMfaStateRepo(Model);
12
+ return {
13
+ async generatePasskeyRegistrationOptions(accountId) {
14
+ const row = await Model.find(accountId);
15
+ if (!row)
16
+ return null;
17
+ const existing = await Credential.query().where('accountId', accountId);
18
+ const options = await ceremonies.generateRegistrationOptions({
19
+ rpName: webauthn.rpName,
20
+ rpID: webauthn.rpId,
21
+ userName: row.email,
22
+ userDisplayName: row.fullName ?? row.email,
23
+ // Não pede attestation (privacidade); confia na verificação local.
24
+ attestationType: 'none',
25
+ // Evita registrar a mesma credencial duas vezes.
26
+ excludeCredentials: existing.map((c) => ({
27
+ id: c.id,
28
+ transports: (c.transports ?? undefined),
29
+ })),
30
+ authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred' },
31
+ });
32
+ return {
33
+ options: options,
34
+ challenge: options.challenge,
35
+ };
36
+ },
37
+ async verifyPasskeyRegistration(accountId, response, expectedChallenge) {
38
+ const row = await Model.find(accountId);
39
+ if (!row)
40
+ return false;
41
+ let verification;
42
+ try {
43
+ verification = await ceremonies.verifyRegistrationResponse({
44
+ response: response,
45
+ expectedChallenge,
46
+ expectedOrigin: webauthn.origin,
47
+ expectedRPID: webauthn.rpId,
48
+ });
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ if (!verification.verified || !verification.registrationInfo)
54
+ return false;
55
+ const { credential } = verification.registrationInfo;
56
+ // publicKey vem como Uint8Array → armazenamos como base64url (texto).
57
+ const publicKey = Buffer.from(credential.publicKey).toString('base64url');
58
+ await Credential.create({
59
+ id: credential.id,
60
+ accountId,
61
+ publicKey,
62
+ counter: credential.counter,
63
+ transports: credential.transports ?? null,
64
+ label: null,
65
+ });
66
+ // Registrar uma passkey também habilita o MFA (2º fator presente). O estado
67
+ // vive em `auth_mfa`: só seta `mfa_enabled_at` se ainda não estiver habilitado
68
+ // (preserva o instante do enrollment original — importante p/ trusted-device).
69
+ const current = await mfaState.read(accountId);
70
+ if (!current?.mfaEnabledAt) {
71
+ await mfaState.upsert(accountId, { mfaEnabledAt: Date.now() });
72
+ }
73
+ return true;
74
+ },
75
+ async generatePasskeyAuthenticationOptions(accountId) {
76
+ const creds = await Credential.query().where('accountId', accountId);
77
+ if (creds.length === 0)
78
+ return null;
79
+ const options = await ceremonies.generateAuthenticationOptions({
80
+ rpID: webauthn.rpId,
81
+ allowCredentials: creds.map((c) => ({
82
+ id: c.id,
83
+ transports: (c.transports ?? undefined),
84
+ })),
85
+ userVerification: 'preferred',
86
+ });
87
+ return {
88
+ options: options,
89
+ challenge: options.challenge,
90
+ };
91
+ },
92
+ async verifyPasskeyAuthentication(accountId, response, expectedChallenge) {
93
+ const resp = response;
94
+ // O credential id vem na resposta (base64url) → acha a credencial da conta.
95
+ const cred = await Credential.query()
96
+ .where('accountId', accountId)
97
+ .where('id', resp?.id ?? '')
98
+ .first();
99
+ if (!cred)
100
+ return false;
101
+ let verification;
102
+ try {
103
+ verification = await ceremonies.verifyAuthenticationResponse({
104
+ response: resp,
105
+ expectedChallenge,
106
+ expectedOrigin: webauthn.origin,
107
+ expectedRPID: webauthn.rpId,
108
+ credential: {
109
+ id: cred.id,
110
+ publicKey: new Uint8Array(Buffer.from(cred.publicKey, 'base64url')),
111
+ counter: cred.counter,
112
+ transports: (cred.transports ?? undefined),
113
+ },
114
+ });
115
+ }
116
+ catch {
117
+ return false;
118
+ }
119
+ if (!verification.verified)
120
+ return false;
121
+ // Atualiza o signature counter (anti-replay).
122
+ cred.counter = verification.authenticationInfo.newCounter;
123
+ await cred.save();
124
+ return true;
125
+ },
126
+ async listPasskeys(accountId) {
127
+ const creds = await Credential.query()
128
+ .where('accountId', accountId)
129
+ .orderBy('createdAt', 'asc');
130
+ return creds.map((c) => ({
131
+ id: c.id,
132
+ label: c.label ?? undefined,
133
+ createdAt: c.createdAt?.toISO?.() ?? String(c.createdAt ?? ''),
134
+ }));
135
+ },
136
+ async removePasskey(accountId, credentialId) {
137
+ await Credential.query().where('accountId', accountId).where('id', credentialId).delete();
138
+ },
139
+ };
140
+ }
@@ -0,0 +1,45 @@
1
+ import { type LucidAccountStoreOptions } from './lucid_account_store.js';
2
+ import type { AccountStore } from './account_store.js';
3
+ import type { PatStore } from '../pat/pat_store.js';
4
+ import type { AuditSink } from '../audit/audit_sink.js';
5
+ /** Models Lucid (compostos dos mixins do authkit) para montar os stores de uma vez. */
6
+ export interface LucidStoresModels {
7
+ /** Model de `withAuthUser()` (+withCredentials/+withMfa). Obrigatório. */
8
+ account: any;
9
+ /** Model de `withPersonalAccessToken()` — habilita o patStore. */
10
+ pat?: any;
11
+ /** Model de `withAuditLog()` — habilita o audit sink. */
12
+ audit?: any;
13
+ /** Model de `withProviderIdentity()` — habilita account linking social. */
14
+ providerIdentity?: any;
15
+ /** Model de `withWebauthnCredential()` — habilita passkeys. */
16
+ webauthnCredential?: any;
17
+ /** Trio de models de organizations — habilita multi-tenancy. */
18
+ organizations?: {
19
+ OrgModel: any;
20
+ MemberModel: any;
21
+ InvitationModel: any;
22
+ };
23
+ }
24
+ export interface LucidStoresResult {
25
+ accountStore: AccountStore;
26
+ patStore?: PatStore;
27
+ audit?: AuditSink;
28
+ }
29
+ /** Options compartilhadas — os models vão em {@link LucidStoresModels}, não aqui. */
30
+ export type LucidStoresOptions = Omit<LucidAccountStoreOptions, 'providerIdentityModel' | 'webauthnCredentialModel' | 'organizationModels'>;
31
+ /**
32
+ * Conveniência que monta `accountStore` (+ `patStore` + `audit`) a partir dos models,
33
+ * declarando `mfaIssuer`/`webauthn`/`encrypter` UMA vez. Substitui o wiring repetido
34
+ * de 5–8 models passados um a um no `config/authkit.ts`.
35
+ *
36
+ * ```ts
37
+ * const { accountStore, patStore, audit } = lucidStores(
38
+ * { account: AuthUser, pat: PersonalAccessToken, audit: AuditLog,
39
+ * providerIdentity: ProviderIdentity, webauthnCredential: WebauthnCredential,
40
+ * organizations: { OrgModel: Organization, MemberModel: OrganizationMember, InvitationModel: OrganizationInvitation } },
41
+ * { mfaIssuer: 'educ(a)ção', webauthn }
42
+ * )
43
+ * ```
44
+ */
45
+ export declare function lucidStores(models: LucidStoresModels, options?: LucidStoresOptions): LucidStoresResult;
@@ -0,0 +1,30 @@
1
+ import { lucidAccountStore } from './lucid_account_store.js';
2
+ import { lucidPatStore } from '../pat/lucid_pat_store.js';
3
+ import { lucidAuditSink } from '../audit/lucid_audit_sink.js';
4
+ /**
5
+ * Conveniência que monta `accountStore` (+ `patStore` + `audit`) a partir dos models,
6
+ * declarando `mfaIssuer`/`webauthn`/`encrypter` UMA vez. Substitui o wiring repetido
7
+ * de 5–8 models passados um a um no `config/authkit.ts`.
8
+ *
9
+ * ```ts
10
+ * const { accountStore, patStore, audit } = lucidStores(
11
+ * { account: AuthUser, pat: PersonalAccessToken, audit: AuditLog,
12
+ * providerIdentity: ProviderIdentity, webauthnCredential: WebauthnCredential,
13
+ * organizations: { OrgModel: Organization, MemberModel: OrganizationMember, InvitationModel: OrganizationInvitation } },
14
+ * { mfaIssuer: 'educ(a)ção', webauthn }
15
+ * )
16
+ * ```
17
+ */
18
+ export function lucidStores(models, options = {}) {
19
+ const accountStore = lucidAccountStore(models.account, {
20
+ ...options,
21
+ providerIdentityModel: models.providerIdentity,
22
+ webauthnCredentialModel: models.webauthnCredential,
23
+ organizationModels: models.organizations,
24
+ });
25
+ return {
26
+ accountStore,
27
+ ...(models.pat ? { patStore: lucidPatStore(models.pat) } : {}),
28
+ ...(models.audit ? { audit: lucidAuditSink(models.audit) } : {}),
29
+ };
30
+ }
@@ -0,0 +1,37 @@
1
+ /** Forma mínima do payload persistido pelo oidc-provider. */
2
+ export interface OidcPayload {
3
+ [key: string]: unknown;
4
+ grantId?: string;
5
+ userCode?: string;
6
+ uid?: string;
7
+ consumed?: unknown;
8
+ }
9
+ /** Um client OIDC enumerado do adapter (id + payload de metadata persistido). */
10
+ export interface EnumeratedClient {
11
+ clientId: string;
12
+ payload: Record<string, unknown>;
13
+ }
14
+ /** Um artefato OIDC enumerado de um model qualquer (id + payload persistido). */
15
+ export interface EnumeratedArtifact {
16
+ id: string;
17
+ payload: Record<string, unknown>;
18
+ }
19
+ /** Contrato que o oidc-provider espera de um adapter (um por model). */
20
+ export interface OidcAdapter {
21
+ upsert(id: string, payload: OidcPayload, expiresIn: number): Promise<void>;
22
+ find(id: string): Promise<OidcPayload | undefined>;
23
+ findByUserCode(userCode: string): Promise<OidcPayload | undefined>;
24
+ findByUid(uid: string): Promise<OidcPayload | undefined>;
25
+ consume(id: string): Promise<void>;
26
+ destroy(id: string): Promise<void>;
27
+ revokeByGrantId(grantId: string): Promise<void>;
28
+ /**
29
+ * Enumeração GENÉRICA dos artefatos do model deste adapter (id + payload). Usada
30
+ * pelo console admin para listar `Client` (CRUD) e `Session`/`Grant`/tokens
31
+ * (sessões ativas + revogação). Capacidade OPCIONAL (estilo `AuditSink.list`):
32
+ * adapters que não conseguem enumerar de forma barata omitem o método e a UI
33
+ * degrada graciosamente. O adapter já é escopado a UM model na construção
34
+ * (`new AdapterClass(model)`), então não recebe parâmetro.
35
+ */
36
+ list?(): Promise<EnumeratedArtifact[]>;
37
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import type { Database } from '@adonisjs/lucid/database';
2
+ import type { EnumeratedArtifact, OidcAdapter, OidcPayload } from './adapter_contract.js';
3
+ export declare class DatabaseAdapter implements OidcAdapter {
4
+ #private;
5
+ private name;
6
+ private db;
7
+ constructor(name: string, db: Database);
8
+ upsert(id: string, payload: OidcPayload, expiresIn: number): Promise<void>;
9
+ find(id: string): Promise<OidcPayload | undefined>;
10
+ findByUid(uid: string): Promise<OidcPayload | undefined>;
11
+ findByUserCode(userCode: string): Promise<OidcPayload | undefined>;
12
+ consume(id: string): Promise<void>;
13
+ destroy(id: string): Promise<void>;
14
+ revokeByGrantId(grantId: string): Promise<void>;
15
+ /**
16
+ * Enumeração genérica dos artefatos do model deste adapter (id + payload).
17
+ * Filtra por `model_name = this.name` e descarta linhas expiradas. Usada pelo
18
+ * console admin para listar `Client` (CRUD) e `Session`/`Grant`/tokens.
19
+ */
20
+ list(): Promise<EnumeratedArtifact[]>;
21
+ }
@@ -0,0 +1,79 @@
1
+ const TABLE = 'authkit_oidc_payloads';
2
+ export class DatabaseAdapter {
3
+ name;
4
+ db;
5
+ constructor(name, db) {
6
+ this.name = name;
7
+ this.db = db;
8
+ }
9
+ #query() {
10
+ return this.db.query().from(TABLE).where('model_name', this.name);
11
+ }
12
+ async upsert(id, payload, expiresIn) {
13
+ // Armazenamos como ISO string para que o parse de expiração seja determinístico
14
+ // independente do backend (SQLite/Postgres) e do formato nativo de timestamp.
15
+ const expiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1000).toISOString() : null;
16
+ const row = {
17
+ id,
18
+ model_name: this.name,
19
+ payload: JSON.stringify(payload),
20
+ grant_id: payload.grantId ?? null,
21
+ user_code: payload.userCode ?? null,
22
+ uid: payload.uid ?? null,
23
+ expires_at: expiresAt,
24
+ };
25
+ const existing = await this.#query().where('id', id).first();
26
+ if (existing) {
27
+ await this.#query().where('id', id).update(row);
28
+ }
29
+ else {
30
+ await this.db.table(TABLE).insert(row);
31
+ }
32
+ }
33
+ async #parse(record) {
34
+ if (!record)
35
+ return undefined;
36
+ if (record.expires_at && new Date(record.expires_at).getTime() <= Date.now()) {
37
+ return undefined;
38
+ }
39
+ return JSON.parse(record.payload);
40
+ }
41
+ async find(id) {
42
+ return this.#parse(await this.#query().where('id', id).first());
43
+ }
44
+ async findByUid(uid) {
45
+ return this.#parse(await this.#query().where('uid', uid).first());
46
+ }
47
+ async findByUserCode(userCode) {
48
+ return this.#parse(await this.#query().where('user_code', userCode).first());
49
+ }
50
+ async consume(id) {
51
+ const found = await this.find(id);
52
+ if (!found)
53
+ return;
54
+ found.consumed = Math.floor(Date.now() / 1000);
55
+ await this.#query().where('id', id).update({ payload: JSON.stringify(found) });
56
+ }
57
+ async destroy(id) {
58
+ await this.#query().where('id', id).delete();
59
+ }
60
+ async revokeByGrantId(grantId) {
61
+ await this.db.query().from(TABLE).where('grant_id', grantId).delete();
62
+ }
63
+ /**
64
+ * Enumeração genérica dos artefatos do model deste adapter (id + payload).
65
+ * Filtra por `model_name = this.name` e descarta linhas expiradas. Usada pelo
66
+ * console admin para listar `Client` (CRUD) e `Session`/`Grant`/tokens.
67
+ */
68
+ async list() {
69
+ const rows = await this.#query().orderBy('id', 'asc');
70
+ const now = Date.now();
71
+ const result = [];
72
+ for (const row of rows) {
73
+ if (row.expires_at && new Date(row.expires_at).getTime() <= now)
74
+ continue;
75
+ result.push({ id: row.id, payload: JSON.parse(row.payload) });
76
+ }
77
+ return result;
78
+ }
79
+ }
@@ -0,0 +1,30 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ import type { OidcAdapter } from './adapter_contract.js';
3
+ export type OidcAdapterClass = new (name: string) => OidcAdapter;
4
+ export interface AdapterFactory {
5
+ resolver(app: ApplicationService): Promise<OidcAdapterClass>;
6
+ }
7
+ export interface RedisAdapterConfig {
8
+ /** nome da conexão do @adonisjs/redis */
9
+ connection: string;
10
+ prefix?: string;
11
+ }
12
+ export interface DatabaseAdapterConfig {
13
+ /** nome da conexão Lucid (default: a primária) */
14
+ connection?: string;
15
+ }
16
+ export declare const adapters: {
17
+ /**
18
+ * Factory para o adapter Redis. O consumidor precisa ter o @adonisjs/redis
19
+ * configurado, pois o resolver resolve o `RedisManager` pelo token `'redis'`
20
+ * do container e obtém a conexão nomeada via `connection(name)`.
21
+ */
22
+ redis(config: RedisAdapterConfig): AdapterFactory;
23
+ /**
24
+ * Factory para o adapter de banco (Lucid). Resolve o `Database` manager pelo
25
+ * token `'lucid.db'`. O `DatabaseAdapter` consome o manager diretamente
26
+ * (`db.query()`/`db.table()`); quando uma conexão específica é solicitada,
27
+ * usamos `db.connection(name)` para obter o cliente daquela conexão.
28
+ */
29
+ database(config?: DatabaseAdapterConfig): AdapterFactory;
30
+ };