@contember/engine-tenant-api 2.0.0-alpha.14 → 2.0.0-alpha.16

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 (534) hide show
  1. package/dist/development/index.cjs +18 -6
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +20 -8
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/development/src/TenantContainer.cjs +7 -1
  6. package/dist/development/src/TenantContainer.cjs.map +1 -1
  7. package/dist/development/src/TenantContainer.js +7 -1
  8. package/dist/development/src/TenantContainer.js.map +1 -1
  9. package/dist/development/src/migrations/2024-08-26-120000-passwordless.cjs +31 -0
  10. package/dist/development/src/migrations/2024-08-26-120000-passwordless.cjs.map +1 -0
  11. package/dist/development/src/migrations/2024-08-26-120000-passwordless.js +32 -0
  12. package/dist/development/src/migrations/2024-08-26-120000-passwordless.js.map +1 -0
  13. package/dist/development/src/migrations/runner.cjs +3 -1
  14. package/dist/development/src/migrations/runner.cjs.map +1 -1
  15. package/dist/development/src/migrations/runner.js +3 -1
  16. package/dist/development/src/migrations/runner.js.map +1 -1
  17. package/dist/development/src/migrations/snapshot.cjs +33 -5
  18. package/dist/development/src/migrations/snapshot.cjs.map +1 -1
  19. package/dist/development/src/migrations/snapshot.js +33 -5
  20. package/dist/development/src/migrations/snapshot.js.map +1 -1
  21. package/dist/development/src/model/authorization/PermissionActions.cjs +5 -0
  22. package/dist/development/src/model/authorization/PermissionActions.cjs.map +1 -1
  23. package/dist/development/src/model/authorization/PermissionActions.js +5 -0
  24. package/dist/development/src/model/authorization/PermissionActions.js.map +1 -1
  25. package/dist/development/src/model/authorization/PermissionsFactory.cjs +5 -0
  26. package/dist/development/src/model/authorization/PermissionsFactory.cjs.map +1 -1
  27. package/dist/development/src/model/authorization/PermissionsFactory.js +5 -0
  28. package/dist/development/src/model/authorization/PermissionsFactory.js.map +1 -1
  29. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.cjs +20 -0
  30. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.cjs.map +1 -0
  31. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.js +20 -0
  32. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.js.map +1 -0
  33. package/dist/development/src/model/commands/person/CreatePersonCommand.cjs +2 -1
  34. package/dist/development/src/model/commands/person/CreatePersonCommand.cjs.map +1 -1
  35. package/dist/development/src/model/commands/person/CreatePersonCommand.js +2 -1
  36. package/dist/development/src/model/commands/person/CreatePersonCommand.js.map +1 -1
  37. package/dist/development/src/model/commands/person/TogglePersonPasswordlessCommand.cjs +18 -0
  38. package/dist/development/src/model/commands/person/TogglePersonPasswordlessCommand.cjs.map +1 -0
  39. package/dist/development/src/model/commands/person/TogglePersonPasswordlessCommand.js +18 -0
  40. package/dist/development/src/model/commands/person/TogglePersonPasswordlessCommand.js.map +1 -0
  41. package/dist/development/src/model/commands/personToken/ActivateOtpCommand.cjs +20 -0
  42. package/dist/development/src/model/commands/personToken/ActivateOtpCommand.cjs.map +1 -0
  43. package/dist/development/src/model/commands/personToken/ActivateOtpCommand.js +20 -0
  44. package/dist/development/src/model/commands/personToken/ActivateOtpCommand.js.map +1 -0
  45. package/dist/development/src/model/commands/personToken/CreatePersonTokenCommand.cjs +33 -0
  46. package/dist/development/src/model/commands/personToken/CreatePersonTokenCommand.cjs.map +1 -0
  47. package/dist/development/src/model/commands/personToken/CreatePersonTokenCommand.js +33 -0
  48. package/dist/development/src/model/commands/personToken/CreatePersonTokenCommand.js.map +1 -0
  49. package/dist/development/src/model/commands/personToken/IncreaseOtpAttemptCommand.cjs +19 -0
  50. package/dist/development/src/model/commands/personToken/IncreaseOtpAttemptCommand.cjs.map +1 -0
  51. package/dist/development/src/model/commands/personToken/IncreaseOtpAttemptCommand.js +19 -0
  52. package/dist/development/src/model/commands/personToken/IncreaseOtpAttemptCommand.js.map +1 -0
  53. package/dist/development/src/model/commands/personToken/InvalidateTokenCommand.cjs +19 -0
  54. package/dist/development/src/model/commands/personToken/InvalidateTokenCommand.cjs.map +1 -0
  55. package/dist/development/src/model/commands/personToken/InvalidateTokenCommand.js +19 -0
  56. package/dist/development/src/model/commands/personToken/InvalidateTokenCommand.js.map +1 -0
  57. package/dist/development/src/model/commands/personToken/ResetPasswordCommand.cjs +28 -0
  58. package/dist/development/src/model/commands/personToken/ResetPasswordCommand.cjs.map +1 -0
  59. package/dist/development/src/model/commands/personToken/ResetPasswordCommand.js +28 -0
  60. package/dist/development/src/model/commands/personToken/ResetPasswordCommand.js.map +1 -0
  61. package/dist/development/src/model/commands/personToken/SavePersonTokenCommand.cjs +28 -0
  62. package/dist/development/src/model/commands/personToken/SavePersonTokenCommand.cjs.map +1 -0
  63. package/dist/development/src/model/commands/personToken/SavePersonTokenCommand.js +28 -0
  64. package/dist/development/src/model/commands/personToken/SavePersonTokenCommand.js.map +1 -0
  65. package/dist/development/src/model/consts/expirations.cjs +7 -0
  66. package/dist/development/src/model/consts/expirations.cjs.map +1 -0
  67. package/dist/development/src/model/consts/expirations.js +7 -0
  68. package/dist/development/src/model/consts/expirations.js.map +1 -0
  69. package/dist/development/src/model/mailing/UserMailer.cjs +10 -1
  70. package/dist/development/src/model/mailing/UserMailer.cjs.map +1 -1
  71. package/dist/development/src/model/mailing/UserMailer.js +10 -1
  72. package/dist/development/src/model/mailing/UserMailer.js.map +1 -1
  73. package/dist/development/src/model/mailing/templates/PasswordlessSignIn.mustache.cjs +17 -0
  74. package/dist/development/src/model/mailing/templates/PasswordlessSignIn.mustache.cjs.map +1 -0
  75. package/dist/development/src/model/mailing/templates/PasswordlessSignIn.mustache.js +18 -0
  76. package/dist/development/src/model/mailing/templates/PasswordlessSignIn.mustache.js.map +1 -0
  77. package/dist/development/src/model/mailing/type.cjs +9 -3
  78. package/dist/development/src/model/mailing/type.cjs.map +1 -1
  79. package/dist/development/src/model/mailing/type.js +9 -3
  80. package/dist/development/src/model/mailing/type.js.map +1 -1
  81. package/dist/development/src/model/queries/configuration/ConfigurationQuery.cjs +21 -0
  82. package/dist/development/src/model/queries/configuration/ConfigurationQuery.cjs.map +1 -0
  83. package/dist/development/src/model/queries/configuration/ConfigurationQuery.js +21 -0
  84. package/dist/development/src/model/queries/configuration/ConfigurationQuery.js.map +1 -0
  85. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.cjs +1 -1
  86. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.cjs.map +1 -1
  87. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.js +1 -1
  88. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.js.map +1 -1
  89. package/dist/development/src/model/queries/personToken/PersonTokenQuery.cjs +29 -0
  90. package/dist/development/src/model/queries/personToken/PersonTokenQuery.cjs.map +1 -0
  91. package/dist/development/src/model/queries/personToken/PersonTokenQuery.js +29 -0
  92. package/dist/development/src/model/queries/personToken/PersonTokenQuery.js.map +1 -0
  93. package/dist/development/src/model/service/ConfigurationManager.cjs +27 -0
  94. package/dist/development/src/model/service/ConfigurationManager.cjs.map +1 -0
  95. package/dist/development/src/model/service/ConfigurationManager.js +27 -0
  96. package/dist/development/src/model/service/ConfigurationManager.js.map +1 -0
  97. package/dist/development/src/model/service/InviteManager.cjs +7 -7
  98. package/dist/development/src/model/service/InviteManager.cjs.map +1 -1
  99. package/dist/development/src/model/service/InviteManager.js +6 -6
  100. package/dist/development/src/model/service/InviteManager.js.map +1 -1
  101. package/dist/development/src/model/service/PasswordChangeManager.cjs +1 -1
  102. package/dist/development/src/model/service/PasswordChangeManager.js +1 -1
  103. package/dist/development/src/model/service/PasswordResetManager.cjs +7 -15
  104. package/dist/development/src/model/service/PasswordResetManager.cjs.map +1 -1
  105. package/dist/development/src/model/service/PasswordResetManager.js +7 -15
  106. package/dist/development/src/model/service/PasswordResetManager.js.map +1 -1
  107. package/dist/development/src/model/service/PasswordlessSignInManager.cjs +135 -0
  108. package/dist/development/src/model/service/PasswordlessSignInManager.cjs.map +1 -0
  109. package/dist/development/src/model/service/PasswordlessSignInManager.js +135 -0
  110. package/dist/development/src/model/service/PasswordlessSignInManager.js.map +1 -0
  111. package/dist/development/src/model/service/PersonManager.cjs +7 -0
  112. package/dist/development/src/model/service/PersonManager.cjs.map +1 -1
  113. package/dist/development/src/model/service/PersonManager.js +7 -0
  114. package/dist/development/src/model/service/PersonManager.js.map +1 -1
  115. package/dist/development/src/model/service/ProjectManager.cjs +2 -2
  116. package/dist/development/src/model/service/ProjectManager.js +2 -2
  117. package/dist/development/src/model/service/RolesManager.cjs +1 -1
  118. package/dist/development/src/model/service/RolesManager.js +1 -1
  119. package/dist/development/src/model/service/SignUpManager.cjs +1 -1
  120. package/dist/development/src/model/service/SignUpManager.js +1 -1
  121. package/dist/development/src/model/service/helpers/getPreferredProject.cjs +13 -0
  122. package/dist/development/src/model/service/helpers/getPreferredProject.cjs.map +1 -0
  123. package/dist/development/src/model/service/helpers/getPreferredProject.js +13 -0
  124. package/dist/development/src/model/service/helpers/getPreferredProject.js.map +1 -0
  125. package/dist/development/src/model/service/idp/providers/OIDCProvider.cjs +2 -1
  126. package/dist/development/src/model/service/idp/providers/OIDCProvider.cjs.map +1 -1
  127. package/dist/development/src/model/service/idp/providers/OIDCProvider.js +2 -1
  128. package/dist/development/src/model/service/idp/providers/OIDCProvider.js.map +1 -1
  129. package/dist/development/src/model/service/idp/providers/OIDCTypes.cjs +2 -1
  130. package/dist/development/src/model/service/idp/providers/OIDCTypes.cjs.map +1 -1
  131. package/dist/development/src/model/service/idp/providers/OIDCTypes.js +2 -1
  132. package/dist/development/src/model/service/idp/providers/OIDCTypes.js.map +1 -1
  133. package/dist/development/src/model/utils/tokenUtils.cjs +39 -0
  134. package/dist/development/src/model/utils/tokenUtils.cjs.map +1 -1
  135. package/dist/development/src/model/utils/tokenUtils.js +40 -1
  136. package/dist/development/src/model/utils/tokenUtils.js.map +1 -1
  137. package/dist/development/src/resolvers/ResolverFactory.cjs +8 -1
  138. package/dist/development/src/resolvers/ResolverFactory.cjs.map +1 -1
  139. package/dist/development/src/resolvers/ResolverFactory.js +8 -1
  140. package/dist/development/src/resolvers/ResolverFactory.js.map +1 -1
  141. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs +41 -0
  142. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs.map +1 -0
  143. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js +41 -0
  144. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js.map +1 -0
  145. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs +83 -0
  146. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs.map +1 -0
  147. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.js +83 -0
  148. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.js.map +1 -0
  149. package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs.map +1 -1
  150. package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.js.map +1 -1
  151. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs +52 -0
  152. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs.map +1 -0
  153. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js +52 -0
  154. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js.map +1 -0
  155. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.cjs +34 -0
  156. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.cjs.map +1 -0
  157. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.js +34 -0
  158. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.js.map +1 -0
  159. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.cjs +1 -0
  160. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.cjs.map +1 -1
  161. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.js +1 -0
  162. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.js.map +1 -1
  163. package/dist/development/src/resolvers/types/ProjectTypeResolver.cjs.map +1 -1
  164. package/dist/development/src/resolvers/types/ProjectTypeResolver.js.map +1 -1
  165. package/dist/development/src/schema/tenant.graphql.cjs +161 -10
  166. package/dist/development/src/schema/tenant.graphql.cjs.map +1 -1
  167. package/dist/development/src/schema/tenant.graphql.js +161 -10
  168. package/dist/development/src/schema/tenant.graphql.js.map +1 -1
  169. package/dist/production/index.cjs +18 -6
  170. package/dist/production/index.cjs.map +1 -1
  171. package/dist/production/index.js +20 -8
  172. package/dist/production/index.js.map +1 -1
  173. package/dist/production/src/TenantContainer.cjs +7 -1
  174. package/dist/production/src/TenantContainer.cjs.map +1 -1
  175. package/dist/production/src/TenantContainer.js +7 -1
  176. package/dist/production/src/TenantContainer.js.map +1 -1
  177. package/dist/production/src/migrations/2024-08-26-120000-passwordless.cjs +31 -0
  178. package/dist/production/src/migrations/2024-08-26-120000-passwordless.cjs.map +1 -0
  179. package/dist/production/src/migrations/2024-08-26-120000-passwordless.js +32 -0
  180. package/dist/production/src/migrations/2024-08-26-120000-passwordless.js.map +1 -0
  181. package/dist/production/src/migrations/runner.cjs +3 -1
  182. package/dist/production/src/migrations/runner.cjs.map +1 -1
  183. package/dist/production/src/migrations/runner.js +3 -1
  184. package/dist/production/src/migrations/runner.js.map +1 -1
  185. package/dist/production/src/migrations/snapshot.cjs +33 -5
  186. package/dist/production/src/migrations/snapshot.cjs.map +1 -1
  187. package/dist/production/src/migrations/snapshot.js +33 -5
  188. package/dist/production/src/migrations/snapshot.js.map +1 -1
  189. package/dist/production/src/model/authorization/PermissionActions.cjs +5 -0
  190. package/dist/production/src/model/authorization/PermissionActions.cjs.map +1 -1
  191. package/dist/production/src/model/authorization/PermissionActions.js +5 -0
  192. package/dist/production/src/model/authorization/PermissionActions.js.map +1 -1
  193. package/dist/production/src/model/authorization/PermissionsFactory.cjs +5 -0
  194. package/dist/production/src/model/authorization/PermissionsFactory.cjs.map +1 -1
  195. package/dist/production/src/model/authorization/PermissionsFactory.js +5 -0
  196. package/dist/production/src/model/authorization/PermissionsFactory.js.map +1 -1
  197. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.cjs +20 -0
  198. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.cjs.map +1 -0
  199. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.js +20 -0
  200. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.js.map +1 -0
  201. package/dist/production/src/model/commands/person/CreatePersonCommand.cjs +2 -1
  202. package/dist/production/src/model/commands/person/CreatePersonCommand.cjs.map +1 -1
  203. package/dist/production/src/model/commands/person/CreatePersonCommand.js +2 -1
  204. package/dist/production/src/model/commands/person/CreatePersonCommand.js.map +1 -1
  205. package/dist/production/src/model/commands/person/TogglePersonPasswordlessCommand.cjs +18 -0
  206. package/dist/production/src/model/commands/person/TogglePersonPasswordlessCommand.cjs.map +1 -0
  207. package/dist/production/src/model/commands/person/TogglePersonPasswordlessCommand.js +18 -0
  208. package/dist/production/src/model/commands/person/TogglePersonPasswordlessCommand.js.map +1 -0
  209. package/dist/production/src/model/commands/personToken/ActivateOtpCommand.cjs +20 -0
  210. package/dist/production/src/model/commands/personToken/ActivateOtpCommand.cjs.map +1 -0
  211. package/dist/production/src/model/commands/personToken/ActivateOtpCommand.js +20 -0
  212. package/dist/production/src/model/commands/personToken/ActivateOtpCommand.js.map +1 -0
  213. package/dist/production/src/model/commands/personToken/CreatePersonTokenCommand.cjs +33 -0
  214. package/dist/production/src/model/commands/personToken/CreatePersonTokenCommand.cjs.map +1 -0
  215. package/dist/production/src/model/commands/personToken/CreatePersonTokenCommand.js +33 -0
  216. package/dist/production/src/model/commands/personToken/CreatePersonTokenCommand.js.map +1 -0
  217. package/dist/production/src/model/commands/personToken/IncreaseOtpAttemptCommand.cjs +19 -0
  218. package/dist/production/src/model/commands/personToken/IncreaseOtpAttemptCommand.cjs.map +1 -0
  219. package/dist/production/src/model/commands/personToken/IncreaseOtpAttemptCommand.js +19 -0
  220. package/dist/production/src/model/commands/personToken/IncreaseOtpAttemptCommand.js.map +1 -0
  221. package/dist/production/src/model/commands/personToken/InvalidateTokenCommand.cjs +19 -0
  222. package/dist/production/src/model/commands/personToken/InvalidateTokenCommand.cjs.map +1 -0
  223. package/dist/production/src/model/commands/personToken/InvalidateTokenCommand.js +19 -0
  224. package/dist/production/src/model/commands/personToken/InvalidateTokenCommand.js.map +1 -0
  225. package/dist/production/src/model/commands/personToken/ResetPasswordCommand.cjs +28 -0
  226. package/dist/production/src/model/commands/personToken/ResetPasswordCommand.cjs.map +1 -0
  227. package/dist/production/src/model/commands/personToken/ResetPasswordCommand.js +28 -0
  228. package/dist/production/src/model/commands/personToken/ResetPasswordCommand.js.map +1 -0
  229. package/dist/production/src/model/commands/personToken/SavePersonTokenCommand.cjs +28 -0
  230. package/dist/production/src/model/commands/personToken/SavePersonTokenCommand.cjs.map +1 -0
  231. package/dist/production/src/model/commands/personToken/SavePersonTokenCommand.js +28 -0
  232. package/dist/production/src/model/commands/personToken/SavePersonTokenCommand.js.map +1 -0
  233. package/dist/production/src/model/consts/expirations.cjs +7 -0
  234. package/dist/production/src/model/consts/expirations.cjs.map +1 -0
  235. package/dist/production/src/model/consts/expirations.js +7 -0
  236. package/dist/production/src/model/consts/expirations.js.map +1 -0
  237. package/dist/production/src/model/mailing/UserMailer.cjs +10 -1
  238. package/dist/production/src/model/mailing/UserMailer.cjs.map +1 -1
  239. package/dist/production/src/model/mailing/UserMailer.js +10 -1
  240. package/dist/production/src/model/mailing/UserMailer.js.map +1 -1
  241. package/dist/production/src/model/mailing/templates/PasswordlessSignIn.mustache.cjs +17 -0
  242. package/dist/production/src/model/mailing/templates/PasswordlessSignIn.mustache.cjs.map +1 -0
  243. package/dist/production/src/model/mailing/templates/PasswordlessSignIn.mustache.js +18 -0
  244. package/dist/production/src/model/mailing/templates/PasswordlessSignIn.mustache.js.map +1 -0
  245. package/dist/production/src/model/mailing/type.cjs +9 -3
  246. package/dist/production/src/model/mailing/type.cjs.map +1 -1
  247. package/dist/production/src/model/mailing/type.js +9 -3
  248. package/dist/production/src/model/mailing/type.js.map +1 -1
  249. package/dist/production/src/model/queries/configuration/ConfigurationQuery.cjs +21 -0
  250. package/dist/production/src/model/queries/configuration/ConfigurationQuery.cjs.map +1 -0
  251. package/dist/production/src/model/queries/configuration/ConfigurationQuery.js +21 -0
  252. package/dist/production/src/model/queries/configuration/ConfigurationQuery.js.map +1 -0
  253. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.cjs +1 -1
  254. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.cjs.map +1 -1
  255. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.js +1 -1
  256. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.js.map +1 -1
  257. package/dist/production/src/model/queries/personToken/PersonTokenQuery.cjs +29 -0
  258. package/dist/production/src/model/queries/personToken/PersonTokenQuery.cjs.map +1 -0
  259. package/dist/production/src/model/queries/personToken/PersonTokenQuery.js +29 -0
  260. package/dist/production/src/model/queries/personToken/PersonTokenQuery.js.map +1 -0
  261. package/dist/production/src/model/service/ConfigurationManager.cjs +27 -0
  262. package/dist/production/src/model/service/ConfigurationManager.cjs.map +1 -0
  263. package/dist/production/src/model/service/ConfigurationManager.js +27 -0
  264. package/dist/production/src/model/service/ConfigurationManager.js.map +1 -0
  265. package/dist/production/src/model/service/InviteManager.cjs +7 -7
  266. package/dist/production/src/model/service/InviteManager.cjs.map +1 -1
  267. package/dist/production/src/model/service/InviteManager.js +6 -6
  268. package/dist/production/src/model/service/InviteManager.js.map +1 -1
  269. package/dist/production/src/model/service/PasswordChangeManager.cjs +1 -1
  270. package/dist/production/src/model/service/PasswordChangeManager.js +1 -1
  271. package/dist/production/src/model/service/PasswordResetManager.cjs +7 -15
  272. package/dist/production/src/model/service/PasswordResetManager.cjs.map +1 -1
  273. package/dist/production/src/model/service/PasswordResetManager.js +7 -15
  274. package/dist/production/src/model/service/PasswordResetManager.js.map +1 -1
  275. package/dist/production/src/model/service/PasswordlessSignInManager.cjs +135 -0
  276. package/dist/production/src/model/service/PasswordlessSignInManager.cjs.map +1 -0
  277. package/dist/production/src/model/service/PasswordlessSignInManager.js +135 -0
  278. package/dist/production/src/model/service/PasswordlessSignInManager.js.map +1 -0
  279. package/dist/production/src/model/service/PersonManager.cjs +7 -0
  280. package/dist/production/src/model/service/PersonManager.cjs.map +1 -1
  281. package/dist/production/src/model/service/PersonManager.js +7 -0
  282. package/dist/production/src/model/service/PersonManager.js.map +1 -1
  283. package/dist/production/src/model/service/ProjectManager.cjs +2 -2
  284. package/dist/production/src/model/service/ProjectManager.js +2 -2
  285. package/dist/production/src/model/service/RolesManager.cjs +1 -1
  286. package/dist/production/src/model/service/RolesManager.js +1 -1
  287. package/dist/production/src/model/service/SignUpManager.cjs +1 -1
  288. package/dist/production/src/model/service/SignUpManager.js +1 -1
  289. package/dist/production/src/model/service/helpers/getPreferredProject.cjs +13 -0
  290. package/dist/production/src/model/service/helpers/getPreferredProject.cjs.map +1 -0
  291. package/dist/production/src/model/service/helpers/getPreferredProject.js +13 -0
  292. package/dist/production/src/model/service/helpers/getPreferredProject.js.map +1 -0
  293. package/dist/production/src/model/service/idp/providers/OIDCProvider.cjs +2 -1
  294. package/dist/production/src/model/service/idp/providers/OIDCProvider.cjs.map +1 -1
  295. package/dist/production/src/model/service/idp/providers/OIDCProvider.js +2 -1
  296. package/dist/production/src/model/service/idp/providers/OIDCProvider.js.map +1 -1
  297. package/dist/production/src/model/service/idp/providers/OIDCTypes.cjs +2 -1
  298. package/dist/production/src/model/service/idp/providers/OIDCTypes.cjs.map +1 -1
  299. package/dist/production/src/model/service/idp/providers/OIDCTypes.js +2 -1
  300. package/dist/production/src/model/service/idp/providers/OIDCTypes.js.map +1 -1
  301. package/dist/production/src/model/utils/tokenUtils.cjs +39 -0
  302. package/dist/production/src/model/utils/tokenUtils.cjs.map +1 -1
  303. package/dist/production/src/model/utils/tokenUtils.js +40 -1
  304. package/dist/production/src/model/utils/tokenUtils.js.map +1 -1
  305. package/dist/production/src/resolvers/ResolverFactory.cjs +8 -1
  306. package/dist/production/src/resolvers/ResolverFactory.cjs.map +1 -1
  307. package/dist/production/src/resolvers/ResolverFactory.js +8 -1
  308. package/dist/production/src/resolvers/ResolverFactory.js.map +1 -1
  309. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs +41 -0
  310. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs.map +1 -0
  311. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js +41 -0
  312. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js.map +1 -0
  313. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs +83 -0
  314. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs.map +1 -0
  315. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.js +83 -0
  316. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.js.map +1 -0
  317. package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs.map +1 -1
  318. package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.js.map +1 -1
  319. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs +52 -0
  320. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs.map +1 -0
  321. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js +52 -0
  322. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js.map +1 -0
  323. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.cjs +34 -0
  324. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.cjs.map +1 -0
  325. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.js +34 -0
  326. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.js.map +1 -0
  327. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.cjs +1 -0
  328. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.cjs.map +1 -1
  329. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.js +1 -0
  330. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.js.map +1 -1
  331. package/dist/production/src/resolvers/types/ProjectTypeResolver.cjs.map +1 -1
  332. package/dist/production/src/resolvers/types/ProjectTypeResolver.js.map +1 -1
  333. package/dist/production/src/schema/tenant.graphql.cjs +161 -10
  334. package/dist/production/src/schema/tenant.graphql.cjs.map +1 -1
  335. package/dist/production/src/schema/tenant.graphql.js +161 -10
  336. package/dist/production/src/schema/tenant.graphql.js.map +1 -1
  337. package/dist/tests/cases/integration/mocked/sql/{createPasswordResetSql.d.ts → createPersonTokenSql.d.ts} +3 -2
  338. package/dist/tests/cases/integration/mocked/sql/createPersonTokenSql.d.ts.map +1 -0
  339. package/dist/tests/cases/integration/mocked/sql/getPersonByEmailSql.d.ts.map +1 -1
  340. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  341. package/dist/types/TenantContainer.d.ts +18 -0
  342. package/dist/types/TenantContainer.d.ts.map +1 -1
  343. package/dist/types/migrations/2024-08-26-120000-passwordless.d.ts +3 -0
  344. package/dist/types/migrations/2024-08-26-120000-passwordless.d.ts.map +1 -0
  345. package/dist/types/migrations/runner.d.ts.map +1 -1
  346. package/dist/types/migrations/snapshot.d.ts.map +1 -1
  347. package/dist/types/model/authorization/PermissionActions.d.ts +25 -0
  348. package/dist/types/model/authorization/PermissionActions.d.ts.map +1 -1
  349. package/dist/types/model/authorization/PermissionsFactory.d.ts.map +1 -1
  350. package/dist/types/model/commands/configuration/UpdateConfigurationCommand.d.ts +8 -0
  351. package/dist/types/model/commands/configuration/UpdateConfigurationCommand.d.ts.map +1 -0
  352. package/dist/types/model/commands/configuration/index.d.ts +2 -0
  353. package/dist/types/model/commands/configuration/index.d.ts.map +1 -0
  354. package/dist/types/model/commands/index.d.ts +2 -2
  355. package/dist/types/model/commands/index.d.ts.map +1 -1
  356. package/dist/types/model/commands/person/CreatePersonCommand.d.ts.map +1 -1
  357. package/dist/types/model/commands/person/TogglePersonPasswordlessCommand.d.ts +8 -0
  358. package/dist/types/model/commands/person/TogglePersonPasswordlessCommand.d.ts.map +1 -0
  359. package/dist/types/model/commands/person/index.d.ts +1 -0
  360. package/dist/types/model/commands/person/index.d.ts.map +1 -1
  361. package/dist/types/model/commands/personToken/ActivateOtpCommand.d.ts +8 -0
  362. package/dist/types/model/commands/personToken/ActivateOtpCommand.d.ts.map +1 -0
  363. package/dist/types/model/commands/personToken/CreatePersonTokenCommand.d.ts +19 -0
  364. package/dist/types/model/commands/personToken/CreatePersonTokenCommand.d.ts.map +1 -0
  365. package/dist/types/model/commands/personToken/IncreaseOtpAttemptCommand.d.ts +7 -0
  366. package/dist/types/model/commands/personToken/IncreaseOtpAttemptCommand.d.ts.map +1 -0
  367. package/dist/types/model/commands/personToken/InvalidateTokenCommand.d.ts +7 -0
  368. package/dist/types/model/commands/personToken/InvalidateTokenCommand.d.ts.map +1 -0
  369. package/dist/types/model/commands/{passwordReset → personToken}/ResetPasswordCommand.d.ts +3 -2
  370. package/dist/types/model/commands/personToken/ResetPasswordCommand.d.ts.map +1 -0
  371. package/dist/types/model/commands/personToken/SavePersonTokenCommand.d.ts +19 -0
  372. package/dist/types/model/commands/personToken/SavePersonTokenCommand.d.ts.map +1 -0
  373. package/dist/types/model/commands/personToken/index.d.ts +7 -0
  374. package/dist/types/model/commands/personToken/index.d.ts.map +1 -0
  375. package/dist/types/model/consts/expirations.d.ts +3 -0
  376. package/dist/types/model/consts/expirations.d.ts.map +1 -0
  377. package/dist/types/model/mailing/UserMailer.d.ts +10 -0
  378. package/dist/types/model/mailing/UserMailer.d.ts.map +1 -1
  379. package/dist/types/model/mailing/templates/PasswordlessSignIn.mustache.d.ts +3 -0
  380. package/dist/types/model/mailing/templates/PasswordlessSignIn.mustache.d.ts.map +1 -0
  381. package/dist/types/model/mailing/type.d.ts +2 -1
  382. package/dist/types/model/mailing/type.d.ts.map +1 -1
  383. package/dist/types/model/queries/configuration/ConfigurationQuery.d.ts +6 -0
  384. package/dist/types/model/queries/configuration/ConfigurationQuery.d.ts.map +1 -0
  385. package/dist/types/model/queries/configuration/index.d.ts +2 -0
  386. package/dist/types/model/queries/configuration/index.d.ts.map +1 -0
  387. package/dist/types/model/queries/index.d.ts +1 -0
  388. package/dist/types/model/queries/index.d.ts.map +1 -1
  389. package/dist/types/model/queries/person/PersonQueryBuilderFactory.d.ts.map +1 -1
  390. package/dist/types/model/queries/person/types.d.ts +1 -0
  391. package/dist/types/model/queries/person/types.d.ts.map +1 -1
  392. package/dist/types/model/queries/personToken/PersonTokenQuery.d.ts +12 -0
  393. package/dist/types/model/queries/personToken/PersonTokenQuery.d.ts.map +1 -0
  394. package/dist/types/model/service/ConfigurationManager.d.ts +9 -0
  395. package/dist/types/model/service/ConfigurationManager.d.ts.map +1 -0
  396. package/dist/types/model/service/InviteManager.d.ts.map +1 -1
  397. package/dist/types/model/service/PasswordResetManager.d.ts +1 -1
  398. package/dist/types/model/service/PasswordResetManager.d.ts.map +1 -1
  399. package/dist/types/model/service/PasswordlessSignInManager.d.ts +54 -0
  400. package/dist/types/model/service/PasswordlessSignInManager.d.ts.map +1 -0
  401. package/dist/types/model/service/PersonManager.d.ts +1 -0
  402. package/dist/types/model/service/PersonManager.d.ts.map +1 -1
  403. package/dist/types/model/service/PersonTokenManager.d.ts +3 -0
  404. package/dist/types/model/service/PersonTokenManager.d.ts.map +1 -0
  405. package/dist/types/model/service/helpers/getPreferredProject.d.ts +3 -0
  406. package/dist/types/model/service/helpers/getPreferredProject.d.ts.map +1 -0
  407. package/dist/types/model/service/idp/providers/AppleProvider.d.ts +2 -0
  408. package/dist/types/model/service/idp/providers/AppleProvider.d.ts.map +1 -1
  409. package/dist/types/model/service/idp/providers/FacebookProvider.d.ts +2 -0
  410. package/dist/types/model/service/idp/providers/FacebookProvider.d.ts.map +1 -1
  411. package/dist/types/model/service/idp/providers/OIDCProvider.d.ts +1 -0
  412. package/dist/types/model/service/idp/providers/OIDCProvider.d.ts.map +1 -1
  413. package/dist/types/model/service/idp/providers/OIDCTypes.d.ts +9 -5
  414. package/dist/types/model/service/idp/providers/OIDCTypes.d.ts.map +1 -1
  415. package/dist/types/model/type/PersonToken.d.ts +16 -0
  416. package/dist/types/model/type/PersonToken.d.ts.map +1 -0
  417. package/dist/types/model/type/index.d.ts +1 -0
  418. package/dist/types/model/type/index.d.ts.map +1 -1
  419. package/dist/types/model/utils/tokenUtils.d.ts +8 -0
  420. package/dist/types/model/utils/tokenUtils.d.ts.map +1 -1
  421. package/dist/types/resolvers/ResolverFactory.d.ts +8 -0
  422. package/dist/types/resolvers/ResolverFactory.d.ts.map +1 -1
  423. package/dist/types/resolvers/mutation/configuration/ConfigurationMutationResolver.d.ts +9 -0
  424. package/dist/types/resolvers/mutation/configuration/ConfigurationMutationResolver.d.ts.map +1 -0
  425. package/dist/types/resolvers/mutation/person/PasswordlessMutationResolver.d.ts +13 -0
  426. package/dist/types/resolvers/mutation/person/PasswordlessMutationResolver.d.ts.map +1 -0
  427. package/dist/types/resolvers/mutation/person/ResetPasswordMutationResolver.d.ts.map +1 -1
  428. package/dist/types/resolvers/mutation/person/TogglePasswordlessMutationResolver.d.ts +13 -0
  429. package/dist/types/resolvers/mutation/person/TogglePasswordlessMutationResolver.d.ts.map +1 -0
  430. package/dist/types/resolvers/query/ConfigurationQueryResolver.d.ts +9 -0
  431. package/dist/types/resolvers/query/ConfigurationQueryResolver.d.ts.map +1 -0
  432. package/dist/types/resolvers/responseHelpers/PersonResponseFactory.d.ts.map +1 -1
  433. package/dist/types/resolvers/types/ProjectTypeResolver.d.ts +3 -3
  434. package/dist/types/schema/index.d.ts +360 -38
  435. package/dist/types/schema/index.d.ts.map +1 -1
  436. package/dist/types/schema/tenant.graphql.d.ts.map +1 -1
  437. package/dist/types/tsconfig.tsbuildinfo +1 -1
  438. package/dist/types/utils/batchQuery.d.ts.map +1 -1
  439. package/{graphql-tenant.codegen.yml → graphql.codegen.yml} +1 -1
  440. package/package.json +22 -26
  441. package/src/TenantContainer.ts +18 -0
  442. package/src/migrations/2024-08-26-120000-passwordless.ts +31 -0
  443. package/src/migrations/runner.ts +2 -0
  444. package/src/migrations/snapshot-template-end.txt +3 -0
  445. package/src/migrations/snapshot.ts +33 -5
  446. package/src/model/authorization/PermissionActions.ts +7 -0
  447. package/src/model/authorization/PermissionsFactory.ts +5 -0
  448. package/src/model/commands/configuration/UpdateConfigurationCommand.ts +26 -0
  449. package/src/model/commands/configuration/index.ts +1 -0
  450. package/src/model/commands/index.ts +2 -2
  451. package/src/model/commands/person/CreatePersonCommand.ts +1 -0
  452. package/src/model/commands/person/TogglePersonPasswordlessCommand.ts +18 -0
  453. package/src/model/commands/person/index.ts +1 -0
  454. package/src/model/commands/personToken/ActivateOtpCommand.ts +24 -0
  455. package/src/model/commands/personToken/CreatePersonTokenCommand.ts +42 -0
  456. package/src/model/commands/personToken/IncreaseOtpAttemptCommand.ts +23 -0
  457. package/src/model/commands/personToken/InvalidateTokenCommand.ts +22 -0
  458. package/src/model/commands/personToken/ResetPasswordCommand.ts +28 -0
  459. package/src/model/commands/personToken/SavePersonTokenCommand.ts +42 -0
  460. package/src/model/commands/personToken/index.ts +6 -0
  461. package/src/model/consts/expirations.ts +2 -0
  462. package/src/model/mailing/UserMailer.ts +14 -0
  463. package/src/model/mailing/templates/PasswordlessSignIn.mustache.ts +15 -0
  464. package/src/model/mailing/type.ts +3 -0
  465. package/src/model/queries/configuration/ConfigurationQuery.ts +30 -0
  466. package/src/model/queries/configuration/index.ts +1 -0
  467. package/src/model/queries/index.ts +1 -0
  468. package/src/model/queries/person/PersonQueryBuilderFactory.ts +1 -0
  469. package/src/model/queries/person/types.ts +1 -0
  470. package/src/model/queries/personToken/PersonTokenQuery.ts +35 -0
  471. package/src/model/service/ConfigurationManager.ts +22 -0
  472. package/src/model/service/InviteManager.ts +5 -6
  473. package/src/model/service/PasswordResetManager.ts +4 -10
  474. package/src/model/service/PasswordlessSignInManager.ts +190 -0
  475. package/src/model/service/PersonManager.ts +6 -0
  476. package/src/model/service/PersonTokenManager.ts +2 -0
  477. package/src/model/service/helpers/getPreferredProject.ts +11 -0
  478. package/src/model/service/idp/providers/OIDCProvider.ts +1 -0
  479. package/src/model/service/idp/providers/OIDCTypes.ts +1 -0
  480. package/src/model/type/PersonToken.ts +21 -0
  481. package/src/model/type/index.ts +1 -0
  482. package/src/model/utils/tokenUtils.ts +47 -0
  483. package/src/resolvers/ResolverFactory.ts +19 -0
  484. package/src/resolvers/mutation/configuration/ConfigurationMutationResolver.ts +29 -0
  485. package/src/resolvers/mutation/person/PasswordlessMutationResolver.ts +81 -0
  486. package/src/resolvers/mutation/person/ResetPasswordMutationResolver.ts +1 -10
  487. package/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.ts +44 -0
  488. package/src/resolvers/query/ConfigurationQueryResolver.ts +21 -0
  489. package/src/resolvers/responseHelpers/PersonResponseFactory.ts +1 -0
  490. package/src/resolvers/types/ProjectTypeResolver.ts +3 -3
  491. package/src/schema/index.ts +360 -35
  492. package/src/schema/tenant.graphql.ts +161 -10
  493. package/tests/cases/integration/mocked/inviteMutations.test.ts +2 -2
  494. package/tests/cases/integration/mocked/sql/{createPasswordResetSql.ts → createPersonTokenSql.ts} +5 -3
  495. package/tests/cases/integration/mocked/sql/getPersonByEmailSql.ts +2 -1
  496. package/tests/cases/integration/mocked/sql/getPersonByIdSql.ts +1 -1
  497. package/tests/cases/integration/mocked/sql/getPersonByIdentity.ts +1 -1
  498. package/tests/cases/integration/mocked/sql/getPersonByIdpSql.ts +1 -1
  499. package/dist/development/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.cjs +0 -30
  500. package/dist/development/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.cjs.map +0 -1
  501. package/dist/development/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.js +0 -30
  502. package/dist/development/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.js.map +0 -1
  503. package/dist/development/src/model/commands/passwordReset/ResetPasswordCommand.cjs +0 -38
  504. package/dist/development/src/model/commands/passwordReset/ResetPasswordCommand.cjs.map +0 -1
  505. package/dist/development/src/model/commands/passwordReset/ResetPasswordCommand.js +0 -38
  506. package/dist/development/src/model/commands/passwordReset/ResetPasswordCommand.js.map +0 -1
  507. package/dist/development/src/model/commands/passwordReset/SavePasswordResetRequestCommand.cjs +0 -24
  508. package/dist/development/src/model/commands/passwordReset/SavePasswordResetRequestCommand.cjs.map +0 -1
  509. package/dist/development/src/model/commands/passwordReset/SavePasswordResetRequestCommand.js +0 -24
  510. package/dist/development/src/model/commands/passwordReset/SavePasswordResetRequestCommand.js.map +0 -1
  511. package/dist/production/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.cjs +0 -30
  512. package/dist/production/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.cjs.map +0 -1
  513. package/dist/production/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.js +0 -30
  514. package/dist/production/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.js.map +0 -1
  515. package/dist/production/src/model/commands/passwordReset/ResetPasswordCommand.cjs +0 -38
  516. package/dist/production/src/model/commands/passwordReset/ResetPasswordCommand.cjs.map +0 -1
  517. package/dist/production/src/model/commands/passwordReset/ResetPasswordCommand.js +0 -38
  518. package/dist/production/src/model/commands/passwordReset/ResetPasswordCommand.js.map +0 -1
  519. package/dist/production/src/model/commands/passwordReset/SavePasswordResetRequestCommand.cjs +0 -24
  520. package/dist/production/src/model/commands/passwordReset/SavePasswordResetRequestCommand.cjs.map +0 -1
  521. package/dist/production/src/model/commands/passwordReset/SavePasswordResetRequestCommand.js +0 -24
  522. package/dist/production/src/model/commands/passwordReset/SavePasswordResetRequestCommand.js.map +0 -1
  523. package/dist/tests/cases/integration/mocked/sql/createPasswordResetSql.d.ts.map +0 -1
  524. package/dist/types/model/commands/passwordReset/CreatePasswordResetRequestCommand.d.ts +0 -12
  525. package/dist/types/model/commands/passwordReset/CreatePasswordResetRequestCommand.d.ts.map +0 -1
  526. package/dist/types/model/commands/passwordReset/ResetPasswordCommand.d.ts.map +0 -1
  527. package/dist/types/model/commands/passwordReset/SavePasswordResetRequestCommand.d.ts +0 -10
  528. package/dist/types/model/commands/passwordReset/SavePasswordResetRequestCommand.d.ts.map +0 -1
  529. package/dist/types/model/commands/passwordReset/index.d.ts +0 -4
  530. package/dist/types/model/commands/passwordReset/index.d.ts.map +0 -1
  531. package/src/model/commands/passwordReset/CreatePasswordResetRequestCommand.ts +0 -25
  532. package/src/model/commands/passwordReset/ResetPasswordCommand.ts +0 -57
  533. package/src/model/commands/passwordReset/SavePasswordResetRequestCommand.ts +0 -28
  534. package/src/model/commands/passwordReset/index.ts +0 -3
