@baseplate-dev/plugin-auth 0.6.17 → 0.6.18

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 (197) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/better-auth/admin/generators/admin-crud-manage-roles-action/admin-crud-manage-roles-action.generator.d.ts +12 -0
  3. package/dist/better-auth/admin/generators/admin-crud-manage-roles-action/generated/index.d.ts +12 -0
  4. package/dist/better-auth/admin/generators/admin-crud-manage-roles-action/generated/template-renderers.d.ts +6 -0
  5. package/dist/better-auth/admin/generators/admin-crud-manage-roles-action/generated/typed-templates.d.ts +6 -0
  6. package/dist/better-auth/admin/generators/admin-crud-reset-password-action/admin-crud-reset-password-action.generator.d.ts +12 -0
  7. package/dist/better-auth/admin/generators/admin-crud-reset-password-action/generated/index.d.ts +12 -0
  8. package/dist/better-auth/admin/generators/admin-crud-reset-password-action/generated/template-renderers.d.ts +6 -0
  9. package/dist/better-auth/admin/generators/admin-crud-reset-password-action/generated/typed-templates.d.ts +12 -0
  10. package/dist/better-auth/admin/generators/admin-crud-roles-column/admin-crud-roles-column.generator.d.ts +6 -0
  11. package/dist/better-auth/generators/react/better-auth-pages/better-auth-pages.generator.d.ts +6 -0
  12. package/dist/better-auth/generators/react/better-auth-pages/generated/index.d.ts +36 -0
  13. package/dist/better-auth/generators/react/better-auth-pages/generated/template-renderers.d.ts +6 -0
  14. package/dist/better-auth/generators/react/better-auth-pages/generated/typed-templates.d.ts +60 -0
  15. package/dist/better-auth/generators/react/react-better-auth/generated/index.d.ts +12 -0
  16. package/dist/better-auth/generators/react/react-better-auth/generated/template-renderers.d.ts +6 -0
  17. package/dist/better-auth/generators/react/react-better-auth/generated/typed-templates.d.ts +6 -0
  18. package/dist/better-auth/generators/react/react-better-auth/react-better-auth.generator.d.ts +6 -0
  19. package/dist/local-auth/admin/common.js +6 -0
  20. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/admin-crud-invite-user-action.generator.d.ts +531 -0
  21. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/admin-crud-invite-user-action.generator.js +119 -0
  22. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/index.d.ts +540 -0
  23. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/index.js +11 -0
  24. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/template-paths.d.ts +12 -0
  25. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/template-paths.js +24 -0
  26. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/template-renderers.d.ts +276 -0
  27. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/template-renderers.js +45 -0
  28. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/typed-templates.d.ts +263 -0
  29. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/generated/typed-templates.js +21 -0
  30. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/index.d.ts +2 -0
  31. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/index.js +2 -0
  32. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/templates/routes/-components/invite-user-dialog.d.ts +21 -0
  33. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/templates/routes/-components/invite-user-dialog.js +69 -0
  34. package/dist/local-auth/admin/generators/admin-crud-invite-user-action/templates/routes/-components/invite-user-dialog.tsx +122 -0
  35. package/dist/local-auth/admin/generators/admin-crud-manage-roles-action/admin-crud-manage-roles-action.generator.d.ts +12 -0
  36. package/dist/local-auth/admin/generators/admin-crud-manage-roles-action/generated/index.d.ts +12 -0
  37. package/dist/local-auth/admin/generators/admin-crud-manage-roles-action/generated/template-renderers.d.ts +6 -0
  38. package/dist/local-auth/admin/generators/admin-crud-manage-roles-action/generated/typed-templates.d.ts +6 -0
  39. package/dist/local-auth/admin/generators/admin-crud-reset-password-action/admin-crud-reset-password-action.generator.d.ts +12 -0
  40. package/dist/local-auth/admin/generators/admin-crud-reset-password-action/generated/index.d.ts +12 -0
  41. package/dist/local-auth/admin/generators/admin-crud-reset-password-action/generated/template-renderers.d.ts +6 -0
  42. package/dist/local-auth/admin/generators/admin-crud-reset-password-action/generated/typed-templates.d.ts +12 -0
  43. package/dist/local-auth/admin/generators/admin-crud-roles-column/admin-crud-roles-column.generator.d.ts +6 -0
  44. package/dist/local-auth/admin/node.js +13 -0
  45. package/dist/local-auth/admin/schema/invite-user-action.d.ts +12 -0
  46. package/dist/local-auth/admin/schema/invite-user-action.js +6 -0
  47. package/dist/local-auth/admin/web.js +8 -0
  48. package/dist/local-auth/core/common.js +7 -2
  49. package/dist/local-auth/core/components/local-auth-definition-editor.js +2 -1
  50. package/dist/local-auth/core/components/local-auth-web-app-settings-form.d.ts +9 -0
  51. package/dist/local-auth/core/components/local-auth-web-app-settings-form.js +11 -0
  52. package/dist/local-auth/core/generators/auth-email-password/auth-email-password.generator.d.ts +6 -0
  53. package/dist/local-auth/core/generators/auth-email-password/auth-email-password.generator.js +66 -6
  54. package/dist/local-auth/core/generators/auth-email-password/generated/index.d.ts +188 -0
  55. package/dist/local-auth/core/generators/auth-email-password/generated/template-paths.d.ts +5 -0
  56. package/dist/local-auth/core/generators/auth-email-password/generated/template-paths.js +5 -0
  57. package/dist/local-auth/core/generators/auth-email-password/generated/template-renderers.d.ts +18 -0
  58. package/dist/local-auth/core/generators/auth-email-password/generated/template-renderers.js +66 -0
  59. package/dist/local-auth/core/generators/auth-email-password/generated/typed-templates.d.ts +192 -0
  60. package/dist/local-auth/core/generators/auth-email-password/generated/typed-templates.js +82 -1
  61. package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/otp.constants.d.ts +19 -0
  62. package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/otp.constants.js +20 -0
  63. package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/otp.constants.ts +22 -0
  64. package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.d.ts +12 -0
  65. package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.js +12 -0
  66. package/dist/local-auth/core/generators/auth-email-password/templates/module/constants/password.constants.ts +14 -0
  67. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-otp.mutations.d.ts +2 -0
  68. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-otp.mutations.js +30 -0
  69. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/email-otp.mutations.ts +38 -0
  70. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/invite.mutations.d.ts +2 -0
  71. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/invite.mutations.js +42 -0
  72. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/invite.mutations.ts +54 -0
  73. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/user-password.mutations.js +2 -19
  74. package/dist/local-auth/core/generators/auth-email-password/templates/module/schema/user-password.mutations.ts +1 -22
  75. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-otp.service.d.ts +37 -0
  76. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-otp.service.js +225 -0
  77. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/email-otp.service.ts +333 -0
  78. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/invite.service.d.ts +39 -0
  79. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/invite.service.js +138 -0
  80. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/invite.service.ts +209 -0
  81. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/password-reset.service.js +3 -3
  82. package/dist/local-auth/core/generators/auth-email-password/templates/module/services/password-reset.service.ts +3 -2
  83. package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.d.ts +3 -1
  84. package/dist/local-auth/core/generators/auth-email-templates/auth-email-templates.generator.js +18 -3
  85. package/dist/local-auth/core/generators/auth-email-templates/generated/index.d.ts +40 -0
  86. package/dist/local-auth/core/generators/auth-email-templates/generated/template-paths.d.ts +2 -0
  87. package/dist/local-auth/core/generators/auth-email-templates/generated/template-paths.js +2 -0
  88. package/dist/local-auth/core/generators/auth-email-templates/generated/template-renderers.d.ts +6 -0
  89. package/dist/local-auth/core/generators/auth-email-templates/generated/template-renderers.js +20 -0
  90. package/dist/local-auth/core/generators/auth-email-templates/generated/typed-templates.d.ts +40 -0
  91. package/dist/local-auth/core/generators/auth-email-templates/generated/typed-templates.js +24 -0
  92. package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/email-otp.email.d.ts +3 -0
  93. package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/email-otp.email.js +18 -0
  94. package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/email-otp.email.tsx +57 -0
  95. package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/invite.email.d.ts +3 -0
  96. package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/invite.email.js +14 -0
  97. package/dist/local-auth/core/generators/auth-email-templates/templates/src/emails/auth/invite.email.tsx +47 -0
  98. package/dist/local-auth/core/generators/auth-module/auth-module.generator.d.ts +4 -0
  99. package/dist/local-auth/core/generators/auth-module/auth-module.generator.js +5 -1
  100. package/dist/local-auth/core/generators/auth-module/generated/index.d.ts +20 -0
  101. package/dist/local-auth/core/generators/auth-module/generated/template-paths.d.ts +1 -0
  102. package/dist/local-auth/core/generators/auth-module/generated/template-paths.js +1 -0
  103. package/dist/local-auth/core/generators/auth-module/generated/template-renderers.d.ts +3 -0
  104. package/dist/local-auth/core/generators/auth-module/generated/template-renderers.js +13 -0
  105. package/dist/local-auth/core/generators/auth-module/generated/ts-import-providers.d.ts +9 -0
  106. package/dist/local-auth/core/generators/auth-module/generated/ts-import-providers.js +6 -0
  107. package/dist/local-auth/core/generators/auth-module/generated/typed-templates.d.ts +17 -0
  108. package/dist/local-auth/core/generators/auth-module/generated/typed-templates.js +20 -0
  109. package/dist/local-auth/core/generators/auth-module/templates/module/services/auth-verification.service.d.ts +4 -0
  110. package/dist/local-auth/core/generators/auth-module/templates/module/services/auth-verification.service.js +1 -1
  111. package/dist/local-auth/core/generators/auth-module/templates/module/services/auth-verification.service.ts +1 -1
  112. package/dist/local-auth/core/generators/auth-module/templates/module/services/code-verification.service.d.ts +66 -0
  113. package/dist/local-auth/core/generators/auth-module/templates/module/services/code-verification.service.js +134 -0
  114. package/dist/local-auth/core/generators/auth-module/templates/module/services/code-verification.service.ts +184 -0
  115. package/dist/local-auth/core/generators/auth-routes/auth-routes.generator.d.ts +8 -0
  116. package/dist/local-auth/core/generators/auth-routes/auth-routes.generator.js +38 -5
  117. package/dist/local-auth/core/generators/auth-routes/generated/index.d.ts +840 -268
  118. package/dist/local-auth/core/generators/auth-routes/generated/template-paths.d.ts +3 -0
  119. package/dist/local-auth/core/generators/auth-routes/generated/template-paths.js +3 -0
  120. package/dist/local-auth/core/generators/auth-routes/generated/template-renderers.d.ts +18 -0
  121. package/dist/local-auth/core/generators/auth-routes/generated/template-renderers.js +51 -0
  122. package/dist/local-auth/core/generators/auth-routes/generated/typed-templates.d.ts +608 -283
  123. package/dist/local-auth/core/generators/auth-routes/generated/typed-templates.js +69 -23
  124. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-otp-constants.d.ts +9 -0
  125. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-otp-constants.js +10 -0
  126. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/-otp-constants.ts +11 -0
  127. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/accept-invite.d.ts +7 -0
  128. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/accept-invite.js +148 -0
  129. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/accept-invite.tsx +264 -0
  130. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login-otp.d.ts +7 -0
  131. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login-otp.js +184 -0
  132. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login-otp.tsx +311 -0
  133. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login.js +1 -1
  134. package/dist/local-auth/core/generators/auth-routes/templates/routes/auth_/login.tsx +2 -9
  135. package/dist/local-auth/core/generators/react-session/generated/index.d.ts +12 -0
  136. package/dist/local-auth/core/generators/react-session/generated/template-renderers.d.ts +6 -0
  137. package/dist/local-auth/core/generators/react-session/generated/typed-templates.d.ts +12 -0
  138. package/dist/local-auth/core/generators/react-session/react-session.generator.d.ts +6 -0
  139. package/dist/local-auth/core/node.js +24 -6
  140. package/dist/local-auth/core/schema/migrations.d.ts +3 -0
  141. package/dist/local-auth/core/schema/migrations.js +36 -0
  142. package/dist/local-auth/core/schema/models.js +8 -0
  143. package/dist/local-auth/core/schema/plugin-definition.d.ts +1 -0
  144. package/dist/local-auth/core/schema/plugin-definition.js +1 -0
  145. package/dist/local-auth/core/schema/web-app-schema.d.ts +15 -0
  146. package/dist/local-auth/core/schema/web-app-schema.js +16 -0
  147. package/dist/local-auth/core/web.js +8 -1
  148. package/dist/web/assets/{_virtual_mf-localSharedImportMap___mfe_internal__plugin_mf_2_auth-ChkXxpXe.js → _virtual_mf-localSharedImportMap___mfe_internal__plugin_mf_2_auth__mf_owner__1-CKKmnLep.js} +42 -34
  149. package/dist/web/assets/{dist-DY7ZXvq4.js → _virtual_mf___mfe_internal__plugin_mf_2_auth__mf_owner__1__loadShare___mf_0_baseplate_mf_2_dev_mf_1_project_mf_2_builder_mf_2_lib__loadShare__.js-Cx7TvZ_H.js} +16717 -373
  150. package/dist/web/assets/{_virtual_mf___mfe_internal__plugin_mf_2_auth__loadShare___mf_0_baseplate_mf_2_dev_mf_1_project_mf_2_builder_mf_2_lib_mf_1_web__loadShare__.js-37vlYRxk.js → _virtual_mf___mfe_internal__plugin_mf_2_auth__mf_owner__1__loadShare___mf_0_baseplate_mf_2_dev_mf_1_project_mf_2_builder_mf_2_lib_mf_1_web__loadShare__.js-D3Nvasea.js} +90 -38
  151. package/dist/web/assets/{_virtual_mf___mfe_internal__plugin_mf_2_auth__loadShare___mf_0_baseplate_mf_2_dev_mf_1_ui_mf_2_components__loadShare__.js-DRSNXPPo.js → _virtual_mf___mfe_internal__plugin_mf_2_auth__mf_owner__1__loadShare___mf_0_baseplate_mf_2_dev_mf_1_ui_mf_2_components__loadShare__.js-C2GDE8Py.js} +1645 -921
  152. package/dist/web/assets/{_virtual_mf___mfe_internal__plugin_mf_2_auth__loadShare___mf_0_tanstack_mf_1_react_mf_2_router__loadShare__.js-DfiQqvVC.js → _virtual_mf___mfe_internal__plugin_mf_2_auth__mf_owner__1__loadShare___mf_0_tanstack_mf_1_react_mf_2_router__loadShare__.js-CiccpWjh.js} +212 -57
  153. package/dist/web/assets/auth-CsHp2bQi.js +1 -0
  154. package/dist/web/assets/common-BGTuTgx7.js +43 -0
  155. package/dist/web/assets/common-C8_sC5pp.js +70 -0
  156. package/dist/web/assets/{common-ByxS61u8.js → common-Co5lW_TK.js} +10 -10
  157. package/dist/web/assets/{common-iHaemino.js → common-CoLuMS7U.js} +6 -6
  158. package/dist/web/assets/common-Dueu_1NG.js +36 -0
  159. package/dist/web/assets/{common-TDf_PrjX.js → common-N3skPbzk.js} +10 -10
  160. package/dist/web/assets/{dist-CrLSslv6.js → dist-DQd1TAJX.js} +273 -132
  161. package/dist/web/assets/{get-auth-plugin-definition-kDCtXq_6.js → get-auth-plugin-definition-DyokUVjX.js} +3 -3
  162. package/dist/web/assets/{hostInit-Cruek6c6.js → hostInit-BCYmw0H5.js} +32 -5
  163. package/dist/web/assets/{mf-entry-bootstrap-0-dfed0275.js → mf-entry-bootstrap-0-3ede9334.js} +2 -1
  164. package/dist/web/assets/{mf-entry-bootstrap-1-5275674a.js → mf-entry-bootstrap-1-3da85eea.js} +3 -2
  165. package/dist/web/assets/{mf-entry-bootstrap-2-39fb9255.js → mf-entry-bootstrap-2-32e24e11.js} +3 -2
  166. package/dist/web/assets/{mf-entry-bootstrap-3-49e64336.js → mf-entry-bootstrap-3-a3cfea9d.js} +3 -2
  167. package/dist/web/assets/{models-DSvs_3bA.js → models-BcPOQC5p.js} +4 -5
  168. package/dist/web/assets/{models-BZmCbizK.js → models-BcUgOGGn.js} +11 -6
  169. package/dist/web/assets/{plugin-definition-CYj29S3q.js → plugin-definition-D1EImXIf.js} +9 -10
  170. package/dist/web/assets/plugin-definition-lw-gB4hU.js +10 -0
  171. package/dist/web/assets/{styles-yjbHBTlw.js → styles-EOyEbGA4.js} +9 -10
  172. package/dist/web/assets/{virtualExposes-CbPBmicF.js → virtualExposes-DWORnjyA.js} +1 -1
  173. package/dist/web/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__plugin-auth__remoteEntry_js-t-KnBiUh.js +747 -0
  174. package/dist/web/assets/{virtual_mf-exposes___mfe_internal__plugin-auth__remoteEntry_js-B6BXIeF1.js → virtual_mf-exposes___mfe_internal__plugin-auth__remoteEntry_js-DZfE3QCR.js} +13 -13
  175. package/dist/web/assets/{web-VqBA3jxZ.js → web-CBVepebK.js} +22 -22
  176. package/dist/web/assets/{web-D0MSKfyv.js → web-Dgb85jhs.js} +47 -47
  177. package/dist/web/assets/{web-CXAHKjIY.js → web-EDeSquSP.js} +28 -28
  178. package/dist/web/assets/{web-1eTcxMhf.js → web-PqAcfBSy.js} +9 -9
  179. package/dist/web/assets/{web-CDAKPPK9.js → web-RhChfBw_.js} +21 -21
  180. package/dist/web/assets/web-kaD9AzNS.js +59 -0
  181. package/dist/web/assets/web-xJ-GnSkC.js +148 -0
  182. package/dist/web/index.html +5 -5
  183. package/dist/web/remoteEntry.js +1 -1
  184. package/package.json +14 -14
  185. package/dist/web/assets/_virtual_mf___mfe_internal__plugin_mf_2_auth__loadShare___mf_0_baseplate_mf_2_dev_mf_1_project_mf_2_builder_mf_2_lib__loadShare__.js-CO5Pvo0y.js +0 -384
  186. package/dist/web/assets/_virtual_mf___mfe_internal__plugin_mf_2_auth__loadShare__zod__loadShare__.js-BEZ7A-cz.js +0 -13566
  187. package/dist/web/assets/auth-BxAE0rgh.js +0 -1
  188. package/dist/web/assets/common-CKl_XlvH.js +0 -37
  189. package/dist/web/assets/common-UpVCKZeW.js +0 -41
  190. package/dist/web/assets/common-crSwCD36.js +0 -37
  191. package/dist/web/assets/model-utils-C0WDb_Ec.js +0 -1599
  192. package/dist/web/assets/plugin-definition-DOMmPL2Z.js +0 -11
  193. package/dist/web/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__plugin-auth__remoteEntry_js-XM6iYVxf.js +0 -259
  194. package/dist/web/assets/virtual_mf-exposes-ssr___mfe_internal__plugin-auth__remoteEntry_js-DGjg7Brm.js +0 -129
  195. package/dist/web/assets/web-DbeAaDTV.js +0 -118
  196. package/dist/web/assets/web-miDovYk_.js +0 -46
  197. package/dist/web/remoteEntry.ssr.js +0 -43
