@contember/engine-tenant-api 2.2.0-alpha.3 → 2.2.0-alpha.6

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 (1316) hide show
  1. package/CLAUDE.md +36 -2
  2. package/dist/development/index.cjs +32 -0
  3. package/dist/development/index.cjs.map +1 -1
  4. package/dist/development/index.js +33 -1
  5. package/dist/development/index.js.map +1 -1
  6. package/dist/development/src/TenantContainer.cjs +15 -3
  7. package/dist/development/src/TenantContainer.cjs.map +1 -1
  8. package/dist/development/src/TenantContainer.js +15 -3
  9. package/dist/development/src/TenantContainer.js.map +1 -1
  10. package/dist/development/src/bridges/system/IdentityFetcher.cjs +2 -1
  11. package/dist/development/src/bridges/system/IdentityFetcher.cjs.map +1 -1
  12. package/dist/development/src/bridges/system/IdentityFetcher.js +2 -1
  13. package/dist/development/src/bridges/system/IdentityFetcher.js.map +1 -1
  14. package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs +10 -0
  15. package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs.map +1 -0
  16. package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.js +11 -0
  17. package/dist/development/src/migrations/2026-06-18-120000-idp-claim-mapping.js.map +1 -0
  18. package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs +9 -0
  19. package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs.map +1 -0
  20. package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.js +10 -0
  21. package/dist/development/src/migrations/2026-08-03-120000-person-enable-auth-log.js.map +1 -0
  22. package/dist/development/src/migrations/2026-08-04-120000-config-panel.cjs +11 -0
  23. package/dist/development/src/migrations/2026-08-04-120000-config-panel.cjs.map +1 -0
  24. package/dist/development/src/migrations/2026-08-04-120000-config-panel.js +12 -0
  25. package/dist/development/src/migrations/2026-08-04-120000-config-panel.js.map +1 -0
  26. package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs +18 -0
  27. package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs.map +1 -0
  28. package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js +19 -0
  29. package/dist/development/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js.map +1 -0
  30. package/dist/development/src/migrations/runner.cjs +11 -2
  31. package/dist/development/src/migrations/runner.cjs.map +1 -1
  32. package/dist/development/src/migrations/runner.js +11 -2
  33. package/dist/development/src/migrations/runner.js.map +1 -1
  34. package/dist/development/src/migrations/snapshot.cjs +8 -2
  35. package/dist/development/src/migrations/snapshot.cjs.map +1 -1
  36. package/dist/development/src/migrations/snapshot.js +8 -2
  37. package/dist/development/src/migrations/snapshot.js.map +1 -1
  38. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.cjs +5 -3
  39. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.cjs.map +1 -1
  40. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.js +5 -3
  41. package/dist/development/src/model/commands/configuration/UpdateConfigurationCommand.js.map +1 -1
  42. package/dist/development/src/model/commands/idp/CreateIdpCommand.cjs +8 -2
  43. package/dist/development/src/model/commands/idp/CreateIdpCommand.cjs.map +1 -1
  44. package/dist/development/src/model/commands/idp/CreateIdpCommand.js +8 -2
  45. package/dist/development/src/model/commands/idp/CreateIdpCommand.js.map +1 -1
  46. package/dist/development/src/model/commands/idp/UpdateIdpCommand.cjs +6 -2
  47. package/dist/development/src/model/commands/idp/UpdateIdpCommand.cjs.map +1 -1
  48. package/dist/development/src/model/commands/idp/UpdateIdpCommand.js +6 -2
  49. package/dist/development/src/model/commands/idp/UpdateIdpCommand.js.map +1 -1
  50. package/dist/development/src/model/commands/membership/{RemoveProjectMembershipsCommand.cjs → RemoveProjectMembershipCommand.cjs} +1 -1
  51. package/dist/development/src/model/commands/membership/RemoveProjectMembershipCommand.cjs.map +1 -0
  52. package/dist/development/src/model/commands/membership/{RemoveProjectMembershipsCommand.js → RemoveProjectMembershipCommand.js} +1 -1
  53. package/dist/development/src/model/commands/membership/RemoveProjectMembershipCommand.js.map +1 -0
  54. package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.cjs +2 -2
  55. package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.cjs.map +1 -1
  56. package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.js +1 -1
  57. package/dist/development/src/model/commands/membership/UpdateProjectMemberCommand.js.map +1 -1
  58. package/dist/development/src/model/commands/person/EnablePersonCommand.cjs +17 -0
  59. package/dist/development/src/model/commands/person/EnablePersonCommand.cjs.map +1 -0
  60. package/dist/development/src/model/commands/person/EnablePersonCommand.js +17 -0
  61. package/dist/development/src/model/commands/person/EnablePersonCommand.js.map +1 -0
  62. package/dist/development/src/model/queries/configuration/ConfigurationQuery.cjs +4 -0
  63. package/dist/development/src/model/queries/configuration/ConfigurationQuery.cjs.map +1 -1
  64. package/dist/development/src/model/queries/configuration/ConfigurationQuery.js +4 -0
  65. package/dist/development/src/model/queries/configuration/ConfigurationQuery.js.map +1 -1
  66. package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs +21 -0
  67. package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs.map +1 -0
  68. package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js +21 -0
  69. package/dist/development/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js.map +1 -0
  70. package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.cjs +1 -1
  71. package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.cjs.map +1 -1
  72. package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.js +1 -1
  73. package/dist/development/src/model/queries/idp/PersonIdentityProvidersQuery.js.map +1 -1
  74. package/dist/development/src/model/queries/idp/helpers.cjs +3 -3
  75. package/dist/development/src/model/queries/idp/helpers.cjs.map +1 -1
  76. package/dist/development/src/model/queries/idp/helpers.js +3 -3
  77. package/dist/development/src/model/queries/idp/helpers.js.map +1 -1
  78. package/dist/development/src/model/queries/membership/ProjectMembersQuery.cjs +1 -1
  79. package/dist/development/src/model/queries/membership/ProjectMembersQuery.cjs.map +1 -1
  80. package/dist/development/src/model/queries/membership/ProjectMembersQuery.js +1 -1
  81. package/dist/development/src/model/queries/membership/ProjectMembersQuery.js.map +1 -1
  82. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.cjs +1 -1
  83. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.cjs.map +1 -1
  84. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.js +1 -1
  85. package/dist/development/src/model/queries/person/PersonQueryBuilderFactory.js.map +1 -1
  86. package/dist/development/src/model/service/AuthLogService.cjs +8 -2
  87. package/dist/development/src/model/service/AuthLogService.cjs.map +1 -1
  88. package/dist/development/src/model/service/AuthLogService.js +8 -2
  89. package/dist/development/src/model/service/AuthLogService.js.map +1 -1
  90. package/dist/development/src/model/service/IDPSignInManager.cjs +29 -2
  91. package/dist/development/src/model/service/IDPSignInManager.cjs.map +1 -1
  92. package/dist/development/src/model/service/IDPSignInManager.js +29 -2
  93. package/dist/development/src/model/service/IDPSignInManager.js.map +1 -1
  94. package/dist/development/src/model/service/PanelAccessResolver.cjs +31 -0
  95. package/dist/development/src/model/service/PanelAccessResolver.cjs.map +1 -0
  96. package/dist/development/src/model/service/PanelAccessResolver.js +31 -0
  97. package/dist/development/src/model/service/PanelAccessResolver.js.map +1 -0
  98. package/dist/development/src/model/service/PasswordResetManager.cjs +5 -0
  99. package/dist/development/src/model/service/PasswordResetManager.cjs.map +1 -1
  100. package/dist/development/src/model/service/PasswordResetManager.js +5 -0
  101. package/dist/development/src/model/service/PasswordResetManager.js.map +1 -1
  102. package/dist/development/src/model/service/PasswordlessSignInManager.cjs +19 -0
  103. package/dist/development/src/model/service/PasswordlessSignInManager.cjs.map +1 -1
  104. package/dist/development/src/model/service/PasswordlessSignInManager.js +19 -0
  105. package/dist/development/src/model/service/PasswordlessSignInManager.js.map +1 -1
  106. package/dist/development/src/model/service/PersonAccessManager.cjs +10 -2
  107. package/dist/development/src/model/service/PersonAccessManager.cjs.map +1 -1
  108. package/dist/development/src/model/service/PersonAccessManager.js +10 -2
  109. package/dist/development/src/model/service/PersonAccessManager.js.map +1 -1
  110. package/dist/development/src/model/service/SignInManager.cjs +5 -0
  111. package/dist/development/src/model/service/SignInManager.cjs.map +1 -1
  112. package/dist/development/src/model/service/SignInManager.js +5 -0
  113. package/dist/development/src/model/service/SignInManager.js.map +1 -1
  114. package/dist/development/src/model/service/apiKey/ApiKeyManager.cjs +4 -3
  115. package/dist/development/src/model/service/apiKey/ApiKeyManager.cjs.map +1 -1
  116. package/dist/development/src/model/service/apiKey/ApiKeyManager.js +4 -3
  117. package/dist/development/src/model/service/apiKey/ApiKeyManager.js.map +1 -1
  118. package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.cjs +7 -0
  119. package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.cjs.map +1 -1
  120. package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.js +8 -1
  121. package/dist/development/src/model/service/apiKey/UnpersistedApiKeyManager.js.map +1 -1
  122. package/dist/development/src/model/service/idp/ClaimMapping.cjs +187 -0
  123. package/dist/development/src/model/service/idp/ClaimMapping.cjs.map +1 -0
  124. package/dist/development/src/model/service/idp/ClaimMapping.js +170 -0
  125. package/dist/development/src/model/service/idp/ClaimMapping.js.map +1 -0
  126. package/dist/development/src/model/service/idp/ClaimMappingEvaluator.cjs +155 -0
  127. package/dist/development/src/model/service/idp/ClaimMappingEvaluator.cjs.map +1 -0
  128. package/dist/development/src/model/service/idp/ClaimMappingEvaluator.js +155 -0
  129. package/dist/development/src/model/service/idp/ClaimMappingEvaluator.js.map +1 -0
  130. package/dist/development/src/model/service/idp/ClaimMappingValidation.cjs +83 -0
  131. package/dist/development/src/model/service/idp/ClaimMappingValidation.cjs.map +1 -0
  132. package/dist/development/src/model/service/idp/ClaimMappingValidation.js +83 -0
  133. package/dist/development/src/model/service/idp/ClaimMappingValidation.js.map +1 -0
  134. package/dist/development/src/model/service/idp/IDPClaimSyncService.cjs +260 -0
  135. package/dist/development/src/model/service/idp/IDPClaimSyncService.cjs.map +1 -0
  136. package/dist/development/src/model/service/idp/IDPClaimSyncService.js +260 -0
  137. package/dist/development/src/model/service/idp/IDPClaimSyncService.js.map +1 -0
  138. package/dist/development/src/model/service/idp/IDPManager.cjs +96 -20
  139. package/dist/development/src/model/service/idp/IDPManager.cjs.map +1 -1
  140. package/dist/development/src/model/service/idp/IDPManager.js +96 -20
  141. package/dist/development/src/model/service/idp/IDPManager.js.map +1 -1
  142. package/dist/development/src/model/service/idp/IdpSessionRevalidator.cjs +55 -1
  143. package/dist/development/src/model/service/idp/IdpSessionRevalidator.cjs.map +1 -1
  144. package/dist/development/src/model/service/idp/IdpSessionRevalidator.js +55 -1
  145. package/dist/development/src/model/service/idp/IdpSessionRevalidator.js.map +1 -1
  146. package/dist/development/src/model/service/idp/PersonIdentityProviderManager.cjs +6 -0
  147. package/dist/development/src/model/service/idp/PersonIdentityProviderManager.cjs.map +1 -1
  148. package/dist/development/src/model/service/idp/PersonIdentityProviderManager.js +6 -0
  149. package/dist/development/src/model/service/idp/PersonIdentityProviderManager.js.map +1 -1
  150. package/dist/development/src/model/service/idp/providers/OIDCHelpers.cjs +69 -33
  151. package/dist/development/src/model/service/idp/providers/OIDCHelpers.cjs.map +1 -1
  152. package/dist/development/src/model/service/idp/providers/OIDCHelpers.js +69 -33
  153. package/dist/development/src/model/service/idp/providers/OIDCHelpers.js.map +1 -1
  154. package/dist/development/src/model/service/idp/providers/OIDCProvider.cjs +4 -1
  155. package/dist/development/src/model/service/idp/providers/OIDCProvider.cjs.map +1 -1
  156. package/dist/development/src/model/service/idp/providers/OIDCProvider.js +4 -1
  157. package/dist/development/src/model/service/idp/providers/OIDCProvider.js.map +1 -1
  158. package/dist/development/src/model/utils/DatabaseContext.cjs +7 -2
  159. package/dist/development/src/model/utils/DatabaseContext.cjs.map +1 -1
  160. package/dist/development/src/model/utils/DatabaseContext.js +8 -3
  161. package/dist/development/src/model/utils/DatabaseContext.js.map +1 -1
  162. package/dist/development/src/resolvers/ResolverFactory.cjs +6 -2
  163. package/dist/development/src/resolvers/ResolverFactory.cjs.map +1 -1
  164. package/dist/development/src/resolvers/ResolverFactory.js +6 -2
  165. package/dist/development/src/resolvers/ResolverFactory.js.map +1 -1
  166. package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs +2 -1
  167. package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs.map +1 -1
  168. package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js +2 -1
  169. package/dist/development/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js.map +1 -1
  170. package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs +2 -1
  171. package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs.map +1 -1
  172. package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js +2 -1
  173. package/dist/development/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js.map +1 -1
  174. package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs +2 -1
  175. package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs.map +1 -1
  176. package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js +2 -1
  177. package/dist/development/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js.map +1 -1
  178. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs +2 -1
  179. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs.map +1 -1
  180. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js +2 -1
  181. package/dist/development/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js.map +1 -1
  182. package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs +2 -1
  183. package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs.map +1 -1
  184. package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js +2 -1
  185. package/dist/development/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js.map +1 -1
  186. package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs +4 -2
  187. package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs.map +1 -1
  188. package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.js +4 -2
  189. package/dist/development/src/resolvers/mutation/idp/AddIDPMutationResolver.js.map +1 -1
  190. package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs +2 -1
  191. package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs.map +1 -1
  192. package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.js +2 -1
  193. package/dist/development/src/resolvers/mutation/idp/DisableIDPMutationResolver.js.map +1 -1
  194. package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs +2 -1
  195. package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs.map +1 -1
  196. package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js +2 -1
  197. package/dist/development/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js.map +1 -1
  198. package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs +2 -1
  199. package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs.map +1 -1
  200. package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.js +2 -1
  201. package/dist/development/src/resolvers/mutation/idp/EnableIDPMutationResolver.js.map +1 -1
  202. package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs +4 -2
  203. package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs.map +1 -1
  204. package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js +4 -2
  205. package/dist/development/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js.map +1 -1
  206. package/dist/development/src/resolvers/mutation/idp/audit.cjs +1 -0
  207. package/dist/development/src/resolvers/mutation/idp/audit.cjs.map +1 -1
  208. package/dist/development/src/resolvers/mutation/idp/audit.js +1 -0
  209. package/dist/development/src/resolvers/mutation/idp/audit.js.map +1 -1
  210. package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs +2 -1
  211. package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs.map +1 -1
  212. package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js +2 -1
  213. package/dist/development/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js.map +1 -1
  214. package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs +2 -1
  215. package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs.map +1 -1
  216. package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.js +2 -1
  217. package/dist/development/src/resolvers/mutation/person/ChangePasswordMutationResolver.js.map +1 -1
  218. package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs +2 -1
  219. package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs.map +1 -1
  220. package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.js +2 -1
  221. package/dist/development/src/resolvers/mutation/person/ChangeProfileMutationResolver.js.map +1 -1
  222. package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs +4 -3
  223. package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs.map +1 -1
  224. package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.js +4 -3
  225. package/dist/development/src/resolvers/mutation/person/DisablePersonMutationResolver.js.map +1 -1
  226. package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs +2 -1
  227. package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs.map +1 -1
  228. package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.js +2 -1
  229. package/dist/development/src/resolvers/mutation/person/EmailOtpMutationResolver.js.map +1 -1
  230. package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs +2 -1
  231. package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs.map +1 -1
  232. package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.js +2 -1
  233. package/dist/development/src/resolvers/mutation/person/EmailVerificationMutationResolver.js.map +1 -1
  234. package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs +60 -0
  235. package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs.map +1 -0
  236. package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.js +60 -0
  237. package/dist/development/src/resolvers/mutation/person/EnablePersonMutationResolver.js.map +1 -0
  238. package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs +2 -1
  239. package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs.map +1 -1
  240. package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.js +2 -1
  241. package/dist/development/src/resolvers/mutation/person/ForceSignOutMutationResolver.js.map +1 -1
  242. package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.cjs +27 -1
  243. package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.cjs.map +1 -1
  244. package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.js +27 -1
  245. package/dist/development/src/resolvers/mutation/person/IDPMutationResolver.js.map +1 -1
  246. package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.cjs +2 -1
  247. package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.cjs.map +1 -1
  248. package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.js +2 -1
  249. package/dist/development/src/resolvers/mutation/person/InviteMutationResolver.js.map +1 -1
  250. package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.cjs +2 -1
  251. package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.cjs.map +1 -1
  252. package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.js +2 -1
  253. package/dist/development/src/resolvers/mutation/person/OtpMutationResolver.js.map +1 -1
  254. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs +6 -1
  255. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs.map +1 -1
  256. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.js +6 -1
  257. package/dist/development/src/resolvers/mutation/person/PasswordlessMutationResolver.js.map +1 -1
  258. package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs +2 -1
  259. package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs.map +1 -1
  260. package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js +2 -1
  261. package/dist/development/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js.map +1 -1
  262. package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs +2 -1
  263. package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs.map +1 -1
  264. package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.js +2 -1
  265. package/dist/development/src/resolvers/mutation/person/ResetPasswordMutationResolver.js.map +1 -1
  266. package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs +2 -1
  267. package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs.map +1 -1
  268. package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js +2 -1
  269. package/dist/development/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js.map +1 -1
  270. package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs +2 -1
  271. package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs.map +1 -1
  272. package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.js +2 -1
  273. package/dist/development/src/resolvers/mutation/person/RevokeSessionMutationResolver.js.map +1 -1
  274. package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.cjs +4 -3
  275. package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.cjs.map +1 -1
  276. package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.js +4 -3
  277. package/dist/development/src/resolvers/mutation/person/SignInMutationResolver.js.map +1 -1
  278. package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.cjs +2 -1
  279. package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.cjs.map +1 -1
  280. package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.js +2 -1
  281. package/dist/development/src/resolvers/mutation/person/SignOutMutationResolver.js.map +1 -1
  282. package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.cjs +2 -1
  283. package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.cjs.map +1 -1
  284. package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.js +2 -1
  285. package/dist/development/src/resolvers/mutation/person/SignUpMutationResolver.js.map +1 -1
  286. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs +2 -1
  287. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs.map +1 -1
  288. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js +2 -1
  289. package/dist/development/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js.map +1 -1
  290. package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs +2 -1
  291. package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs.map +1 -1
  292. package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.js +2 -1
  293. package/dist/development/src/resolvers/mutation/project/CreateProjectMutationResolver.js.map +1 -1
  294. package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs +2 -1
  295. package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs.map +1 -1
  296. package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js +2 -1
  297. package/dist/development/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js.map +1 -1
  298. package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs +2 -1
  299. package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs.map +1 -1
  300. package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.js +2 -1
  301. package/dist/development/src/resolvers/mutation/project/UpdateProjectMutationResolver.js.map +1 -1
  302. package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs +2 -1
  303. package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs.map +1 -1
  304. package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js +2 -1
  305. package/dist/development/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js.map +1 -1
  306. package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs +2 -1
  307. package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs.map +1 -1
  308. package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js +2 -1
  309. package/dist/development/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js.map +1 -1
  310. package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs +2 -1
  311. package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs.map +1 -1
  312. package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js +2 -1
  313. package/dist/development/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js.map +1 -1
  314. package/dist/development/src/resolvers/query/ApiKeyQueryResolver.cjs +2 -1
  315. package/dist/development/src/resolvers/query/ApiKeyQueryResolver.cjs.map +1 -1
  316. package/dist/development/src/resolvers/query/ApiKeyQueryResolver.js +2 -1
  317. package/dist/development/src/resolvers/query/ApiKeyQueryResolver.js.map +1 -1
  318. package/dist/development/src/resolvers/query/AuthLogQueryResolver.cjs +2 -1
  319. package/dist/development/src/resolvers/query/AuthLogQueryResolver.cjs.map +1 -1
  320. package/dist/development/src/resolvers/query/AuthLogQueryResolver.js +2 -1
  321. package/dist/development/src/resolvers/query/AuthLogQueryResolver.js.map +1 -1
  322. package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.cjs +2 -1
  323. package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.cjs.map +1 -1
  324. package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.js +2 -1
  325. package/dist/development/src/resolvers/query/AuthPolicyQueryResolver.js.map +1 -1
  326. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.cjs +2 -1
  327. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.cjs.map +1 -1
  328. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.js +2 -1
  329. package/dist/development/src/resolvers/query/ConfigurationQueryResolver.js.map +1 -1
  330. package/dist/development/src/resolvers/query/IDPQueryResolver.cjs +2 -1
  331. package/dist/development/src/resolvers/query/IDPQueryResolver.cjs.map +1 -1
  332. package/dist/development/src/resolvers/query/IDPQueryResolver.js +2 -1
  333. package/dist/development/src/resolvers/query/IDPQueryResolver.js.map +1 -1
  334. package/dist/development/src/resolvers/query/MailTemplateQueryResolver.cjs +2 -1
  335. package/dist/development/src/resolvers/query/MailTemplateQueryResolver.cjs.map +1 -1
  336. package/dist/development/src/resolvers/query/MailTemplateQueryResolver.js +2 -1
  337. package/dist/development/src/resolvers/query/MailTemplateQueryResolver.js.map +1 -1
  338. package/dist/development/src/resolvers/query/PersonQueryResolver.cjs +2 -1
  339. package/dist/development/src/resolvers/query/PersonQueryResolver.cjs.map +1 -1
  340. package/dist/development/src/resolvers/query/PersonQueryResolver.js +2 -1
  341. package/dist/development/src/resolvers/query/PersonQueryResolver.js.map +1 -1
  342. package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.cjs +2 -1
  343. package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.cjs.map +1 -1
  344. package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.js +2 -1
  345. package/dist/development/src/resolvers/query/ProjectMembersQueryResolver.js.map +1 -1
  346. package/dist/development/src/resolvers/query/ProjectQueryResolver.cjs +5 -3
  347. package/dist/development/src/resolvers/query/ProjectQueryResolver.cjs.map +1 -1
  348. package/dist/development/src/resolvers/query/ProjectQueryResolver.js +5 -3
  349. package/dist/development/src/resolvers/query/ProjectQueryResolver.js.map +1 -1
  350. package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs +2 -1
  351. package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs.map +1 -1
  352. package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.js +2 -1
  353. package/dist/development/src/resolvers/responseHelpers/ApiKeyResponseFactory.js.map +1 -1
  354. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.cjs +5 -0
  355. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.cjs.map +1 -1
  356. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.js +5 -0
  357. package/dist/development/src/resolvers/responseHelpers/PersonResponseFactory.js.map +1 -1
  358. package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.cjs +23 -0
  359. package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.cjs.map +1 -0
  360. package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.js +23 -0
  361. package/dist/development/src/resolvers/responseHelpers/ProjectResponseFactory.js.map +1 -0
  362. package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.cjs +2 -1
  363. package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.cjs.map +1 -1
  364. package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.js +2 -1
  365. package/dist/development/src/resolvers/responseHelpers/SignInResponseFactory.js.map +1 -1
  366. package/dist/development/src/resolvers/types/IdentityTypeResolver.cjs +37 -4
  367. package/dist/development/src/resolvers/types/IdentityTypeResolver.cjs.map +1 -1
  368. package/dist/development/src/resolvers/types/IdentityTypeResolver.js +37 -4
  369. package/dist/development/src/resolvers/types/IdentityTypeResolver.js.map +1 -1
  370. package/dist/development/src/resolvers/types/PersonTypeResolver.cjs +30 -1
  371. package/dist/development/src/resolvers/types/PersonTypeResolver.cjs.map +1 -1
  372. package/dist/development/src/resolvers/types/PersonTypeResolver.js +30 -1
  373. package/dist/development/src/resolvers/types/PersonTypeResolver.js.map +1 -1
  374. package/dist/development/src/resolvers/types/ProjectTypeResolver.cjs +25 -1
  375. package/dist/development/src/resolvers/types/ProjectTypeResolver.cjs.map +1 -1
  376. package/dist/development/src/resolvers/types/ProjectTypeResolver.js +25 -1
  377. package/dist/development/src/resolvers/types/ProjectTypeResolver.js.map +1 -1
  378. package/dist/development/src/schema/tenant.graphql.cjs +144 -0
  379. package/dist/development/src/schema/tenant.graphql.cjs.map +1 -1
  380. package/dist/development/src/schema/tenant.graphql.js +144 -0
  381. package/dist/development/src/schema/tenant.graphql.js.map +1 -1
  382. package/dist/production/index.cjs +32 -0
  383. package/dist/production/index.cjs.map +1 -1
  384. package/dist/production/index.js +33 -1
  385. package/dist/production/index.js.map +1 -1
  386. package/dist/production/src/TenantContainer.cjs +15 -3
  387. package/dist/production/src/TenantContainer.cjs.map +1 -1
  388. package/dist/production/src/TenantContainer.js +15 -3
  389. package/dist/production/src/TenantContainer.js.map +1 -1
  390. package/dist/production/src/bridges/system/IdentityFetcher.cjs +2 -1
  391. package/dist/production/src/bridges/system/IdentityFetcher.cjs.map +1 -1
  392. package/dist/production/src/bridges/system/IdentityFetcher.js +2 -1
  393. package/dist/production/src/bridges/system/IdentityFetcher.js.map +1 -1
  394. package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs +10 -0
  395. package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.cjs.map +1 -0
  396. package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.js +11 -0
  397. package/dist/production/src/migrations/2026-06-18-120000-idp-claim-mapping.js.map +1 -0
  398. package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs +9 -0
  399. package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.cjs.map +1 -0
  400. package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.js +10 -0
  401. package/dist/production/src/migrations/2026-08-03-120000-person-enable-auth-log.js.map +1 -0
  402. package/dist/production/src/migrations/2026-08-04-120000-config-panel.cjs +11 -0
  403. package/dist/production/src/migrations/2026-08-04-120000-config-panel.cjs.map +1 -0
  404. package/dist/production/src/migrations/2026-08-04-120000-config-panel.js +12 -0
  405. package/dist/production/src/migrations/2026-08-04-120000-config-panel.js.map +1 -0
  406. package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs +18 -0
  407. package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.cjs.map +1 -0
  408. package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js +19 -0
  409. package/dist/production/src/migrations/2026-09-04-120000-idp-disable-local-authentication.js.map +1 -0
  410. package/dist/production/src/migrations/runner.cjs +11 -2
  411. package/dist/production/src/migrations/runner.cjs.map +1 -1
  412. package/dist/production/src/migrations/runner.js +11 -2
  413. package/dist/production/src/migrations/runner.js.map +1 -1
  414. package/dist/production/src/migrations/snapshot.cjs +8 -2
  415. package/dist/production/src/migrations/snapshot.cjs.map +1 -1
  416. package/dist/production/src/migrations/snapshot.js +8 -2
  417. package/dist/production/src/migrations/snapshot.js.map +1 -1
  418. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.cjs +5 -3
  419. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.cjs.map +1 -1
  420. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.js +5 -3
  421. package/dist/production/src/model/commands/configuration/UpdateConfigurationCommand.js.map +1 -1
  422. package/dist/production/src/model/commands/idp/CreateIdpCommand.cjs +8 -2
  423. package/dist/production/src/model/commands/idp/CreateIdpCommand.cjs.map +1 -1
  424. package/dist/production/src/model/commands/idp/CreateIdpCommand.js +8 -2
  425. package/dist/production/src/model/commands/idp/CreateIdpCommand.js.map +1 -1
  426. package/dist/production/src/model/commands/idp/UpdateIdpCommand.cjs +6 -2
  427. package/dist/production/src/model/commands/idp/UpdateIdpCommand.cjs.map +1 -1
  428. package/dist/production/src/model/commands/idp/UpdateIdpCommand.js +6 -2
  429. package/dist/production/src/model/commands/idp/UpdateIdpCommand.js.map +1 -1
  430. package/dist/production/src/model/commands/membership/{RemoveProjectMembershipsCommand.cjs → RemoveProjectMembershipCommand.cjs} +1 -1
  431. package/dist/production/src/model/commands/membership/RemoveProjectMembershipCommand.cjs.map +1 -0
  432. package/dist/production/src/model/commands/membership/{RemoveProjectMembershipsCommand.js → RemoveProjectMembershipCommand.js} +1 -1
  433. package/dist/production/src/model/commands/membership/RemoveProjectMembershipCommand.js.map +1 -0
  434. package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.cjs +2 -2
  435. package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.cjs.map +1 -1
  436. package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.js +1 -1
  437. package/dist/production/src/model/commands/membership/UpdateProjectMemberCommand.js.map +1 -1
  438. package/dist/production/src/model/commands/person/EnablePersonCommand.cjs +17 -0
  439. package/dist/production/src/model/commands/person/EnablePersonCommand.cjs.map +1 -0
  440. package/dist/production/src/model/commands/person/EnablePersonCommand.js +17 -0
  441. package/dist/production/src/model/commands/person/EnablePersonCommand.js.map +1 -0
  442. package/dist/production/src/model/queries/configuration/ConfigurationQuery.cjs +4 -0
  443. package/dist/production/src/model/queries/configuration/ConfigurationQuery.cjs.map +1 -1
  444. package/dist/production/src/model/queries/configuration/ConfigurationQuery.js +4 -0
  445. package/dist/production/src/model/queries/configuration/ConfigurationQuery.js.map +1 -1
  446. package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs +21 -0
  447. package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.cjs.map +1 -0
  448. package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js +21 -0
  449. package/dist/production/src/model/queries/idp/LocalAuthDisablingIdpsQuery.js.map +1 -0
  450. package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.cjs +1 -1
  451. package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.cjs.map +1 -1
  452. package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.js +1 -1
  453. package/dist/production/src/model/queries/idp/PersonIdentityProvidersQuery.js.map +1 -1
  454. package/dist/production/src/model/queries/idp/helpers.cjs +3 -3
  455. package/dist/production/src/model/queries/idp/helpers.cjs.map +1 -1
  456. package/dist/production/src/model/queries/idp/helpers.js +3 -3
  457. package/dist/production/src/model/queries/idp/helpers.js.map +1 -1
  458. package/dist/production/src/model/queries/membership/ProjectMembersQuery.cjs +1 -1
  459. package/dist/production/src/model/queries/membership/ProjectMembersQuery.cjs.map +1 -1
  460. package/dist/production/src/model/queries/membership/ProjectMembersQuery.js +1 -1
  461. package/dist/production/src/model/queries/membership/ProjectMembersQuery.js.map +1 -1
  462. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.cjs +1 -1
  463. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.cjs.map +1 -1
  464. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.js +1 -1
  465. package/dist/production/src/model/queries/person/PersonQueryBuilderFactory.js.map +1 -1
  466. package/dist/production/src/model/service/AuthLogService.cjs +8 -2
  467. package/dist/production/src/model/service/AuthLogService.cjs.map +1 -1
  468. package/dist/production/src/model/service/AuthLogService.js +8 -2
  469. package/dist/production/src/model/service/AuthLogService.js.map +1 -1
  470. package/dist/production/src/model/service/IDPSignInManager.cjs +29 -2
  471. package/dist/production/src/model/service/IDPSignInManager.cjs.map +1 -1
  472. package/dist/production/src/model/service/IDPSignInManager.js +29 -2
  473. package/dist/production/src/model/service/IDPSignInManager.js.map +1 -1
  474. package/dist/production/src/model/service/PanelAccessResolver.cjs +31 -0
  475. package/dist/production/src/model/service/PanelAccessResolver.cjs.map +1 -0
  476. package/dist/production/src/model/service/PanelAccessResolver.js +31 -0
  477. package/dist/production/src/model/service/PanelAccessResolver.js.map +1 -0
  478. package/dist/production/src/model/service/PasswordResetManager.cjs +5 -0
  479. package/dist/production/src/model/service/PasswordResetManager.cjs.map +1 -1
  480. package/dist/production/src/model/service/PasswordResetManager.js +5 -0
  481. package/dist/production/src/model/service/PasswordResetManager.js.map +1 -1
  482. package/dist/production/src/model/service/PasswordlessSignInManager.cjs +19 -0
  483. package/dist/production/src/model/service/PasswordlessSignInManager.cjs.map +1 -1
  484. package/dist/production/src/model/service/PasswordlessSignInManager.js +19 -0
  485. package/dist/production/src/model/service/PasswordlessSignInManager.js.map +1 -1
  486. package/dist/production/src/model/service/PersonAccessManager.cjs +10 -2
  487. package/dist/production/src/model/service/PersonAccessManager.cjs.map +1 -1
  488. package/dist/production/src/model/service/PersonAccessManager.js +10 -2
  489. package/dist/production/src/model/service/PersonAccessManager.js.map +1 -1
  490. package/dist/production/src/model/service/SignInManager.cjs +5 -0
  491. package/dist/production/src/model/service/SignInManager.cjs.map +1 -1
  492. package/dist/production/src/model/service/SignInManager.js +5 -0
  493. package/dist/production/src/model/service/SignInManager.js.map +1 -1
  494. package/dist/production/src/model/service/apiKey/ApiKeyManager.cjs +4 -3
  495. package/dist/production/src/model/service/apiKey/ApiKeyManager.cjs.map +1 -1
  496. package/dist/production/src/model/service/apiKey/ApiKeyManager.js +4 -3
  497. package/dist/production/src/model/service/apiKey/ApiKeyManager.js.map +1 -1
  498. package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.cjs +7 -0
  499. package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.cjs.map +1 -1
  500. package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.js +8 -1
  501. package/dist/production/src/model/service/apiKey/UnpersistedApiKeyManager.js.map +1 -1
  502. package/dist/production/src/model/service/idp/ClaimMapping.cjs +187 -0
  503. package/dist/production/src/model/service/idp/ClaimMapping.cjs.map +1 -0
  504. package/dist/production/src/model/service/idp/ClaimMapping.js +170 -0
  505. package/dist/production/src/model/service/idp/ClaimMapping.js.map +1 -0
  506. package/dist/production/src/model/service/idp/ClaimMappingEvaluator.cjs +155 -0
  507. package/dist/production/src/model/service/idp/ClaimMappingEvaluator.cjs.map +1 -0
  508. package/dist/production/src/model/service/idp/ClaimMappingEvaluator.js +155 -0
  509. package/dist/production/src/model/service/idp/ClaimMappingEvaluator.js.map +1 -0
  510. package/dist/production/src/model/service/idp/ClaimMappingValidation.cjs +83 -0
  511. package/dist/production/src/model/service/idp/ClaimMappingValidation.cjs.map +1 -0
  512. package/dist/production/src/model/service/idp/ClaimMappingValidation.js +83 -0
  513. package/dist/production/src/model/service/idp/ClaimMappingValidation.js.map +1 -0
  514. package/dist/production/src/model/service/idp/IDPClaimSyncService.cjs +260 -0
  515. package/dist/production/src/model/service/idp/IDPClaimSyncService.cjs.map +1 -0
  516. package/dist/production/src/model/service/idp/IDPClaimSyncService.js +260 -0
  517. package/dist/production/src/model/service/idp/IDPClaimSyncService.js.map +1 -0
  518. package/dist/production/src/model/service/idp/IDPManager.cjs +96 -20
  519. package/dist/production/src/model/service/idp/IDPManager.cjs.map +1 -1
  520. package/dist/production/src/model/service/idp/IDPManager.js +96 -20
  521. package/dist/production/src/model/service/idp/IDPManager.js.map +1 -1
  522. package/dist/production/src/model/service/idp/IdpSessionRevalidator.cjs +55 -1
  523. package/dist/production/src/model/service/idp/IdpSessionRevalidator.cjs.map +1 -1
  524. package/dist/production/src/model/service/idp/IdpSessionRevalidator.js +55 -1
  525. package/dist/production/src/model/service/idp/IdpSessionRevalidator.js.map +1 -1
  526. package/dist/production/src/model/service/idp/PersonIdentityProviderManager.cjs +6 -0
  527. package/dist/production/src/model/service/idp/PersonIdentityProviderManager.cjs.map +1 -1
  528. package/dist/production/src/model/service/idp/PersonIdentityProviderManager.js +6 -0
  529. package/dist/production/src/model/service/idp/PersonIdentityProviderManager.js.map +1 -1
  530. package/dist/production/src/model/service/idp/providers/OIDCHelpers.cjs +69 -33
  531. package/dist/production/src/model/service/idp/providers/OIDCHelpers.cjs.map +1 -1
  532. package/dist/production/src/model/service/idp/providers/OIDCHelpers.js +69 -33
  533. package/dist/production/src/model/service/idp/providers/OIDCHelpers.js.map +1 -1
  534. package/dist/production/src/model/service/idp/providers/OIDCProvider.cjs +4 -1
  535. package/dist/production/src/model/service/idp/providers/OIDCProvider.cjs.map +1 -1
  536. package/dist/production/src/model/service/idp/providers/OIDCProvider.js +4 -1
  537. package/dist/production/src/model/service/idp/providers/OIDCProvider.js.map +1 -1
  538. package/dist/production/src/model/utils/DatabaseContext.cjs +7 -2
  539. package/dist/production/src/model/utils/DatabaseContext.cjs.map +1 -1
  540. package/dist/production/src/model/utils/DatabaseContext.js +8 -3
  541. package/dist/production/src/model/utils/DatabaseContext.js.map +1 -1
  542. package/dist/production/src/resolvers/ResolverFactory.cjs +6 -2
  543. package/dist/production/src/resolvers/ResolverFactory.cjs.map +1 -1
  544. package/dist/production/src/resolvers/ResolverFactory.js +6 -2
  545. package/dist/production/src/resolvers/ResolverFactory.js.map +1 -1
  546. package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs +2 -1
  547. package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.cjs.map +1 -1
  548. package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js +2 -1
  549. package/dist/production/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js.map +1 -1
  550. package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs +2 -1
  551. package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.cjs.map +1 -1
  552. package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js +2 -1
  553. package/dist/production/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js.map +1 -1
  554. package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs +2 -1
  555. package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.cjs.map +1 -1
  556. package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js +2 -1
  557. package/dist/production/src/resolvers/mutation/configuration/AuthPolicyMutationResolver.js.map +1 -1
  558. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs +2 -1
  559. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.cjs.map +1 -1
  560. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js +2 -1
  561. package/dist/production/src/resolvers/mutation/configuration/ConfigurationMutationResolver.js.map +1 -1
  562. package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs +2 -1
  563. package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.cjs.map +1 -1
  564. package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js +2 -1
  565. package/dist/production/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js.map +1 -1
  566. package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs +4 -2
  567. package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.cjs.map +1 -1
  568. package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.js +4 -2
  569. package/dist/production/src/resolvers/mutation/idp/AddIDPMutationResolver.js.map +1 -1
  570. package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs +2 -1
  571. package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.cjs.map +1 -1
  572. package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.js +2 -1
  573. package/dist/production/src/resolvers/mutation/idp/DisableIDPMutationResolver.js.map +1 -1
  574. package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs +2 -1
  575. package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.cjs.map +1 -1
  576. package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js +2 -1
  577. package/dist/production/src/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.js.map +1 -1
  578. package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs +2 -1
  579. package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.cjs.map +1 -1
  580. package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.js +2 -1
  581. package/dist/production/src/resolvers/mutation/idp/EnableIDPMutationResolver.js.map +1 -1
  582. package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs +4 -2
  583. package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.cjs.map +1 -1
  584. package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js +4 -2
  585. package/dist/production/src/resolvers/mutation/idp/UpdateIDPMutationResolver.js.map +1 -1
  586. package/dist/production/src/resolvers/mutation/idp/audit.cjs +1 -0
  587. package/dist/production/src/resolvers/mutation/idp/audit.cjs.map +1 -1
  588. package/dist/production/src/resolvers/mutation/idp/audit.js +1 -0
  589. package/dist/production/src/resolvers/mutation/idp/audit.js.map +1 -1
  590. package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs +2 -1
  591. package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.cjs.map +1 -1
  592. package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js +2 -1
  593. package/dist/production/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js.map +1 -1
  594. package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs +2 -1
  595. package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.cjs.map +1 -1
  596. package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.js +2 -1
  597. package/dist/production/src/resolvers/mutation/person/ChangePasswordMutationResolver.js.map +1 -1
  598. package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs +2 -1
  599. package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.cjs.map +1 -1
  600. package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.js +2 -1
  601. package/dist/production/src/resolvers/mutation/person/ChangeProfileMutationResolver.js.map +1 -1
  602. package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs +4 -3
  603. package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.cjs.map +1 -1
  604. package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.js +4 -3
  605. package/dist/production/src/resolvers/mutation/person/DisablePersonMutationResolver.js.map +1 -1
  606. package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs +2 -1
  607. package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.cjs.map +1 -1
  608. package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.js +2 -1
  609. package/dist/production/src/resolvers/mutation/person/EmailOtpMutationResolver.js.map +1 -1
  610. package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs +2 -1
  611. package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.cjs.map +1 -1
  612. package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.js +2 -1
  613. package/dist/production/src/resolvers/mutation/person/EmailVerificationMutationResolver.js.map +1 -1
  614. package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs +60 -0
  615. package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.cjs.map +1 -0
  616. package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.js +60 -0
  617. package/dist/production/src/resolvers/mutation/person/EnablePersonMutationResolver.js.map +1 -0
  618. package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs +2 -1
  619. package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.cjs.map +1 -1
  620. package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.js +2 -1
  621. package/dist/production/src/resolvers/mutation/person/ForceSignOutMutationResolver.js.map +1 -1
  622. package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.cjs +27 -1
  623. package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.cjs.map +1 -1
  624. package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.js +27 -1
  625. package/dist/production/src/resolvers/mutation/person/IDPMutationResolver.js.map +1 -1
  626. package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.cjs +2 -1
  627. package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.cjs.map +1 -1
  628. package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.js +2 -1
  629. package/dist/production/src/resolvers/mutation/person/InviteMutationResolver.js.map +1 -1
  630. package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.cjs +2 -1
  631. package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.cjs.map +1 -1
  632. package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.js +2 -1
  633. package/dist/production/src/resolvers/mutation/person/OtpMutationResolver.js.map +1 -1
  634. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs +6 -1
  635. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.cjs.map +1 -1
  636. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.js +6 -1
  637. package/dist/production/src/resolvers/mutation/person/PasswordlessMutationResolver.js.map +1 -1
  638. package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs +2 -1
  639. package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.cjs.map +1 -1
  640. package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js +2 -1
  641. package/dist/production/src/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.js.map +1 -1
  642. package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs +2 -1
  643. package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.cjs.map +1 -1
  644. package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.js +2 -1
  645. package/dist/production/src/resolvers/mutation/person/ResetPasswordMutationResolver.js.map +1 -1
  646. package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs +2 -1
  647. package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.cjs.map +1 -1
  648. package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js +2 -1
  649. package/dist/production/src/resolvers/mutation/person/ResetPersonMfaMutationResolver.js.map +1 -1
  650. package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs +2 -1
  651. package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.cjs.map +1 -1
  652. package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.js +2 -1
  653. package/dist/production/src/resolvers/mutation/person/RevokeSessionMutationResolver.js.map +1 -1
  654. package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.cjs +4 -3
  655. package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.cjs.map +1 -1
  656. package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.js +4 -3
  657. package/dist/production/src/resolvers/mutation/person/SignInMutationResolver.js.map +1 -1
  658. package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.cjs +2 -1
  659. package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.cjs.map +1 -1
  660. package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.js +2 -1
  661. package/dist/production/src/resolvers/mutation/person/SignOutMutationResolver.js.map +1 -1
  662. package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.cjs +2 -1
  663. package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.cjs.map +1 -1
  664. package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.js +2 -1
  665. package/dist/production/src/resolvers/mutation/person/SignUpMutationResolver.js.map +1 -1
  666. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs +2 -1
  667. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.cjs.map +1 -1
  668. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js +2 -1
  669. package/dist/production/src/resolvers/mutation/person/TogglePasswordlessMutationResolver.js.map +1 -1
  670. package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs +2 -1
  671. package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.cjs.map +1 -1
  672. package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.js +2 -1
  673. package/dist/production/src/resolvers/mutation/project/CreateProjectMutationResolver.js.map +1 -1
  674. package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs +2 -1
  675. package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.cjs.map +1 -1
  676. package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js +2 -1
  677. package/dist/production/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js.map +1 -1
  678. package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs +2 -1
  679. package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.cjs.map +1 -1
  680. package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.js +2 -1
  681. package/dist/production/src/resolvers/mutation/project/UpdateProjectMutationResolver.js.map +1 -1
  682. package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs +2 -1
  683. package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.cjs.map +1 -1
  684. package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js +2 -1
  685. package/dist/production/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js.map +1 -1
  686. package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs +2 -1
  687. package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.cjs.map +1 -1
  688. package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js +2 -1
  689. package/dist/production/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js.map +1 -1
  690. package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs +2 -1
  691. package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.cjs.map +1 -1
  692. package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js +2 -1
  693. package/dist/production/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js.map +1 -1
  694. package/dist/production/src/resolvers/query/ApiKeyQueryResolver.cjs +2 -1
  695. package/dist/production/src/resolvers/query/ApiKeyQueryResolver.cjs.map +1 -1
  696. package/dist/production/src/resolvers/query/ApiKeyQueryResolver.js +2 -1
  697. package/dist/production/src/resolvers/query/ApiKeyQueryResolver.js.map +1 -1
  698. package/dist/production/src/resolvers/query/AuthLogQueryResolver.cjs +2 -1
  699. package/dist/production/src/resolvers/query/AuthLogQueryResolver.cjs.map +1 -1
  700. package/dist/production/src/resolvers/query/AuthLogQueryResolver.js +2 -1
  701. package/dist/production/src/resolvers/query/AuthLogQueryResolver.js.map +1 -1
  702. package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.cjs +2 -1
  703. package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.cjs.map +1 -1
  704. package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.js +2 -1
  705. package/dist/production/src/resolvers/query/AuthPolicyQueryResolver.js.map +1 -1
  706. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.cjs +2 -1
  707. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.cjs.map +1 -1
  708. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.js +2 -1
  709. package/dist/production/src/resolvers/query/ConfigurationQueryResolver.js.map +1 -1
  710. package/dist/production/src/resolvers/query/IDPQueryResolver.cjs +2 -1
  711. package/dist/production/src/resolvers/query/IDPQueryResolver.cjs.map +1 -1
  712. package/dist/production/src/resolvers/query/IDPQueryResolver.js +2 -1
  713. package/dist/production/src/resolvers/query/IDPQueryResolver.js.map +1 -1
  714. package/dist/production/src/resolvers/query/MailTemplateQueryResolver.cjs +2 -1
  715. package/dist/production/src/resolvers/query/MailTemplateQueryResolver.cjs.map +1 -1
  716. package/dist/production/src/resolvers/query/MailTemplateQueryResolver.js +2 -1
  717. package/dist/production/src/resolvers/query/MailTemplateQueryResolver.js.map +1 -1
  718. package/dist/production/src/resolvers/query/PersonQueryResolver.cjs +2 -1
  719. package/dist/production/src/resolvers/query/PersonQueryResolver.cjs.map +1 -1
  720. package/dist/production/src/resolvers/query/PersonQueryResolver.js +2 -1
  721. package/dist/production/src/resolvers/query/PersonQueryResolver.js.map +1 -1
  722. package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.cjs +2 -1
  723. package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.cjs.map +1 -1
  724. package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.js +2 -1
  725. package/dist/production/src/resolvers/query/ProjectMembersQueryResolver.js.map +1 -1
  726. package/dist/production/src/resolvers/query/ProjectQueryResolver.cjs +5 -3
  727. package/dist/production/src/resolvers/query/ProjectQueryResolver.cjs.map +1 -1
  728. package/dist/production/src/resolvers/query/ProjectQueryResolver.js +5 -3
  729. package/dist/production/src/resolvers/query/ProjectQueryResolver.js.map +1 -1
  730. package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs +2 -1
  731. package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.cjs.map +1 -1
  732. package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.js +2 -1
  733. package/dist/production/src/resolvers/responseHelpers/ApiKeyResponseFactory.js.map +1 -1
  734. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.cjs +5 -0
  735. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.cjs.map +1 -1
  736. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.js +5 -0
  737. package/dist/production/src/resolvers/responseHelpers/PersonResponseFactory.js.map +1 -1
  738. package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.cjs +23 -0
  739. package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.cjs.map +1 -0
  740. package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.js +23 -0
  741. package/dist/production/src/resolvers/responseHelpers/ProjectResponseFactory.js.map +1 -0
  742. package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.cjs +2 -1
  743. package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.cjs.map +1 -1
  744. package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.js +2 -1
  745. package/dist/production/src/resolvers/responseHelpers/SignInResponseFactory.js.map +1 -1
  746. package/dist/production/src/resolvers/types/IdentityTypeResolver.cjs +37 -4
  747. package/dist/production/src/resolvers/types/IdentityTypeResolver.cjs.map +1 -1
  748. package/dist/production/src/resolvers/types/IdentityTypeResolver.js +37 -4
  749. package/dist/production/src/resolvers/types/IdentityTypeResolver.js.map +1 -1
  750. package/dist/production/src/resolvers/types/PersonTypeResolver.cjs +30 -1
  751. package/dist/production/src/resolvers/types/PersonTypeResolver.cjs.map +1 -1
  752. package/dist/production/src/resolvers/types/PersonTypeResolver.js +30 -1
  753. package/dist/production/src/resolvers/types/PersonTypeResolver.js.map +1 -1
  754. package/dist/production/src/resolvers/types/ProjectTypeResolver.cjs +25 -1
  755. package/dist/production/src/resolvers/types/ProjectTypeResolver.cjs.map +1 -1
  756. package/dist/production/src/resolvers/types/ProjectTypeResolver.js +25 -1
  757. package/dist/production/src/resolvers/types/ProjectTypeResolver.js.map +1 -1
  758. package/dist/production/src/schema/tenant.graphql.cjs +144 -0
  759. package/dist/production/src/schema/tenant.graphql.cjs.map +1 -1
  760. package/dist/production/src/schema/tenant.graphql.js +144 -0
  761. package/dist/production/src/schema/tenant.graphql.js.map +1 -1
  762. package/dist/tests/cases/integration/mocked/configurationPanel.test.d.ts +2 -0
  763. package/dist/tests/cases/integration/mocked/configurationPanel.test.d.ts.map +1 -0
  764. package/dist/tests/cases/integration/mocked/disablePersonMutation.test.d.ts +2 -0
  765. package/dist/tests/cases/integration/mocked/disablePersonMutation.test.d.ts.map +1 -0
  766. package/dist/tests/cases/integration/mocked/enablePersonMutation.test.d.ts +2 -0
  767. package/dist/tests/cases/integration/mocked/enablePersonMutation.test.d.ts.map +1 -0
  768. package/dist/tests/cases/integration/mocked/gql/addProjectMember.d.ts.map +1 -1
  769. package/dist/tests/cases/integration/mocked/gql/changeMyPassword.d.ts.map +1 -1
  770. package/dist/tests/cases/integration/mocked/gql/changeMyProfile.d.ts.map +1 -1
  771. package/dist/tests/cases/integration/mocked/gql/changePassword.d.ts.map +1 -1
  772. package/dist/tests/cases/integration/mocked/gql/changeProfile.d.ts.map +1 -1
  773. package/dist/tests/cases/integration/mocked/gql/confirmOtp.d.ts.map +1 -1
  774. package/dist/tests/cases/integration/mocked/gql/createApiKey.d.ts.map +1 -1
  775. package/dist/tests/cases/integration/mocked/gql/createResetPasswordRequest.d.ts.map +1 -1
  776. package/dist/tests/cases/integration/mocked/gql/createSessionToken.d.ts.map +1 -1
  777. package/dist/tests/cases/integration/mocked/gql/emailOtp.d.ts.map +1 -1
  778. package/dist/tests/cases/integration/mocked/gql/emailVerification.d.ts.map +1 -1
  779. package/dist/tests/cases/integration/mocked/gql/invite.d.ts.map +1 -1
  780. package/dist/tests/cases/integration/mocked/gql/myIdentityProviders.d.ts.map +1 -1
  781. package/dist/tests/cases/integration/mocked/gql/passwordless.d.ts +4 -1
  782. package/dist/tests/cases/integration/mocked/gql/passwordless.d.ts.map +1 -1
  783. package/dist/tests/cases/integration/mocked/gql/prepareOtp.d.ts.map +1 -1
  784. package/dist/tests/cases/integration/mocked/gql/resetPassword.d.ts.map +1 -1
  785. package/dist/tests/cases/integration/mocked/gql/signIn.d.ts.map +1 -1
  786. package/dist/tests/cases/integration/mocked/gql/signInIdp.d.ts.map +1 -1
  787. package/dist/tests/cases/integration/mocked/gql/signUp.d.ts.map +1 -1
  788. package/dist/tests/cases/integration/mocked/gql/unmanagedInvite.d.ts.map +1 -1
  789. package/dist/tests/cases/integration/mocked/gql/updateProjectMember.d.ts.map +1 -1
  790. package/dist/tests/cases/integration/mocked/idpClaimMappingConfig.test.d.ts +2 -0
  791. package/dist/tests/cases/integration/mocked/idpClaimMappingConfig.test.d.ts.map +1 -0
  792. package/dist/tests/cases/integration/mocked/localAuthenticationDisabled.test.d.ts +2 -0
  793. package/dist/tests/cases/integration/mocked/localAuthenticationDisabled.test.d.ts.map +1 -0
  794. package/dist/tests/cases/integration/mocked/permissionsQuery.test.d.ts +2 -0
  795. package/dist/tests/cases/integration/mocked/permissionsQuery.test.d.ts.map +1 -0
  796. package/dist/tests/cases/integration/mocked/signInIdpClaimMapping.test.d.ts +2 -0
  797. package/dist/tests/cases/integration/mocked/signInIdpClaimMapping.test.d.ts.map +1 -0
  798. package/dist/tests/cases/integration/mocked/signInIdpClaimMappingFixes.test.d.ts +2 -0
  799. package/dist/tests/cases/integration/mocked/signInIdpClaimMappingFixes.test.d.ts.map +1 -0
  800. package/dist/tests/cases/integration/mocked/signInIdpClaimMappingSafety.test.d.ts +2 -0
  801. package/dist/tests/cases/integration/mocked/signInIdpClaimMappingSafety.test.d.ts.map +1 -0
  802. package/dist/tests/cases/integration/mocked/sql/authLogSql.d.ts.map +1 -1
  803. package/dist/tests/cases/integration/mocked/sql/authPolicySql.d.ts.map +1 -1
  804. package/dist/tests/cases/integration/mocked/sql/consumeBackupCodeSql.d.ts.map +1 -1
  805. package/dist/tests/cases/integration/mocked/sql/createApiKeySql.d.ts.map +1 -1
  806. package/dist/tests/cases/integration/mocked/sql/createIdentitySql.d.ts.map +1 -1
  807. package/dist/tests/cases/integration/mocked/sql/createMembershipSql.d.ts.map +1 -1
  808. package/dist/tests/cases/integration/mocked/sql/createMembershipVariableSql.d.ts.map +1 -1
  809. package/dist/tests/cases/integration/mocked/sql/createPersonSql.d.ts.map +1 -1
  810. package/dist/tests/cases/integration/mocked/sql/createPersonTokenSql.d.ts.map +1 -1
  811. package/dist/tests/cases/integration/mocked/sql/createSessionKeySql.d.ts.map +1 -1
  812. package/dist/tests/cases/integration/mocked/sql/disableApiKeySql.d.ts.map +1 -1
  813. package/dist/tests/cases/integration/mocked/sql/disableOneOffKeySql.d.ts.map +1 -1
  814. package/dist/tests/cases/integration/mocked/sql/emailOtpSql.d.ts.map +1 -1
  815. package/dist/tests/cases/integration/mocked/sql/generateBackupCodesSql.d.ts.map +1 -1
  816. package/dist/tests/cases/integration/mocked/sql/getApiKeySql.d.ts.map +1 -1
  817. package/dist/tests/cases/integration/mocked/sql/getConfigSql.d.ts.map +1 -1
  818. package/dist/tests/cases/integration/mocked/sql/getIdentityByIdSql.d.ts.map +1 -1
  819. package/dist/tests/cases/integration/mocked/sql/getIdentityProjectsSql.d.ts.map +1 -1
  820. package/dist/tests/cases/integration/mocked/sql/getIdpBySlugSql.d.ts.map +1 -1
  821. package/dist/tests/cases/integration/mocked/sql/getIdpSessionByApiKeySql.d.ts.map +1 -1
  822. package/dist/tests/cases/integration/mocked/sql/getMailTemplateSql.d.ts.map +1 -1
  823. package/dist/tests/cases/integration/mocked/sql/getNextLoginAttemptSql.d.ts.map +1 -1
  824. package/dist/tests/cases/integration/mocked/sql/getNextMailAttemptSql.d.ts +1 -1
  825. package/dist/tests/cases/integration/mocked/sql/getNextMailAttemptSql.d.ts.map +1 -1
  826. package/dist/tests/cases/integration/mocked/sql/getPersonByEmailSql.d.ts.map +1 -1
  827. package/dist/tests/cases/integration/mocked/sql/getPersonByIdSql.d.ts.map +1 -1
  828. package/dist/tests/cases/integration/mocked/sql/getPersonByIdentity.d.ts.map +1 -1
  829. package/dist/tests/cases/integration/mocked/sql/getPersonByIdpSql.d.ts.map +1 -1
  830. package/dist/tests/cases/integration/mocked/sql/getPersonsByIdentitySql.d.ts.map +1 -1
  831. package/dist/tests/cases/integration/mocked/sql/getProjectBySlugSql.d.ts +1 -1
  832. package/dist/tests/cases/integration/mocked/sql/getProjectBySlugSql.d.ts.map +1 -1
  833. package/dist/tests/cases/integration/mocked/sql/getProjectMembershipSql.d.ts.map +1 -1
  834. package/dist/tests/cases/integration/mocked/sql/listApiKeysSql.d.ts.map +1 -1
  835. package/dist/tests/cases/integration/mocked/sql/listPersonsSql.d.ts +2 -0
  836. package/dist/tests/cases/integration/mocked/sql/listPersonsSql.d.ts.map +1 -1
  837. package/dist/tests/cases/integration/mocked/sql/listProjectSecretsSql.d.ts.map +1 -1
  838. package/dist/tests/cases/integration/mocked/sql/listSessionsSql.d.ts.map +1 -1
  839. package/dist/tests/cases/integration/mocked/sql/localAuthDisablingIdpsSql.d.ts +10 -0
  840. package/dist/tests/cases/integration/mocked/sql/localAuthDisablingIdpsSql.d.ts.map +1 -0
  841. package/dist/tests/cases/integration/mocked/sql/loginHistorySql.d.ts.map +1 -1
  842. package/dist/tests/cases/integration/mocked/sql/patchVariablesSql.d.ts.map +1 -1
  843. package/dist/tests/cases/integration/mocked/sql/personIdentityProvidersSql.d.ts +1 -0
  844. package/dist/tests/cases/integration/mocked/sql/personIdentityProvidersSql.d.ts.map +1 -1
  845. package/dist/tests/cases/integration/mocked/sql/removeMembershipSql.d.ts +8 -0
  846. package/dist/tests/cases/integration/mocked/sql/removeMembershipSql.d.ts.map +1 -0
  847. package/dist/tests/cases/integration/mocked/sql/selectMembershipsSql.d.ts.map +1 -1
  848. package/dist/tests/cases/integration/mocked/sql/setEmailOtpEnabledSql.d.ts.map +1 -1
  849. package/dist/tests/cases/integration/mocked/sql/sqlTransaction.d.ts.map +1 -1
  850. package/dist/tests/cases/integration/mocked/sql/updatePesonNameSql.d.ts.map +1 -1
  851. package/dist/tests/cases/integration/mocked/sql/updatePesonPasswordSql.d.ts.map +1 -1
  852. package/dist/tests/cases/unit/databaseContextRetry.test.d.ts +2 -0
  853. package/dist/tests/cases/unit/databaseContextRetry.test.d.ts.map +1 -0
  854. package/dist/tests/cases/unit/idp/claimMappingEvaluator.test.d.ts +2 -0
  855. package/dist/tests/cases/unit/idp/claimMappingEvaluator.test.d.ts.map +1 -0
  856. package/dist/tests/cases/unit/idp/claimMappingValidation.test.d.ts +2 -0
  857. package/dist/tests/cases/unit/idp/claimMappingValidation.test.d.ts.map +1 -0
  858. package/dist/tests/cases/unit/idp/idpManagerConfigMerge.test.d.ts +2 -0
  859. package/dist/tests/cases/unit/idp/idpManagerConfigMerge.test.d.ts.map +1 -0
  860. package/dist/tests/cases/unit/idp/idpManagerUnknownConfigKeys.test.d.ts +2 -0
  861. package/dist/tests/cases/unit/idp/idpManagerUnknownConfigKeys.test.d.ts.map +1 -0
  862. package/dist/tests/cases/unit/idp/oidcClaims.test.d.ts +2 -0
  863. package/dist/tests/cases/unit/idp/oidcClaims.test.d.ts.map +1 -0
  864. package/dist/tests/cases/unit/panelAccessResolver.test.d.ts +2 -0
  865. package/dist/tests/cases/unit/panelAccessResolver.test.d.ts.map +1 -0
  866. package/dist/tests/cases/unit/updateConfigurationCommand.test.d.ts +2 -0
  867. package/dist/tests/cases/unit/updateConfigurationCommand.test.d.ts.map +1 -0
  868. package/dist/tests/src/IdPMock.d.ts.map +1 -1
  869. package/dist/tests/src/dbUtils.d.ts.map +1 -1
  870. package/dist/tests/src/tags.d.ts.map +1 -1
  871. package/dist/tests/src/testGraphql.d.ts.map +1 -1
  872. package/dist/tests/src/testTenant.d.ts +7 -1
  873. package/dist/tests/src/testTenant.d.ts.map +1 -1
  874. package/dist/tests/src/testUuid.d.ts.map +1 -1
  875. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  876. package/dist/types/TenantContainer.d.ts +21 -13
  877. package/dist/types/TenantContainer.d.ts.map +1 -1
  878. package/dist/types/bridges/system/IdentityFetcher.d.ts +2 -2
  879. package/dist/types/bridges/system/IdentityFetcher.d.ts.map +1 -1
  880. package/dist/types/exceptions.d.ts.map +1 -1
  881. package/dist/types/migrations/2026-06-18-120000-idp-claim-mapping.d.ts +3 -0
  882. package/dist/types/migrations/2026-06-18-120000-idp-claim-mapping.d.ts.map +1 -0
  883. package/dist/types/migrations/2026-08-03-120000-person-enable-auth-log.d.ts +3 -0
  884. package/dist/types/migrations/2026-08-03-120000-person-enable-auth-log.d.ts.map +1 -0
  885. package/dist/types/migrations/2026-08-04-120000-config-panel.d.ts +3 -0
  886. package/dist/types/migrations/2026-08-04-120000-config-panel.d.ts.map +1 -0
  887. package/dist/types/migrations/2026-09-04-120000-idp-disable-local-authentication.d.ts +3 -0
  888. package/dist/types/migrations/2026-09-04-120000-idp-disable-local-authentication.d.ts.map +1 -0
  889. package/dist/types/migrations/runner.d.ts.map +1 -1
  890. package/dist/types/migrations/snapshot-factory.d.ts.map +1 -1
  891. package/dist/types/migrations/snapshot.d.ts.map +1 -1
  892. package/dist/types/migrations/tenantCredentials.d.ts.map +1 -1
  893. package/dist/types/model/authorization/AclSchemaAccessNodeFactory.d.ts.map +1 -1
  894. package/dist/types/model/authorization/DirectPermissionsAccessNode.d.ts.map +1 -1
  895. package/dist/types/model/authorization/Identity.d.ts.map +1 -1
  896. package/dist/types/model/authorization/IdentityFactory.d.ts.map +1 -1
  897. package/dist/types/model/authorization/IdentityScope.d.ts.map +1 -1
  898. package/dist/types/model/authorization/MembershipMatcher.d.ts.map +1 -1
  899. package/dist/types/model/authorization/PermissionActions.d.ts.map +1 -1
  900. package/dist/types/model/authorization/PermissionContext.d.ts.map +1 -1
  901. package/dist/types/model/authorization/PermissionContextFactory.d.ts.map +1 -1
  902. package/dist/types/model/authorization/PermissionsFactory.d.ts.map +1 -1
  903. package/dist/types/model/authorization/ProjectScope.d.ts.map +1 -1
  904. package/dist/types/model/authorization/ProjectScopeFactory.d.ts.map +1 -1
  905. package/dist/types/model/commands/CommandBus.d.ts.map +1 -1
  906. package/dist/types/model/commands/apiKey/ApiKeyHelper.d.ts.map +1 -1
  907. package/dist/types/model/commands/apiKey/CreateApiKeyCommand.d.ts.map +1 -1
  908. package/dist/types/model/commands/apiKey/DisableApiKeyCommand.d.ts.map +1 -1
  909. package/dist/types/model/commands/apiKey/DisableIdentityApiKeysCommand.d.ts.map +1 -1
  910. package/dist/types/model/commands/apiKey/DisableOneOffApiKeyCommand.d.ts.map +1 -1
  911. package/dist/types/model/commands/apiKey/ProlongApiKeyCommand.d.ts +1 -1
  912. package/dist/types/model/commands/apiKey/ProlongApiKeyCommand.d.ts.map +1 -1
  913. package/dist/types/model/commands/authLog/CreateAuthLogEntryCommand.d.ts.map +1 -1
  914. package/dist/types/model/commands/authPolicy/CreateAuthPolicyCommand.d.ts.map +1 -1
  915. package/dist/types/model/commands/authPolicy/DeleteAuthPolicyCommand.d.ts.map +1 -1
  916. package/dist/types/model/commands/authPolicy/UpdateAuthPolicyCommand.d.ts.map +1 -1
  917. package/dist/types/model/commands/backupCode/ConsumeBackupCodeCommand.d.ts.map +1 -1
  918. package/dist/types/model/commands/backupCode/CreateBackupCodeCommand.d.ts.map +1 -1
  919. package/dist/types/model/commands/backupCode/DeleteBackupCodesCommand.d.ts.map +1 -1
  920. package/dist/types/model/commands/configuration/UpdateConfigurationCommand.d.ts.map +1 -1
  921. package/dist/types/model/commands/identity/CreateIdentityCommand.d.ts.map +1 -1
  922. package/dist/types/model/commands/identity/PatchIdentityGlobalRoles.d.ts.map +1 -1
  923. package/dist/types/model/commands/idp/ClaimIdpRevalidationCommand.d.ts.map +1 -1
  924. package/dist/types/model/commands/idp/CreateIdpCommand.d.ts.map +1 -1
  925. package/dist/types/model/commands/idp/CreateIdpSessionCommand.d.ts.map +1 -1
  926. package/dist/types/model/commands/idp/DisableIdpCommand.d.ts.map +1 -1
  927. package/dist/types/model/commands/idp/DisconnectPersonIdentityProviderCommand.d.ts.map +1 -1
  928. package/dist/types/model/commands/idp/EnableIdpCommand.d.ts.map +1 -1
  929. package/dist/types/model/commands/idp/UpdateIdpCommand.d.ts.map +1 -1
  930. package/dist/types/model/commands/idp/UpdateIdpSessionCommand.d.ts.map +1 -1
  931. package/dist/types/model/commands/mailTemplate/AddMailTemplateCommand.d.ts.map +1 -1
  932. package/dist/types/model/commands/mailTemplate/RemoveMailTemplateCommand.d.ts.map +1 -1
  933. package/dist/types/model/commands/membership/AddProjectMemberCommand.d.ts.map +1 -1
  934. package/dist/types/model/commands/membership/CreateOrUpdateProjectMembershipCommand.d.ts.map +1 -1
  935. package/dist/types/model/commands/membership/RemoveProjectMemberCommand.d.ts.map +1 -1
  936. package/dist/types/model/commands/membership/{RemoveProjectMembershipsCommand.d.ts → RemoveProjectMembershipCommand.d.ts} +1 -1
  937. package/dist/types/model/commands/membership/RemoveProjectMembershipCommand.d.ts.map +1 -0
  938. package/dist/types/model/commands/membership/UpdateProjectMemberCommand.d.ts.map +1 -1
  939. package/dist/types/model/commands/membership/index.d.ts +2 -1
  940. package/dist/types/model/commands/membership/index.d.ts.map +1 -1
  941. package/dist/types/model/commands/membership/variables/PatchProjectMembershipVariableValuesCommand.d.ts.map +1 -1
  942. package/dist/types/model/commands/membership/variables/PatchProjectMembershipVariablesCommand.d.ts.map +1 -1
  943. package/dist/types/model/commands/membership/variables/SetProjectMembershipVariableValuesCommand.d.ts.map +1 -1
  944. package/dist/types/model/commands/membership/variables/index.d.ts +1 -0
  945. package/dist/types/model/commands/membership/variables/index.d.ts.map +1 -1
  946. package/dist/types/model/commands/otp/ConfirmOtpCommand.d.ts.map +1 -1
  947. package/dist/types/model/commands/otp/DisableOtpCommand.d.ts.map +1 -1
  948. package/dist/types/model/commands/otp/PrepareOtpCommand.d.ts.map +1 -1
  949. package/dist/types/model/commands/otp/ReEncryptOtpSecretCommand.d.ts.map +1 -1
  950. package/dist/types/model/commands/otp/SetEmailOtpEnabledCommand.d.ts.map +1 -1
  951. package/dist/types/model/commands/person/ChangePasswordCommand.d.ts.map +1 -1
  952. package/dist/types/model/commands/person/ChangeProfileCommand.d.ts.map +1 -1
  953. package/dist/types/model/commands/person/CreatePersonCommand.d.ts.map +1 -1
  954. package/dist/types/model/commands/person/CreatePersonIdentityProviderIdentifierCommand.d.ts.map +1 -1
  955. package/dist/types/model/commands/person/DisablePersonCommand.d.ts.map +1 -1
  956. package/dist/types/model/commands/person/EnablePersonCommand.d.ts +7 -0
  957. package/dist/types/model/commands/person/EnablePersonCommand.d.ts.map +1 -0
  958. package/dist/types/model/commands/person/MarkEmailVerifiedCommand.d.ts.map +1 -1
  959. package/dist/types/model/commands/person/ResetPersonMfaCommand.d.ts.map +1 -1
  960. package/dist/types/model/commands/person/SetMfaGraceUntilCommand.d.ts.map +1 -1
  961. package/dist/types/model/commands/person/TogglePersonPasswordlessCommand.d.ts.map +1 -1
  962. package/dist/types/model/commands/personToken/ActivateOtpCommand.d.ts.map +1 -1
  963. package/dist/types/model/commands/personToken/ClaimOtpAttemptCommand.d.ts.map +1 -1
  964. package/dist/types/model/commands/personToken/CreatePersonTokenCommand.d.ts.map +1 -1
  965. package/dist/types/model/commands/personToken/IncreaseOtpAttemptCommand.d.ts.map +1 -1
  966. package/dist/types/model/commands/personToken/InvalidateEmailOtpTokensCommand.d.ts.map +1 -1
  967. package/dist/types/model/commands/personToken/InvalidateTokenCommand.d.ts.map +1 -1
  968. package/dist/types/model/commands/personToken/ResetPasswordCommand.d.ts.map +1 -1
  969. package/dist/types/model/commands/personToken/SaveEmailOtpTokenCommand.d.ts.map +1 -1
  970. package/dist/types/model/commands/personToken/SavePersonTokenCommand.d.ts.map +1 -1
  971. package/dist/types/model/commands/project/CreateProjectCommand.d.ts.map +1 -1
  972. package/dist/types/model/commands/project/SetProjectSecretCommand.d.ts.map +1 -1
  973. package/dist/types/model/commands/project/UpdateProjectCommand.d.ts.map +1 -1
  974. package/dist/types/model/commands/rateLimit/RecordRateLimitEventCommand.d.ts.map +1 -1
  975. package/dist/types/model/dtos/Password.d.ts.map +1 -1
  976. package/dist/types/model/mailing/UserMailer.d.ts.map +1 -1
  977. package/dist/types/model/mailing/templates/BackupCodesExhausted.mustache.d.ts.map +1 -1
  978. package/dist/types/model/mailing/templates/EmailChangeNotify.mustache.d.ts.map +1 -1
  979. package/dist/types/model/mailing/templates/EmailChangeVerify.mustache.d.ts.map +1 -1
  980. package/dist/types/model/mailing/templates/EmailOtp.mustache.d.ts.map +1 -1
  981. package/dist/types/model/mailing/templates/EmailVerification.mustache.d.ts.map +1 -1
  982. package/dist/types/model/mailing/templates/ExistingUserInvited.mustache.d.ts.map +1 -1
  983. package/dist/types/model/mailing/templates/ForcedSignOut.mustache.d.ts.map +1 -1
  984. package/dist/types/model/mailing/templates/Layout.mustache.d.ts.map +1 -1
  985. package/dist/types/model/mailing/templates/NewUserInvited.mustache.d.ts.map +1 -1
  986. package/dist/types/model/mailing/templates/PasswordReset.mustache.d.ts.map +1 -1
  987. package/dist/types/model/mailing/templates/PasswordlessSignIn.mustache.d.ts.map +1 -1
  988. package/dist/types/model/mailing/templates/UnusualLogin.mustache.d.ts.map +1 -1
  989. package/dist/types/model/mailing/type.d.ts.map +1 -1
  990. package/dist/types/model/queries/apiKey/ApiKeyListQuery.d.ts.map +1 -1
  991. package/dist/types/model/queries/apiKey/ApiKeyQuery.d.ts.map +1 -1
  992. package/dist/types/model/queries/apiKey/ApiKeySessionsQuery.d.ts.map +1 -1
  993. package/dist/types/model/queries/authLog/AuthLogQuery.d.ts.map +1 -1
  994. package/dist/types/model/queries/authLog/NextLoginAttemptQuery.d.ts.map +1 -1
  995. package/dist/types/model/queries/authLog/NextMailAttemptQuery.d.ts.map +1 -1
  996. package/dist/types/model/queries/authPolicy/AuthPoliciesQuery.d.ts.map +1 -1
  997. package/dist/types/model/queries/configuration/ConfigurationQuery.d.ts.map +1 -1
  998. package/dist/types/model/queries/identity/IdentityQuery.d.ts.map +1 -1
  999. package/dist/types/model/queries/idp/IdentityProviderBySlugQuery.d.ts.map +1 -1
  1000. package/dist/types/model/queries/idp/IdentityProvidersQuery.d.ts.map +1 -1
  1001. package/dist/types/model/queries/idp/IdpSessionByApiKeyQuery.d.ts.map +1 -1
  1002. package/dist/types/model/queries/idp/IdpSessionsBySidQuery.d.ts.map +1 -1
  1003. package/dist/types/model/queries/idp/IdpSessionsBySubQuery.d.ts.map +1 -1
  1004. package/dist/types/model/queries/idp/LocalAuthDisablingIdpsQuery.d.ts +18 -0
  1005. package/dist/types/model/queries/idp/LocalAuthDisablingIdpsQuery.d.ts.map +1 -0
  1006. package/dist/types/model/queries/idp/PersonIdentityProvidersQuery.d.ts +1 -0
  1007. package/dist/types/model/queries/idp/PersonIdentityProvidersQuery.d.ts.map +1 -1
  1008. package/dist/types/model/queries/idp/helpers.d.ts +1 -1
  1009. package/dist/types/model/queries/idp/helpers.d.ts.map +1 -1
  1010. package/dist/types/model/queries/idp/index.d.ts +1 -0
  1011. package/dist/types/model/queries/idp/index.d.ts.map +1 -1
  1012. package/dist/types/model/queries/idp/types.d.ts +1 -0
  1013. package/dist/types/model/queries/idp/types.d.ts.map +1 -1
  1014. package/dist/types/model/queries/mailTemplate/MailTemplateListQuery.d.ts.map +1 -1
  1015. package/dist/types/model/queries/mailTemplate/MailTemplateQuery.d.ts.map +1 -1
  1016. package/dist/types/model/queries/membership/AllProjectRolesByIdentityQuery.d.ts.map +1 -1
  1017. package/dist/types/model/queries/membership/ProjectMembersQuery.d.ts.map +1 -1
  1018. package/dist/types/model/queries/membership/ProjectMembershipByIdentityQuery.d.ts.map +1 -1
  1019. package/dist/types/model/queries/membership/ProjectRolesByIdentityQuery.d.ts.map +1 -1
  1020. package/dist/types/model/queries/membership/ProjectSlugSpecification.d.ts.map +1 -1
  1021. package/dist/types/model/queries/person/PersonByIdPQuery.d.ts.map +1 -1
  1022. package/dist/types/model/queries/person/PersonByIdentityBatchQuery.d.ts.map +1 -1
  1023. package/dist/types/model/queries/person/PersonQuery.d.ts.map +1 -1
  1024. package/dist/types/model/queries/person/PersonQueryBuilderFactory.d.ts.map +1 -1
  1025. package/dist/types/model/queries/person/PersonsQuery.d.ts.map +1 -1
  1026. package/dist/types/model/queries/person/types.d.ts +1 -0
  1027. package/dist/types/model/queries/person/types.d.ts.map +1 -1
  1028. package/dist/types/model/queries/personToken/PersonTokenQuery.d.ts.map +1 -1
  1029. package/dist/types/model/queries/project/ProjectBySlugQuery.d.ts.map +1 -1
  1030. package/dist/types/model/queries/project/ProjectSecretKeysQuery.d.ts.map +1 -1
  1031. package/dist/types/model/queries/project/ProjectSecretsQuery.d.ts.map +1 -1
  1032. package/dist/types/model/queries/project/ProjectUpdateTimestampQuery.d.ts.map +1 -1
  1033. package/dist/types/model/queries/project/ProjectsByIdentityQuery.d.ts.map +1 -1
  1034. package/dist/types/model/queries/project/ProjectsQuery.d.ts.map +1 -1
  1035. package/dist/types/model/queries/rateLimit/RateLimitCountQuery.d.ts.map +1 -1
  1036. package/dist/types/model/service/AuthLogService.d.ts.map +1 -1
  1037. package/dist/types/model/service/AuthPolicyManager.d.ts.map +1 -1
  1038. package/dist/types/model/service/AuthPolicyResolver.d.ts.map +1 -1
  1039. package/dist/types/model/service/BackupCodeManager.d.ts.map +1 -1
  1040. package/dist/types/model/service/ConfigurationManager.d.ts.map +1 -1
  1041. package/dist/types/model/service/EmailChangeManager.d.ts.map +1 -1
  1042. package/dist/types/model/service/EmailOtpManager.d.ts.map +1 -1
  1043. package/dist/types/model/service/EmailValidator.d.ts.map +1 -1
  1044. package/dist/types/model/service/EmailVerificationManager.d.ts.map +1 -1
  1045. package/dist/types/model/service/HibpChecker.d.ts.map +1 -1
  1046. package/dist/types/model/service/IDPSignInManager.d.ts +11 -1
  1047. package/dist/types/model/service/IDPSignInManager.d.ts.map +1 -1
  1048. package/dist/types/model/service/InviteManager.d.ts.map +1 -1
  1049. package/dist/types/model/service/LoginRiskAnalyzer.d.ts +1 -1
  1050. package/dist/types/model/service/LoginRiskAnalyzer.d.ts.map +1 -1
  1051. package/dist/types/model/service/MailTemplateManager.d.ts.map +1 -1
  1052. package/dist/types/model/service/MembershipValidator.d.ts.map +1 -1
  1053. package/dist/types/model/service/OtpAuthenticator.d.ts.map +1 -1
  1054. package/dist/types/model/service/OtpManager.d.ts.map +1 -1
  1055. package/dist/types/model/service/PanelAccessResolver.d.ts +19 -0
  1056. package/dist/types/model/service/PanelAccessResolver.d.ts.map +1 -0
  1057. package/dist/types/model/service/PasswordChangeManager.d.ts.map +1 -1
  1058. package/dist/types/model/service/PasswordResetManager.d.ts.map +1 -1
  1059. package/dist/types/model/service/PasswordStrengthValidator.d.ts.map +1 -1
  1060. package/dist/types/model/service/PasswordlessSignInManager.d.ts.map +1 -1
  1061. package/dist/types/model/service/PersonAccessManager.d.ts +5 -2
  1062. package/dist/types/model/service/PersonAccessManager.d.ts.map +1 -1
  1063. package/dist/types/model/service/PersonManager.d.ts.map +1 -1
  1064. package/dist/types/model/service/ProjectManager.d.ts.map +1 -1
  1065. package/dist/types/model/service/ProjectMemberManager.d.ts.map +1 -1
  1066. package/dist/types/model/service/RateLimiter.d.ts.map +1 -1
  1067. package/dist/types/model/service/RolesManager.d.ts.map +1 -1
  1068. package/dist/types/model/service/SecretsManager.d.ts.map +1 -1
  1069. package/dist/types/model/service/SignInManager.d.ts.map +1 -1
  1070. package/dist/types/model/service/SignOutManager.d.ts.map +1 -1
  1071. package/dist/types/model/service/SignUpManager.d.ts.map +1 -1
  1072. package/dist/types/model/service/apiKey/ApiKeyManager.d.ts.map +1 -1
  1073. package/dist/types/model/service/apiKey/ApiKeyService.d.ts.map +1 -1
  1074. package/dist/types/model/service/apiKey/UnpersistedApiKeyManager.d.ts +18 -0
  1075. package/dist/types/model/service/apiKey/UnpersistedApiKeyManager.d.ts.map +1 -1
  1076. package/dist/types/model/service/captcha/CaptchaValidator.d.ts.map +1 -1
  1077. package/dist/types/model/service/captcha/HCaptchaProvider.d.ts.map +1 -1
  1078. package/dist/types/model/service/captcha/RecaptchaV3Provider.d.ts.map +1 -1
  1079. package/dist/types/model/service/captcha/TurnstileProvider.d.ts.map +1 -1
  1080. package/dist/types/model/service/helpers/getPreferredProject.d.ts.map +1 -1
  1081. package/dist/types/model/service/helpers/isPasswordlessEnabled.d.ts.map +1 -1
  1082. package/dist/types/model/service/idp/BackchannelLogoutManager.d.ts.map +1 -1
  1083. package/dist/types/model/service/idp/ClaimMapping.d.ts +330 -0
  1084. package/dist/types/model/service/idp/ClaimMapping.d.ts.map +1 -0
  1085. package/dist/types/model/service/idp/ClaimMappingEvaluator.d.ts +30 -0
  1086. package/dist/types/model/service/idp/ClaimMappingEvaluator.d.ts.map +1 -0
  1087. package/dist/types/model/service/idp/ClaimMappingValidation.d.ts +55 -0
  1088. package/dist/types/model/service/idp/ClaimMappingValidation.d.ts.map +1 -0
  1089. package/dist/types/model/service/idp/IDPClaimSyncService.d.ts +113 -0
  1090. package/dist/types/model/service/idp/IDPClaimSyncService.d.ts.map +1 -0
  1091. package/dist/types/model/service/idp/IDPHandlerRegistry.d.ts.map +1 -1
  1092. package/dist/types/model/service/idp/IDPManager.d.ts +31 -1
  1093. package/dist/types/model/service/idp/IDPManager.d.ts.map +1 -1
  1094. package/dist/types/model/service/idp/IdentityProviderHandler.d.ts +7 -0
  1095. package/dist/types/model/service/idp/IdentityProviderHandler.d.ts.map +1 -1
  1096. package/dist/types/model/service/idp/IdpSessionRevalidator.d.ts +13 -1
  1097. package/dist/types/model/service/idp/IdpSessionRevalidator.d.ts.map +1 -1
  1098. package/dist/types/model/service/idp/PersonIdentityProviderManager.d.ts.map +1 -1
  1099. package/dist/types/model/service/idp/index.d.ts +4 -0
  1100. package/dist/types/model/service/idp/index.d.ts.map +1 -1
  1101. package/dist/types/model/service/idp/providers/AppleProvider.d.ts +2 -2
  1102. package/dist/types/model/service/idp/providers/AppleProvider.d.ts.map +1 -1
  1103. package/dist/types/model/service/idp/providers/FacebookProvider.d.ts +2 -2
  1104. package/dist/types/model/service/idp/providers/FacebookProvider.d.ts.map +1 -1
  1105. package/dist/types/model/service/idp/providers/OIDCHelpers.d.ts +13 -1
  1106. package/dist/types/model/service/idp/providers/OIDCHelpers.d.ts.map +1 -1
  1107. package/dist/types/model/service/idp/providers/OIDCProvider.d.ts +1 -1
  1108. package/dist/types/model/service/idp/providers/OIDCProvider.d.ts.map +1 -1
  1109. package/dist/types/model/service/idp/providers/OIDCTypes.d.ts +5 -5
  1110. package/dist/types/model/service/idp/providers/helpers.d.ts.map +1 -1
  1111. package/dist/types/model/service/index.d.ts +1 -0
  1112. package/dist/types/model/service/index.d.ts.map +1 -1
  1113. package/dist/types/model/service/membershipUtils.d.ts.map +1 -1
  1114. package/dist/types/model/type/AuthLog.d.ts +1 -1
  1115. package/dist/types/model/type/AuthLog.d.ts.map +1 -1
  1116. package/dist/types/model/type/Config.d.ts +2 -0
  1117. package/dist/types/model/type/Config.d.ts.map +1 -1
  1118. package/dist/types/model/type/IdentityProvider.d.ts +2 -0
  1119. package/dist/types/model/type/IdentityProvider.d.ts.map +1 -1
  1120. package/dist/types/model/type/RateLimit.d.ts +6 -6
  1121. package/dist/types/model/type/RateLimit.d.ts.map +1 -1
  1122. package/dist/types/model/utils/DatabaseContext.d.ts +14 -1
  1123. package/dist/types/model/utils/DatabaseContext.d.ts.map +1 -1
  1124. package/dist/types/model/utils/Response.d.ts.map +1 -1
  1125. package/dist/types/model/utils/email.d.ts.map +1 -1
  1126. package/dist/types/model/utils/hex.d.ts.map +1 -1
  1127. package/dist/types/model/utils/interval.d.ts.map +1 -1
  1128. package/dist/types/model/utils/time.d.ts.map +1 -1
  1129. package/dist/types/model/utils/token.d.ts.map +1 -1
  1130. package/dist/types/resolvers/ResolverFactory.d.ts +2 -0
  1131. package/dist/types/resolvers/ResolverFactory.d.ts.map +1 -1
  1132. package/dist/types/resolvers/TenantResolverContextFactory.d.ts.map +1 -1
  1133. package/dist/types/resolvers/errorUtils.d.ts.map +1 -1
  1134. package/dist/types/resolvers/membershipUtils.d.ts.map +1 -1
  1135. package/dist/types/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.d.ts.map +1 -1
  1136. package/dist/types/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.d.ts.map +1 -1
  1137. package/dist/types/resolvers/mutation/configuration/AuthPolicyMutationResolver.d.ts.map +1 -1
  1138. package/dist/types/resolvers/mutation/configuration/ConfigurationMutationResolver.d.ts.map +1 -1
  1139. package/dist/types/resolvers/mutation/identity/GlobalRolesMutationResolver.d.ts.map +1 -1
  1140. package/dist/types/resolvers/mutation/idp/AddIDPMutationResolver.d.ts.map +1 -1
  1141. package/dist/types/resolvers/mutation/idp/DisableIDPMutationResolver.d.ts.map +1 -1
  1142. package/dist/types/resolvers/mutation/idp/DisconnectMyIdentityProviderMutationResolver.d.ts.map +1 -1
  1143. package/dist/types/resolvers/mutation/idp/EnableIDPMutationResolver.d.ts.map +1 -1
  1144. package/dist/types/resolvers/mutation/idp/UpdateIDPMutationResolver.d.ts.map +1 -1
  1145. package/dist/types/resolvers/mutation/idp/audit.d.ts.map +1 -1
  1146. package/dist/types/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.d.ts.map +1 -1
  1147. package/dist/types/resolvers/mutation/person/ChangePasswordMutationResolver.d.ts.map +1 -1
  1148. package/dist/types/resolvers/mutation/person/ChangeProfileMutationResolver.d.ts.map +1 -1
  1149. package/dist/types/resolvers/mutation/person/DisablePersonMutationResolver.d.ts +1 -1
  1150. package/dist/types/resolvers/mutation/person/DisablePersonMutationResolver.d.ts.map +1 -1
  1151. package/dist/types/resolvers/mutation/person/EmailOtpMutationResolver.d.ts.map +1 -1
  1152. package/dist/types/resolvers/mutation/person/EmailVerificationMutationResolver.d.ts.map +1 -1
  1153. package/dist/types/resolvers/mutation/person/EnablePersonMutationResolver.d.ts +11 -0
  1154. package/dist/types/resolvers/mutation/person/EnablePersonMutationResolver.d.ts.map +1 -0
  1155. package/dist/types/resolvers/mutation/person/ForceSignOutMutationResolver.d.ts.map +1 -1
  1156. package/dist/types/resolvers/mutation/person/IDPMutationResolver.d.ts.map +1 -1
  1157. package/dist/types/resolvers/mutation/person/InviteMutationResolver.d.ts.map +1 -1
  1158. package/dist/types/resolvers/mutation/person/OtpMutationResolver.d.ts.map +1 -1
  1159. package/dist/types/resolvers/mutation/person/PasswordlessMutationResolver.d.ts.map +1 -1
  1160. package/dist/types/resolvers/mutation/person/RegenerateBackupCodesMutationResolver.d.ts.map +1 -1
  1161. package/dist/types/resolvers/mutation/person/ResetPasswordMutationResolver.d.ts.map +1 -1
  1162. package/dist/types/resolvers/mutation/person/ResetPersonMfaMutationResolver.d.ts.map +1 -1
  1163. package/dist/types/resolvers/mutation/person/RevokeSessionMutationResolver.d.ts.map +1 -1
  1164. package/dist/types/resolvers/mutation/person/SignInMutationResolver.d.ts.map +1 -1
  1165. package/dist/types/resolvers/mutation/person/SignOutMutationResolver.d.ts.map +1 -1
  1166. package/dist/types/resolvers/mutation/person/SignUpMutationResolver.d.ts.map +1 -1
  1167. package/dist/types/resolvers/mutation/person/TogglePasswordlessMutationResolver.d.ts.map +1 -1
  1168. package/dist/types/resolvers/mutation/project/CreateProjectMutationResolver.d.ts.map +1 -1
  1169. package/dist/types/resolvers/mutation/project/SetProjectSecretMutationResolver.d.ts.map +1 -1
  1170. package/dist/types/resolvers/mutation/project/UpdateProjectMutationResolver.d.ts.map +1 -1
  1171. package/dist/types/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.d.ts.map +1 -1
  1172. package/dist/types/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.d.ts.map +1 -1
  1173. package/dist/types/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.d.ts.map +1 -1
  1174. package/dist/types/resolvers/mutation/projectMember/audit.d.ts +1 -1
  1175. package/dist/types/resolvers/mutation/projectMember/audit.d.ts.map +1 -1
  1176. package/dist/types/resolvers/query/ApiKeyQueryResolver.d.ts.map +1 -1
  1177. package/dist/types/resolvers/query/AuthLogQueryResolver.d.ts.map +1 -1
  1178. package/dist/types/resolvers/query/AuthPolicyQueryResolver.d.ts.map +1 -1
  1179. package/dist/types/resolvers/query/ConfigurationQueryResolver.d.ts.map +1 -1
  1180. package/dist/types/resolvers/query/IDPQueryResolver.d.ts.map +1 -1
  1181. package/dist/types/resolvers/query/MailTemplateQueryResolver.d.ts.map +1 -1
  1182. package/dist/types/resolvers/query/MeQueryResolver.d.ts.map +1 -1
  1183. package/dist/types/resolvers/query/PersonQueryResolver.d.ts.map +1 -1
  1184. package/dist/types/resolvers/query/ProjectMembersQueryResolver.d.ts.map +1 -1
  1185. package/dist/types/resolvers/query/ProjectQueryResolver.d.ts.map +1 -1
  1186. package/dist/types/resolvers/responseHelpers/ApiKeyResponseFactory.d.ts.map +1 -1
  1187. package/dist/types/resolvers/responseHelpers/PersonResponseFactory.d.ts.map +1 -1
  1188. package/dist/types/resolvers/responseHelpers/ProjectResponseFactory.d.ts +10 -0
  1189. package/dist/types/resolvers/responseHelpers/ProjectResponseFactory.d.ts.map +1 -0
  1190. package/dist/types/resolvers/responseHelpers/SignInResponseFactory.d.ts.map +1 -1
  1191. package/dist/types/resolvers/types/IdentityTypeResolver.d.ts.map +1 -1
  1192. package/dist/types/resolvers/types/PersonTypeResolver.d.ts +15 -1
  1193. package/dist/types/resolvers/types/PersonTypeResolver.d.ts.map +1 -1
  1194. package/dist/types/resolvers/types/ProjectTypeResolver.d.ts +15 -6
  1195. package/dist/types/resolvers/types/ProjectTypeResolver.d.ts.map +1 -1
  1196. package/dist/types/schema/index.d.ts +194 -4
  1197. package/dist/types/schema/index.d.ts.map +1 -1
  1198. package/dist/types/schema/tenant.graphql.d.ts.map +1 -1
  1199. package/dist/types/schema/types.d.ts +2 -2
  1200. package/dist/types/schema/types.d.ts.map +1 -1
  1201. package/dist/types/tsconfig.tsbuildinfo +1 -1
  1202. package/dist/types/utils/Mailer.d.ts.map +1 -1
  1203. package/dist/types/utils/TemplateRenderer.d.ts.map +1 -1
  1204. package/dist/types/utils/array.d.ts.map +1 -1
  1205. package/dist/types/utils/batchQuery.d.ts.map +1 -1
  1206. package/package.json +12 -12
  1207. package/src/TenantContainer.ts +17 -3
  1208. package/src/migrations/2026-06-18-120000-idp-claim-mapping.ts +15 -0
  1209. package/src/migrations/2026-08-03-120000-person-enable-auth-log.ts +12 -0
  1210. package/src/migrations/2026-08-04-120000-config-panel.ts +13 -0
  1211. package/src/migrations/2026-09-04-120000-idp-disable-local-authentication.ts +18 -0
  1212. package/src/migrations/runner.ts +8 -0
  1213. package/src/migrations/snapshot.ts +8 -2
  1214. package/src/model/commands/configuration/UpdateConfigurationCommand.ts +5 -4
  1215. package/src/model/commands/idp/CreateIdpCommand.ts +7 -1
  1216. package/src/model/commands/idp/UpdateIdpCommand.ts +5 -1
  1217. package/src/model/commands/membership/UpdateProjectMemberCommand.ts +1 -1
  1218. package/src/model/commands/membership/index.ts +2 -1
  1219. package/src/model/commands/membership/variables/index.ts +1 -0
  1220. package/src/model/commands/person/EnablePersonCommand.ts +18 -0
  1221. package/src/model/queries/configuration/ConfigurationQuery.ts +4 -0
  1222. package/src/model/queries/idp/LocalAuthDisablingIdpsQuery.ts +41 -0
  1223. package/src/model/queries/idp/PersonIdentityProvidersQuery.ts +2 -0
  1224. package/src/model/queries/idp/helpers.ts +3 -2
  1225. package/src/model/queries/idp/index.ts +1 -0
  1226. package/src/model/queries/idp/types.ts +1 -0
  1227. package/src/model/queries/membership/ProjectMembersQuery.ts +1 -0
  1228. package/src/model/queries/person/PersonQueryBuilderFactory.ts +1 -0
  1229. package/src/model/queries/person/types.ts +1 -0
  1230. package/src/model/service/AuthLogService.ts +18 -2
  1231. package/src/model/service/IDPSignInManager.ts +49 -1
  1232. package/src/model/service/PanelAccessResolver.ts +32 -0
  1233. package/src/model/service/PasswordResetManager.ts +9 -1
  1234. package/src/model/service/PasswordlessSignInManager.ts +23 -1
  1235. package/src/model/service/PersonAccessManager.ts +19 -3
  1236. package/src/model/service/SignInManager.ts +9 -1
  1237. package/src/model/service/apiKey/ApiKeyManager.ts +5 -3
  1238. package/src/model/service/apiKey/UnpersistedApiKeyManager.ts +24 -0
  1239. package/src/model/service/idp/ClaimMapping.ts +283 -0
  1240. package/src/model/service/idp/ClaimMappingEvaluator.ts +226 -0
  1241. package/src/model/service/idp/ClaimMappingValidation.ts +158 -0
  1242. package/src/model/service/idp/IDPClaimSyncService.ts +401 -0
  1243. package/src/model/service/idp/IDPManager.ts +126 -21
  1244. package/src/model/service/idp/IdentityProviderHandler.ts +7 -0
  1245. package/src/model/service/idp/IdpSessionRevalidator.ts +90 -0
  1246. package/src/model/service/idp/PersonIdentityProviderManager.ts +8 -0
  1247. package/src/model/service/idp/index.ts +4 -0
  1248. package/src/model/service/idp/providers/OIDCHelpers.ts +161 -53
  1249. package/src/model/service/idp/providers/OIDCProvider.ts +4 -1
  1250. package/src/model/service/index.ts +1 -0
  1251. package/src/model/type/AuthLog.ts +3 -0
  1252. package/src/model/type/Config.ts +3 -0
  1253. package/src/model/type/IdentityProvider.ts +2 -0
  1254. package/src/model/utils/DatabaseContext.ts +27 -6
  1255. package/src/resolvers/ResolverFactory.ts +6 -0
  1256. package/src/resolvers/mutation/idp/AddIDPMutationResolver.ts +1 -0
  1257. package/src/resolvers/mutation/idp/UpdateIDPMutationResolver.ts +1 -0
  1258. package/src/resolvers/mutation/idp/audit.ts +1 -0
  1259. package/src/resolvers/mutation/person/DisablePersonMutationResolver.ts +3 -3
  1260. package/src/resolvers/mutation/person/EnablePersonMutationResolver.ts +50 -0
  1261. package/src/resolvers/mutation/person/IDPMutationResolver.ts +31 -0
  1262. package/src/resolvers/mutation/person/PasswordlessMutationResolver.ts +7 -0
  1263. package/src/resolvers/mutation/person/SignInMutationResolver.ts +2 -2
  1264. package/src/resolvers/query/ProjectQueryResolver.ts +3 -2
  1265. package/src/resolvers/responseHelpers/PersonResponseFactory.ts +5 -0
  1266. package/src/resolvers/responseHelpers/ProjectResponseFactory.ts +24 -0
  1267. package/src/resolvers/types/IdentityTypeResolver.ts +39 -3
  1268. package/src/resolvers/types/PersonTypeResolver.ts +35 -2
  1269. package/src/resolvers/types/ProjectTypeResolver.ts +33 -1
  1270. package/src/schema/index.ts +212 -0
  1271. package/src/schema/tenant.graphql.ts +144 -0
  1272. package/tests/cases/integration/mocked/configurationPanel.test.ts +105 -0
  1273. package/tests/cases/integration/mocked/disablePersonMutation.test.ts +89 -0
  1274. package/tests/cases/integration/mocked/enablePersonMutation.test.ts +130 -0
  1275. package/tests/cases/integration/mocked/gql/passwordless.ts +10 -0
  1276. package/tests/cases/integration/mocked/idpClaimMappingConfig.test.ts +332 -0
  1277. package/tests/cases/integration/mocked/listProjectMembersQuery.test.ts +8 -3
  1278. package/tests/cases/integration/mocked/localAuthenticationDisabled.test.ts +182 -0
  1279. package/tests/cases/integration/mocked/permissionsQuery.test.ts +153 -0
  1280. package/tests/cases/integration/mocked/personIdentityProviders.test.ts +67 -0
  1281. package/tests/cases/integration/mocked/personsQuery.test.ts +38 -5
  1282. package/tests/cases/integration/mocked/signInAnomalyDetection.test.ts +11 -0
  1283. package/tests/cases/integration/mocked/signInIdpClaimMapping.test.ts +1258 -0
  1284. package/tests/cases/integration/mocked/signInIdpClaimMappingFixes.test.ts +344 -0
  1285. package/tests/cases/integration/mocked/signInIdpClaimMappingSafety.test.ts +531 -0
  1286. package/tests/cases/integration/mocked/signInIdpMutation.test.ts +5 -0
  1287. package/tests/cases/integration/mocked/signInMfaEnforcement.test.ts +7 -0
  1288. package/tests/cases/integration/mocked/signInMutation.test.ts +14 -0
  1289. package/tests/cases/integration/mocked/signInPasswordlessMutation.test.ts +36 -0
  1290. package/tests/cases/integration/mocked/sql/getConfigSql.ts +3 -0
  1291. package/tests/cases/integration/mocked/sql/getIdpBySlugSql.ts +1 -1
  1292. package/tests/cases/integration/mocked/sql/getProjectBySlugSql.ts +1 -1
  1293. package/tests/cases/integration/mocked/sql/listPersonsSql.ts +5 -2
  1294. package/tests/cases/integration/mocked/sql/localAuthDisablingIdpsSql.ts +21 -0
  1295. package/tests/cases/integration/mocked/sql/personIdentityProvidersSql.ts +3 -1
  1296. package/tests/cases/integration/mocked/sql/removeMembershipSql.ts +14 -0
  1297. package/tests/cases/integration/mocked/trustForwardedClientInfo.test.ts +3 -0
  1298. package/tests/cases/unit/databaseContextRetry.test.ts +81 -0
  1299. package/tests/cases/unit/idp/claimMappingEvaluator.test.ts +554 -0
  1300. package/tests/cases/unit/idp/claimMappingValidation.test.ts +134 -0
  1301. package/tests/cases/unit/idp/idpManagerConfigMerge.test.ts +97 -0
  1302. package/tests/cases/unit/idp/idpManagerUnknownConfigKeys.test.ts +108 -0
  1303. package/tests/cases/unit/idp/idpSessionRevalidator.test.ts +226 -24
  1304. package/tests/cases/unit/idp/oidcClaims.test.ts +29 -0
  1305. package/tests/cases/unit/idp/oidcResponse.test.ts +54 -0
  1306. package/tests/cases/unit/idp/oidcRevalidate.test.ts +94 -2
  1307. package/tests/cases/unit/panelAccessResolver.test.ts +57 -0
  1308. package/tests/cases/unit/updateConfigurationCommand.test.ts +63 -0
  1309. package/tests/src/IdPMock.ts +4 -0
  1310. package/tests/src/testTenant.ts +32 -1
  1311. package/dist/development/src/model/commands/membership/RemoveProjectMembershipsCommand.cjs.map +0 -1
  1312. package/dist/development/src/model/commands/membership/RemoveProjectMembershipsCommand.js.map +0 -1
  1313. package/dist/production/src/model/commands/membership/RemoveProjectMembershipsCommand.cjs.map +0 -1
  1314. package/dist/production/src/model/commands/membership/RemoveProjectMembershipsCommand.js.map +0 -1
  1315. package/dist/types/model/commands/membership/RemoveProjectMembershipsCommand.d.ts.map +0 -1
  1316. /package/src/model/commands/membership/{RemoveProjectMembershipsCommand.ts → RemoveProjectMembershipCommand.ts} +0 -0