@@ -1,12 +1,12 @@
1
1
  import "../type/ApiKey.js";
2
2
  import "@contember/database";
3
3
  import "node:crypto";
4
+ import { ResponseError, ResponseOk } from "../utils/Response.js";
4
5
  import { CreatePersonCommand } from "../commands/person/CreatePersonCommand.js";
5
6
  import { CreateIdentityCommand } from "../commands/identity/CreateIdentityCommand.js";
6
7
  import { CreateOrUpdateProjectMembershipCommand } from "../commands/membership/CreateOrUpdateProjectMembershipCommand.js";
7
- import { ResponseError, ResponseOk } from "../utils/Response.js";
8
- import { CreatePasswordResetRequestCommand } from "../commands/passwordReset/CreatePasswordResetRequestCommand.js";
9
- import { SavePasswordResetRequestCommand } from "../commands/passwordReset/SavePasswordResetRequestCommand.js";
8
+ import { CreatePersonTokenCommand } from "../commands/personToken/CreatePersonTokenCommand.js";
9
+ import { SavePersonTokenCommand } from "../commands/personToken/SavePersonTokenCommand.js";
10
10
  import "../queries/apiKey/ApiKeyQuery.js";
11
11
  import { PersonQuery } from "../queries/person/PersonQuery.js";