@@ -0,0 +1,54 @@
1
+ // @ts-nocheck
2
+
3
+ import { acceptInvite, inviteUser, validateInviteToken } from '$servicesInvite';
4
+ import { userSessionPayload } from '%authModuleImports';
5
+ import { builder } from '%pothosImports';
6
+
7
+ builder.mutationField('inviteUser', (t) =>
8
+ t.fieldWithInputPayload({
9
+ authorize: TPL_ADMIN_ROLES,
10
+ payload: {
11
+ user: t.payload.field({
12
+ type: TPL_USER_OBJECT_TYPE,
13
+ }),
14
+ },
15
+ input: {
16
+ userId: t.input.field({ required: true, type: 'Uuid' }),
17
+ },
18
+ resolve: async (_root, { input }, context) =>
19
+ inviteUser({ userId: input.userId, context }),
20
+ }),
21
+ );
22
+
23
+ builder.mutationField('validateInviteToken', (t) =>
24
+ t.fieldWithInputPayload({
25
+ authorize: ['public'],
26
+ payload: {
27
+ email: t.payload.field({ type: 'String' }),
28
+ },
29
+ input: {
30
+ token: t.input.field({ required: true, type: 'String' }),
31
+ },
32
+ resolve: async (_root, { input }) =>
33
+ validateInviteToken({ token: input.token }),
34
+ }),
35
+ );
36
+
37
+ builder.mutationField('acceptInvite', (t) =>
38
+ t.fieldWithInputPayload({
39
+ authorize: ['public'],
40
+ payload: {
41
+ session: t.payload.field({ type: userSessionPayload }),
42
+ },
43
+ input: {
44
+ token: t.input.field({ required: true, type: 'String' }),
45
+ newPassword: t.input.field({ required: true, type: 'String' }),
46
+ },
47
+ resolve: async (_root, { input }, context) =>
48
+ acceptInvite({
49
+ token: input.token,
50
+ newPassword: input.newPassword,
51
+ context,
52
+ }),
53
+ }),
54
+ );
@@ -1,25 +1,8 @@
1
1
  // @ts-nocheck