@@ -19,7 +19,9 @@ const CreatePersonIdentityProviderIdentifierCommand = require("../commands/perso
19
19
  const CreateIdentityCommand = require("../commands/identity/CreateIdentityCommand.cjs");
20
20
  const CreateAuthLogEntryCommand = require("../commands/authLog/CreateAuthLogEntryCommand.cjs");
21
21
  require("./idp/IDPRevalidation.cjs");
22
+ const ClaimMapping = require("./idp/ClaimMapping.cjs");
22
23
  const IDPValidationError = require("./idp/IDPValidationError.cjs");
24
+ require("@contember/schema-utils");
23
25
  const IDPResponseError = require("./idp/IDPResponseError.cjs");
24
26
  require("./idp/providers/AppleProvider.cjs");
25
27
  require("openid-client");
@@ -31,9 +33,10 @@ const CreateIdpSessionCommand = require("../commands/idp/CreateIdpSessionCommand
31
33
  const Password = require("../dtos/Password.cjs");
32
34
  const AuthLogService = require("./AuthLogService.cjs");
33
35
  class IDPSignInManager {
34
- constructor(apiKeyManager, idpRegistry) {
36
+ constructor(apiKeyManager, idpRegistry, claimSyncService) {
35
37
  this.apiKeyManager = apiKeyManager;
36
38
  this.idpRegistry = idpRegistry;
39
+ this.claimSyncService = claimSyncService;
37
40
  }
38
41
  async signInIDP(dbContext, idpSlug, responseData, expiration, requestInfo, trustForwardedInfo) {
39
42
  return dbContext.transaction(async (db) => {
@@ -89,6 +92,27 @@ class IDPSignInManager {
89
92
  })
90
93
  });
91
94
  }
95
+ let mapping = null;
96
+ let claimMappingFailed = false;
97
+ try {
98
+ mapping = ClaimMapping.parseClaimMapping(provider.configuration);
99
+ } catch {
100
+ claimMappingFailed = true;
101
+ }
102
+ let claimMappingAudit = null;
103
+ if (mapping) {
104
+ const syncResult = await this.claimSyncService.sync(
105
+ db,
106
+ mapping,
107
+ claim,
108
+ { id: personRow.identity_id },
109
+ resolved.isNewPerson === true
110
+ );
111
+ claimMappingAudit = syncResult.audit;
112
+ if (syncResult.droppedUnsafeRules) {
113
+ claimMappingFailed = true;
114
+ }
115
+ }
92
116
  const { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(
93
117
  db,
94
118
  personRow.identity_id,
@@ -120,6 +144,9 @@ class IDPSignInManager {
120
144
  person: personRow,
121
145
  token: sessionToken,
122
146
  idpResponse: claim,
147
+ claimMappingAudit,
148
+ claimMappingFailed,
149
+ identityProviderId: provider.id,
123
150
  [AuthLogService.AuthLogService.Key]: new AuthLogService.AuthLogService.Bag({
124
151
  personId: personRow.id,
125
152
  identityProviderId: provider.id,
@@ -169,7 +196,7 @@ class IDPSignInManager {
169
196
  if (provider.autoSignUp) {
170
197
  const signedUpPerson = await this.signUp(db, claim, provider);
171
198
  await this.saveIdpIdentifier(db, provider, claim, signedUpPerson);
172
- return { person: signedUpPerson };
199
+ return { person: signedUpPerson, isNewPerson: true };
173
200
  }
174
201
  return { person: null };
175
202
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IDPSignInManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/IDPSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { IdentityProviderBySlugQuery, PersonByIdPQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { IDPHandlerRegistry, IDPResponse, IDPResponseError, IDPValidationError } from './idp/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { InitSignInIdpErrorCode, InitSignInIdpResult, SignInIdpErrorCode } from '../../schema/index.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ApiKeyRequestInfo, CreateIdentityCommand, CreatePersonCommand, CreatePersonIdentityProviderIdentifierCommand } from '../commands/index.js'\nimport { CreateIdpSessionCommand } from '../commands/idp/CreateIdpSessionCommand.js'\nimport { CreateAuthLogEntryCommand } from '../commands/authLog/CreateAuthLogEntryCommand.js'\nimport { TenantRole } from '../authorization/index.js'\nimport { NoPassword } from '../dtos/index.js'\nimport { IdentityProviderRow } from '../queries/idp/types.js'\nimport { AuthLogService } from './AuthLogService.js'\n\nclass IDPSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly idpRegistry: IDPHandlerRegistry,\n\t) {}\n\n\tasync signInIDP(\n\t\tdbContext: DatabaseContext,\n\t\tidpSlug: string,\n\t\tresponseData: unknown,\n\t\texpiration?: number,\n\t\trequestInfo?: ApiKeyRequestInfo,\n\t\ttrustForwardedInfo?: boolean,\n\t): Promise<IDPSignInManager.SignInIDPResponse> {\n\t\treturn dbContext.transaction(async (db): Promise<IDPSignInManager.SignInIDPResponse> => {\n\t\t\tconst provider = await db.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\t\tif (!provider || provider.disabledAt) {\n\t\t\t\tthrow new Error('provider not found')\n\t\t\t}\n\t\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\t\tlet claim: IDPResponse\n\t\t\ttry {\n\t\t\t\tclaim = await providerService.processResponse(\n\t\t\t\t\tvalidatedConfig,\n\t\t\t\t\tresponseData,\n\t\t\t\t)\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof IDPResponseError) {\n\t\t\t\t\treturn new ResponseError('INVALID_IDP_RESPONSE', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow e\n\t\t\t}\n\t\t\tconst resolved = await this.resolvePerson(db, claim, provider)\n\t\t\tconst personRow = resolved.person\n\n\t\t\tif (!personRow) {\n\t\t\t\t// Keep the external error generic (no account-existence leak), but\n\t\t\t\t// record the email-verification gate block distinctly in the audit\n\t\t\t\t// log — it is a takeover-grade event, not an ordinary \"not found\".\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${claim.email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: resolved.blockedPersonId,\n\t\t\t\t\t\teventData: resolved.blockedReason ? { reason: resolved.blockedReason } : undefined,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person with e-mail ${claim.email} is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(\n\t\t\t\tdb,\n\t\t\t\tpersonRow.identity_id,\n\t\t\t\texpiration,\n\t\t\t\trequestInfo,\n\t\t\t\ttrustForwardedInfo,\n\t\t\t)\n\n\t\t\t// Bind the federated-session state to this session so it can be re-validated\n\t\t\t// against the IdP later. Present only when the provider supports it and\n\t\t\t// revalidation is enabled on the IdP configuration (A24). Refresh tokens must be\n\t\t\t// encrypted at rest, so when no encryption key is configured we skip persisting a\n\t\t\t// token-bearing session (it would otherwise crash or store secrets in plaintext) —\n\t\t\t// the session then behaves like a plain session with no re-validation.\n\t\t\tif (claim.idpSession) {\n\t\t\t\tconst hasTokens = !!claim.idpSession.tokens && Object.keys(claim.idpSession.tokens).length > 0\n\t\t\t\tif (!hasTokens || db.providers.encryptionEnabled) {\n\t\t\t\t\tawait db.commandBus.execute(new CreateIdpSessionCommand(apiKeyId, provider.id, claim.idpSession))\n\t\t\t\t} else {\n\t\t\t\t\t// Re-validation is enabled on this IdP but no encryption key is configured, so we\n\t\t\t\t\t// won't store the token-bearing session — it silently degrades to a plain,\n\t\t\t\t\t// non-revalidated session. Audit the downgrade (errorCode `encryption_disabled`)\n\t\t\t\t\t// so the operator can see that a session they expected to be continuously\n\t\t\t\t\t// re-validated is in fact not protected, instead of failing closed at sign-in.\n\t\t\t\t\tawait db.commandBus.execute(\n\t\t\t\t\t\tnew CreateAuthLogEntryCommand({\n\t\t\t\t\t\t\ttype: 'idp_session_revalidation_failed',\n\t\t\t\t\t\t\tinvokedById: personRow.identity_id,\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t\tpersonTokenId: apiKeyId,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\terrorCode: 'encryption_disabled',\n\t\t\t\t\t\t\tipAddress: requestInfo?.ip,\n\t\t\t\t\t\t\tuserAgent: requestInfo?.userAgent,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tidpResponse: claim,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync initSignInIDP(dbContext: DatabaseContext, idpSlug: string, data: unknown): Promise<IDPSignInManager.InitSignInIDPResponse> {\n\t\tconst provider = await dbContext.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\tif (!provider || provider.disabledAt) {\n\t\t\treturn new ResponseError('PROVIDER_NOT_FOUND', `Identity provider ${idpSlug} not found`)\n\t\t}\n\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\ttry {\n\t\t\tconst initResponse = await providerService.initAuth(validatedConfig, data)\n\n\t\t\tconst publicConfig = providerService.getPublicConfiguration\n\t\t\t\t? providerService.getPublicConfiguration(validatedConfig)\n\t\t\t\t: validatedConfig\n\n\t\t\treturn new ResponseOk({\n\t\t\t\t...initResponse,\n\t\t\t\tidpConfiguration: provider.initReturnsConfig ? publicConfig : null,\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message)\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tprivate async resolvePerson(db: DatabaseContext, claim: IDPResponse, provider: IdentityProviderRow): Promise<IDPSignInManager.ResolvePersonResult> {\n\t\tconst personByIdPQuery = new PersonByIdPQuery(provider.id, claim.externalIdentifier)\n\t\tconst personByIdp = await db.queryHandler.fetch(personByIdPQuery)\n\t\tif (personByIdp) {\n\t\t\treturn { person: personByIdp }\n\t\t}\n\n\t\tif (!provider.exclusive) {\n\t\t\tconst personByEmail = typeof claim.email === 'string' && claim.email\n\t\t\t\t? await db.queryHandler.fetch(PersonQuery.byEmail(claim.email))\n\t\t\t\t: null\n\t\t\tif (personByEmail) {\n\t\t\t\t// Auto-linking an IdP identity to a pre-existing local account by\n\t\t\t\t// e-mail is takeover-grade: if the provider returns an unverified\n\t\t\t\t// (or attacker-controlled) e-mail, it could hijack the account. When\n\t\t\t\t// the provider requires a verified e-mail, refuse to link — and to\n\t\t\t\t// sign in — unless the address is asserted verified. `assumeEmailVerified`\n\t\t\t\t// lets a trusted IdP that never emits the claim still satisfy the gate.\n\t\t\t\tconst emailVerified = provider.assumeEmailVerified || claim.emailVerified === true\n\t\t\t\tif (provider.requireVerifiedEmail && !emailVerified) {\n\t\t\t\t\treturn { person: null, blockedReason: 'idp_email_unverified', blockedPersonId: personByEmail.id }\n\t\t\t\t}\n\t\t\t\tawait this.saveIdpIdentifier(db, provider, claim, personByEmail)\n\t\t\t\treturn { person: personByEmail }\n\t\t\t}\n\t\t}\n\n\t\tif (provider.autoSignUp) {\n\t\t\tconst signedUpPerson = await this.signUp(db, claim, provider)\n\t\t\tawait this.saveIdpIdentifier(db, provider, claim, signedUpPerson)\n\t\t\treturn { person: signedUpPerson }\n\t\t}\n\n\t\treturn { person: null }\n\t}\n\n\tprivate async signUp(db: DatabaseContext, { email, name, externalIdentifier }: IDPResponse, provider: IdentityProviderRow): Promise<PersonRow> {\n\t\tconst roles = [TenantRole.PERSON]\n\t\tconst identityId = await db.commandBus.execute(new CreateIdentityCommand(roles))\n\t\tconst newPerson = await db.commandBus.execute(\n\t\t\tnew CreatePersonCommand({\n\t\t\t\tidentityId,\n\t\t\t\temail: provider.exclusive ? undefined : email,\n\t\t\t\tpassword: NoPassword,\n\t\t\t\tname: name ?? email?.split('@')[0] ?? externalIdentifier,\n\t\t\t\tidpOnly: provider.exclusive,\n\t\t\t}),\n\t\t)\n\n\t\treturn {\n\t\t\t...newPerson,\n\t\t\troles,\n\t\t}\n\t}\n\n\tprivate async saveIdpIdentifier(db: DatabaseContext, provider: IdentityProviderRow, claim: IDPResponse, person: PersonRow) {\n\t\tawait db.commandBus.execute(new CreatePersonIdentityProviderIdentifierCommand(provider.id, person.id, claim.externalIdentifier))\n\t}\n}\n\nnamespace IDPSignInManager {\n\texport type ResolvePersonResult = {\n\t\treadonly person: PersonRow | null\n\t\treadonly blockedReason?: 'idp_email_unverified'\n\t\treadonly blockedPersonId?: string\n\t}\n\n\texport type InitSignInIDPResponse = Response<InitSignInIdpResult, InitSignInIdpErrorCode>\n\n\tinterface SignInIDPResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\treadonly idpResponse?: Record<string, unknown>\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\n\texport type SignInIDPResponse = Response<SignInIDPResult, SignInIdpErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n}\n\nexport { IDPSignInManager }\n"],"names":["IdentityProviderBySlugQuery","IDPResponseError","ResponseError","AuthLogService","IDPValidationError","CreateIdpSessionCommand","CreateAuthLogEntryCommand","ResponseOk","PersonByIdPQuery","PersonQuery","TenantRole","CreateIdentityCommand","CreatePersonCommand","NoPassword","CreatePersonIdentityProviderIdentifierCommand"],"mappings":"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"}
1
+ {"version":3,"file":"IDPSignInManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/IDPSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { IdentityProviderBySlugQuery, PersonByIdPQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { IDPHandlerRegistry, IDPResponse, IDPResponseError, IDPValidationError } from './idp/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { InitSignInIdpErrorCode, InitSignInIdpResult, SignInIdpErrorCode } from '../../schema/index.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ApiKeyRequestInfo, CreateIdentityCommand, CreatePersonCommand, CreatePersonIdentityProviderIdentifierCommand } from '../commands/index.js'\nimport { CreateIdpSessionCommand } from '../commands/idp/CreateIdpSessionCommand.js'\nimport { CreateAuthLogEntryCommand } from '../commands/authLog/CreateAuthLogEntryCommand.js'\nimport { TenantRole } from '../authorization/index.js'\nimport { NoPassword } from '../dtos/index.js'\nimport { IdentityProviderRow } from '../queries/idp/types.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { ClaimMappingAudit, IDPClaimSyncService } from './idp/IDPClaimSyncService.js'\nimport { ClaimMapping, parseClaimMapping } from './idp/ClaimMapping.js'\n\nclass IDPSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly idpRegistry: IDPHandlerRegistry,\n\t\tprivate readonly claimSyncService: IDPClaimSyncService,\n\t) {}\n\n\tasync signInIDP(\n\t\tdbContext: DatabaseContext,\n\t\tidpSlug: string,\n\t\tresponseData: unknown,\n\t\texpiration?: number,\n\t\trequestInfo?: ApiKeyRequestInfo,\n\t\ttrustForwardedInfo?: boolean,\n\t): Promise<IDPSignInManager.SignInIDPResponse> {\n\t\treturn dbContext.transaction(async (db): Promise<IDPSignInManager.SignInIDPResponse> => {\n\t\t\tconst provider = await db.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\t\tif (!provider || provider.disabledAt) {\n\t\t\t\tthrow new Error('provider not found')\n\t\t\t}\n\t\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\t\tlet claim: IDPResponse\n\t\t\ttry {\n\t\t\t\tclaim = await providerService.processResponse(\n\t\t\t\t\tvalidatedConfig,\n\t\t\t\t\tresponseData,\n\t\t\t\t)\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof IDPResponseError) {\n\t\t\t\t\treturn new ResponseError('INVALID_IDP_RESPONSE', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow e\n\t\t\t}\n\t\t\tconst resolved = await this.resolvePerson(db, claim, provider)\n\t\t\tconst personRow = resolved.person\n\n\t\t\tif (!personRow) {\n\t\t\t\t// Keep the external error generic (no account-existence leak), but\n\t\t\t\t// record the email-verification gate block distinctly in the audit\n\t\t\t\t// log — it is a takeover-grade event, not an ordinary \"not found\".\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${claim.email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: resolved.blockedPersonId,\n\t\t\t\t\t\teventData: resolved.blockedReason ? { reason: resolved.blockedReason } : undefined,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person with e-mail ${claim.email} is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// A09 — map IdP claims to project memberships. Returns a `{ before, after }` delta only\n\t\t\t// when something actually changed; the resolver emits the `idp_role_mapped` audit from it\n\t\t\t// (audit stays at the resolver layer).\n\t\t\t//\n\t\t\t// Fail-open on a MALFORMED/out-of-band `claimMapping`: parsing is caught so a bad config can\n\t\t\t// never lock the user out — sign-in proceeds without claim mapping and the resolver emits an\n\t\t\t// `idp_role_mapping_failed` marker. A DB error during the apply itself is NOT caught: it\n\t\t\t// propagates and rolls back the whole sign-in transaction, so a half-applied set of grants is\n\t\t\t// never committed (failing sign-in on an infra error is the safe outcome).\n\t\t\tlet mapping: ClaimMapping | null = null\n\t\t\tlet claimMappingFailed = false\n\t\t\ttry {\n\t\t\t\tmapping = parseClaimMapping(provider.configuration)\n\t\t\t} catch {\n\t\t\t\tclaimMappingFailed = true\n\t\t\t}\n\t\t\tlet claimMappingAudit: ClaimMappingAudit | null = null\n\t\t\tif (mapping) {\n\t\t\t\tconst syncResult = await this.claimSyncService.sync(\n\t\t\t\t\tdb,\n\t\t\t\t\tmapping,\n\t\t\t\t\tclaim,\n\t\t\t\t\t{ id: personRow.identity_id },\n\t\t\t\t\tresolved.isNewPerson === true,\n\t\t\t\t)\n\t\t\t\tclaimMappingAudit = syncResult.audit\n\t\t\t\t// The apply-time safety backstop dropped a configured rule (config-time validation was skipped, or\n\t\t\t\t// the project's ACL drifted since): surface the same fail-open marker as a malformed config, so a\n\t\t\t\t// silently-unapplied grant is visible to the operator. The resolver emits `idp_role_mapping_failed`.\n\t\t\t\tif (syncResult.droppedUnsafeRules) {\n\t\t\t\t\tclaimMappingFailed = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(\n\t\t\t\tdb,\n\t\t\t\tpersonRow.identity_id,\n\t\t\t\texpiration,\n\t\t\t\trequestInfo,\n\t\t\t\ttrustForwardedInfo,\n\t\t\t)\n\n\t\t\t// Bind the federated-session state to this session so it can be re-validated\n\t\t\t// against the IdP later. Present only when the provider supports it and\n\t\t\t// revalidation is enabled on the IdP configuration (A24). Refresh tokens must be\n\t\t\t// encrypted at rest, so when no encryption key is configured we skip persisting a\n\t\t\t// token-bearing session (it would otherwise crash or store secrets in plaintext) —\n\t\t\t// the session then behaves like a plain session with no re-validation.\n\t\t\tif (claim.idpSession) {\n\t\t\t\tconst hasTokens = !!claim.idpSession.tokens && Object.keys(claim.idpSession.tokens).length > 0\n\t\t\t\tif (!hasTokens || db.providers.encryptionEnabled) {\n\t\t\t\t\tawait db.commandBus.execute(new CreateIdpSessionCommand(apiKeyId, provider.id, claim.idpSession))\n\t\t\t\t} else {\n\t\t\t\t\t// Re-validation is enabled on this IdP but no encryption key is configured, so we\n\t\t\t\t\t// won't store the token-bearing session — it silently degrades to a plain,\n\t\t\t\t\t// non-revalidated session. Audit the downgrade (errorCode `encryption_disabled`)\n\t\t\t\t\t// so the operator can see that a session they expected to be continuously\n\t\t\t\t\t// re-validated is in fact not protected, instead of failing closed at sign-in.\n\t\t\t\t\tawait db.commandBus.execute(\n\t\t\t\t\t\tnew CreateAuthLogEntryCommand({\n\t\t\t\t\t\t\ttype: 'idp_session_revalidation_failed',\n\t\t\t\t\t\t\tinvokedById: personRow.identity_id,\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t\tpersonTokenId: apiKeyId,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\terrorCode: 'encryption_disabled',\n\t\t\t\t\t\t\tipAddress: requestInfo?.ip,\n\t\t\t\t\t\t\tuserAgent: requestInfo?.userAgent,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tidpResponse: claim,\n\t\t\t\tclaimMappingAudit,\n\t\t\t\tclaimMappingFailed,\n\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync initSignInIDP(dbContext: DatabaseContext, idpSlug: string, data: unknown): Promise<IDPSignInManager.InitSignInIDPResponse> {\n\t\tconst provider = await dbContext.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\tif (!provider || provider.disabledAt) {\n\t\t\treturn new ResponseError('PROVIDER_NOT_FOUND', `Identity provider ${idpSlug} not found`)\n\t\t}\n\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\ttry {\n\t\t\tconst initResponse = await providerService.initAuth(validatedConfig, data)\n\n\t\t\tconst publicConfig = providerService.getPublicConfiguration\n\t\t\t\t? providerService.getPublicConfiguration(validatedConfig)\n\t\t\t\t: validatedConfig\n\n\t\t\treturn new ResponseOk({\n\t\t\t\t...initResponse,\n\t\t\t\tidpConfiguration: provider.initReturnsConfig ? publicConfig : null,\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message)\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tprivate async resolvePerson(db: DatabaseContext, claim: IDPResponse, provider: IdentityProviderRow): Promise<IDPSignInManager.ResolvePersonResult> {\n\t\tconst personByIdPQuery = new PersonByIdPQuery(provider.id, claim.externalIdentifier)\n\t\tconst personByIdp = await db.queryHandler.fetch(personByIdPQuery)\n\t\tif (personByIdp) {\n\t\t\treturn { person: personByIdp }\n\t\t}\n\n\t\tif (!provider.exclusive) {\n\t\t\tconst personByEmail = typeof claim.email === 'string' && claim.email\n\t\t\t\t? await db.queryHandler.fetch(PersonQuery.byEmail(claim.email))\n\t\t\t\t: null\n\t\t\tif (personByEmail) {\n\t\t\t\t// Auto-linking an IdP identity to a pre-existing local account by\n\t\t\t\t// e-mail is takeover-grade: if the provider returns an unverified\n\t\t\t\t// (or attacker-controlled) e-mail, it could hijack the account. When\n\t\t\t\t// the provider requires a verified e-mail, refuse to link — and to\n\t\t\t\t// sign in — unless the address is asserted verified. `assumeEmailVerified`\n\t\t\t\t// lets a trusted IdP that never emits the claim still satisfy the gate.\n\t\t\t\tconst emailVerified = provider.assumeEmailVerified || claim.emailVerified === true\n\t\t\t\tif (provider.requireVerifiedEmail && !emailVerified) {\n\t\t\t\t\treturn { person: null, blockedReason: 'idp_email_unverified', blockedPersonId: personByEmail.id }\n\t\t\t\t}\n\t\t\t\tawait this.saveIdpIdentifier(db, provider, claim, personByEmail)\n\t\t\t\treturn { person: personByEmail }\n\t\t\t}\n\t\t}\n\n\t\tif (provider.autoSignUp) {\n\t\t\tconst signedUpPerson = await this.signUp(db, claim, provider)\n\t\t\tawait this.saveIdpIdentifier(db, provider, claim, signedUpPerson)\n\t\t\treturn { person: signedUpPerson, isNewPerson: true }\n\t\t}\n\n\t\treturn { person: null }\n\t}\n\n\tprivate async signUp(db: DatabaseContext, { email, name, externalIdentifier }: IDPResponse, provider: IdentityProviderRow): Promise<PersonRow> {\n\t\tconst roles = [TenantRole.PERSON]\n\t\tconst identityId = await db.commandBus.execute(new CreateIdentityCommand(roles))\n\t\tconst newPerson = await db.commandBus.execute(\n\t\t\tnew CreatePersonCommand({\n\t\t\t\tidentityId,\n\t\t\t\temail: provider.exclusive ? undefined : email,\n\t\t\t\tpassword: NoPassword,\n\t\t\t\tname: name ?? email?.split('@')[0] ?? externalIdentifier,\n\t\t\t\tidpOnly: provider.exclusive,\n\t\t\t}),\n\t\t)\n\n\t\treturn {\n\t\t\t...newPerson,\n\t\t\troles,\n\t\t}\n\t}\n\n\tprivate async saveIdpIdentifier(db: DatabaseContext, provider: IdentityProviderRow, claim: IDPResponse, person: PersonRow) {\n\t\tawait db.commandBus.execute(new CreatePersonIdentityProviderIdentifierCommand(provider.id, person.id, claim.externalIdentifier))\n\t}\n}\n\nnamespace IDPSignInManager {\n\texport type ResolvePersonResult = {\n\t\treadonly person: PersonRow | null\n\t\treadonly blockedReason?: 'idp_email_unverified'\n\t\treadonly blockedPersonId?: string\n\t\t/** True when the person row was just created by auto-sign-up (drives the `sticky` claim-mapping policy). */\n\t\treadonly isNewPerson?: boolean\n\t}\n\n\texport type InitSignInIDPResponse = Response<InitSignInIdpResult, InitSignInIdpErrorCode>\n\n\tinterface SignInIDPResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\treadonly idpResponse?: Record<string, unknown>\n\t\t/** Identity provider the sign-in went through (for the resolver's audit). */\n\t\treadonly identityProviderId?: string\n\t\t/** Claim-mapping (A09) before/after delta — present only when a mapping changed grants. */\n\t\treadonly claimMappingAudit?: ClaimMappingAudit | null\n\t\t/** True when claim mapping failed and was skipped (fail-open) — drives the `idp_role_mapping_failed` audit. */\n\t\treadonly claimMappingFailed?: boolean\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\n\texport type SignInIDPResponse = Response<SignInIDPResult, SignInIdpErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n}\n\nexport { IDPSignInManager }\n"],"names":["IdentityProviderBySlugQuery","IDPResponseError","ResponseError","AuthLogService","IDPValidationError","parseClaimMapping","CreateIdpSessionCommand","CreateAuthLogEntryCommand","ResponseOk","PersonByIdPQuery","PersonQuery","TenantRole","CreateIdentityCommand","CreatePersonCommand","NoPassword","CreatePersonIdentityProviderIdentifierCommand"],"mappings":"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"}
@@ -17,7 +17,9 @@ import { CreatePersonIdentityProviderIdentifierCommand } from "../commands/perso
17
17
  import { CreateIdentityCommand } from "../commands/identity/CreateIdentityCommand.js";
18
18
  import { CreateAuthLogEntryCommand } from "../commands/authLog/CreateAuthLogEntryCommand.js";
19
19
  import "./idp/IDPRevalidation.js";
20
+ import { parseClaimMapping } from "./idp/ClaimMapping.js";
20
21
  import { IDPValidationError } from "./idp/IDPValidationError.js";
22
+ import "@contember/schema-utils";
21
23
  import { IDPResponseError } from "./idp/IDPResponseError.js";
22
24
  import "./idp/providers/AppleProvider.js";
23
25
  import "openid-client";
@@ -29,9 +31,10 @@ import { CreateIdpSessionCommand } from "../commands/idp/CreateIdpSessionCommand
29
31
  import { NoPassword } from "../dtos/Password.js";
30
32
  import { AuthLogService } from "./AuthLogService.js";
31
33
  class IDPSignInManager {
32
- constructor(apiKeyManager, idpRegistry) {
34
+ constructor(apiKeyManager, idpRegistry, claimSyncService) {
33
35
  this.apiKeyManager = apiKeyManager;
34
36
  this.idpRegistry = idpRegistry;
37
+ this.claimSyncService = claimSyncService;
35
38
  }
36
39
  async signInIDP(dbContext, idpSlug, responseData, expiration, requestInfo, trustForwardedInfo) {
37
40
  return dbContext.transaction(async (db) => {
@@ -87,6 +90,27 @@ class IDPSignInManager {
87
90
  })
88
91
  });
89
92
  }
93
+ let mapping = null;
94
+ let claimMappingFailed = false;
95
+ try {
96
+ mapping = parseClaimMapping(provider.configuration);
97
+ } catch {
98
+ claimMappingFailed = true;
99
+ }
100
+ let claimMappingAudit = null;
101
+ if (mapping) {
102
+ const syncResult = await this.claimSyncService.sync(
103
+ db,
104
+ mapping,
105
+ claim,
106
+ { id: personRow.identity_id },
107
+ resolved.isNewPerson === true
108
+ );
109
+ claimMappingAudit = syncResult.audit;
110
+ if (syncResult.droppedUnsafeRules) {
111
+ claimMappingFailed = true;
112
+ }
113
+ }
90
114
  const { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(
91
115
  db,
92
116
  personRow.identity_id,
@@ -118,6 +142,9 @@ class IDPSignInManager {
118
142
  person: personRow,
119
143
  token: sessionToken,
120
144
  idpResponse: claim,
145
+ claimMappingAudit,
146
+ claimMappingFailed,
147
+ identityProviderId: provider.id,
121
148
  [AuthLogService.Key]: new AuthLogService.Bag({
122
149
  personId: personRow.id,
123
150
  identityProviderId: provider.id,
@@ -167,7 +194,7 @@ class IDPSignInManager {
167
194
  if (provider.autoSignUp) {
168
195
  const signedUpPerson = await this.signUp(db, claim, provider);
169
196
  await this.saveIdpIdentifier(db, provider, claim, signedUpPerson);
170
- return { person: signedUpPerson };
197
+ return { person: signedUpPerson, isNewPerson: true };
171
198
  }
172
199
  return { person: null };
173
200
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IDPSignInManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/IDPSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { IdentityProviderBySlugQuery, PersonByIdPQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { IDPHandlerRegistry, IDPResponse, IDPResponseError, IDPValidationError } from './idp/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { InitSignInIdpErrorCode, InitSignInIdpResult, SignInIdpErrorCode } from '../../schema/index.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ApiKeyRequestInfo, CreateIdentityCommand, CreatePersonCommand, CreatePersonIdentityProviderIdentifierCommand } from '../commands/index.js'\nimport { CreateIdpSessionCommand } from '../commands/idp/CreateIdpSessionCommand.js'\nimport { CreateAuthLogEntryCommand } from '../commands/authLog/CreateAuthLogEntryCommand.js'\nimport { TenantRole } from '../authorization/index.js'\nimport { NoPassword } from '../dtos/index.js'\nimport { IdentityProviderRow } from '../queries/idp/types.js'\nimport { AuthLogService } from './AuthLogService.js'\n\nclass IDPSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly idpRegistry: IDPHandlerRegistry,\n\t) {}\n\n\tasync signInIDP(\n\t\tdbContext: DatabaseContext,\n\t\tidpSlug: string,\n\t\tresponseData: unknown,\n\t\texpiration?: number,\n\t\trequestInfo?: ApiKeyRequestInfo,\n\t\ttrustForwardedInfo?: boolean,\n\t): Promise<IDPSignInManager.SignInIDPResponse> {\n\t\treturn dbContext.transaction(async (db): Promise<IDPSignInManager.SignInIDPResponse> => {\n\t\t\tconst provider = await db.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\t\tif (!provider || provider.disabledAt) {\n\t\t\t\tthrow new Error('provider not found')\n\t\t\t}\n\t\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\t\tlet claim: IDPResponse\n\t\t\ttry {\n\t\t\t\tclaim = await providerService.processResponse(\n\t\t\t\t\tvalidatedConfig,\n\t\t\t\t\tresponseData,\n\t\t\t\t)\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof IDPResponseError) {\n\t\t\t\t\treturn new ResponseError('INVALID_IDP_RESPONSE', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow e\n\t\t\t}\n\t\t\tconst resolved = await this.resolvePerson(db, claim, provider)\n\t\t\tconst personRow = resolved.person\n\n\t\t\tif (!personRow) {\n\t\t\t\t// Keep the external error generic (no account-existence leak), but\n\t\t\t\t// record the email-verification gate block distinctly in the audit\n\t\t\t\t// log — it is a takeover-grade event, not an ordinary \"not found\".\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${claim.email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: resolved.blockedPersonId,\n\t\t\t\t\t\teventData: resolved.blockedReason ? { reason: resolved.blockedReason } : undefined,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person with e-mail ${claim.email} is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(\n\t\t\t\tdb,\n\t\t\t\tpersonRow.identity_id,\n\t\t\t\texpiration,\n\t\t\t\trequestInfo,\n\t\t\t\ttrustForwardedInfo,\n\t\t\t)\n\n\t\t\t// Bind the federated-session state to this session so it can be re-validated\n\t\t\t// against the IdP later. Present only when the provider supports it and\n\t\t\t// revalidation is enabled on the IdP configuration (A24). Refresh tokens must be\n\t\t\t// encrypted at rest, so when no encryption key is configured we skip persisting a\n\t\t\t// token-bearing session (it would otherwise crash or store secrets in plaintext) —\n\t\t\t// the session then behaves like a plain session with no re-validation.\n\t\t\tif (claim.idpSession) {\n\t\t\t\tconst hasTokens = !!claim.idpSession.tokens && Object.keys(claim.idpSession.tokens).length > 0\n\t\t\t\tif (!hasTokens || db.providers.encryptionEnabled) {\n\t\t\t\t\tawait db.commandBus.execute(new CreateIdpSessionCommand(apiKeyId, provider.id, claim.idpSession))\n\t\t\t\t} else {\n\t\t\t\t\t// Re-validation is enabled on this IdP but no encryption key is configured, so we\n\t\t\t\t\t// won't store the token-bearing session — it silently degrades to a plain,\n\t\t\t\t\t// non-revalidated session. Audit the downgrade (errorCode `encryption_disabled`)\n\t\t\t\t\t// so the operator can see that a session they expected to be continuously\n\t\t\t\t\t// re-validated is in fact not protected, instead of failing closed at sign-in.\n\t\t\t\t\tawait db.commandBus.execute(\n\t\t\t\t\t\tnew CreateAuthLogEntryCommand({\n\t\t\t\t\t\t\ttype: 'idp_session_revalidation_failed',\n\t\t\t\t\t\t\tinvokedById: personRow.identity_id,\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t\tpersonTokenId: apiKeyId,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\terrorCode: 'encryption_disabled',\n\t\t\t\t\t\t\tipAddress: requestInfo?.ip,\n\t\t\t\t\t\t\tuserAgent: requestInfo?.userAgent,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tidpResponse: claim,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync initSignInIDP(dbContext: DatabaseContext, idpSlug: string, data: unknown): Promise<IDPSignInManager.InitSignInIDPResponse> {\n\t\tconst provider = await dbContext.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\tif (!provider || provider.disabledAt) {\n\t\t\treturn new ResponseError('PROVIDER_NOT_FOUND', `Identity provider ${idpSlug} not found`)\n\t\t}\n\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\ttry {\n\t\t\tconst initResponse = await providerService.initAuth(validatedConfig, data)\n\n\t\t\tconst publicConfig = providerService.getPublicConfiguration\n\t\t\t\t? providerService.getPublicConfiguration(validatedConfig)\n\t\t\t\t: validatedConfig\n\n\t\t\treturn new ResponseOk({\n\t\t\t\t...initResponse,\n\t\t\t\tidpConfiguration: provider.initReturnsConfig ? publicConfig : null,\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message)\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tprivate async resolvePerson(db: DatabaseContext, claim: IDPResponse, provider: IdentityProviderRow): Promise<IDPSignInManager.ResolvePersonResult> {\n\t\tconst personByIdPQuery = new PersonByIdPQuery(provider.id, claim.externalIdentifier)\n\t\tconst personByIdp = await db.queryHandler.fetch(personByIdPQuery)\n\t\tif (personByIdp) {\n\t\t\treturn { person: personByIdp }\n\t\t}\n\n\t\tif (!provider.exclusive) {\n\t\t\tconst personByEmail = typeof claim.email === 'string' && claim.email\n\t\t\t\t? await db.queryHandler.fetch(PersonQuery.byEmail(claim.email))\n\t\t\t\t: null\n\t\t\tif (personByEmail) {\n\t\t\t\t// Auto-linking an IdP identity to a pre-existing local account by\n\t\t\t\t// e-mail is takeover-grade: if the provider returns an unverified\n\t\t\t\t// (or attacker-controlled) e-mail, it could hijack the account. When\n\t\t\t\t// the provider requires a verified e-mail, refuse to link — and to\n\t\t\t\t// sign in — unless the address is asserted verified. `assumeEmailVerified`\n\t\t\t\t// lets a trusted IdP that never emits the claim still satisfy the gate.\n\t\t\t\tconst emailVerified = provider.assumeEmailVerified || claim.emailVerified === true\n\t\t\t\tif (provider.requireVerifiedEmail && !emailVerified) {\n\t\t\t\t\treturn { person: null, blockedReason: 'idp_email_unverified', blockedPersonId: personByEmail.id }\n\t\t\t\t}\n\t\t\t\tawait this.saveIdpIdentifier(db, provider, claim, personByEmail)\n\t\t\t\treturn { person: personByEmail }\n\t\t\t}\n\t\t}\n\n\t\tif (provider.autoSignUp) {\n\t\t\tconst signedUpPerson = await this.signUp(db, claim, provider)\n\t\t\tawait this.saveIdpIdentifier(db, provider, claim, signedUpPerson)\n\t\t\treturn { person: signedUpPerson }\n\t\t}\n\n\t\treturn { person: null }\n\t}\n\n\tprivate async signUp(db: DatabaseContext, { email, name, externalIdentifier }: IDPResponse, provider: IdentityProviderRow): Promise<PersonRow> {\n\t\tconst roles = [TenantRole.PERSON]\n\t\tconst identityId = await db.commandBus.execute(new CreateIdentityCommand(roles))\n\t\tconst newPerson = await db.commandBus.execute(\n\t\t\tnew CreatePersonCommand({\n\t\t\t\tidentityId,\n\t\t\t\temail: provider.exclusive ? undefined : email,\n\t\t\t\tpassword: NoPassword,\n\t\t\t\tname: name ?? email?.split('@')[0] ?? externalIdentifier,\n\t\t\t\tidpOnly: provider.exclusive,\n\t\t\t}),\n\t\t)\n\n\t\treturn {\n\t\t\t...newPerson,\n\t\t\troles,\n\t\t}\n\t}\n\n\tprivate async saveIdpIdentifier(db: DatabaseContext, provider: IdentityProviderRow, claim: IDPResponse, person: PersonRow) {\n\t\tawait db.commandBus.execute(new CreatePersonIdentityProviderIdentifierCommand(provider.id, person.id, claim.externalIdentifier))\n\t}\n}\n\nnamespace IDPSignInManager {\n\texport type ResolvePersonResult = {\n\t\treadonly person: PersonRow | null\n\t\treadonly blockedReason?: 'idp_email_unverified'\n\t\treadonly blockedPersonId?: string\n\t}\n\n\texport type InitSignInIDPResponse = Response<InitSignInIdpResult, InitSignInIdpErrorCode>\n\n\tinterface SignInIDPResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\treadonly idpResponse?: Record<string, unknown>\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\n\texport type SignInIDPResponse = Response<SignInIDPResult, SignInIdpErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n}\n\nexport { IDPSignInManager }\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAM,iBAAiB;AAAA,EACtB,YACkB,eACA,aAChB;AAFgB,SAAA,gBAAA;AACA,SAAA,cAAA;AAAA,EACf;AAAA,EAEH,MAAM,UACL,WACA,SACA,cACA,YACA,aACA,oBAC8C;AAC9C,WAAO,UAAU,YAAY,OAAO,OAAoD;AACvF,YAAM,WAAW,MAAM,GAAG,aAAa,MAAM,IAAI,4BAA4B,OAAO,CAAC;AACrF,UAAI,CAAC,YAAY,SAAS,YAAY;AACrC,cAAM,IAAI,MAAM,oBAAoB;AAAA,MACrC;AACA,YAAM,kBAAkB,KAAK,YAAY,WAAW,SAAS,IAAI;AACjE,YAAM,kBAAkB,gBAAgB,sBAAsB,SAAS,aAAa;AACpF,UAAI;AACJ,UAAI;AACH,gBAAQ,MAAM,gBAAgB;AAAA,UAC7B;AAAA,UACA;AAAA,QAAA;AAAA,MAEF,SAAS,GAAG;AACX,YAAI,aAAa,kBAAkB;AAClC,iBAAO,IAAI,cAAc,wBAAwB,EAAE,SAAS;AAAA,YAC3D,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI;AAAA,cAC5C,UAAU;AAAA,cACV,oBAAoB,SAAS;AAAA,YAAA,CAC7B;AAAA,UAAA,CACD;AAAA,QACF;AACA,YAAI,aAAa,oBAAoB;AACpC,iBAAO,IAAI,cAAc,yBAAyB,EAAE,SAAS;AAAA,YAC5D,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI;AAAA,cAC5C,UAAU;AAAA,cACV,oBAAoB,SAAS;AAAA,YAAA,CAC7B;AAAA,UAAA,CACD;AAAA,QACF;AACA,cAAM;AAAA,MACP;AACA,YAAM,WAAW,MAAM,KAAK,cAAc,IAAI,OAAO,QAAQ;AAC7D,YAAM,YAAY,SAAS;AAE3B,UAAI,CAAC,WAAW;AAIf,eAAO,IAAI,cAAc,oBAAoB,UAAU,MAAM,KAAK,cAAc;AAAA,UAC/E,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI;AAAA,YAC5C,oBAAoB,SAAS;AAAA,YAC7B,aAAa,MAAM;AAAA,YACnB,UAAU,SAAS;AAAA,YACnB,WAAW,SAAS,gBAAgB,EAAE,QAAQ,SAAS,kBAAkB;AAAA,UAAA,CACzE;AAAA,QAAA,CACD;AAAA,MACF;AAEA,UAAI,UAAU,gBAAgB,MAAM;AACnC,eAAO,IAAI,cAAc,mBAAmB,sBAAsB,MAAM,KAAK,gBAAgB;AAAA,UAC5F,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI;AAAA,YAC5C,oBAAoB,SAAS;AAAA,YAC7B,aAAa,MAAM;AAAA,YACnB,UAAU,UAAU;AAAA,UAAA,CACpB;AAAA,QAAA,CACD;AAAA,MACF;AAEA,YAAM,EAAE,IAAI,UAAU,OAAO,iBAAiB,MAAM,KAAK,cAAc;AAAA,QACtE;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AASD,UAAI,MAAM,YAAY;AACrB,cAAM,YAAY,CAAC,CAAC,MAAM,WAAW,UAAU,OAAO,KAAK,MAAM,WAAW,MAAM,EAAE,SAAS;AAC7F,YAAI,CAAC,aAAa,GAAG,UAAU,mBAAmB;AACjD,gBAAM,GAAG,WAAW,QAAQ,IAAI,wBAAwB,UAAU,SAAS,IAAI,MAAM,UAAU,CAAC;AAAA,QACjG,OAAO;AAMN,gBAAM,GAAG,WAAW;AAAA,YACnB,IAAI,0BAA0B;AAAA,cAC7B,MAAM;AAAA,cACN,aAAa,UAAU;AAAA,cACvB,UAAU,UAAU;AAAA,cACpB,oBAAoB,SAAS;AAAA,cAC7B,eAAe;AAAA,cACf,SAAS;AAAA,cACT,WAAW;AAAA,cACX,WAAW,aAAa;AAAA,cACxB,WAAW,aAAa;AAAA,YAAA,CACxB;AAAA,UAAA;AAAA,QAEH;AAAA,MACD;AAEA,aAAO,IAAI,WAAW;AAAA,QACrB,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,aAAa;AAAA,QACb,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI;AAAA,UAC5C,UAAU,UAAU;AAAA,UACpB,oBAAoB,SAAS;AAAA,UAC7B,aAAa,MAAM;AAAA,QAAA,CACnB;AAAA,MAAA,CACD;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,WAA4B,SAAiB,MAAgE;AAChI,UAAM,WAAW,MAAM,UAAU,aAAa,MAAM,IAAI,4BAA4B,OAAO,CAAC;AAC5F,QAAI,CAAC,YAAY,SAAS,YAAY;AACrC,aAAO,IAAI,cAAc,sBAAsB,qBAAqB,OAAO,YAAY;AAAA,IACxF;AACA,UAAM,kBAAkB,KAAK,YAAY,WAAW,SAAS,IAAI;AACjE,UAAM,kBAAkB,gBAAgB,sBAAsB,SAAS,aAAa;AACpF,QAAI;AACH,YAAM,eAAe,MAAM,gBAAgB,SAAS,iBAAiB,IAAI;AAEzE,YAAM,eAAe,gBAAgB,yBAClC,gBAAgB,uBAAuB,eAAe,IACtD;AAEH,aAAO,IAAI,WAAW;AAAA,QACrB,GAAG;AAAA,QACH,kBAAkB,SAAS,oBAAoB,eAAe;AAAA,MAAA,CAC9D;AAAA,IACF,SAAS,GAAG;AACX,UAAI,aAAa,oBAAoB;AACpC,eAAO,IAAI,cAAc,yBAAyB,EAAE,OAAO;AAAA,MAC5D;AACA,YAAM;AAAA,IACP;AAAA,EACD;AAAA,EAEA,MAAc,cAAc,IAAqB,OAAoB,UAA8E;AAClJ,UAAM,mBAAmB,IAAI,iBAAiB,SAAS,IAAI,MAAM,kBAAkB;AACnF,UAAM,cAAc,MAAM,GAAG,aAAa,MAAM,gBAAgB;AAChE,QAAI,aAAa;AAChB,aAAO,EAAE,QAAQ,YAAA;AAAA,IAClB;AAEA,QAAI,CAAC,SAAS,WAAW;AACxB,YAAM,gBAAgB,OAAO,MAAM,UAAU,YAAY,MAAM,QAC5D,MAAM,GAAG,aAAa,MAAM,YAAY,QAAQ,MAAM,KAAK,CAAC,IAC5D;AACH,UAAI,eAAe;AAOlB,cAAM,gBAAgB,SAAS,uBAAuB,MAAM,kBAAkB;AAC9E,YAAI,SAAS,wBAAwB,CAAC,eAAe;AACpD,iBAAO,EAAE,QAAQ,MAAM,eAAe,wBAAwB,iBAAiB,cAAc,GAAA;AAAA,QAC9F;AACA,cAAM,KAAK,kBAAkB,IAAI,UAAU,OAAO,aAAa;AAC/D,eAAO,EAAE,QAAQ,cAAA;AAAA,MAClB;AAAA,IACD;AAEA,QAAI,SAAS,YAAY;AACxB,YAAM,iBAAiB,MAAM,KAAK,OAAO,IAAI,OAAO,QAAQ;AAC5D,YAAM,KAAK,kBAAkB,IAAI,UAAU,OAAO,cAAc;AAChE,aAAO,EAAE,QAAQ,eAAA;AAAA,IAClB;AAEA,WAAO,EAAE,QAAQ,KAAA;AAAA,EAClB;AAAA,EAEA,MAAc,OAAO,IAAqB,EAAE,OAAO,MAAM,mBAAA,GAAmC,UAAmD;AAC9I,UAAM,QAAQ,CAAC,WAAW,MAAM;AAChC,UAAM,aAAa,MAAM,GAAG,WAAW,QAAQ,IAAI,sBAAsB,KAAK,CAAC;AAC/E,UAAM,YAAY,MAAM,GAAG,WAAW;AAAA,MACrC,IAAI,oBAAoB;AAAA,QACvB;AAAA,QACA,OAAO,SAAS,YAAY,SAAY;AAAA,QACxC,UAAU;AAAA,QACV,MAAM,QAAQ,OAAO,MAAM,GAAG,EAAE,CAAC,KAAK;AAAA,QACtC,SAAS,SAAS;AAAA,MAAA,CAClB;AAAA,IAAA;AAGF,WAAO;AAAA,MACN,GAAG;AAAA,MACH;AAAA,IAAA;AAAA,EAEF;AAAA,EAEA,MAAc,kBAAkB,IAAqB,UAA+B,OAAoB,QAAmB;AAC1H,UAAM,GAAG,WAAW,QAAQ,IAAI,8CAA8C,SAAS,IAAI,OAAO,IAAI,MAAM,kBAAkB,CAAC;AAAA,EAChI;AACD;"}
1
+ {"version":3,"file":"IDPSignInManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/IDPSignInManager.ts"],"sourcesContent":["import { ApiKeyManager } from './apiKey/index.js'\nimport { IdentityProviderBySlugQuery, PersonByIdPQuery, PersonQuery, PersonRow } from '../queries/index.js'\nimport { IDPHandlerRegistry, IDPResponse, IDPResponseError, IDPValidationError } from './idp/index.js'\nimport { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { InitSignInIdpErrorCode, InitSignInIdpResult, SignInIdpErrorCode } from '../../schema/index.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ApiKeyRequestInfo, CreateIdentityCommand, CreatePersonCommand, CreatePersonIdentityProviderIdentifierCommand } from '../commands/index.js'\nimport { CreateIdpSessionCommand } from '../commands/idp/CreateIdpSessionCommand.js'\nimport { CreateAuthLogEntryCommand } from '../commands/authLog/CreateAuthLogEntryCommand.js'\nimport { TenantRole } from '../authorization/index.js'\nimport { NoPassword } from '../dtos/index.js'\nimport { IdentityProviderRow } from '../queries/idp/types.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { ClaimMappingAudit, IDPClaimSyncService } from './idp/IDPClaimSyncService.js'\nimport { ClaimMapping, parseClaimMapping } from './idp/ClaimMapping.js'\n\nclass IDPSignInManager {\n\tconstructor(\n\t\tprivate readonly apiKeyManager: ApiKeyManager,\n\t\tprivate readonly idpRegistry: IDPHandlerRegistry,\n\t\tprivate readonly claimSyncService: IDPClaimSyncService,\n\t) {}\n\n\tasync signInIDP(\n\t\tdbContext: DatabaseContext,\n\t\tidpSlug: string,\n\t\tresponseData: unknown,\n\t\texpiration?: number,\n\t\trequestInfo?: ApiKeyRequestInfo,\n\t\ttrustForwardedInfo?: boolean,\n\t): Promise<IDPSignInManager.SignInIDPResponse> {\n\t\treturn dbContext.transaction(async (db): Promise<IDPSignInManager.SignInIDPResponse> => {\n\t\t\tconst provider = await db.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\t\tif (!provider || provider.disabledAt) {\n\t\t\t\tthrow new Error('provider not found')\n\t\t\t}\n\t\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\t\tlet claim: IDPResponse\n\t\t\ttry {\n\t\t\t\tclaim = await providerService.processResponse(\n\t\t\t\t\tvalidatedConfig,\n\t\t\t\t\tresponseData,\n\t\t\t\t)\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof IDPResponseError) {\n\t\t\t\t\treturn new ResponseError('INVALID_IDP_RESPONSE', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message, {\n\t\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\t\tpersonId: undefined,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow e\n\t\t\t}\n\t\t\tconst resolved = await this.resolvePerson(db, claim, provider)\n\t\t\tconst personRow = resolved.person\n\n\t\t\tif (!personRow) {\n\t\t\t\t// Keep the external error generic (no account-existence leak), but\n\t\t\t\t// record the email-verification gate block distinctly in the audit\n\t\t\t\t// log — it is a takeover-grade event, not an ordinary \"not found\".\n\t\t\t\treturn new ResponseError('PERSON_NOT_FOUND', `Person ${claim.email} not found`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: resolved.blockedPersonId,\n\t\t\t\t\t\teventData: resolved.blockedReason ? { reason: resolved.blockedReason } : undefined,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (personRow.disabled_at !== null) {\n\t\t\t\treturn new ResponseError('PERSON_DISABLED', `Person with e-mail ${claim.email} is disabled`, {\n\t\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// A09 — map IdP claims to project memberships. Returns a `{ before, after }` delta only\n\t\t\t// when something actually changed; the resolver emits the `idp_role_mapped` audit from it\n\t\t\t// (audit stays at the resolver layer).\n\t\t\t//\n\t\t\t// Fail-open on a MALFORMED/out-of-band `claimMapping`: parsing is caught so a bad config can\n\t\t\t// never lock the user out — sign-in proceeds without claim mapping and the resolver emits an\n\t\t\t// `idp_role_mapping_failed` marker. A DB error during the apply itself is NOT caught: it\n\t\t\t// propagates and rolls back the whole sign-in transaction, so a half-applied set of grants is\n\t\t\t// never committed (failing sign-in on an infra error is the safe outcome).\n\t\t\tlet mapping: ClaimMapping | null = null\n\t\t\tlet claimMappingFailed = false\n\t\t\ttry {\n\t\t\t\tmapping = parseClaimMapping(provider.configuration)\n\t\t\t} catch {\n\t\t\t\tclaimMappingFailed = true\n\t\t\t}\n\t\t\tlet claimMappingAudit: ClaimMappingAudit | null = null\n\t\t\tif (mapping) {\n\t\t\t\tconst syncResult = await this.claimSyncService.sync(\n\t\t\t\t\tdb,\n\t\t\t\t\tmapping,\n\t\t\t\t\tclaim,\n\t\t\t\t\t{ id: personRow.identity_id },\n\t\t\t\t\tresolved.isNewPerson === true,\n\t\t\t\t)\n\t\t\t\tclaimMappingAudit = syncResult.audit\n\t\t\t\t// The apply-time safety backstop dropped a configured rule (config-time validation was skipped, or\n\t\t\t\t// the project's ACL drifted since): surface the same fail-open marker as a malformed config, so a\n\t\t\t\t// silently-unapplied grant is visible to the operator. The resolver emits `idp_role_mapping_failed`.\n\t\t\t\tif (syncResult.droppedUnsafeRules) {\n\t\t\t\t\tclaimMappingFailed = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { id: apiKeyId, token: sessionToken } = await this.apiKeyManager.createSessionApiKeyWithId(\n\t\t\t\tdb,\n\t\t\t\tpersonRow.identity_id,\n\t\t\t\texpiration,\n\t\t\t\trequestInfo,\n\t\t\t\ttrustForwardedInfo,\n\t\t\t)\n\n\t\t\t// Bind the federated-session state to this session so it can be re-validated\n\t\t\t// against the IdP later. Present only when the provider supports it and\n\t\t\t// revalidation is enabled on the IdP configuration (A24). Refresh tokens must be\n\t\t\t// encrypted at rest, so when no encryption key is configured we skip persisting a\n\t\t\t// token-bearing session (it would otherwise crash or store secrets in plaintext) —\n\t\t\t// the session then behaves like a plain session with no re-validation.\n\t\t\tif (claim.idpSession) {\n\t\t\t\tconst hasTokens = !!claim.idpSession.tokens && Object.keys(claim.idpSession.tokens).length > 0\n\t\t\t\tif (!hasTokens || db.providers.encryptionEnabled) {\n\t\t\t\t\tawait db.commandBus.execute(new CreateIdpSessionCommand(apiKeyId, provider.id, claim.idpSession))\n\t\t\t\t} else {\n\t\t\t\t\t// Re-validation is enabled on this IdP but no encryption key is configured, so we\n\t\t\t\t\t// won't store the token-bearing session — it silently degrades to a plain,\n\t\t\t\t\t// non-revalidated session. Audit the downgrade (errorCode `encryption_disabled`)\n\t\t\t\t\t// so the operator can see that a session they expected to be continuously\n\t\t\t\t\t// re-validated is in fact not protected, instead of failing closed at sign-in.\n\t\t\t\t\tawait db.commandBus.execute(\n\t\t\t\t\t\tnew CreateAuthLogEntryCommand({\n\t\t\t\t\t\t\ttype: 'idp_session_revalidation_failed',\n\t\t\t\t\t\t\tinvokedById: personRow.identity_id,\n\t\t\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\t\t\tpersonTokenId: apiKeyId,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\terrorCode: 'encryption_disabled',\n\t\t\t\t\t\t\tipAddress: requestInfo?.ip,\n\t\t\t\t\t\t\tuserAgent: requestInfo?.userAgent,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new ResponseOk({\n\t\t\t\tperson: personRow,\n\t\t\t\ttoken: sessionToken,\n\t\t\t\tidpResponse: claim,\n\t\t\t\tclaimMappingAudit,\n\t\t\t\tclaimMappingFailed,\n\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({\n\t\t\t\t\tpersonId: personRow.id,\n\t\t\t\t\tidentityProviderId: provider.id,\n\t\t\t\t\tpersonInput: claim.email,\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\t}\n\n\tasync initSignInIDP(dbContext: DatabaseContext, idpSlug: string, data: unknown): Promise<IDPSignInManager.InitSignInIDPResponse> {\n\t\tconst provider = await dbContext.queryHandler.fetch(new IdentityProviderBySlugQuery(idpSlug))\n\t\tif (!provider || provider.disabledAt) {\n\t\t\treturn new ResponseError('PROVIDER_NOT_FOUND', `Identity provider ${idpSlug} not found`)\n\t\t}\n\t\tconst providerService = this.idpRegistry.getHandler(provider.type)\n\t\tconst validatedConfig = providerService.validateConfiguration(provider.configuration)\n\t\ttry {\n\t\t\tconst initResponse = await providerService.initAuth(validatedConfig, data)\n\n\t\t\tconst publicConfig = providerService.getPublicConfiguration\n\t\t\t\t? providerService.getPublicConfiguration(validatedConfig)\n\t\t\t\t: validatedConfig\n\n\t\t\treturn new ResponseOk({\n\t\t\t\t...initResponse,\n\t\t\t\tidpConfiguration: provider.initReturnsConfig ? publicConfig : null,\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tif (e instanceof IDPValidationError) {\n\t\t\t\treturn new ResponseError('IDP_VALIDATION_FAILED', e.message)\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tprivate async resolvePerson(db: DatabaseContext, claim: IDPResponse, provider: IdentityProviderRow): Promise<IDPSignInManager.ResolvePersonResult> {\n\t\tconst personByIdPQuery = new PersonByIdPQuery(provider.id, claim.externalIdentifier)\n\t\tconst personByIdp = await db.queryHandler.fetch(personByIdPQuery)\n\t\tif (personByIdp) {\n\t\t\treturn { person: personByIdp }\n\t\t}\n\n\t\tif (!provider.exclusive) {\n\t\t\tconst personByEmail = typeof claim.email === 'string' && claim.email\n\t\t\t\t? await db.queryHandler.fetch(PersonQuery.byEmail(claim.email))\n\t\t\t\t: null\n\t\t\tif (personByEmail) {\n\t\t\t\t// Auto-linking an IdP identity to a pre-existing local account by\n\t\t\t\t// e-mail is takeover-grade: if the provider returns an unverified\n\t\t\t\t// (or attacker-controlled) e-mail, it could hijack the account. When\n\t\t\t\t// the provider requires a verified e-mail, refuse to link — and to\n\t\t\t\t// sign in — unless the address is asserted verified. `assumeEmailVerified`\n\t\t\t\t// lets a trusted IdP that never emits the claim still satisfy the gate.\n\t\t\t\tconst emailVerified = provider.assumeEmailVerified || claim.emailVerified === true\n\t\t\t\tif (provider.requireVerifiedEmail && !emailVerified) {\n\t\t\t\t\treturn { person: null, blockedReason: 'idp_email_unverified', blockedPersonId: personByEmail.id }\n\t\t\t\t}\n\t\t\t\tawait this.saveIdpIdentifier(db, provider, claim, personByEmail)\n\t\t\t\treturn { person: personByEmail }\n\t\t\t}\n\t\t}\n\n\t\tif (provider.autoSignUp) {\n\t\t\tconst signedUpPerson = await this.signUp(db, claim, provider)\n\t\t\tawait this.saveIdpIdentifier(db, provider, claim, signedUpPerson)\n\t\t\treturn { person: signedUpPerson, isNewPerson: true }\n\t\t}\n\n\t\treturn { person: null }\n\t}\n\n\tprivate async signUp(db: DatabaseContext, { email, name, externalIdentifier }: IDPResponse, provider: IdentityProviderRow): Promise<PersonRow> {\n\t\tconst roles = [TenantRole.PERSON]\n\t\tconst identityId = await db.commandBus.execute(new CreateIdentityCommand(roles))\n\t\tconst newPerson = await db.commandBus.execute(\n\t\t\tnew CreatePersonCommand({\n\t\t\t\tidentityId,\n\t\t\t\temail: provider.exclusive ? undefined : email,\n\t\t\t\tpassword: NoPassword,\n\t\t\t\tname: name ?? email?.split('@')[0] ?? externalIdentifier,\n\t\t\t\tidpOnly: provider.exclusive,\n\t\t\t}),\n\t\t)\n\n\t\treturn {\n\t\t\t...newPerson,\n\t\t\troles,\n\t\t}\n\t}\n\n\tprivate async saveIdpIdentifier(db: DatabaseContext, provider: IdentityProviderRow, claim: IDPResponse, person: PersonRow) {\n\t\tawait db.commandBus.execute(new CreatePersonIdentityProviderIdentifierCommand(provider.id, person.id, claim.externalIdentifier))\n\t}\n}\n\nnamespace IDPSignInManager {\n\texport type ResolvePersonResult = {\n\t\treadonly person: PersonRow | null\n\t\treadonly blockedReason?: 'idp_email_unverified'\n\t\treadonly blockedPersonId?: string\n\t\t/** True when the person row was just created by auto-sign-up (drives the `sticky` claim-mapping policy). */\n\t\treadonly isNewPerson?: boolean\n\t}\n\n\texport type InitSignInIDPResponse = Response<InitSignInIdpResult, InitSignInIdpErrorCode>\n\n\tinterface SignInIDPResult {\n\t\treadonly person: PersonRow\n\t\treadonly token: string\n\t\treadonly idpResponse?: Record<string, unknown>\n\t\t/** Identity provider the sign-in went through (for the resolver's audit). */\n\t\treadonly identityProviderId?: string\n\t\t/** Claim-mapping (A09) before/after delta — present only when a mapping changed grants. */\n\t\treadonly claimMappingAudit?: ClaimMappingAudit | null\n\t\t/** True when claim mapping failed and was skipped (fail-open) — drives the `idp_role_mapping_failed` audit. */\n\t\treadonly claimMappingFailed?: boolean\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n\n\texport type SignInIDPResponse = Response<SignInIDPResult, SignInIdpErrorCode, {\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}>\n}\n\nexport { IDPSignInManager }\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("../queries/apiKey/ApiKeyQuery.cjs");
4
+ require("@contember/database");
5
+ require("../type/ApiKey.cjs");
6
+ const ConfigurationQuery = require("../queries/configuration/ConfigurationQuery.cjs");
7
+ const AllProjectRolesByIdentityQuery = require("../queries/membership/AllProjectRolesByIdentityQuery.cjs");
8
+ require("../authorization/PermissionActions.cjs");
9
+ require("@contember/authorization");
10
+ require("../authorization/PermissionContext.cjs");
11
+ require("../authorization/PermissionsFactory.cjs");
12
+ require("@contember/schema");
13
+ class PanelAccessResolver {
14
+ constructor(providers) {
15
+ this.providers = providers;
16
+ }
17
+ async isAllowed(db, identityId, globalRoles) {
18
+ const config = await db.queryHandler.fetch(new ConfigurationQuery.ConfigurationQuery(this.providers));
19
+ const policy = config.panel;
20
+ if (policy.globalRoles.some((role) => globalRoles.includes(role))) {
21
+ return true;
22
+ }
23
+ if (policy.projectRoles.length === 0) {
24
+ return false;
25
+ }
26
+ const projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery.AllProjectRolesByIdentityQuery(identityId));
27
+ return projectRoles.some((it) => policy.projectRoles.includes(it.role));
28
+ }
29
+ }
30
+ exports.PanelAccessResolver = PanelAccessResolver;
31
+ //# sourceMappingURL=PanelAccessResolver.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelAccessResolver.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PanelAccessResolver.ts"],"sourcesContent":["import { DatabaseContext } from '../utils/index.js'\nimport { AllProjectRolesByIdentityQuery, ConfigurationQuery } from '../queries/index.js'\nimport { Providers } from '../providers.js'\n\n/**\n * Decides whether an identity may enter the management panel served by the engine.\n *\n * This is an **entry gate for the console, not an authorization system**: everything the panel shows\n * still goes through the tenant ACL, and whoever gets in could equally call `/tenant` directly. Its\n * job is to keep the console door shut for accounts that have no business there, so an admin surface\n * on a public API port does not look like a leak.\n *\n * An identity is allowed when it holds one of `globalRoles`, or a membership with one of\n * `projectRoles` in **any** project. Empty lists mean nobody.\n */\nexport class PanelAccessResolver {\n\tconstructor(private readonly providers: Providers) {}\n\n\tasync isAllowed(db: DatabaseContext, identityId: string, globalRoles: readonly string[]): Promise<boolean> {\n\t\tconst config = await db.queryHandler.fetch(new ConfigurationQuery(this.providers))\n\t\tconst policy = config.panel\n\n\t\tif (policy.globalRoles.some(role => globalRoles.includes(role))) {\n\t\t\treturn true\n\t\t}\n\t\tif (policy.projectRoles.length === 0) {\n\t\t\treturn false\n\t\t}\n\t\tconst projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery(identityId))\n\t\treturn projectRoles.some(it => policy.projectRoles.includes(it.role))\n\t}\n}\n"],"names":["ConfigurationQuery","AllProjectRolesByIdentityQuery"],"mappings":";;;;;;;;;;;;AAeO,MAAM,oBAAoB;AAAA,EAChC,YAA6B,WAAsB;AAAtB,SAAA,YAAA;AAAA,EAAuB;AAAA,EAEpD,MAAM,UAAU,IAAqB,YAAoB,aAAkD;AAC1G,UAAM,SAAS,MAAM,GAAG,aAAa,MAAM,IAAIA,mBAAAA,mBAAmB,KAAK,SAAS,CAAC;AACjF,UAAM,SAAS,OAAO;AAEtB,QAAI,OAAO,YAAY,KAAK,CAAA,SAAQ,YAAY,SAAS,IAAI,CAAC,GAAG;AAChE,aAAO;AAAA,IACR;AACA,QAAI,OAAO,aAAa,WAAW,GAAG;AACrC,aAAO;AAAA,IACR;AACA,UAAM,eAAe,MAAM,GAAG,aAAa,MAAM,IAAIC,+BAAAA,+BAA+B,UAAU,CAAC;AAC/F,WAAO,aAAa,KAAK,CAAA,OAAM,OAAO,aAAa,SAAS,GAAG,IAAI,CAAC;AAAA,EACrE;AACD;;"}
@@ -0,0 +1,31 @@
1
+ import "../queries/apiKey/ApiKeyQuery.js";
2
+ import "@contember/database";
3
+ import "../type/ApiKey.js";
4
+ import { ConfigurationQuery } from "../queries/configuration/ConfigurationQuery.js";
5
+ import { AllProjectRolesByIdentityQuery } from "../queries/membership/AllProjectRolesByIdentityQuery.js";
6
+ import "../authorization/PermissionActions.js";
7
+ import "@contember/authorization";
8
+ import "../authorization/PermissionContext.js";
9
+ import "../authorization/PermissionsFactory.js";
10
+ import "@contember/schema";
11
+ class PanelAccessResolver {
12
+ constructor(providers) {
13
+ this.providers = providers;
14
+ }
15
+ async isAllowed(db, identityId, globalRoles) {
16
+ const config = await db.queryHandler.fetch(new ConfigurationQuery(this.providers));
17
+ const policy = config.panel;
18
+ if (policy.globalRoles.some((role) => globalRoles.includes(role))) {
19
+ return true;
20
+ }
21
+ if (policy.projectRoles.length === 0) {
22
+ return false;
23
+ }
24
+ const projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery(identityId));
25
+ return projectRoles.some((it) => policy.projectRoles.includes(it.role));
26
+ }
27
+ }
28
+ export {
29
+ PanelAccessResolver
30
+ };
31
+ //# sourceMappingURL=PanelAccessResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelAccessResolver.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PanelAccessResolver.ts"],"sourcesContent":["import { DatabaseContext } from '../utils/index.js'\nimport { AllProjectRolesByIdentityQuery, ConfigurationQuery } from '../queries/index.js'\nimport { Providers } from '../providers.js'\n\n/**\n * Decides whether an identity may enter the management panel served by the engine.\n *\n * This is an **entry gate for the console, not an authorization system**: everything the panel shows\n * still goes through the tenant ACL, and whoever gets in could equally call `/tenant` directly. Its\n * job is to keep the console door shut for accounts that have no business there, so an admin surface\n * on a public API port does not look like a leak.\n *\n * An identity is allowed when it holds one of `globalRoles`, or a membership with one of\n * `projectRoles` in **any** project. Empty lists mean nobody.\n */\nexport class PanelAccessResolver {\n\tconstructor(private readonly providers: Providers) {}\n\n\tasync isAllowed(db: DatabaseContext, identityId: string, globalRoles: readonly string[]): Promise<boolean> {\n\t\tconst config = await db.queryHandler.fetch(new ConfigurationQuery(this.providers))\n\t\tconst policy = config.panel\n\n\t\tif (policy.globalRoles.some(role => globalRoles.includes(role))) {\n\t\t\treturn true\n\t\t}\n\t\tif (policy.projectRoles.length === 0) {\n\t\t\treturn false\n\t\t}\n\t\tconst projectRoles = await db.queryHandler.fetch(new AllProjectRolesByIdentityQuery(identityId))\n\t\treturn projectRoles.some(it => policy.projectRoles.includes(it.role))\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;;;AAeO,MAAM,oBAAoB;AAAA,EAChC,YAA6B,WAAsB;AAAtB,SAAA,YAAA;AAAA,EAAuB;AAAA,EAEpD,MAAM,UAAU,IAAqB,YAAoB,aAAkD;AAC1G,UAAM,SAAS,MAAM,GAAG,aAAa,MAAM,IAAI,mBAAmB,KAAK,SAAS,CAAC;AACjF,UAAM,SAAS,OAAO;AAEtB,QAAI,OAAO,YAAY,KAAK,CAAA,SAAQ,YAAY,SAAS,IAAI,CAAC,GAAG;AAChE,aAAO;AAAA,IACR;AACA,QAAI,OAAO,aAAa,WAAW,GAAG;AACrC,aAAO;AAAA,IACR;AACA,UAAM,eAAe,MAAM,GAAG,aAAa,MAAM,IAAI,+BAA+B,UAAU,CAAC;AAC/F,WAAO,aAAa,KAAK,CAAA,OAAM,OAAO,aAAa,SAAS,GAAG,IAAI,CAAC;AAAA,EACrE;AACD;"}
@@ -6,6 +6,7 @@ require("@contember/database");
6
6
  require("../type/ApiKey.cjs");
7
7
  const ConfigurationQuery = require("../queries/configuration/ConfigurationQuery.cjs");
8
8
  const exceptions = require("../../exceptions.cjs");
9
+ const LocalAuthDisablingIdpsQuery = require("../queries/idp/LocalAuthDisablingIdpsQuery.cjs");
9
10
  require("../authorization/PermissionActions.cjs");
10
11
  require("@contember/authorization");
11
12
  require("../authorization/PermissionContext.cjs");
@@ -28,6 +29,10 @@ class PasswordResetManager {
28
29
  if (!person.email) {
29
30
  throw new exceptions.ImplementationException();
30
31
  }
32
+ const exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery.LocalAuthDisablingIdpsQuery(person.id));
33
+ if (exclusiveIdps.length > 0) {
34
+ return;
35
+ }
31
36
  const nextAllowed = await dbContext.queryHandler.fetch(
32
37
  new NextMailAttemptQuery.NextMailAttemptQuery(person.email, "password_reset_init", "password_reset")
33
38
  );
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordResetManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\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\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\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\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\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\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 config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":["ImplementationException","NextMailAttemptQuery","CreatePersonTokenCommand","getPreferredProject","ConfigurationQuery","PersonTokenQuery","ResponseError","AuthLogService","ResetPasswordCommand","ResponseOk"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBACA,2BAChB;AAHgB,SAAA,SAAA;AACA,SAAA,iBAAA;AACA,SAAA,4BAAA;AAAA,EACf;AAAA,EAEH,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AAChB,QAAI,CAAC,OAAO,OAAO;AAClB,YAAM,IAAIA,WAAAA,wBAAA;AAAA,IACX;AAKA,UAAM,cAAc,MAAM,UAAU,aAAa;AAAA,MAChD,IAAIC,0CAAqB,OAAO,OAAO,uBAAuB,gBAAgB;AAAA,IAAA;AAE/E,QAAI,cAAc,oBAAI,QAAQ;AAC7B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM,UAAU,WAAW,QAAQC,yBAAAA,yBAAyB,2BAA2B,OAAO,EAAE,CAAC;AAChH,UAAM,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAUC,oBAAAA,oBAAoB,UAAU,YAAY,WAAW,IAAI;AAEzE,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MAAA;AAAA,MAEvB;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAAA;AAAA,IAC3B;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACvH,UAAM,SAAS,MAAM,UAAU,aAAa,MAAM,IAAIC,mBAAAA,mBAAmB,UAAU,SAAS,CAAC;AAC7F,UAAM,WAAW,MAAM,UAAU,aAAa,MAAMC,iBAAAA,iBAAiB,QAAQ,OAAO,gBAAgB,CAAC;AACrG,QAAI,CAAC,UAAU;AACd,aAAO,IAAIC,SAAAA,cAAc,mBAAmB,mBAAmB;AAAA,QAC9D,CAACC,eAAAA,eAAe,GAAG,GAAG,IAAIA,eAAAA,eAAe,IAAI,CAAA,CAAE;AAAA,MAAA,CAC/C;AAAA,IACF;AAEA,UAAM,cAAc,IAAIA,eAAAA,eAAe,IAAI;AAAA,MAC1C,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,IAAA,CAClB;AACD,UAAM,eAAe,MAAM,KAAK,0BAA0B,OAAO,UAAU,OAAO,UAAU,mBAAmB;AAC/G,QAAI,CAAC,aAAa,IAAI;AACrB,aAAO,IAAID,SAAAA,cAAc,aAAa,OAAO,aAAa,cAAc;AAAA,QACvE,GAAG,aAAa,YAAY,CAAA;AAAA,QAC5B,CAACC,eAAAA,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,UAAM,sBAAsB,MAAM,UAAU,WAAW,QAAQ,IAAIC,qBAAAA,qBAAqB,OAAO,QAAQ,CAAC;AACxG,QAAI,CAAC,oBAAoB,IAAI;AAC5B,aAAO,IAAIF,SAAAA,cAAc,oBAAoB,OAAO,oBAAoB,cAAc;AAAA,QACrF,GAAG,oBAAoB,YAAY,CAAA;AAAA,QACnC,CAACC,eAAAA,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,WAAO,IAAIE,SAAAA,WAAW;AAAA,MACrB,CAACF,eAAAA,eAAe,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACF;AACD;;"}
1
+ {"version":3,"file":"PasswordResetManager.cjs","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, LocalAuthDisablingIdpsQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\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\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\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\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// A person federated through a provider with `disableLocalAuthentication`\n\t\t// cannot sign in with a password, so a reset mail would only offer them a\n\t\t// credential the tenant refuses — and one more link worth phishing.\n\t\tconst exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id))\n\t\tif (exclusiveIdps.length > 0) {\n\t\t\treturn\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\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\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 config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":["ImplementationException","LocalAuthDisablingIdpsQuery","NextMailAttemptQuery","CreatePersonTokenCommand","getPreferredProject","ConfigurationQuery","PersonTokenQuery","ResponseError","AuthLogService","ResetPasswordCommand","ResponseOk"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBACA,2BAChB;AAHgB,SAAA,SAAA;AACA,SAAA,iBAAA;AACA,SAAA,4BAAA;AAAA,EACf;AAAA,EAEH,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AAChB,QAAI,CAAC,OAAO,OAAO;AAClB,YAAM,IAAIA,WAAAA,wBAAA;AAAA,IACX;AAKA,UAAM,gBAAgB,MAAM,UAAU,aAAa,MAAM,IAAIC,4BAAAA,4BAA4B,OAAO,EAAE,CAAC;AACnG,QAAI,cAAc,SAAS,GAAG;AAC7B;AAAA,IACD;AAKA,UAAM,cAAc,MAAM,UAAU,aAAa;AAAA,MAChD,IAAIC,0CAAqB,OAAO,OAAO,uBAAuB,gBAAgB;AAAA,IAAA;AAE/E,QAAI,cAAc,oBAAI,QAAQ;AAC7B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM,UAAU,WAAW,QAAQC,yBAAAA,yBAAyB,2BAA2B,OAAO,EAAE,CAAC;AAChH,UAAM,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAUC,oBAAAA,oBAAoB,UAAU,YAAY,WAAW,IAAI;AAEzE,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MAAA;AAAA,MAEvB;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAAA;AAAA,IAC3B;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACvH,UAAM,SAAS,MAAM,UAAU,aAAa,MAAM,IAAIC,mBAAAA,mBAAmB,UAAU,SAAS,CAAC;AAC7F,UAAM,WAAW,MAAM,UAAU,aAAa,MAAMC,iBAAAA,iBAAiB,QAAQ,OAAO,gBAAgB,CAAC;AACrG,QAAI,CAAC,UAAU;AACd,aAAO,IAAIC,SAAAA,cAAc,mBAAmB,mBAAmB;AAAA,QAC9D,CAACC,eAAAA,eAAe,GAAG,GAAG,IAAIA,eAAAA,eAAe,IAAI,CAAA,CAAE;AAAA,MAAA,CAC/C;AAAA,IACF;AAEA,UAAM,cAAc,IAAIA,eAAAA,eAAe,IAAI;AAAA,MAC1C,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,IAAA,CAClB;AACD,UAAM,eAAe,MAAM,KAAK,0BAA0B,OAAO,UAAU,OAAO,UAAU,mBAAmB;AAC/G,QAAI,CAAC,aAAa,IAAI;AACrB,aAAO,IAAID,SAAAA,cAAc,aAAa,OAAO,aAAa,cAAc;AAAA,QACvE,GAAG,aAAa,YAAY,CAAA;AAAA,QAC5B,CAACC,eAAAA,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,UAAM,sBAAsB,MAAM,UAAU,WAAW,QAAQ,IAAIC,qBAAAA,qBAAqB,OAAO,QAAQ,CAAC;AACxG,QAAI,CAAC,oBAAoB,IAAI;AAC5B,aAAO,IAAIF,SAAAA,cAAc,oBAAoB,OAAO,oBAAoB,cAAc;AAAA,QACrF,GAAG,oBAAoB,YAAY,CAAA;AAAA,QACnC,CAACC,eAAAA,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,WAAO,IAAIE,SAAAA,WAAW;AAAA,MACrB,CAACF,eAAAA,eAAe,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACF;AACD;;"}
@@ -4,6 +4,7 @@ import "@contember/database";
4
4
  import "../type/ApiKey.js";
5
5
  import { ConfigurationQuery } from "../queries/configuration/ConfigurationQuery.js";
6
6
  import { ImplementationException } from "../../exceptions.js";
7
+ import { LocalAuthDisablingIdpsQuery } from "../queries/idp/LocalAuthDisablingIdpsQuery.js";
7
8
  import "../authorization/PermissionActions.js";
8
9
  import "@contember/authorization";
9
10
  import "../authorization/PermissionContext.js";
@@ -26,6 +27,10 @@ class PasswordResetManager {
26
27
  if (!person.email) {
27
28
  throw new ImplementationException();
28
29
  }
30
+ const exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id));
31
+ if (exclusiveIdps.length > 0) {
32
+ return;
33
+ }
29
34
  const nextAllowed = await dbContext.queryHandler.fetch(
30
35
  new NextMailAttemptQuery(person.email, "password_reset_init", "password_reset")
31
36
  );
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordResetManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\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\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\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\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\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\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 config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAoBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBACA,2BAChB;AAHgB,SAAA,SAAA;AACA,SAAA,iBAAA;AACA,SAAA,4BAAA;AAAA,EACf;AAAA,EAEH,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AAChB,QAAI,CAAC,OAAO,OAAO;AAClB,YAAM,IAAI,wBAAA;AAAA,IACX;AAKA,UAAM,cAAc,MAAM,UAAU,aAAa;AAAA,MAChD,IAAI,qBAAqB,OAAO,OAAO,uBAAuB,gBAAgB;AAAA,IAAA;AAE/E,QAAI,cAAc,oBAAI,QAAQ;AAC7B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM,UAAU,WAAW,QAAQ,yBAAyB,2BAA2B,OAAO,EAAE,CAAC;AAChH,UAAM,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAU,oBAAoB,UAAU,YAAY,WAAW,IAAI;AAEzE,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MAAA;AAAA,MAEvB;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAAA;AAAA,IAC3B;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACvH,UAAM,SAAS,MAAM,UAAU,aAAa,MAAM,IAAI,mBAAmB,UAAU,SAAS,CAAC;AAC7F,UAAM,WAAW,MAAM,UAAU,aAAa,MAAM,iBAAiB,QAAQ,OAAO,gBAAgB,CAAC;AACrG,QAAI,CAAC,UAAU;AACd,aAAO,IAAI,cAAc,mBAAmB,mBAAmB;AAAA,QAC9D,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI,CAAA,CAAE;AAAA,MAAA,CAC/C;AAAA,IACF;AAEA,UAAM,cAAc,IAAI,eAAe,IAAI;AAAA,MAC1C,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,IAAA,CAClB;AACD,UAAM,eAAe,MAAM,KAAK,0BAA0B,OAAO,UAAU,OAAO,UAAU,mBAAmB;AAC/G,QAAI,CAAC,aAAa,IAAI;AACrB,aAAO,IAAI,cAAc,aAAa,OAAO,aAAa,cAAc;AAAA,QACvE,GAAG,aAAa,YAAY,CAAA;AAAA,QAC5B,CAAC,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,UAAM,sBAAsB,MAAM,UAAU,WAAW,QAAQ,IAAI,qBAAqB,OAAO,QAAQ,CAAC;AACxG,QAAI,CAAC,oBAAoB,IAAI;AAC5B,aAAO,IAAI,cAAc,oBAAoB,OAAO,oBAAoB,cAAc;AAAA,QACrF,GAAG,oBAAoB,YAAY,CAAA;AAAA,QACnC,CAAC,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,WAAO,IAAI,WAAW;AAAA,MACrB,CAAC,eAAe,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACF;AACD;"}
1
+ {"version":3,"file":"PasswordResetManager.js","sources":["../../../../../../packages/engine-tenant-api/src/model/service/PasswordResetManager.ts"],"sourcesContent":["import { Response, ResponseError, ResponseOk } from '../utils/Response.js'\nimport { UserMailer } from '../mailing/index.js'\nimport { ConfigurationQuery, LocalAuthDisablingIdpsQuery, PersonRow } from '../queries/index.js'\nimport { PermissionContext } from '../authorization/index.js'\nimport { ProjectManager } from './ProjectManager.js'\nimport { DatabaseContext } from '../utils/index.js'\nimport { ImplementationException } from '../../exceptions.js'\nimport { getPreferredProject } from './helpers/getPreferredProject.js'\nimport { CreatePersonTokenCommand, ResetPasswordCommand } from '../commands/personToken/index.js'\nimport { PasswordStrengthValidator } from './PasswordStrengthValidator.js'\nimport { ResetPasswordErrorCode, WeakPasswordReason } from '../../schema/index.js'\nimport { PersonTokenQuery } from '../queries/personToken/PersonTokenQuery.js'\nimport { AuthLogService } from './AuthLogService.js'\nimport { NextMailAttemptQuery } from '../queries/authLog/NextMailAttemptQuery.js'\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\tprivate readonly passwordStrengthValidator: PasswordStrengthValidator,\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\tif (!person.email) {\n\t\t\tthrow new ImplementationException()\n\t\t}\n\n\t\t// A person federated through a provider with `disableLocalAuthentication`\n\t\t// cannot sign in with a password, so a reset mail would only offer them a\n\t\t// credential the tenant refuses — and one more link worth phishing.\n\t\tconst exclusiveIdps = await dbContext.queryHandler.fetch(new LocalAuthDisablingIdpsQuery(person.id))\n\t\tif (exclusiveIdps.length > 0) {\n\t\t\treturn\n\t\t}\n\n\t\t// Per-email exponential backoff on outbound mails — don't spam a real\n\t\t// user with reset mails just because attackers keep poking the\n\t\t// endpoint. Reuses login_* backoff config against person_auth_log.\n\t\tconst nextAllowed = await dbContext.queryHandler.fetch(\n\t\t\tnew NextMailAttemptQuery(person.email, 'password_reset_init', 'password_reset'),\n\t\t)\n\t\tif (nextAllowed > new Date()) {\n\t\t\treturn\n\t\t}\n\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\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 config = await dbContext.queryHandler.fetch(new ConfigurationQuery(dbContext.providers))\n\t\tconst tokenRow = await dbContext.queryHandler.fetch(PersonTokenQuery.byToken(token, 'password_reset'))\n\t\tif (!tokenRow) {\n\t\t\treturn new ResponseError('TOKEN_NOT_FOUND', 'Token not found', {\n\t\t\t\t[AuthLogService.Key]: new AuthLogService.Bag({}),\n\t\t\t})\n\t\t}\n\n\t\tconst authLogData = new AuthLogService.Bag({\n\t\t\tpersonId: tokenRow.person_id,\n\t\t\ttokenId: tokenRow.id,\n\t\t})\n\t\tconst weakPassword = await this.passwordStrengthValidator.verify(password, config.password, 'PASSWORD_TOO_WEAK')\n\t\tif (!weakPassword.ok) {\n\t\t\treturn new ResponseError(weakPassword.error, weakPassword.errorMessage, {\n\t\t\t\t...weakPassword.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\tconst resetPasswordResult = await dbContext.commandBus.execute(new ResetPasswordCommand(token, password))\n\t\tif (!resetPasswordResult.ok) {\n\t\t\treturn new ResponseError(resetPasswordResult.error, resetPasswordResult.errorMessage, {\n\t\t\t\t...resetPasswordResult.metadata ?? {},\n\t\t\t\t[AuthLogService.Key]: authLogData,\n\t\t\t})\n\t\t}\n\t\treturn new ResponseOk({\n\t\t\t[AuthLogService.Key]: authLogData,\n\t\t})\n\t}\n}\n\nexport type ResetPasswordResponse = Response<\n\t{\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t},\n\tResetPasswordErrorCode,\n\t{\n\t\tweakPasswordReasons?: WeakPasswordReason[]\n\t\t[AuthLogService.Key]: AuthLogService.Bag\n\t}\n>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAoBO,MAAM,qBAAqB;AAAA,EACjC,YACkB,QACA,gBACA,2BAChB;AAHgB,SAAA,SAAA;AACA,SAAA,iBAAA;AACA,SAAA,4BAAA;AAAA,EACf;AAAA,EAEH,MAAa,2BACZ,WACA,mBACA,QACA,cAA2B,CAAA,GACX;AAChB,QAAI,CAAC,OAAO,OAAO;AAClB,YAAM,IAAI,wBAAA;AAAA,IACX;AAKA,UAAM,gBAAgB,MAAM,UAAU,aAAa,MAAM,IAAI,4BAA4B,OAAO,EAAE,CAAC;AACnG,QAAI,cAAc,SAAS,GAAG;AAC7B;AAAA,IACD;AAKA,UAAM,cAAc,MAAM,UAAU,aAAa;AAAA,MAChD,IAAI,qBAAqB,OAAO,OAAO,uBAAuB,gBAAgB;AAAA,IAAA;AAE/E,QAAI,cAAc,oBAAI,QAAQ;AAC7B;AAAA,IACD;AAEA,UAAM,SAAS,MAAM,UAAU,WAAW,QAAQ,yBAAyB,2BAA2B,OAAO,EAAE,CAAC;AAChH,UAAM,WAAW,MAAM,KAAK,eAAe,sBAAsB,WAAW,OAAO,aAAa,iBAAiB;AACjH,UAAM,UAAU,oBAAoB,UAAU,YAAY,WAAW,IAAI;AAEzE,UAAM,KAAK,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,QACC,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,QACd,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,MAAA;AAAA,MAEvB;AAAA,QACC,SAAS,YAAY,eAAe;AAAA,QACpC,WAAW,SAAS,MAAM;AAAA,MAAA;AAAA,IAC3B;AAAA,EAEF;AAAA,EAEA,MAAa,cAAc,WAA4B,OAAe,UAAkD;AACvH,UAAM,SAAS,MAAM,UAAU,aAAa,MAAM,IAAI,mBAAmB,UAAU,SAAS,CAAC;AAC7F,UAAM,WAAW,MAAM,UAAU,aAAa,MAAM,iBAAiB,QAAQ,OAAO,gBAAgB,CAAC;AACrG,QAAI,CAAC,UAAU;AACd,aAAO,IAAI,cAAc,mBAAmB,mBAAmB;AAAA,QAC9D,CAAC,eAAe,GAAG,GAAG,IAAI,eAAe,IAAI,CAAA,CAAE;AAAA,MAAA,CAC/C;AAAA,IACF;AAEA,UAAM,cAAc,IAAI,eAAe,IAAI;AAAA,MAC1C,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,IAAA,CAClB;AACD,UAAM,eAAe,MAAM,KAAK,0BAA0B,OAAO,UAAU,OAAO,UAAU,mBAAmB;AAC/G,QAAI,CAAC,aAAa,IAAI;AACrB,aAAO,IAAI,cAAc,aAAa,OAAO,aAAa,cAAc;AAAA,QACvE,GAAG,aAAa,YAAY,CAAA;AAAA,QAC5B,CAAC,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,UAAM,sBAAsB,MAAM,UAAU,WAAW,QAAQ,IAAI,qBAAqB,OAAO,QAAQ,CAAC;AACxG,QAAI,CAAC,oBAAoB,IAAI;AAC5B,aAAO,IAAI,cAAc,oBAAoB,OAAO,oBAAoB,cAAc;AAAA,QACrF,GAAG,oBAAoB,YAAY,CAAA;AAAA,QACnC,CAAC,eAAe,GAAG,GAAG;AAAA,MAAA,CACtB;AAAA,IACF;AACA,WAAO,IAAI,WAAW;AAAA,MACrB,CAAC,eAAe,GAAG,GAAG;AAAA,IAAA,CACtB;AAAA,EACF;AACD;"}
@@ -6,6 +6,7 @@ require("../type/ApiKey.cjs");
6
6
  const ConfigurationQuery = require("../queries/configuration/ConfigurationQuery.cjs");
7
7
  const exceptions = require("../../exceptions.cjs");
8
8
  const PersonQuery = require("../queries/person/PersonQuery.cjs");
9
+ const LocalAuthDisablingIdpsQuery = require("../queries/idp/LocalAuthDisablingIdpsQuery.cjs");
9
10
  require("../authorization/PermissionActions.cjs");
10
11
  require("@contember/authorization");
11
12
  require("../authorization/PermissionContext.cjs");
@@ -48,6 +49,15 @@ class PasswordlessSignInManager {
48
49
  })
49
50
  });
50
51
  }
52
+ const exclusiveIdps = await db2.queryHandler.fetch(new LocalAuthDisablingIdpsQuery.LocalAuthDisablingIdpsQuery(person.id));
53
+ if (exclusiveIdps.length > 0) {
54
+ return new Response.ResponseError("IDP_REQUIRED", `Sign in using ${exclusiveIdps.join(" or ")}`, {
55
+ [AuthLogService.AuthLogService.Key]: new AuthLogService.AuthLogService.Bag({
56
+ personInput: email,
57
+ personId: person.id
58
+ })
59
+ });
60
+ }
51
61
  if (!isPasswordlessEnabled.isPasswordlessEnabled(configuration.passwordless.enabled, person.passwordless_enabled)) {
52
62
  return new Response.ResponseError("PASSWORDLESS_DISABLED", "Passwordless sign-in is disabled for this person", {
53
63
  [AuthLogService.AuthLogService.Key]: new AuthLogService.AuthLogService.Bag({
@@ -149,6 +159,15 @@ class PasswordlessSignInManager {
149
159
  })
150
160
  });
151
161
  }
162
+ const exclusiveIdps = await db2.queryHandler.fetch(new LocalAuthDisablingIdpsQuery.LocalAuthDisablingIdpsQuery(personRow.id));
163
+ if (exclusiveIdps.length > 0) {
164
+ return new Response.ResponseError("IDP_REQUIRED", `Sign in using ${exclusiveIdps.join(" or ")}`, {
165
+ [AuthLogService.AuthLogService.Key]: new AuthLogService.AuthLogService.Bag({
166
+ personId: personRow.id,
167
+ tokenId: tokenResult?.id
168
+ })
169
+ });
170
+ }
152
171
  let usedBackupCode = false;
153
172
  if (personRow.otp_secret && personRow.otp_activated_at) {
154
173
  if (mfaOtp) {