12
12
  import "../authorization/PermissionActions.js";
@@ -18,7 +18,7 @@ import "@contember/schema";
18
18
  import { createAppendMembershipVariables } from "./membershipUtils.js";
19
19
  import { PasswordPlain, NoPassword } from "../dtos/Password.js";
20
20
  import { validateEmail } from "../utils/email.js";
21
- const INVITATION_RESET_TOKEN_EXPIRATION_MINUTES = 60 * 24;
21
+ import { INVITATION_RESET_TOKEN_EXPIRATION_MINUTES } from "../consts/expirations.js";
22
22
  class InviteManager {
23
23
  constructor(providers, mailer, projectSchemaResolver) {
24
24
  this.providers = providers;
@@ -55,11 +55,11 @@ class InviteManager {
55
55
  password: passwordWrapper
56
56
  }));
57
57
  if (method === "RESET_PASSWORD") {
58
- const result = await trx.commandBus.execute(new CreatePasswordResetRequestCommand(person.id, await this.getInviteExpiration(project.slug)));
58
+ const result = await trx.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id, await this.getInviteExpiration(project.slug)));
59
59
  resetToken = result.token;
60
60
  }
61
61
  if (passwordResetTokenHash) {
62
- await trx.commandBus.execute(new SavePasswordResetRequestCommand(person.id, passwordResetTokenHash, await this.getInviteExpiration(project.slug)));
62
+ await trx.commandBus.execute(new SavePersonTokenCommand(person.id, passwordResetTokenHash, "password_reset", await this.getInviteExpiration(project.slug)));
63
63
  }
64
64
  }