2
- import { authenticateUserWithEmailAndPassword, changeUserPassword, registerUserWithEmailAndPassword, resetUserPassword, } from '$servicesUserPassword';
2
+ import { authenticateUserWithEmailAndPassword, changeUserPassword, resetUserPassword, } from '$servicesUserPassword';
3
3
  import { userSessionPayload } from '%authModuleImports';
4
4
  import { builder } from '%pothosImports';
5
- builder.mutationField('registerWithEmailPassword', (t) => t.fieldWithInputPayload({
6
- authorize: ['public'],
7
- payload: {
8
- session: t.payload.field({ type: userSessionPayload }),
9
- },
10
- input: {
11
- email: t.input.field({ required: true, type: 'String' }),
12
- name: t.input.field({ required: false, type: 'String' }),
13
- password: t.input.field({ required: true, type: 'String' }),
14
- },
15
- resolve: async (root, { input }, context) => registerUserWithEmailAndPassword({
16
- input: {
17
- ...input,
18
- name: input.name ?? undefined,
19
- },
20
- context,
21
- }),
22
- }));
5
+ TPL_REGISTER_MUTATION;
23
6
  builder.mutationField('loginWithEmailPassword', (t) => t.fieldWithInputPayload({
24
7
  authorize: ['public'],
25
8
  payload: {
@@ -3,33 +3,12 @@
3
3
  import {
4
4
  authenticateUserWithEmailAndPassword,
5
5
  changeUserPassword,
6
- registerUserWithEmailAndPassword,
7
6
  resetUserPassword,
8
7
  } from '$servicesUserPassword';
9
8
  import { userSessionPayload } from '%authModuleImports';
10
9
  import { builder } from '%pothosImports';
11
10
 
12
- builder.mutationField('registerWithEmailPassword', (t) =>
13
- t.fieldWithInputPayload({
14
- authorize: ['public'],
15
- payload: {
16
- session: t.payload.field({ type: userSessionPayload }),
17
- },
18
- input: {
19
- email: t.input.field({ required: true, type: 'String' }),
20
- name: t.input.field({ required: false, type: 'String' }),
21
- password: t.input.field({ required: true, type: 'String' }),
22
- },
23
- resolve: async (root, { input }, context) =>
24
- registerUserWithEmailAndPassword({
25
- input: {
26
- ...input,
27
- name: input.name ?? undefined,
28
- },
29
- context,
30
- }),
31
- }),
32
- );
11
+ TPL_REGISTER_MUTATION;
33
12
 
34
13
  builder.mutationField('loginWithEmailPassword', (t) =>
35
14
  t.fieldWithInputPayload({
@@ -0,0 +1,37 @@
1
+ import type { RequestServiceContext, RequestServiceContextWith } from '%requestServiceContextImports';
2
+ import type { UserSessionPayload } from '%userSessionTypesImports';
3
+ /**
4
+ * Emails a single-use sign-in code to the given address.
5
+ *
6
+ * A code is sent whether or not an account exists — verifying one signs the
7
+ * user in, creating the account on first use — so this endpoint reveals
8
+ * nothing about which addresses are registered.
9
+ */
10
+ export declare function requestEmailOtp({ email: rawEmail, context, }: {
11
+ email: string;
12
+ context: RequestServiceContextWith<'email'>;
13
+ }): Promise<{
14
+ success: true;
15
+ }>;
16
+ /**
17
+ * Signs a user in with an emailed code, creating the account on first use.
18
+ *
19
+ * A verified code proves control of the inbox, so the account it creates (or
20
+ * signs in to) is marked as having a verified email. Accounts created this way
21
+ * have no password until the user goes through the password reset flow.
22
+ *
23
+ * @throws BadRequestError `name-required` when the code is valid but the
24
+ * address has no account yet and no name was supplied. The code is left intact
25
+ * so the client can collect a name and retry with it.
26
+ */
27
+ export declare function signInWithEmailOtp({ input, context, }: {
28
+ input: {
29
+ email: string;
30
+ code: string;
31
+ name?: string;
32
+ };
33
+ context: RequestServiceContext;
34
+ }): Promise<{
35
+ session: UserSessionPayload;
36
+ }>;
37
+ //# sourceMappingURL=email-otp.service.d.ts.map
@@ -0,0 +1,225 @@
1
+ // @ts-nocheck
2
+ import { EMAIL_OTP_EXPIRY_SEC, EMAIL_OTP_LENGTH, EMAIL_OTP_MAX_ATTEMPTS, } from '$constantsOtp';
3
+ import { PASSWORD_MAX_LENGTH } from '$constantsPassword';
4
+ import { consumeCodeVerification, createCodeVerification, validateCodeVerification, } from '%authModuleImports';
5
+ import { isDevelopment } from '%configServiceImports';
6
+ import { BadRequestError, handleZodRequestValidationError, } from '%errorHandlerServiceImports';
7
+ import { prisma } from '%prismaImports';
8
+ import { memoizeRateLimiter } from '%rateLimitImports';
9
+ import * as crypto from 'node:crypto';
10
+ import z from 'zod';
11
+ const PROVIDER_ID = 'email-otp';
12
+ const EMAIL_OTP_TYPE = 'email-otp';
13
+ /**
14
+ * Rate limiters for emailed sign-in codes.
15
+ */
16
+ // Per-email burst limit: 3 codes / 15 minutes
17
+ const getEmailOtpRequestEmailLimiter = memoizeRateLimiter('email-otp-email', {
18
+ points: 3,
19
+ duration: 60 * 15, // 15 minutes
20
+ });
21
+ // Per-email daily cap. Each new code resets that code's attempt budget, so
22
+ // this is what actually bounds guesses per day: 10 codes x 5 attempts.
23
+ const getEmailOtpRequestEmailDailyLimiter = memoizeRateLimiter('email-otp-email-daily', {
24
+ points: 10,
25
+ duration: 60 * 60 * 24, // 1 day
26
+ });
27
+ // Per-IP rate limit: 10 codes/hour (prevents email scanning)
28
+ const getEmailOtpRequestIpLimiter = memoizeRateLimiter('email-otp-ip', {
29
+ points: 10,
30
+ duration: 60 * 60, // 1 hour
31
+ });
32
+ // Deliberately no global limiter here. A shared counter would let anyone who
33
+ // exhausts it lock every user out of signing in, and accounts created through
34
+ // this flow have no password to fall back on. Distributed abuse is bounded by
35
+ // the per-IP limit above; protecting the email provider from a cost or
36
+ // reputation spike belongs in its own quotas and alerting, not in the login
37
+ // path.
38
+ // Per-address verification limit. Unlike the per-code attempt budget this
39
+ // survives the code being reissued, and unlike the per-IP limit it survives
40
+ // the attacker rotating IPs.
41
+ const getEmailOtpVerifyEmailLimiter = memoizeRateLimiter('email-otp-verify-email', {
42
+ points: 10,
43
+ duration: 60 * 60, // 1 hour
44
+ blockDuration: 60 * 60, // Block for 1 hour if exceeded
45
+ });
46
+ // Per-IP verification limit, on top of each code's own attempt budget
47
+ const getEmailOtpVerifyIpLimiter = memoizeRateLimiter('email-otp-verify-ip', {
48
+ points: 20,
49
+ duration: 60 * 60, // 1 hour
50
+ blockDuration: 60 * 60, // Block for 1 hour if exceeded
51
+ });
52
+ /**
53
+ * Cookie holding the id of the pending verification.
54
+ *
55
+ * Requiring it at verification binds a code to the browser that asked for it,
56
+ * so a code read over someone's shoulder or talked out of them over the phone
57
+ * cannot be redeemed elsewhere.
58
+ */
59
+ const EMAIL_OTP_COOKIE_NAME = 'email-otp-verification';
60
+ function getEmailOtpCookieOptions() {
61
+ return {
62
+ httpOnly: true,
63
+ sameSite: 'lax',
64
+ secure: !isDevelopment(),
65
+ maxAge: EMAIL_OTP_EXPIRY_SEC,
66
+ path: '/',
67
+ };
68
+ }
69
+ const emailSchema = z.object({
70
+ email: z
71
+ .email()
72
+ .max(PASSWORD_MAX_LENGTH)
73
+ .transform((value) => value.toLowerCase()),
74
+ });
75
+ /**
76
+ * Generates a numeric code using rejection sampling so every digit is equally
77
+ * likely. 250 is the largest multiple of 10 within a byte, so values above it
78
+ * are discarded rather than folded back and over-weighting digits 0-5.
79
+ */
80
+ function generateNumericCode(length) {
81
+ const digits = Array.from({ length }, () => {
82
+ let value = 256;
83
+ while (value >= 250) {
84
+ value = crypto.randomBytes(1).readUInt8(0);
85
+ }
86
+ return String(value % 10);
87
+ });
88
+ return digits.join('');
89
+ }
90
+ /**
91
+ * Emails a single-use sign-in code to the given address.
92
+ *
93
+ * A code is sent whether or not an account exists — verifying one signs the
94
+ * user in, creating the account on first use — so this endpoint reveals
95
+ * nothing about which addresses are registered.
96
+ */
97
+ export async function requestEmailOtp({ email: rawEmail, context, }) {
98
+ const { services } = context;
99
+ const { email } = await emailSchema
100
+ .parseAsync({ email: rawEmail })
101
+ .catch(handleZodRequestValidationError);
102
+ await Promise.all([
103
+ getEmailOtpRequestIpLimiter().consumeOrThrow(context.reqInfo.ip, 'Too many sign-in code requests. Please try again later.', 'too-many-requests'),
104
+ getEmailOtpRequestEmailLimiter().consumeOrThrow(email, 'Too many sign-in code requests. Please try again later.', 'too-many-requests'),
105
+ getEmailOtpRequestEmailDailyLimiter().consumeOrThrow(email, 'Too many sign-in code requests. Please try again later.', 'too-many-requests'),
106
+ ]);
107
+ const code = generateNumericCode(EMAIL_OTP_LENGTH);
108
+ const { id: verificationId } = await createCodeVerification({
109
+ type: EMAIL_OTP_TYPE,
110
+ identifier: email,
111
+ code,
112
+ expiresInSec: EMAIL_OTP_EXPIRY_SEC,
113
+ });
114
+ context.cookieStore.set(EMAIL_OTP_COOKIE_NAME, verificationId, getEmailOtpCookieOptions());
115
+ await services.email.send(TPL_EMAIL_OTP_EMAIL, {
116
+ to: email,
117
+ data: { code, expiryMinutes: Math.floor(EMAIL_OTP_EXPIRY_SEC / 60) },
118
+ });
119
+ return { success: true };
120
+ }
121
+ const verifyEmailOtpSchema = z.object({
122
+ email: z
123
+ .email()
124
+ .max(PASSWORD_MAX_LENGTH)
125
+ .transform((value) => value.toLowerCase()),
126
+ code: z.string().length(EMAIL_OTP_LENGTH),
127
+ // Blank and whitespace-only names are normalized to absent rather than
128
+ // rejected, so a client that always sends the field still gets the
129
+ // `name-required` response rather than a generic validation failure.
130
+ name: z
131
+ .string()
132
+ .max(100)
133
+ .optional()
134
+ .transform((value) => {
135
+ const trimmed = value?.trim();
136
+ return trimmed ? trimmed : undefined;
137
+ }),
138
+ });
139
+ /**
140
+ * Signs a user in with an emailed code, creating the account on first use.
141
+ *
142
+ * A verified code proves control of the inbox, so the account it creates (or
143
+ * signs in to) is marked as having a verified email. Accounts created this way
144
+ * have no password until the user goes through the password reset flow.
145
+ *
146
+ * @throws BadRequestError `name-required` when the code is valid but the
147
+ * address has no account yet and no name was supplied. The code is left intact
148
+ * so the client can collect a name and retry with it.
149
+ */
150
+ export async function signInWithEmailOtp({ input, context, }) {
151
+ const { email, code, name } = await verifyEmailOtpSchema
152
+ .parseAsync(input)
153
+ .catch(handleZodRequestValidationError);
154
+ await getEmailOtpVerifyIpLimiter().consumeOrThrow(context.reqInfo.ip, 'Too many sign-in attempts. Please try again later.', 'too-many-requests');
155
+ // A code is only redeemable in the browser that requested it.
156
+ const verificationId = context.cookieStore.get(EMAIL_OTP_COOKIE_NAME);
157
+ if (!verificationId) {
158
+ throw new BadRequestError('This code must be entered in the browser that requested it', 'verification-context-missing');
159
+ }
160
+ // Establish that this browser owns the outstanding code before spending any
161
+ // of the address's budget. Charging first would let anyone lock a chosen
162
+ // address out of signing in just by posting its email with a junk code —
163
+ // which is worse than it sounds, because an account created through this
164
+ // flow has no password to fall back on.
165
+ const challenge = await prisma.authVerification.findUnique({
166
+ where: { type_identifier: { type: EMAIL_OTP_TYPE, identifier: email } },
167
+ select: { id: true },
168
+ });
169
+ if (challenge?.id !== verificationId) {
170
+ throw new BadRequestError('Invalid or expired code', 'invalid-code');
171
+ }
172
+ await getEmailOtpVerifyEmailLimiter().consumeOrThrow(email, 'Too many sign-in attempts. Please try again later.', 'too-many-requests');
173
+ const record = await validateCodeVerification({
174
+ type: EMAIL_OTP_TYPE,
175
+ identifier: email,
176
+ code,
177
+ maxAttempts: EMAIL_OTP_MAX_ATTEMPTS,
178
+ });
179
+ if (!record) {
180
+ throw new BadRequestError('Invalid or expired code', 'invalid-code');
181
+ }
182
+ // Re-checked because a fresh code may have been issued since the lookup
183
+ // above, which would have replaced the id this browser is holding.
184
+ if (record.id !== verificationId) {
185
+ throw new BadRequestError('Invalid or expired code', 'invalid-code');
186
+ }
187
+ // Asking for a name only when the address is new would normally leak whether
188
+ // an account exists. Gating it behind a valid code keeps that safe: only
189
+ // someone who controls the mailbox reaches this point.
190
+ TPL_NAME_REQUIRED_CHECK;
191
+ // Spending the code and settling the account commit together, so a failure
192
+ // partway through leaves the code still usable rather than burning it and
193
+ // forcing the user to request another.
194
+ const userId = await prisma.$transaction(async (tx) => {
195
+ if (!(await consumeCodeVerification({ id: record.id, client: tx }))) {
196
+ throw new BadRequestError('Invalid or expired code', 'invalid-code');
197
+ }
198
+ // Receiving the code proves control of the address, so the account is
199
+ // created (or marked) as verified. An existing user's name is left alone.
200
+ const { id } = await tx.user.upsert({
201
+ where: { email },
202
+ create: {
203
+ email,
204
+ name,
205
+ emailVerified: true,
206
+ accounts: {
207
+ create: {
208
+ accountId: email,
209
+ providerId: PROVIDER_ID,
210
+ },
211
+ },
212
+ },
213
+ update: { emailVerified: true },
214
+ select: { id: true },
215
+ });
216
+ return id;
217
+ });
218
+ context.cookieStore.clear(EMAIL_OTP_COOKIE_NAME, getEmailOtpCookieOptions());
219
+ // Outside the transaction: session creation manages its own storage through
220
+ // the request context. If it fails the code is spent, but the account now
221
+ // exists, so retrying signs the user in without asking for a name again.
222
+ const session = await context.services.userSession.createSession(userId, context);
223
+ return { session };
224
+ }
225
+ //# sourceMappingURL=email-otp.service.js.map