65
65
  for (const membershipUpdate of createAppendMembershipVariables(memberships)) {
@@ -1 +1 @@
1
- {"version":3,"file":"InviteManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/InviteManager.ts"],"sourcesContent":["import {\n\tCreateIdentityCommand,\n\tCreateOrUpdateProjectMembershipCommand,\n\tCreatePasswordResetRequestCommand,\n\tCreatePersonCommand,\n\tSavePasswordResetRequestCommand,\n} from '../commands'\nimport { Providers } from '../providers'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { Project, ProjectSchemaResolver } from '../type'\nimport { InviteErrorCode, InviteMethod } from '../../schema'\nimport { TenantRole } from '../authorization'\nimport { UserMailer } from '../mailing'\nimport { createAppendMembershipVariables } from './membershipUtils'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport { DatabaseContext, TokenHash } from '../utils'\nimport { NoPassword, PasswordPlain } from '../dtos'\nimport { Acl } from '@contember/schema'\nimport { validateEmail } from '../utils/email'\n\nexport interface InviteData {\n\temail: string\n\tname?: string\n\tproject: Project\n\tmemberships: readonly Acl.Membership[]\n\tnoEmail?: boolean\n\tpassword?: string\n\temailVariant?: string\n\tmethod?: InviteMethod\n\tpasswordResetTokenHash?: TokenHash\n}\n\nconst INVITATION_RESET_TOKEN_EXPIRATION_MINUTES = 60 * 24\n\nexport class InviteManager {\n\tconstructor(\n\t\tprivate readonly providers: Providers,\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectSchemaResolver: ProjectSchemaResolver,\n\t) { }\n\n\tasync invite(\n\t\tdbContext: DatabaseContext,\n\t\t{\n\t\t\temail,\n\t\t\tproject,\n\t\t\tname,\n\t\t\tmemberships,\n\t\t\tmethod,\n\t\t\temailVariant,\n\t\t\tnoEmail = false,\n\t\t\tpassword,\n\t\t\tpasswordResetTokenHash,\n\t\t}: InviteData,\n\t): Promise<InviteResponse> {\n\t\tif (!validateEmail(email.trim())) {\n\t\t\treturn new ResponseError('INVALID_EMAIL_FORMAT', 'E-mail address is not in a valid format')\n\t\t}\n\n\t\treturn await dbContext.transaction(async trx => {\n\t\t\tlet person: Omit<PersonRow, 'roles'> | null = await trx.queryHandler.fetch(PersonQuery.byEmail(email))\n\t\t\tconst isNew = !person\n\t\t\tlet generatedPassword: string | null = null\n\t\t\tlet resetToken: string | null = null\n\t\t\tif (!person) {\n\t\t\t\tconst identityId = await trx.commandBus.execute(new CreateIdentityCommand([TenantRole.PERSON]))\n\n\t\t\t\tgeneratedPassword = password ??\n\t\t\t\t\t(method === 'CREATE_PASSWORD' ? (await this.providers.randomBytes(9)).toString('base64') : null)\n\t\t\t\tconst passwordWrapper = generatedPassword !== null ? new PasswordPlain(generatedPassword) : NoPassword\n\n\t\t\t\tperson = await trx.commandBus.execute(new CreatePersonCommand({\n\t\t\t\t\tidentityId,\n\t\t\t\t\temail,\n\t\t\t\t\tname,\n\t\t\t\t\tpassword: passwordWrapper,\n\t\t\t\t}))\n\t\t\t\tif (method === 'RESET_PASSWORD') {\n\t\t\t\t\tconst result = await trx.commandBus.execute(new CreatePasswordResetRequestCommand(person.id, await this.getInviteExpiration(project.slug)))\n\t\t\t\t\tresetToken = result.token\n\t\t\t\t}\n\t\t\t\tif (passwordResetTokenHash) {\n\t\t\t\t\tawait trx.commandBus.execute(new SavePasswordResetRequestCommand(person.id, passwordResetTokenHash, await this.getInviteExpiration(project.slug)))\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const membershipUpdate of createAppendMembershipVariables(memberships)) {\n\t\t\t\tawait trx.commandBus.execute(new CreateOrUpdateProjectMembershipCommand(project.id, person.identity_id, membershipUpdate))\n\t\t\t}\n\t\t\tif (!noEmail) {\n\t\t\t\tconst customMailOptions = {\n\t\t\t\t\tprojectId: project.id,\n\t\t\t\t\tvariant: emailVariant ?? '',\n\t\t\t\t}\n\t\t\t\tif (isNew) {\n\t\t\t\t\tawait this.mailer.sendNewUserInvitedMail(\n\t\t\t\t\t\ttrx,\n\t\t\t\t\t\t{ email, project: project.name, projectSlug: project.slug, password: generatedPassword, token: resetToken },\n\t\t\t\t\t\tcustomMailOptions,\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tawait this.mailer.sendExistingUserInvitedEmail(trx, { email, project: project.name, projectSlug: project.slug }, customMailOptions)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new ResponseOk(new InviteResult(person, isNew))\n\t\t})\n\t}\n\n\tprivate async getInviteExpiration(projectSlug: string): Promise<number> {\n\t\tconst schema = await this.projectSchemaResolver.getSchema(projectSlug)\n\n\t\treturn schema?.settings.tenant?.inviteExpirationMinutes ?? INVITATION_RESET_TOKEN_EXPIRATION_MINUTES\n\t}\n}\n\nexport type InviteResponse = Response<InviteResult, InviteErrorCode>\n\nexport class InviteResult {\n\tconstructor(public readonly person: Omit<PersonRow, 'roles'>, public readonly isNew: boolean) { }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAgCA,MAAM,4CAA4C,KAAK;AAEhD,MAAM,cAAc;AAAA,EAC1B,YACkB,WACA,QACA,uBAChB;AAHgB,SAAA,YAAA;AACA,SAAA,SAAA;AACA,SAAA,wBAAA;AAAA,EACd;AAAA,EAEJ,MAAM,OACL,WACA;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EAAA,GAEyB;AAC1B,QAAI,CAAC,cAAc,MAAM,KAAM,CAAA,GAAG;AAC1B,aAAA,IAAI,cAAc,wBAAwB,yCAAyC;AAAA,IAC3F;AAEA,WAAO,MAAM,UAAU,YAAY,OAAM,QAAO;AAC3C,UAAA,SAA0C,MAAM,IAAI,aAAa,MAAM,YAAY,QAAQ,KAAK,CAAC;AACrG,YAAM,QAAQ,CAAC;AACf,UAAI,oBAAmC;AACvC,UAAI,aAA4B;AAChC,UAAI,CAAC,QAAQ;AACN,cAAA,aAAa,MAAM,IAAI,WAAW,QAAQ,IAAI,sBAAsB,CAAC,WAAW,MAAM,CAAC,CAAC;AAE1E,4BAAA,aAClB,WAAW,qBAAqB,MAAM,KAAK,UAAU,YAAY,CAAC,GAAG,SAAS,QAAQ,IAAI;AAC5F,cAAM,kBAAkB,sBAAsB,OAAO,IAAI,cAAc,iBAAiB,IAAI;AAE5F,iBAAS,MAAM,IAAI,WAAW,QAAQ,IAAI,oBAAoB;AAAA,UAC7D;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QACV,CAAA,CAAC;AACF,YAAI,WAAW,kBAAkB;AAChC,gBAAM,SAAS,MAAM,IAAI,WAAW,QAAQ,IAAI,kCAAkC,OAAO,IAAI,MAAM,KAAK,oBAAoB,QAAQ,IAAI,CAAC,CAAC;AAC1I,uBAAa,OAAO;AAAA,QACrB;AACA,YAAI,wBAAwB;AAC3B,gBAAM,IAAI,WAAW,QAAQ,IAAI,gCAAgC,OAAO,IAAI,wBAAwB,MAAM,KAAK,oBAAoB,QAAQ,IAAI,CAAC,CAAC;AAAA,QAClJ;AAAA,MACD;AACW,iBAAA,oBAAoB,gCAAgC,WAAW,GAAG;AACtE,cAAA,IAAI,WAAW,QAAQ,IAAI,uCAAuC,QAAQ,IAAI,OAAO,aAAa,gBAAgB,CAAC;AAAA,MAC1H;AACA,UAAI,CAAC,SAAS;AACb,cAAM,oBAAoB;AAAA,UACzB,WAAW,QAAQ;AAAA,UACnB,SAAS,gBAAgB;AAAA,QAAA;AAE1B,YAAI,OAAO;AACV,gBAAM,KAAK,OAAO;AAAA,YACjB;AAAA,YACA,EAAE,OAAO,SAAS,QAAQ,MAAM,aAAa,QAAQ,MAAM,UAAU,mBAAmB,OAAO,WAAW;AAAA,YAC1G;AAAA,UAAA;AAAA,QACD,OACM;AACN,gBAAM,KAAK,OAAO,6BAA6B,KAAK,EAAE,OAAO,SAAS,QAAQ,MAAM,aAAa,QAAQ,QAAQ,iBAAiB;AAAA,QACnI;AAAA,MACD;AACA,aAAO,IAAI,WAAW,IAAI,aAAa,QAAQ,KAAK,CAAC;AAAA,IAAA,CACrD;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,aAAsC;AACvE,UAAM,SAAS,MAAM,KAAK,sBAAsB,UAAU,WAAW;AAE9D,WAAA,QAAQ,SAAS,QAAQ,2BAA2B;AAAA,EAC5D;AACD;AAIO,MAAM,aAAa;AAAA,EACzB,YAA4B,QAAkD,OAAgB;AAAlE,SAAA,SAAA;AAAkD,SAAA,QAAA;AAAA,EAAkB;AACjG;"}
1
+ {"version":3,"file":"InviteManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/InviteManager.ts"],"sourcesContent":["import {\n\tCreateIdentityCommand,\n\tCreateOrUpdateProjectMembershipCommand,\n\tCreatePersonCommand,\n\tCreatePersonTokenCommand,\n\tSavePersonTokenCommand,\n} from '../commands'\nimport { Providers } from '../providers'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { Project, ProjectSchemaResolver } from '../type'\nimport { InviteErrorCode, InviteMethod } from '../../schema'\nimport { TenantRole } from '../authorization'\nimport { UserMailer } from '../mailing'\nimport { createAppendMembershipVariables } from './membershipUtils'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport { DatabaseContext, TokenHash } from '../utils'\nimport { NoPassword, PasswordPlain } from '../dtos'\nimport { Acl } from '@contember/schema'\nimport { validateEmail } from '../utils/email'\nimport { INVITATION_RESET_TOKEN_EXPIRATION_MINUTES } from '../consts/expirations'\n\nexport interface InviteData {\n\temail: string\n\tname?: string\n\tproject: Project\n\tmemberships: readonly Acl.Membership[]\n\tnoEmail?: boolean\n\tpassword?: string\n\temailVariant?: string\n\tmethod?: InviteMethod\n\tpasswordResetTokenHash?: TokenHash\n}\n\nexport class InviteManager {\n\tconstructor(\n\t\tprivate readonly providers: Providers,\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectSchemaResolver: ProjectSchemaResolver,\n\t) { }\n\n\tasync invite(\n\t\tdbContext: DatabaseContext,\n\t\t{\n\t\t\temail,\n\t\t\tproject,\n\t\t\tname,\n\t\t\tmemberships,\n\t\t\tmethod,\n\t\t\temailVariant,\n\t\t\tnoEmail = false,\n\t\t\tpassword,\n\t\t\tpasswordResetTokenHash,\n\t\t}: InviteData,\n\t): Promise<InviteResponse> {\n\t\tif (!validateEmail(email.trim())) {\n\t\t\treturn new ResponseError('INVALID_EMAIL_FORMAT', 'E-mail address is not in a valid format')\n\t\t}\n\n\t\treturn await dbContext.transaction(async trx => {\n\t\t\tlet person: Omit<PersonRow, 'roles'> | null = await trx.queryHandler.fetch(PersonQuery.byEmail(email))\n\t\t\tconst isNew = !person\n\t\t\tlet generatedPassword: string | null = null\n\t\t\tlet resetToken: string | null = null\n\t\t\tif (!person) {\n\t\t\t\tconst identityId = await trx.commandBus.execute(new CreateIdentityCommand([TenantRole.PERSON]))\n\n\t\t\t\tgeneratedPassword = password ??\n\t\t\t\t\t(method === 'CREATE_PASSWORD' ? (await this.providers.randomBytes(9)).toString('base64') : null)\n\t\t\t\tconst passwordWrapper = generatedPassword !== null ? new PasswordPlain(generatedPassword) : NoPassword\n\n\t\t\t\tperson = await trx.commandBus.execute(new CreatePersonCommand({\n\t\t\t\t\tidentityId,\n\t\t\t\t\temail,\n\t\t\t\t\tname,\n\t\t\t\t\tpassword: passwordWrapper,\n\t\t\t\t}))\n\t\t\t\tif (method === 'RESET_PASSWORD') {\n\t\t\t\t\tconst result = await trx.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id, await this.getInviteExpiration(project.slug)))\n\t\t\t\t\tresetToken = result.token\n\t\t\t\t}\n\t\t\t\tif (passwordResetTokenHash) {\n\t\t\t\t\tawait trx.commandBus.execute(new SavePersonTokenCommand(person.id, passwordResetTokenHash, 'password_reset', await this.getInviteExpiration(project.slug)))\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const membershipUpdate of createAppendMembershipVariables(memberships)) {\n\t\t\t\tawait trx.commandBus.execute(new CreateOrUpdateProjectMembershipCommand(project.id, person.identity_id, membershipUpdate))\n\t\t\t}\n\t\t\tif (!noEmail) {\n\t\t\t\tconst customMailOptions = {\n\t\t\t\t\tprojectId: project.id,\n\t\t\t\t\tvariant: emailVariant ?? '',\n\t\t\t\t}\n\t\t\t\tif (isNew) {\n\t\t\t\t\tawait this.mailer.sendNewUserInvitedMail(\n\t\t\t\t\t\ttrx,\n\t\t\t\t\t\t{ email, project: project.name, projectSlug: project.slug, password: generatedPassword, token: resetToken },\n\t\t\t\t\t\tcustomMailOptions,\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tawait this.mailer.sendExistingUserInvitedEmail(trx, { email, project: project.name, projectSlug: project.slug }, customMailOptions)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new ResponseOk(new InviteResult(person, isNew))\n\t\t})\n\t}\n\n\tprivate async getInviteExpiration(projectSlug: string): Promise<number> {\n\t\tconst schema = await this.projectSchemaResolver.getSchema(projectSlug)\n\n\t\treturn schema?.settings.tenant?.inviteExpirationMinutes ?? INVITATION_RESET_TOKEN_EXPIRATION_MINUTES\n\t}\n}\n\nexport type InviteResponse = Response<InviteResult, InviteErrorCode>\n\nexport class InviteResult {\n\tconstructor(public readonly person: Omit<PersonRow, 'roles'>, public readonly isNew: boolean) { }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAiCO,MAAM,cAAc;AAAA,EAC1B,YACkB,WACA,QACA,uBAChB;AAHgB,SAAA,YAAA;AACA,SAAA,SAAA;AACA,SAAA,wBAAA;AAAA,EACd;AAAA,EAEJ,MAAM,OACL,WACA;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EAAA,GAEyB;AAC1B,QAAI,CAAC,cAAc,MAAM,KAAM,CAAA,GAAG;AAC1B,aAAA,IAAI,cAAc,wBAAwB,yCAAyC;AAAA,IAC3F;AAEA,WAAO,MAAM,UAAU,YAAY,OAAM,QAAO;AAC3C,UAAA,SAA0C,MAAM,IAAI,aAAa,MAAM,YAAY,QAAQ,KAAK,CAAC;AACrG,YAAM,QAAQ,CAAC;AACf,UAAI,oBAAmC;AACvC,UAAI,aAA4B;AAChC,UAAI,CAAC,QAAQ;AACN,cAAA,aAAa,MAAM,IAAI,WAAW,QAAQ,IAAI,sBAAsB,CAAC,WAAW,MAAM,CAAC,CAAC;AAE1E,4BAAA,aAClB,WAAW,qBAAqB,MAAM,KAAK,UAAU,YAAY,CAAC,GAAG,SAAS,QAAQ,IAAI;AAC5F,cAAM,kBAAkB,sBAAsB,OAAO,IAAI,cAAc,iBAAiB,IAAI;AAE5F,iBAAS,MAAM,IAAI,WAAW,QAAQ,IAAI,oBAAoB;AAAA,UAC7D;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QACV,CAAA,CAAC;AACF,YAAI,WAAW,kBAAkB;AAChC,gBAAM,SAAS,MAAM,IAAI,WAAW,QAAQ,yBAAyB,2BAA2B,OAAO,IAAI,MAAM,KAAK,oBAAoB,QAAQ,IAAI,CAAC,CAAC;AACxJ,uBAAa,OAAO;AAAA,QACrB;AACA,YAAI,wBAAwB;AAC3B,gBAAM,IAAI,WAAW,QAAQ,IAAI,uBAAuB,OAAO,IAAI,wBAAwB,kBAAkB,MAAM,KAAK,oBAAoB,QAAQ,IAAI,CAAC,CAAC;AAAA,QAC3J;AAAA,MACD;AACW,iBAAA,oBAAoB,gCAAgC,WAAW,GAAG;AACtE,cAAA,IAAI,WAAW,QAAQ,IAAI,uCAAuC,QAAQ,IAAI,OAAO,aAAa,gBAAgB,CAAC;AAAA,MAC1H;AACA,UAAI,CAAC,SAAS;AACb,cAAM,oBAAoB;AAAA,UACzB,WAAW,QAAQ;AAAA,UACnB,SAAS,gBAAgB;AAAA,QAAA;AAE1B,YAAI,OAAO;AACV,gBAAM,KAAK,OAAO;AAAA,YACjB;AAAA,YACA,EAAE,OAAO,SAAS,QAAQ,MAAM,aAAa,QAAQ,MAAM,UAAU,mBAAmB,OAAO,WAAW;AAAA,YAC1G;AAAA,UAAA;AAAA,QACD,OACM;AACN,gBAAM,KAAK,OAAO,6BAA6B,KAAK,EAAE,OAAO,SAAS,QAAQ,MAAM,aAAa,QAAQ,QAAQ,iBAAiB;AAAA,QACnI;AAAA,MACD;AACA,aAAO,IAAI,WAAW,IAAI,aAAa,QAAQ,KAAK,CAAC;AAAA,IAAA,CACrD;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,aAAsC;AACvE,UAAM,SAAS,MAAM,KAAK,sBAAsB,UAAU,WAAW;AAE9D,WAAA,QAAQ,SAAS,QAAQ,2BAA2B;AAAA,EAC5D;AACD;AAIO,MAAM,aAAa;AAAA,EACzB,YAA4B,QAAkD,OAAgB;AAAlE,SAAA,SAAA;AAAkD,SAAA,QAAA;AAAA,EAAkB;AACjG;"}
@@ -3,8 +3,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  require("../type/ApiKey.cjs");
4
4
  require("@contember/database");
5
5
  require("node:crypto");
6
- const ChangePasswordCommand = require("../commands/person/ChangePasswordCommand.cjs");
7
6
  const Response = require("../utils/Response.cjs");
7
+ const ChangePasswordCommand = require("../commands/person/ChangePasswordCommand.cjs");
8
8
  const password = require("../utils/password.cjs");
9
9
  class PasswordChangeManager {
10
10
  constructor(providers) {
@@ -1,8 +1,8 @@
1
1
  import "../type/ApiKey.js";
2
2
  import "@contember/database";
3
3
  import "node:crypto";
4
- import { ChangePasswordCommand } from "../commands/person/ChangePasswordCommand.js";
5
4
  import { ResponseError, ResponseOk } from "../utils/Response.js";
5
+ import { ChangePasswordCommand } from "../commands/person/ChangePasswordCommand.js";
6
6
  import { getPasswordWeaknessMessage } from "../utils/password.js";
7
7
  class PasswordChangeManager {
8
8
  constructor(providers) {
@@ -1,29 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- require("../type/ApiKey.cjs");
4
- require("@contember/database");
5
- require("node:crypto");
6
- const exceptions = require("../../exceptions.cjs");
7
3
  const Response = require("../utils/Response.cjs");
8
- const CreatePasswordResetRequestCommand = require("../commands/passwordReset/CreatePasswordResetRequestCommand.cjs");
9
- const ResetPasswordCommand = require("../commands/passwordReset/ResetPasswordCommand.cjs");
10
4
  const password = require("../utils/password.cjs");
5
+ const exceptions = require("../../exceptions.cjs");
6
+ const getPreferredProject = require("./helpers/getPreferredProject.cjs");
7
+ require("@contember/database");
8
+ const CreatePersonTokenCommand = require("../commands/personToken/CreatePersonTokenCommand.cjs");
9
+ const ResetPasswordCommand = require("../commands/personToken/ResetPasswordCommand.cjs");
11
10
  class PasswordResetManager {
12
11
  constructor(mailer, projectManager) {
13
12
  this.mailer = mailer;
14
13
  this.projectManager = projectManager;
15
14
  }
16
15
  async createPasswordResetRequest(dbContext, permissionContext, person, mailOptions = {}) {
17
- const result = await dbContext.commandBus.execute(new CreatePasswordResetRequestCommand.CreatePasswordResetRequestCommand(person.id));
16
+ const result = await dbContext.commandBus.execute(CreatePersonTokenCommand.CreatePersonTokenCommand.createPasswordResetRequest(person.id));
18
17
  const projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext);
19
- const project = (() => {
20
- if (projects.length === 1) {
21
- return projects[0];
22
- } else if (mailOptions.project) {
23
- return projects.find((it) => it.slug === mailOptions.project) || null;
24
- }
25
- return null;
26
- })();
18
+ const project = getPreferredProject.getPreferredProject(projects, mailOptions.project ?? null);
27
19
  if (!person.email) {
28
20
  throw new exceptions.ImplementationException();
29
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordResetManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { CreatePasswordResetRequestCommand, ResetPasswordCommand, ResetPasswordCommandErrorCode } from '../commands'\nimport { Response, ResponseError } from '../utils/Response'\nimport { getPasswordWeaknessMessage } from '../utils/password'\nimport { UserMailer } from '../mailing'\nimport { PersonRow } from '../queries'\nimport { PermissionContext } from '../authorization'\nimport { ProjectManager } from './ProjectManager'\nimport { DatabaseContext } from '../utils'\nimport { ImplementationException } from '../../exceptions'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t) { }\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tconst result = await dbContext.commandBus.execute(new CreatePasswordResetRequestCommand(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = (() => {\n\t\t\tif (projects.length === 1) {\n\t\t\t\treturn projects[0]\n\t\t\t} else if (mailOptions.project) {\n\t\t\t\treturn projects.find(it => it.slug === mailOptions.project) || null\n\t\t\t}\n\t\t\treturn null\n\t\t})()\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst weakPassword = getPasswordWeaknessMessage(password)\n\t\tif (weakPassword) {\n\t\t\treturn new ResponseError('PASSWORD_TOO_WEAK', weakPassword)\n\t\t}\n\t\treturn await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t}\n}\n\nexport type ResetPasswordErrorCode = 'PASSWORD_TOO_WEAK'\n\nexport type ResetPasswordResponse = Response<null, ResetPasswordErrorCode | ResetPasswordCommandErrorCode>\n"],"names":["CreatePasswordResetRequestCommand","ImplementationException","password","getPasswordWeaknessMessage","ResponseError","ResetPasswordCommand"],"mappings":";;;;;;;;;;AAeO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBAChB;AAFgB,SAAA,SAAA;AACA,SAAA,iBAAA;AAAA,EACd;AAAA,EAEJ,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AACV,UAAA,SAAS,MAAM,UAAU,WAAW,QAAQ,IAAIA,oEAAkC,OAAO,EAAE,CAAC;AAC5F,UAAA,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,WAAW,MAAM;AAClB,UAAA,SAAS,WAAW,GAAG;AAC1B,eAAO,SAAS,CAAC;AAAA,MAAA,WACP,YAAY,SAAS;AAC/B,eAAO,SAAS,KAAK,CAAA,OAAM,GAAG,SAAS,YAAY,OAAO,KAAK;AAAA,MAChE;AACO,aAAA;AAAA,IAAA;AAEJ,QAAA,CAAC,OAAO,OAAO;AAClB,YAAM,IAAIC,WAAwB,wBAAA;AAAA,IACnC;AAEA,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAC3B;AAAA,IAAA;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAeC,YAAkD;AACjH,UAAA,eAAeC,oCAA2BD,UAAQ;AACxD,QAAI,cAAc;AACV,aAAA,IAAIE,SAAc,cAAA,qBAAqB,YAAY;AAAA,IAC3D;AACO,WAAA,MAAM,UAAU,WAAW,QAAQ,IAAIC,qBAAAA,qBAAqB,OAAOH,UAAQ,CAAC;AAAA,EACpF;AACD;;"}
1
+ {"version":3,"file":"PasswordResetManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError } from '../utils/Response'\nimport { getPasswordWeaknessMessage } from '../utils/password'\nimport { UserMailer } from '../mailing'\nimport { PersonRow } from '../queries'\nimport { PermissionContext } from '../authorization'\nimport { ProjectManager } from './ProjectManager'\nimport { DatabaseContext } from '../utils'\nimport { ImplementationException } from '../../exceptions'\nimport { getPreferredProject } from './helpers/getPreferredProject'\nimport { CreatePersonTokenCommand, ResetPasswordCommand, ResetPasswordCommandErrorCode } from '../commands/personToken'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t) { }\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tconst result = await dbContext.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = getPreferredProject(projects, mailOptions.project ?? null)\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst weakPassword = getPasswordWeaknessMessage(password)\n\t\tif (weakPassword) {\n\t\t\treturn new ResponseError('PASSWORD_TOO_WEAK', weakPassword)\n\t\t}\n\t\treturn await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t}\n}\n\nexport type ResetPasswordErrorCode = 'PASSWORD_TOO_WEAK'\n\nexport type ResetPasswordResponse = Response<null, ResetPasswordErrorCode | ResetPasswordCommandErrorCode>\n"],"names":["CreatePersonTokenCommand","getPreferredProject","ImplementationException","password","getPasswordWeaknessMessage","ResponseError","ResetPasswordCommand"],"mappings":";;;;;;;;;AAgBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBAChB;AAFgB,SAAA,SAAA;AACA,SAAA,iBAAA;AAAA,EACd;AAAA,EAEJ,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AACV,UAAA,SAAS,MAAM,UAAU,WAAW,QAAQA,yBAAyB,yBAAA,2BAA2B,OAAO,EAAE,CAAC;AAC1G,UAAA,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAUC,oBAAAA,oBAAoB,UAAU,YAAY,WAAW,IAAI;AACrE,QAAA,CAAC,OAAO,OAAO;AAClB,YAAM,IAAIC,WAAwB,wBAAA;AAAA,IACnC;AAEA,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAC3B;AAAA,IAAA;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAeC,YAAkD;AACjH,UAAA,eAAeC,oCAA2BD,UAAQ;AACxD,QAAI,cAAc;AACV,aAAA,IAAIE,SAAc,cAAA,qBAAqB,YAAY;AAAA,IAC3D;AACO,WAAA,MAAM,UAAU,WAAW,QAAQ,IAAIC,qBAAAA,qBAAqB,OAAOH,UAAQ,CAAC;AAAA,EACpF;AACD;;"}
@@ -1,27 +1,19 @@
1
- import "../type/ApiKey.js";
2
- import "@contember/database";
3
- import "node:crypto";
4
- import { ImplementationException } from "../../exceptions.js";
5
1
  import { ResponseError } from "../utils/Response.js";
6
- import { CreatePasswordResetRequestCommand } from "../commands/passwordReset/CreatePasswordResetRequestCommand.js";
7
- import { ResetPasswordCommand } from "../commands/passwordReset/ResetPasswordCommand.js";
8
2
  import { getPasswordWeaknessMessage } from "../utils/password.js";
3
+ import { ImplementationException } from "../../exceptions.js";
4
+ import { getPreferredProject } from "./helpers/getPreferredProject.js";
5
+ import "@contember/database";
6
+ import { CreatePersonTokenCommand } from "../commands/personToken/CreatePersonTokenCommand.js";
7
+ import { ResetPasswordCommand } from "../commands/personToken/ResetPasswordCommand.js";
9
8
  class PasswordResetManager {
10
9
  constructor(mailer, projectManager) {
11
10
  this.mailer = mailer;
12
11
  this.projectManager = projectManager;
13
12
  }
14
13
  async createPasswordResetRequest(dbContext, permissionContext, person, mailOptions = {}) {
15
- const result = await dbContext.commandBus.execute(new CreatePasswordResetRequestCommand(person.id));
14
+ const result = await dbContext.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id));
16
15
  const projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext);
17
- const project = (() => {
18
- if (projects.length === 1) {
19
- return projects[0];
20
- } else if (mailOptions.project) {
21
- return projects.find((it) => it.slug === mailOptions.project) || null;
22
- }
23
- return null;
24
- })();
16
+ const project = getPreferredProject(projects, mailOptions.project ?? null);
25
17
  if (!person.email) {
26
18
  throw new ImplementationException();
27
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordResetManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { CreatePasswordResetRequestCommand, ResetPasswordCommand, ResetPasswordCommandErrorCode } from '../commands'\nimport { Response, ResponseError } from '../utils/Response'\nimport { getPasswordWeaknessMessage } from '../utils/password'\nimport { UserMailer } from '../mailing'\nimport { PersonRow } from '../queries'\nimport { PermissionContext } from '../authorization'\nimport { ProjectManager } from './ProjectManager'\nimport { DatabaseContext } from '../utils'\nimport { ImplementationException } from '../../exceptions'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t) { }\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tconst result = await dbContext.commandBus.execute(new CreatePasswordResetRequestCommand(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = (() => {\n\t\t\tif (projects.length === 1) {\n\t\t\t\treturn projects[0]\n\t\t\t} else if (mailOptions.project) {\n\t\t\t\treturn projects.find(it => it.slug === mailOptions.project) || null\n\t\t\t}\n\t\t\treturn null\n\t\t})()\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst weakPassword = getPasswordWeaknessMessage(password)\n\t\tif (weakPassword) {\n\t\t\treturn new ResponseError('PASSWORD_TOO_WEAK', weakPassword)\n\t\t}\n\t\treturn await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t}\n}\n\nexport type ResetPasswordErrorCode = 'PASSWORD_TOO_WEAK'\n\nexport type ResetPasswordResponse = Response<null, ResetPasswordErrorCode | ResetPasswordCommandErrorCode>\n"],"names":[],"mappings":";;;;;;;;AAeO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBAChB;AAFgB,SAAA,SAAA;AACA,SAAA,iBAAA;AAAA,EACd;AAAA,EAEJ,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AACV,UAAA,SAAS,MAAM,UAAU,WAAW,QAAQ,IAAI,kCAAkC,OAAO,EAAE,CAAC;AAC5F,UAAA,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,WAAW,MAAM;AAClB,UAAA,SAAS,WAAW,GAAG;AAC1B,eAAO,SAAS,CAAC;AAAA,MAAA,WACP,YAAY,SAAS;AAC/B,eAAO,SAAS,KAAK,CAAA,OAAM,GAAG,SAAS,YAAY,OAAO,KAAK;AAAA,MAChE;AACO,aAAA;AAAA,IAAA;AAEJ,QAAA,CAAC,OAAO,OAAO;AAClB,YAAM,IAAI,wBAAwB;AAAA,IACnC;AAEA,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAC3B;AAAA,IAAA;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACjH,UAAA,eAAe,2BAA2B,QAAQ;AACxD,QAAI,cAAc;AACV,aAAA,IAAI,cAAc,qBAAqB,YAAY;AAAA,IAC3D;AACO,WAAA,MAAM,UAAU,WAAW,QAAQ,IAAI,qBAAqB,OAAO,QAAQ,CAAC;AAAA,EACpF;AACD;"}
1
+ {"version":3,"file":"PasswordResetManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError } from '../utils/Response'\nimport { getPasswordWeaknessMessage } from '../utils/password'\nimport { UserMailer } from '../mailing'\nimport { PersonRow } from '../queries'\nimport { PermissionContext } from '../authorization'\nimport { ProjectManager } from './ProjectManager'\nimport { DatabaseContext } from '../utils'\nimport { ImplementationException } from '../../exceptions'\nimport { getPreferredProject } from './helpers/getPreferredProject'\nimport { CreatePersonTokenCommand, ResetPasswordCommand, ResetPasswordCommandErrorCode } from '../commands/personToken'\n\ninterface MailOptions {\n\tproject?: string\n\tmailVariant?: string\n}\n\nexport class PasswordResetManager {\n\tconstructor(\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t) { }\n\n\tpublic async createPasswordResetRequest(\n\t\tdbContext: DatabaseContext,\n\t\tpermissionContext: PermissionContext,\n\t\tperson: PersonRow,\n\t\tmailOptions: MailOptions = {},\n\t): Promise<void> {\n\t\tconst result = await dbContext.commandBus.execute(CreatePersonTokenCommand.createPasswordResetRequest(person.id))\n\t\tconst projects = await this.projectManager.getProjectsByIdentity(dbContext, person.identity_id, permissionContext)\n\t\tconst project = getPreferredProject(projects, mailOptions.project ?? null)\n\t\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\tawait this.mailer.sendPasswordResetEmail(\n\t\t\tdbContext,\n\t\t\t{\n\t\t\t\temail: person.email,\n\t\t\t\ttoken: result.token,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t},\n\t\t\t{\n\t\t\t\tvariant: mailOptions.mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async resetPassword(dbContext: DatabaseContext, token: string, password: string): Promise<ResetPasswordResponse> {\n\t\tconst weakPassword = getPasswordWeaknessMessage(password)\n\t\tif (weakPassword) {\n\t\t\treturn new ResponseError('PASSWORD_TOO_WEAK', weakPassword)\n\t\t}\n\t\treturn await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t}\n}\n\nexport type ResetPasswordErrorCode = 'PASSWORD_TOO_WEAK'\n\nexport type ResetPasswordResponse = Response<null, ResetPasswordErrorCode | ResetPasswordCommandErrorCode>\n"],"names":[],"mappings":";;;;;;;AAgBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBAChB;AAFgB,SAAA,SAAA;AACA,SAAA,iBAAA;AAAA,EACd;AAAA,EAEJ,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AACV,UAAA,SAAS,MAAM,UAAU,WAAW,QAAQ,yBAAyB,2BAA2B,OAAO,EAAE,CAAC;AAC1G,UAAA,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAU,oBAAoB,UAAU,YAAY,WAAW,IAAI;AACrE,QAAA,CAAC,OAAO,OAAO;AAClB,YAAM,IAAI,wBAAwB;AAAA,IACnC;AAEA,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAC3B;AAAA,IAAA;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACjH,UAAA,eAAe,2BAA2B,QAAQ;AACxD,QAAI,cAAc;AACV,aAAA,IAAI,cAAc,qBAAqB,YAAY;AAAA,IAC3D;AACO,WAAA,MAAM,UAAU,WAAW,QAAQ,IAAI,qBAAqB,OAAO,QAAQ,CAAC;AAAA,EACpF;AACD;"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("../queries/apiKey/ApiKeyQuery.cjs");
4
+ require("@contember/database");
5
+ const exceptions = require("../../exceptions.cjs");
6
+ const PersonQuery = require("../queries/person/PersonQuery.cjs");
7
+ require("../authorization/PermissionActions.cjs");
8
+ require("@contember/authorization");
9
+ require("../authorization/PermissionContext.cjs");
10
+ require("../authorization/PermissionsFactory.cjs");
11
+ require("@contember/schema");
12
+ const Response = require("../utils/Response.cjs");
13
+ require("../type/ApiKey.cjs");
14
+ const ActivateOtpCommand = require("../commands/personToken/ActivateOtpCommand.cjs");
15
+ const CreatePersonTokenCommand = require("../commands/personToken/CreatePersonTokenCommand.cjs");
16
+ const InvalidateTokenCommand = require("../commands/personToken/InvalidateTokenCommand.cjs");
17
+ const IncreaseOtpAttemptCommand = require("../commands/personToken/IncreaseOtpAttemptCommand.cjs");
18
+ const PersonTokenQuery = require("../queries/personToken/PersonTokenQuery.cjs");
19
+ const tokenUtils = require("../utils/tokenUtils.cjs");
20
+ const getPreferredProject = require("./helpers/getPreferredProject.cjs");
21
+ class PasswordlessSignInManager {
22
+ constructor(apiKeyManager, configurationManager, mailer, projectManager, otpAuthenticator) {
23
+ this.apiKeyManager = apiKeyManager;
24
+ this.configurationManager = configurationManager;
25
+ this.mailer = mailer;
26
+ this.projectManager = projectManager;
27
+ this.otpAuthenticator = otpAuthenticator;
28
+ }
29
+ async initSignInPasswordless({ db, permissionContext, mailVariant, mailProject, email }) {
30
+ return db.transaction(async (db2) => {
31
+ const configuration = await this.configurationManager.fetchConfiguration(db2);
32
+ if (configuration.passwordless.enabled === "never") {
33
+ return new Response.ResponseError("PASSWORDLESS_DISABLED", "Passwordless sign-in is disabled");
34
+ }
35
+ const person = await db2.queryHandler.fetch(PersonQuery.PersonQuery.byEmail(email));
36
+ if (!person) {
37
+ return new Response.ResponseError("PERSON_NOT_FOUND", `Person ${email} not found`);
38
+ }
39
+ if (!this.isEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {
40
+ return new Response.ResponseError("PASSWORDLESS_DISABLED", "Passwordless sign-in is disabled for this person");
41
+ }
42
+ const createTokenCommand = CreatePersonTokenCommand.CreatePersonTokenCommand.createPasswordlessRequest(person.id, configuration.passwordless.expirationMinutes);
43
+ const result = await db2.commandBus.execute(createTokenCommand);
44
+ const url = this.formatUrl(configuration.passwordless.url ?? null, result.token, result.id, email) ?? void 0;
45
+ const projects = await this.projectManager.getProjectsByIdentity(db2, person.identity_id, permissionContext);
46
+ const project = getPreferredProject.getPreferredProject(projects, mailProject ?? null);
47
+ await this.mailer.sendPasswordlessEmail(db2, {
48
+ email,
49
+ token: result.token,
50
+ url,
51
+ project: project?.name,
52
+ projectSlug: project?.slug
53
+ }, {
54
+ variant: mailVariant || "",
55
+ projectId: project?.id ?? null
56
+ });
57
+ return new Response.ResponseOk({ requestId: result.id, expiresAt: result.expiresAt });
58
+ });
59
+ }
60
+ formatUrl(url, token, requestId, email) {
61
+ if (!url) {
62
+ return null;
63
+ }
64
+ const urlObj = new URL(url);
65
+ urlObj.searchParams.set("token", token);
66
+ urlObj.searchParams.set("request_id", requestId);
67
+ urlObj.searchParams.set("email", email);
68
+ return urlObj.toString();
69
+ }
70
+ async signInPasswordless({ db, expiration, token, requestId, mfaOtp, validationType }) {
71
+ return db.transaction(async (db2) => {
72
+ const tokenResult = await db2.queryHandler.fetch(PersonTokenQuery.PersonTokenQuery.byId(requestId, "passwordless"));
73
+ const tokenValidationResult = tokenUtils.validateToken({
74
+ entry: tokenResult,
75
+ token,
76
+ now: db2.providers.now(),
77
+ validationType
78
+ });
79
+ if (!tokenValidationResult.ok) {
80
+ if (tokenValidationResult.error === "TOKEN_INVALID" && validationType === "otp") {
81
+ await db2.commandBus.execute(new IncreaseOtpAttemptCommand.IncreaseOtpAttemptCommand(tokenResult.id));
82
+ }
83
+ return tokenValidationResult;
84
+ }
85
+ const personRow = await db2.queryHandler.fetch(PersonQuery.PersonQuery.byId(tokenValidationResult.result.person_id));
86
+ if (!personRow) {
87
+ throw new exceptions.ImplementationException();
88
+ }
89
+ if (personRow.disabled_at !== null) {
90
+ return new Response.ResponseError("PERSON_DISABLED", `Person is disabled`);
91
+ }
92
+ if (personRow.otp_uri && personRow.otp_activated_at) {
93
+ if (!mfaOtp) {
94
+ return new Response.ResponseError("OTP_REQUIRED", `2FA is enabled. OTP token is required`);
95
+ }
96
+ if (!this.otpAuthenticator.validate({ uri: personRow.otp_uri }, mfaOtp)) {
97
+ return new Response.ResponseError("INVALID_OTP_TOKEN", "OTP token validation has failed");
98
+ }
99
+ }
100
+ await db2.commandBus.execute(new InvalidateTokenCommand.InvalidateTokenCommand(tokenValidationResult.result.id));
101
+ const sessionToken = await this.apiKeyManager.createSessionApiKey(db2, personRow.identity_id, expiration);
102
+ return new Response.ResponseOk({ person: personRow, token: sessionToken });
103
+ });
104
+ }
105
+ async activatePasswordlessOtp({ db, token, requestId, otpHash }) {
106
+ return db.transaction(async (db2) => {
107
+ const tokenResult = await db2.queryHandler.fetch(PersonTokenQuery.PersonTokenQuery.byId(requestId, "passwordless"));
108
+ const tokenValidationResult = tokenUtils.validateToken({
109
+ entry: tokenResult,
110
+ token,
111
+ now: db2.providers.now(),
112
+ validationType: "token"
113
+ });
114
+ if (!tokenValidationResult.ok) {
115
+ return tokenValidationResult;
116
+ }
117
+ await db2.commandBus.execute(new ActivateOtpCommand.ActivateOtpCommand(tokenValidationResult.result.id, otpHash));
118
+ return new Response.ResponseOk(null);
119
+ });
120
+ }
121
+ isEnabled(globalValue, personValue) {
122
+ switch (globalValue) {
123
+ case "always":
124
+ return true;
125
+ case "never":
126
+ return false;
127
+ case "optIn":
128
+ return personValue === true;
129
+ case "optOut":
130
+ return personValue !== false;
131
+ }
132
+ }
133
+ }
134
+ exports.PasswordlessSignInManager = PasswordlessSignInManager;
135
+ //# sourceMappingURL=PasswordlessSignInManager.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordlessSignInManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordlessSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport {\n\tActivatePasswordlessOtpErrorCode,\n\tConfigPolicy,\n\tInitSignInPasswordlessErrorCode,\n\tInitSignInPasswordlessResult,\n\tSignInPasswordlessErrorCode,\n} from '../../schema'\nimport { DatabaseContext, validateToken } from '../utils'\nimport { ConfigurationManager } from './ConfigurationManager'\nimport { UserMailer } from '../mailing'\nimport { ActivateOtpCommand, CreatePersonTokenCommand, IncreaseOtpAttemptCommand } from '../commands'\nimport { getPreferredProject } from './helpers/getPreferredProject'\nimport { ProjectManager } from './ProjectManager'\nimport { PermissionContext } from '../authorization'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery'\nimport { ImplementationException } from '../../exceptions'\nimport { OtpAuthenticator } from './OtpAuthenticator'\nimport { InvalidateTokenCommand } from '../commands/personToken/InvalidateTokenCommand'\nimport { PersonToken } from '../type'\n\nclass PasswordlessSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly configurationManager: ConfigurationManager,\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly otpAuthenticator: OtpAuthenticator,\n\n\t) {}\n\n\tasync initSignInPasswordless({ db, permissionContext, mailVariant, mailProject, email }: {\n\t\tdb: DatabaseContext\n\t\tpermissionContext: PermissionContext\n\t\temail: string\n\t\tmailVariant?: string\n\t\tmailProject?: string\n\t}): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> => {\n\t\t\tconst configuration = await this.configurationManager.fetchConfiguration(db)\n\t\t\tif (configuration.passwordless.enabled === 'never') {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled')\n\t\t\t}\n\n\t\t\tconst person = await db.queryHandler.fetch(PersonQuery.byEmail(email))\n\t\t\tif (!person) {\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${email} not found`)\n\t\t\t}\n\t\t\tif (!this.isEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled for this person')\n\t\t\t}\n\n\t\t\tconst createTokenCommand = CreatePersonTokenCommand.createPasswordlessRequest(person.id, configuration.passwordless.expirationMinutes)\n\t\t\tconst result = await db.commandBus.execute(createTokenCommand)\n\n\n\t\t\tconst url = this.formatUrl(configuration.passwordless.url ?? null, result.token, result.id, email) ?? undefined\n\n\t\t\tconst projects = await this.projectManager.getProjectsByIdentity(db, person.identity_id, permissionContext)\n\t\t\tconst project = getPreferredProject(projects, mailProject ?? null)\n\n\t\t\tawait this.mailer.sendPasswordlessEmail(db, {\n\t\t\t\temail,\n\t\t\t\ttoken: result.token,\n\t\t\t\turl,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t}, {\n\t\t\t\tvariant: mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t})\n\n\t\t\treturn new ResponseOk({ requestId: result.id, expiresAt: result.expiresAt })\n\t\t})\n\t}\n\n\tprivate formatUrl(url: string | null, token: string, requestId: string, email: string): string | null {\n\t\tif (!url) {\n\t\t\treturn null\n\t\t}\n\t\tconst urlObj = new URL(url)\n\t\turlObj.searchParams.set('token', token)\n\t\turlObj.searchParams.set('request_id', requestId)\n\t\turlObj.searchParams.set('email', email)\n\t\treturn urlObj.toString()\n\t}\n\n\tasync signInPasswordless({ db, expiration, token, requestId, mfaOtp, validationType }: {\n\t\tdb: DatabaseContext\n\t\tvalidationType: PersonToken.ValidationType\n\t\trequestId: string\n\t\ttoken: string\n\t\tmfaOtp?: string\n\t\texpiration?: number\n\t}): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> => {\n\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType,\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\tif (tokenValidationResult.error === 'TOKEN_INVALID' && validationType === 'otp') {\n\t\t\t\t\tawait db.commandBus.execute(new IncreaseOtpAttemptCommand(tokenResult!.id))\n\t\t\t\t}\n\t\t\t\treturn tokenValidationResult\n\t\t\t}\n\t\t\tconst personRow = await db.queryHandler.fetch(PersonQuery.byId(tokenValidationResult.result.person_id))\n\t\t\tif (!personRow) {\n\t\t\t\tthrow new ImplementationException()\n\t\t\t}\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person is disabled`)\n\t\t\t}\n\n\t\t\tif (personRow.otp_uri && personRow.otp_activated_at) {\n\t\t\t\tif (!mfaOtp) {\n\t\t\t\t\treturn new ResponseError('OTP_REQUIRED', `2FA is enabled. OTP token is required`)\n\t\t\t\t}\n\n\t\t\t\tif (!this.otpAuthenticator.validate({ uri: personRow.otp_uri }, mfaOtp)) {\n\t\t\t\t\treturn new ResponseError('INVALID_OTP_TOKEN', 'OTP token validation has failed')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait db.commandBus.execute(new InvalidateTokenCommand(tokenValidationResult.result.id))\n\t\t\tconst sessionToken = await this.apiKeyManager.createSessionApiKey(db, personRow.identity_id, expiration)\n\n\t\t\treturn new ResponseOk({ person: personRow, token: sessionToken })\n\t\t})\n\t}\n\n\tasync activatePasswordlessOtp({ db, token, requestId, otpHash }: {\n\t\tdb: DatabaseContext\n\t\trequestId: string\n\t\ttoken: string\n\t\totpHash: string\n\t}): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> => {\n\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType: 'token',\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\treturn tokenValidationResult\n\t\t\t}\n\n\t\t\tawait db.commandBus.execute(new ActivateOtpCommand(tokenValidationResult.result.id, otpHash))\n\n\t\t\treturn new ResponseOk(null)\n\t\t})\n\t}\n\n\tprivate isEnabled(globalValue: ConfigPolicy, personValue: boolean | null): boolean {\n\t\tswitch (globalValue) {\n\t\t\tcase 'always':\n\t\t\t\treturn true\n\t\t\tcase 'never':\n\t\t\t\treturn false\n\t\t\tcase 'optIn':\n\t\t\t\treturn personValue === true\n\t\t\tcase 'optOut':\n\t\t\t\treturn personValue !== false\n\t\t}\n\t}\n}\n\nnamespace PasswordlessSignInManager {\n\texport type InitSignInPasswordlessResponse = Response<InitSignInPasswordlessResult, InitSignInPasswordlessErrorCode>\n\n\n\tinterface SignInPasswordlessResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t}\n\texport type SignInPasswordlessResponse = Response<SignInPasswordlessResult, SignInPasswordlessErrorCode>\n\n\texport type ActivatePasswordlessOtpResponse = Response<null, ActivatePasswordlessOtpErrorCode>\n}\n\nexport { PasswordlessSignInManager }\n"],"names":["db","ResponseError","PersonQuery","CreatePersonTokenCommand","getPreferredProject","ResponseOk","PersonTokenQuery","validateToken","IncreaseOtpAttemptCommand","ImplementationException","InvalidateTokenCommand","ActivateOtpCommand"],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ import "../queries/apiKey/ApiKeyQuery.js";
2
+ import "@contember/database";
3
+ import { ImplementationException } from "../../exceptions.js";
4
+ import { PersonQuery } from "../queries/person/PersonQuery.js";
5
+ import "../authorization/PermissionActions.js";
6
+ import "@contember/authorization";
7
+ import "../authorization/PermissionContext.js";
8
+ import "../authorization/PermissionsFactory.js";
9
+ import "@contember/schema";
10
+ import { ResponseError, ResponseOk } from "../utils/Response.js";
11
+ import "../type/ApiKey.js";
12
+ import { ActivateOtpCommand } from "../commands/personToken/ActivateOtpCommand.js";
13
+ import { CreatePersonTokenCommand } from "../commands/personToken/CreatePersonTokenCommand.js";
14
+ import { InvalidateTokenCommand } from "../commands/personToken/InvalidateTokenCommand.js";
15
+ import { IncreaseOtpAttemptCommand } from "../commands/personToken/IncreaseOtpAttemptCommand.js";
16
+ import { PersonTokenQuery } from "../queries/personToken/PersonTokenQuery.js";
17
+ import { validateToken } from "../utils/tokenUtils.js";
18
+ import { getPreferredProject } from "./helpers/getPreferredProject.js";
19
+ class PasswordlessSignInManager {
20
+ constructor(apiKeyManager, configurationManager, mailer, projectManager, otpAuthenticator) {
21
+ this.apiKeyManager = apiKeyManager;
22
+ this.configurationManager = configurationManager;
23
+ this.mailer = mailer;
24
+ this.projectManager = projectManager;
25
+ this.otpAuthenticator = otpAuthenticator;
26
+ }
27
+ async initSignInPasswordless({ db, permissionContext, mailVariant, mailProject, email }) {
28
+ return db.transaction(async (db2) => {
29
+ const configuration = await this.configurationManager.fetchConfiguration(db2);
30
+ if (configuration.passwordless.enabled === "never") {
31
+ return new ResponseError("PASSWORDLESS_DISABLED", "Passwordless sign-in is disabled");
32
+ }
33
+ const person = await db2.queryHandler.fetch(PersonQuery.byEmail(email));
34
+ if (!person) {
35
+ return new ResponseError("PERSON_NOT_FOUND", `Person ${email} not found`);
36
+ }
37
+ if (!this.isEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {
38
+ return new ResponseError("PASSWORDLESS_DISABLED", "Passwordless sign-in is disabled for this person");
39
+ }
40
+ const createTokenCommand = CreatePersonTokenCommand.createPasswordlessRequest(person.id, configuration.passwordless.expirationMinutes);
41
+ const result = await db2.commandBus.execute(createTokenCommand);
42
+ const url = this.formatUrl(configuration.passwordless.url ?? null, result.token, result.id, email) ?? void 0;
43
+ const projects = await this.projectManager.getProjectsByIdentity(db2, person.identity_id, permissionContext);
44
+ const project = getPreferredProject(projects, mailProject ?? null);
45
+ await this.mailer.sendPasswordlessEmail(db2, {
46
+ email,
47
+ token: result.token,
48
+ url,
49
+ project: project?.name,
50
+ projectSlug: project?.slug
51
+ }, {
52
+ variant: mailVariant || "",
53
+ projectId: project?.id ?? null
54
+ });
55
+ return new ResponseOk({ requestId: result.id, expiresAt: result.expiresAt });
56
+ });
57
+ }
58
+ formatUrl(url, token, requestId, email) {
59
+ if (!url) {
60
+ return null;
61
+ }
62
+ const urlObj = new URL(url);
63
+ urlObj.searchParams.set("token", token);
64
+ urlObj.searchParams.set("request_id", requestId);
65
+ urlObj.searchParams.set("email", email);
66
+ return urlObj.toString();
67
+ }
68
+ async signInPasswordless({ db, expiration, token, requestId, mfaOtp, validationType }) {
69
+ return db.transaction(async (db2) => {
70
+ const tokenResult = await db2.queryHandler.fetch(PersonTokenQuery.byId(requestId, "passwordless"));
71
+ const tokenValidationResult = validateToken({
72
+ entry: tokenResult,
73
+ token,
74
+ now: db2.providers.now(),
75
+ validationType
76
+ });
77
+ if (!tokenValidationResult.ok) {
78
+ if (tokenValidationResult.error === "TOKEN_INVALID" && validationType === "otp") {
79
+ await db2.commandBus.execute(new IncreaseOtpAttemptCommand(tokenResult.id));
80
+ }
81
+ return tokenValidationResult;
82
+ }
83
+ const personRow = await db2.queryHandler.fetch(PersonQuery.byId(tokenValidationResult.result.person_id));
84
+ if (!personRow) {
85
+ throw new ImplementationException();
86
+ }
87
+ if (personRow.disabled_at !== null) {
88
+ return new ResponseError("PERSON_DISABLED", `Person is disabled`);
89
+ }
90
+ if (personRow.otp_uri && personRow.otp_activated_at) {
91
+ if (!mfaOtp) {
92
+ return new ResponseError("OTP_REQUIRED", `2FA is enabled. OTP token is required`);
93
+ }
94
+ if (!this.otpAuthenticator.validate({ uri: personRow.otp_uri }, mfaOtp)) {
95
+ return new ResponseError("INVALID_OTP_TOKEN", "OTP token validation has failed");
96
+ }
97
+ }
98
+ await db2.commandBus.execute(new InvalidateTokenCommand(tokenValidationResult.result.id));
99
+ const sessionToken = await this.apiKeyManager.createSessionApiKey(db2, personRow.identity_id, expiration);
100
+ return new ResponseOk({ person: personRow, token: sessionToken });
101
+ });
102
+ }
103
+ async activatePasswordlessOtp({ db, token, requestId, otpHash }) {
104
+ return db.transaction(async (db2) => {
105
+ const tokenResult = await db2.queryHandler.fetch(PersonTokenQuery.byId(requestId, "passwordless"));
106
+ const tokenValidationResult = validateToken({
107
+ entry: tokenResult,
108
+ token,
109
+ now: db2.providers.now(),
110
+ validationType: "token"
111
+ });
112
+ if (!tokenValidationResult.ok) {
113
+ return tokenValidationResult;
114
+ }
115
+ await db2.commandBus.execute(new ActivateOtpCommand(tokenValidationResult.result.id, otpHash));
116
+ return new ResponseOk(null);
117
+ });
118
+ }
119
+ isEnabled(globalValue, personValue) {
120
+ switch (globalValue) {
121
+ case "always":
122
+ return true;
123
+ case "never":
124
+ return false;
125
+ case "optIn":
126
+ return personValue === true;
127
+ case "optOut":
128
+ return personValue !== false;
129
+ }
130
+ }
131
+ }
132
+ export {
133
+ PasswordlessSignInManager
134
+ };
135
+ //# sourceMappingURL=PasswordlessSignInManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordlessSignInManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordlessSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport {\n\tActivatePasswordlessOtpErrorCode,\n\tConfigPolicy,\n\tInitSignInPasswordlessErrorCode,\n\tInitSignInPasswordlessResult,\n\tSignInPasswordlessErrorCode,\n} from '../../schema'\nimport { DatabaseContext, validateToken } from '../utils'\nimport { ConfigurationManager } from './ConfigurationManager'\nimport { UserMailer } from '../mailing'\nimport { ActivateOtpCommand, CreatePersonTokenCommand, IncreaseOtpAttemptCommand } from '../commands'\nimport { getPreferredProject } from './helpers/getPreferredProject'\nimport { ProjectManager } from './ProjectManager'\nimport { PermissionContext } from '../authorization'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery'\nimport { ImplementationException } from '../../exceptions'\nimport { OtpAuthenticator } from './OtpAuthenticator'\nimport { InvalidateTokenCommand } from '../commands/personToken/InvalidateTokenCommand'\nimport { PersonToken } from '../type'\n\nclass PasswordlessSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly configurationManager: ConfigurationManager,\n\t\tprivate readonly mailer: UserMailer,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly otpAuthenticator: OtpAuthenticator,\n\n\t) {}\n\n\tasync initSignInPasswordless({ db, permissionContext, mailVariant, mailProject, email }: {\n\t\tdb: DatabaseContext\n\t\tpermissionContext: PermissionContext\n\t\temail: string\n\t\tmailVariant?: string\n\t\tmailProject?: string\n\t}): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.InitSignInPasswordlessResponse> => {\n\t\t\tconst configuration = await this.configurationManager.fetchConfiguration(db)\n\t\t\tif (configuration.passwordless.enabled === 'never') {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled')\n\t\t\t}\n\n\t\t\tconst person = await db.queryHandler.fetch(PersonQuery.byEmail(email))\n\t\t\tif (!person) {\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${email} not found`)\n\t\t\t}\n\t\t\tif (!this.isEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {\n\t\t\t\treturn new ResponseError('PASSWORDLESS_DISABLED', 'Passwordless sign-in is disabled for this person')\n\t\t\t}\n\n\t\t\tconst createTokenCommand = CreatePersonTokenCommand.createPasswordlessRequest(person.id, configuration.passwordless.expirationMinutes)\n\t\t\tconst result = await db.commandBus.execute(createTokenCommand)\n\n\n\t\t\tconst url = this.formatUrl(configuration.passwordless.url ?? null, result.token, result.id, email) ?? undefined\n\n\t\t\tconst projects = await this.projectManager.getProjectsByIdentity(db, person.identity_id, permissionContext)\n\t\t\tconst project = getPreferredProject(projects, mailProject ?? null)\n\n\t\t\tawait this.mailer.sendPasswordlessEmail(db, {\n\t\t\t\temail,\n\t\t\t\ttoken: result.token,\n\t\t\t\turl,\n\t\t\t\tproject: project?.name,\n\t\t\t\tprojectSlug: project?.slug,\n\t\t\t}, {\n\t\t\t\tvariant: mailVariant || '',\n\t\t\t\tprojectId: project?.id ?? null,\n\t\t\t})\n\n\t\t\treturn new ResponseOk({ requestId: result.id, expiresAt: result.expiresAt })\n\t\t})\n\t}\n\n\tprivate formatUrl(url: string | null, token: string, requestId: string, email: string): string | null {\n\t\tif (!url) {\n\t\t\treturn null\n\t\t}\n\t\tconst urlObj = new URL(url)\n\t\turlObj.searchParams.set('token', token)\n\t\turlObj.searchParams.set('request_id', requestId)\n\t\turlObj.searchParams.set('email', email)\n\t\treturn urlObj.toString()\n\t}\n\n\tasync signInPasswordless({ db, expiration, token, requestId, mfaOtp, validationType }: {\n\t\tdb: DatabaseContext\n\t\tvalidationType: PersonToken.ValidationType\n\t\trequestId: string\n\t\ttoken: string\n\t\tmfaOtp?: string\n\t\texpiration?: number\n\t}): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.SignInPasswordlessResponse> => {\n\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType,\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\tif (tokenValidationResult.error === 'TOKEN_INVALID' && validationType === 'otp') {\n\t\t\t\t\tawait db.commandBus.execute(new IncreaseOtpAttemptCommand(tokenResult!.id))\n\t\t\t\t}\n\t\t\t\treturn tokenValidationResult\n\t\t\t}\n\t\t\tconst personRow = await db.queryHandler.fetch(PersonQuery.byId(tokenValidationResult.result.person_id))\n\t\t\tif (!personRow) {\n\t\t\t\tthrow new ImplementationException()\n\t\t\t}\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person is disabled`)\n\t\t\t}\n\n\t\t\tif (personRow.otp_uri && personRow.otp_activated_at) {\n\t\t\t\tif (!mfaOtp) {\n\t\t\t\t\treturn new ResponseError('OTP_REQUIRED', `2FA is enabled. OTP token is required`)\n\t\t\t\t}\n\n\t\t\t\tif (!this.otpAuthenticator.validate({ uri: personRow.otp_uri }, mfaOtp)) {\n\t\t\t\t\treturn new ResponseError('INVALID_OTP_TOKEN', 'OTP token validation has failed')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait db.commandBus.execute(new InvalidateTokenCommand(tokenValidationResult.result.id))\n\t\t\tconst sessionToken = await this.apiKeyManager.createSessionApiKey(db, personRow.identity_id, expiration)\n\n\t\t\treturn new ResponseOk({ person: personRow, token: sessionToken })\n\t\t})\n\t}\n\n\tasync activatePasswordlessOtp({ db, token, requestId, otpHash }: {\n\t\tdb: DatabaseContext\n\t\trequestId: string\n\t\ttoken: string\n\t\totpHash: string\n\t}): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> {\n\t\treturn db.transaction(async (db): Promise<PasswordlessSignInManager.ActivatePasswordlessOtpResponse> => {\n\n\t\t\tconst tokenResult = await db.queryHandler.fetch(PersonTokenQuery.byId(requestId, 'passwordless'))\n\t\t\tconst tokenValidationResult = validateToken({\n\t\t\t\tentry: tokenResult,\n\t\t\t\ttoken,\n\t\t\t\tnow: db.providers.now(),\n\t\t\t\tvalidationType: 'token',\n\t\t\t})\n\t\t\tif (!tokenValidationResult.ok) {\n\t\t\t\treturn tokenValidationResult\n\t\t\t}\n\n\t\t\tawait db.commandBus.execute(new ActivateOtpCommand(tokenValidationResult.result.id, otpHash))\n\n\t\t\treturn new ResponseOk(null)\n\t\t})\n\t}\n\n\tprivate isEnabled(globalValue: ConfigPolicy, personValue: boolean | null): boolean {\n\t\tswitch (globalValue) {\n\t\t\tcase 'always':\n\t\t\t\treturn true\n\t\t\tcase 'never':\n\t\t\t\treturn false\n\t\t\tcase 'optIn':\n\t\t\t\treturn personValue === true\n\t\t\tcase 'optOut':\n\t\t\t\treturn personValue !== false\n\t\t}\n\t}\n}\n\nnamespace PasswordlessSignInManager {\n\texport type InitSignInPasswordlessResponse = Response<InitSignInPasswordlessResult, InitSignInPasswordlessErrorCode>\n\n\n\tinterface SignInPasswordlessResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t}\n\texport type SignInPasswordlessResponse = Response<SignInPasswordlessResult, SignInPasswordlessErrorCode>\n\n\texport type ActivatePasswordlessOtpResponse = Response<null, ActivatePasswordlessOtpErrorCode>\n}\n\nexport { PasswordlessSignInManager }\n"],"names":["db"],"mappings":"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"}
@@ -10,6 +10,9 @@ require("@contember/authorization");
10
10
  require("../authorization/PermissionContext.cjs");
11
11
  require("../authorization/PermissionsFactory.cjs");
12
12
  require("@contember/schema");
13
+ require("../type/ApiKey.cjs");
14
+ require("node:crypto");
15
+ const TogglePersonPasswordlessCommand = require("../commands/person/TogglePersonPasswordlessCommand.cjs");
13
16
  class PersonManager {
14
17
  constructor(emailValidator) {
15
18
  this.emailValidator = emailValidator;
@@ -29,6 +32,10 @@ class PersonManager {
29
32
  await dbContext.commandBus.execute(new ChangeProfileCommand.ChangeProfileCommand(person.id, data));
30
33
  return new Response.ResponseOk(null);
31
34
  }
35
+ async togglePasswordless(dbContext, person, value) {
36
+ await dbContext.commandBus.execute(new TogglePersonPasswordlessCommand.TogglePersonPasswordlessCommand(person.id, value));
37
+ return new Response.ResponseOk(null);
38
+ }
32
39
  }
33
40
  exports.PersonManager = PersonManager;
34
41
  //# sourceMappingURL=PersonManager.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"PersonManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PersonManager.ts"],"sourcesContent":["import { ChangeProfileCommand, ChangeProfileData } from '../commands/person/ChangeProfileCommand'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { DatabaseContext } from '../utils'\nimport { EmailValidator, EmailValidatorError } from './EmailValidator'\n\nclass PersonManager {\n\tconstructor(\n\t\tprivate readonly emailValidator: EmailValidator,\n\t) {\n\t}\n\n\tasync findPersonById(dbContext: DatabaseContext, personId: string): Promise<PersonRow | null> {\n\t\treturn await dbContext.queryHandler.fetch(\n\t\t\tPersonQuery.byId(personId),\n\t\t)\n\t}\n\n\tasync changeProfile(dbContext: DatabaseContext, person: PersonRow, data: ChangeProfileData): Promise<PersonManager.ProfileChangeResponse> {\n\t\tif (data.email !== undefined && person.email !== data.email) {\n\t\t\tconst validationError = await this.emailValidator.validateEmail(dbContext, data.email)\n\t\t\tif (validationError !== null) {\n\t\t\t\treturn new ResponseError(validationError.error, validationError.errorMessage)\n\t\t\t}\n\t\t}\n\t\tawait dbContext.commandBus.execute(new ChangeProfileCommand(person.id, data))\n\t\treturn new ResponseOk(null)\n\t}\n\n}\n\nnamespace PersonManager {\n\texport type ProfileChangeResponse = Response<null, EmailValidatorError>\n}\n\nexport { PersonManager }\n"],"names":["PersonQuery","ResponseError","ChangeProfileCommand","ResponseOk"],"mappings":";;;;;;;;;;;;AAMA,MAAM,cAAc;AAAA,EACnB,YACkB,gBAChB;AADgB,SAAA,iBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,eAAe,WAA4B,UAA6C;AACtF,WAAA,MAAM,UAAU,aAAa;AAAA,MACnCA,YAAA,YAAY,KAAK,QAAQ;AAAA,IAAA;AAAA,EAE3B;AAAA,EAEA,MAAM,cAAc,WAA4B,QAAmB,MAAuE;AACzI,QAAI,KAAK,UAAU,UAAa,OAAO,UAAU,KAAK,OAAO;AAC5D,YAAM,kBAAkB,MAAM,KAAK,eAAe,cAAc,WAAW,KAAK,KAAK;AACrF,UAAI,oBAAoB,MAAM;AAC7B,eAAO,IAAIC,SAAA,cAAc,gBAAgB,OAAO,gBAAgB,YAAY;AAAA,MAC7E;AAAA,IACD;AACM,UAAA,UAAU,WAAW,QAAQ,IAAIC,0CAAqB,OAAO,IAAI,IAAI,CAAC;AACrE,WAAA,IAAIC,SAAAA,WAAW,IAAI;AAAA,EAC3B;AAED;;"}
1
+ {"version":3,"file":"PersonManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PersonManager.ts"],"sourcesContent":["import { ChangeProfileCommand, ChangeProfileData } from '../commands/person/ChangeProfileCommand'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { DatabaseContext } from '../utils'\nimport { EmailValidator, EmailValidatorError } from './EmailValidator'\nimport { TogglePersonPasswordlessCommand } from '../commands'\n\nclass PersonManager {\n\tconstructor(\n\t\tprivate readonly emailValidator: EmailValidator,\n\t) {\n\t}\n\n\tasync findPersonById(dbContext: DatabaseContext, personId: string): Promise<PersonRow | null> {\n\t\treturn await dbContext.queryHandler.fetch(\n\t\t\tPersonQuery.byId(personId),\n\t\t)\n\t}\n\n\tasync changeProfile(dbContext: DatabaseContext, person: PersonRow, data: ChangeProfileData): Promise<PersonManager.ProfileChangeResponse> {\n\t\tif (data.email !== undefined && person.email !== data.email) {\n\t\t\tconst validationError = await this.emailValidator.validateEmail(dbContext, data.email)\n\t\t\tif (validationError !== null) {\n\t\t\t\treturn new ResponseError(validationError.error, validationError.errorMessage)\n\t\t\t}\n\t\t}\n\t\tawait dbContext.commandBus.execute(new ChangeProfileCommand(person.id, data))\n\t\treturn new ResponseOk(null)\n\t}\n\n\tasync togglePasswordless(dbContext: DatabaseContext, person: PersonRow, value: boolean): Promise<Response<null, never>> {\n\t\tawait dbContext.commandBus.execute(new TogglePersonPasswordlessCommand(person.id, value))\n\t\treturn new ResponseOk(null)\n\t}\n\n}\n\nnamespace PersonManager {\n\texport type ProfileChangeResponse = Response<null, EmailValidatorError>\n}\n\nexport { PersonManager }\n"],"names":["PersonQuery","ResponseError","ChangeProfileCommand","ResponseOk","TogglePersonPasswordlessCommand"],"mappings":";;;;;;;;;;;;;;;AAOA,MAAM,cAAc;AAAA,EACnB,YACkB,gBAChB;AADgB,SAAA,iBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,eAAe,WAA4B,UAA6C;AACtF,WAAA,MAAM,UAAU,aAAa;AAAA,MACnCA,YAAA,YAAY,KAAK,QAAQ;AAAA,IAAA;AAAA,EAE3B;AAAA,EAEA,MAAM,cAAc,WAA4B,QAAmB,MAAuE;AACzI,QAAI,KAAK,UAAU,UAAa,OAAO,UAAU,KAAK,OAAO;AAC5D,YAAM,kBAAkB,MAAM,KAAK,eAAe,cAAc,WAAW,KAAK,KAAK;AACrF,UAAI,oBAAoB,MAAM;AAC7B,eAAO,IAAIC,SAAA,cAAc,gBAAgB,OAAO,gBAAgB,YAAY;AAAA,MAC7E;AAAA,IACD;AACM,UAAA,UAAU,WAAW,QAAQ,IAAIC,0CAAqB,OAAO,IAAI,IAAI,CAAC;AACrE,WAAA,IAAIC,SAAAA,WAAW,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,mBAAmB,WAA4B,QAAmB,OAAgD;AACjH,UAAA,UAAU,WAAW,QAAQ,IAAIC,gEAAgC,OAAO,IAAI,KAAK,CAAC;AACjF,WAAA,IAAID,SAAAA,WAAW,IAAI;AAAA,EAC3B;AAED;;"}
@@ -8,6 +8,9 @@ import "@contember/authorization";
8
8
  import "../authorization/PermissionContext.js";
9
9
  import "../authorization/PermissionsFactory.js";
10
10
  import "@contember/schema";
11
+ import "../type/ApiKey.js";
12
+ import "node:crypto";
13
+ import { TogglePersonPasswordlessCommand } from "../commands/person/TogglePersonPasswordlessCommand.js";
11
14
  class PersonManager {
12
15
  constructor(emailValidator) {
13
16
  this.emailValidator = emailValidator;
@@ -27,6 +30,10 @@ class PersonManager {
27
30
  await dbContext.commandBus.execute(new ChangeProfileCommand(person.id, data));
28
31
  return new ResponseOk(null);
29
32
  }
33
+ async togglePasswordless(dbContext, person, value) {
34
+ await dbContext.commandBus.execute(new TogglePersonPasswordlessCommand(person.id, value));
35
+ return new ResponseOk(null);
36
+ }
30
37
  }
31
38
  export {
32
39
  PersonManager
@@ -1 +1 @@
1
- {"version":3,"file":"PersonManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PersonManager.ts"],"sourcesContent":["import { ChangeProfileCommand, ChangeProfileData } from '../commands/person/ChangeProfileCommand'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { DatabaseContext } from '../utils'\nimport { EmailValidator, EmailValidatorError } from './EmailValidator'\n\nclass PersonManager {\n\tconstructor(\n\t\tprivate readonly emailValidator: EmailValidator,\n\t) {\n\t}\n\n\tasync findPersonById(dbContext: DatabaseContext, personId: string): Promise<PersonRow | null> {\n\t\treturn await dbContext.queryHandler.fetch(\n\t\t\tPersonQuery.byId(personId),\n\t\t)\n\t}\n\n\tasync changeProfile(dbContext: DatabaseContext, person: PersonRow, data: ChangeProfileData): Promise<PersonManager.ProfileChangeResponse> {\n\t\tif (data.email !== undefined && person.email !== data.email) {\n\t\t\tconst validationError = await this.emailValidator.validateEmail(dbContext, data.email)\n\t\t\tif (validationError !== null) {\n\t\t\t\treturn new ResponseError(validationError.error, validationError.errorMessage)\n\t\t\t}\n\t\t}\n\t\tawait dbContext.commandBus.execute(new ChangeProfileCommand(person.id, data))\n\t\treturn new ResponseOk(null)\n\t}\n\n}\n\nnamespace PersonManager {\n\texport type ProfileChangeResponse = Response<null, EmailValidatorError>\n}\n\nexport { PersonManager }\n"],"names":[],"mappings":";;;;;;;;;;AAMA,MAAM,cAAc;AAAA,EACnB,YACkB,gBAChB;AADgB,SAAA,iBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,eAAe,WAA4B,UAA6C;AACtF,WAAA,MAAM,UAAU,aAAa;AAAA,MACnC,YAAY,KAAK,QAAQ;AAAA,IAAA;AAAA,EAE3B;AAAA,EAEA,MAAM,cAAc,WAA4B,QAAmB,MAAuE;AACzI,QAAI,KAAK,UAAU,UAAa,OAAO,UAAU,KAAK,OAAO;AAC5D,YAAM,kBAAkB,MAAM,KAAK,eAAe,cAAc,WAAW,KAAK,KAAK;AACrF,UAAI,oBAAoB,MAAM;AAC7B,eAAO,IAAI,cAAc,gBAAgB,OAAO,gBAAgB,YAAY;AAAA,MAC7E;AAAA,IACD;AACM,UAAA,UAAU,WAAW,QAAQ,IAAI,qBAAqB,OAAO,IAAI,IAAI,CAAC;AACrE,WAAA,IAAI,WAAW,IAAI;AAAA,EAC3B;AAED;"}
1
+ {"version":3,"file":"PersonManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PersonManager.ts"],"sourcesContent":["import { ChangeProfileCommand, ChangeProfileData } from '../commands/person/ChangeProfileCommand'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response'\nimport { PersonQuery, PersonRow } from '../queries'\nimport { DatabaseContext } from '../utils'\nimport { EmailValidator, EmailValidatorError } from './EmailValidator'\nimport { TogglePersonPasswordlessCommand } from '../commands'\n\nclass PersonManager {\n\tconstructor(\n\t\tprivate readonly emailValidator: EmailValidator,\n\t) {\n\t}\n\n\tasync findPersonById(dbContext: DatabaseContext, personId: string): Promise<PersonRow | null> {\n\t\treturn await dbContext.queryHandler.fetch(\n\t\t\tPersonQuery.byId(personId),\n\t\t)\n\t}\n\n\tasync changeProfile(dbContext: DatabaseContext, person: PersonRow, data: ChangeProfileData): Promise<PersonManager.ProfileChangeResponse> {\n\t\tif (data.email !== undefined && person.email !== data.email) {\n\t\t\tconst validationError = await this.emailValidator.validateEmail(dbContext, data.email)\n\t\t\tif (validationError !== null) {\n\t\t\t\treturn new ResponseError(validationError.error, validationError.errorMessage)\n\t\t\t}\n\t\t}\n\t\tawait dbContext.commandBus.execute(new ChangeProfileCommand(person.id, data))\n\t\treturn new ResponseOk(null)\n\t}\n\n\tasync togglePasswordless(dbContext: DatabaseContext, person: PersonRow, value: boolean): Promise<Response<null, never>> {\n\t\tawait dbContext.commandBus.execute(new TogglePersonPasswordlessCommand(person.id, value))\n\t\treturn new ResponseOk(null)\n\t}\n\n}\n\nnamespace PersonManager {\n\texport type ProfileChangeResponse = Response<null, EmailValidatorError>\n}\n\nexport { PersonManager }\n"],"names":[],"mappings":";;;;;;;;;;;;;AAOA,MAAM,cAAc;AAAA,EACnB,YACkB,gBAChB;AADgB,SAAA,iBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,eAAe,WAA4B,UAA6C;AACtF,WAAA,MAAM,UAAU,aAAa;AAAA,MACnC,YAAY,KAAK,QAAQ;AAAA,IAAA;AAAA,EAE3B;AAAA,EAEA,MAAM,cAAc,WAA4B,QAAmB,MAAuE;AACzI,QAAI,KAAK,UAAU,UAAa,OAAO,UAAU,KAAK,OAAO;AAC5D,YAAM,kBAAkB,MAAM,KAAK,eAAe,cAAc,WAAW,KAAK,KAAK;AACrF,UAAI,oBAAoB,MAAM;AAC7B,eAAO,IAAI,cAAc,gBAAgB,OAAO,gBAAgB,YAAY;AAAA,MAC7E;AAAA,IACD;AACM,UAAA,UAAU,WAAW,QAAQ,IAAI,qBAAqB,OAAO,IAAI,IAAI,CAAC;AACrE,WAAA,IAAI,WAAW,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,mBAAmB,WAA4B,QAAmB,OAAgD;AACjH,UAAA,UAAU,WAAW,QAAQ,IAAI,gCAAgC,OAAO,IAAI,KAAK,CAAC;AACjF,WAAA,IAAI,WAAW,IAAI;AAAA,EAC3B;AAED;"}