@contember/engine-tenant-api 1.3.0-alpha.7 → 1.3.0-beta.1

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 (374) hide show
  1. package/dist/src/TenantContainer.d.ts +17 -3
  2. package/dist/src/TenantContainer.d.ts.map +1 -1
  3. package/dist/src/TenantContainer.js +7 -0
  4. package/dist/src/TenantContainer.js.map +1 -1
  5. package/dist/src/bridges/system/IdentityFetcher.d.ts +1 -1
  6. package/dist/src/bridges/system/IdentityFetcher.d.ts.map +1 -1
  7. package/dist/src/migrations/2023-01-20-135500-person-email-normalize.d.ts +3 -0
  8. package/dist/src/migrations/2023-01-20-135500-person-email-normalize.d.ts.map +1 -0
  9. package/dist/src/migrations/2023-01-20-135500-person-email-normalize.js +28 -0
  10. package/dist/src/migrations/2023-01-20-135500-person-email-normalize.js.map +1 -0
  11. package/dist/src/migrations/2023-06-03-104000-person-disabled.d.ts +3 -0
  12. package/dist/src/migrations/2023-06-03-104000-person-disabled.d.ts.map +1 -0
  13. package/dist/src/migrations/2023-06-03-104000-person-disabled.js +11 -0
  14. package/dist/src/migrations/2023-06-03-104000-person-disabled.js.map +1 -0
  15. package/dist/src/migrations/runner.d.ts.map +1 -1
  16. package/dist/src/migrations/runner.js +4 -0
  17. package/dist/src/migrations/runner.js.map +1 -1
  18. package/dist/src/migrations/snapshot.d.ts.map +1 -1
  19. package/dist/src/migrations/snapshot.js +1 -0
  20. package/dist/src/migrations/snapshot.js.map +1 -1
  21. package/dist/src/model/authorization/AclSchemaAccessNodeFactory.d.ts.map +1 -1
  22. package/dist/src/model/authorization/AclSchemaAccessNodeFactory.js +14 -9
  23. package/dist/src/model/authorization/AclSchemaAccessNodeFactory.js.map +1 -1
  24. package/dist/src/model/authorization/MembershipMatcher.d.ts +1 -1
  25. package/dist/src/model/authorization/MembershipMatcher.d.ts.map +1 -1
  26. package/dist/src/model/authorization/PermissionActions.d.ts +21 -0
  27. package/dist/src/model/authorization/PermissionActions.d.ts.map +1 -1
  28. package/dist/src/model/authorization/PermissionActions.js +4 -2
  29. package/dist/src/model/authorization/PermissionActions.js.map +1 -1
  30. package/dist/src/model/authorization/PermissionContext.d.ts +1 -1
  31. package/dist/src/model/authorization/PermissionContext.d.ts.map +1 -1
  32. package/dist/src/model/authorization/PermissionsFactory.d.ts.map +1 -1
  33. package/dist/src/model/authorization/PermissionsFactory.js +6 -3
  34. package/dist/src/model/authorization/PermissionsFactory.js.map +1 -1
  35. package/dist/src/model/authorization/Roles.js +1 -1
  36. package/dist/src/model/authorization/Roles.js.map +1 -1
  37. package/dist/src/model/commands/apiKey/CreateApiKeyCommand.d.ts +1 -1
  38. package/dist/src/model/commands/apiKey/CreateApiKeyCommand.d.ts.map +1 -1
  39. package/dist/src/model/commands/identity/PatchIdentityGlobalRoles.d.ts +9 -0
  40. package/dist/src/model/commands/identity/PatchIdentityGlobalRoles.d.ts.map +1 -0
  41. package/dist/src/model/commands/identity/PatchIdentityGlobalRoles.js +29 -0
  42. package/dist/src/model/commands/identity/PatchIdentityGlobalRoles.js.map +1 -0
  43. package/dist/src/model/commands/identity/index.d.ts +1 -0
  44. package/dist/src/model/commands/identity/index.d.ts.map +1 -1
  45. package/dist/src/model/commands/identity/index.js +1 -0
  46. package/dist/src/model/commands/identity/index.js.map +1 -1
  47. package/dist/src/model/commands/idp/UpdateIdpCommand.d.ts +1 -1
  48. package/dist/src/model/commands/idp/UpdateIdpCommand.d.ts.map +1 -1
  49. package/dist/src/model/commands/membership/AddProjectMemberCommand.d.ts +2 -6
  50. package/dist/src/model/commands/membership/AddProjectMemberCommand.d.ts.map +1 -1
  51. package/dist/src/model/commands/membership/AddProjectMemberCommand.js +5 -11
  52. package/dist/src/model/commands/membership/AddProjectMemberCommand.js.map +1 -1
  53. package/dist/src/model/commands/membership/RemoveProjectMemberCommand.d.ts +1 -1
  54. package/dist/src/model/commands/membership/RemoveProjectMemberCommand.d.ts.map +1 -1
  55. package/dist/src/model/commands/membership/RemoveProjectMemberCommand.js +1 -2
  56. package/dist/src/model/commands/membership/RemoveProjectMemberCommand.js.map +1 -1
  57. package/dist/src/model/commands/membership/UpdateProjectMemberCommand.d.ts +1 -1
  58. package/dist/src/model/commands/membership/UpdateProjectMemberCommand.d.ts.map +1 -1
  59. package/dist/src/model/commands/membership/UpdateProjectMemberCommand.js +2 -3
  60. package/dist/src/model/commands/membership/UpdateProjectMemberCommand.js.map +1 -1
  61. package/dist/src/model/commands/membership/types.d.ts +3 -3
  62. package/dist/src/model/commands/membership/types.d.ts.map +1 -1
  63. package/dist/src/model/commands/passwordReset/ResetPasswordCommand.d.ts +2 -6
  64. package/dist/src/model/commands/passwordReset/ResetPasswordCommand.d.ts.map +1 -1
  65. package/dist/src/model/commands/passwordReset/ResetPasswordCommand.js +5 -11
  66. package/dist/src/model/commands/passwordReset/ResetPasswordCommand.js.map +1 -1
  67. package/dist/src/model/commands/person/CreatePersonCommand.d.ts.map +1 -1
  68. package/dist/src/model/commands/person/CreatePersonCommand.js +10 -5
  69. package/dist/src/model/commands/person/CreatePersonCommand.js.map +1 -1
  70. package/dist/src/model/commands/person/DisablePersonCommand.d.ts +7 -0
  71. package/dist/src/model/commands/person/DisablePersonCommand.d.ts.map +1 -0
  72. package/dist/src/model/commands/person/DisablePersonCommand.js +22 -0
  73. package/dist/src/model/commands/person/DisablePersonCommand.js.map +1 -0
  74. package/dist/src/model/dtos/Password.d.ts +1 -1
  75. package/dist/src/model/dtos/Password.d.ts.map +1 -1
  76. package/dist/src/model/mailing/type.js +1 -1
  77. package/dist/src/model/mailing/type.js.map +1 -1
  78. package/dist/src/model/queries/apiKey/ApiKeyQuery.d.ts +23 -0
  79. package/dist/src/model/queries/apiKey/ApiKeyQuery.d.ts.map +1 -0
  80. package/dist/src/model/queries/apiKey/ApiKeyQuery.js +45 -0
  81. package/dist/src/model/queries/apiKey/ApiKeyQuery.js.map +1 -0
  82. package/dist/src/model/queries/apiKey/index.d.ts +1 -1
  83. package/dist/src/model/queries/apiKey/index.d.ts.map +1 -1
  84. package/dist/src/model/queries/apiKey/index.js +1 -1
  85. package/dist/src/model/queries/apiKey/index.js.map +1 -1
  86. package/dist/src/model/queries/idp/types.d.ts +4 -4
  87. package/dist/src/model/queries/idp/types.d.ts.map +1 -1
  88. package/dist/src/model/queries/membership/ProjectMembersQuery.d.ts +1 -1
  89. package/dist/src/model/queries/membership/ProjectMembersQuery.d.ts.map +1 -1
  90. package/dist/src/model/queries/membership/ProjectMembersQuery.js +3 -4
  91. package/dist/src/model/queries/membership/ProjectMembersQuery.js.map +1 -1
  92. package/dist/src/model/queries/person/PersonQuery.d.ts +4 -3
  93. package/dist/src/model/queries/person/PersonQuery.d.ts.map +1 -1
  94. package/dist/src/model/queries/person/PersonQuery.js +22 -0
  95. package/dist/src/model/queries/person/PersonQuery.js.map +1 -1
  96. package/dist/src/model/queries/person/PersonQueryBuilderFactory.d.ts.map +1 -1
  97. package/dist/src/model/queries/person/PersonQueryBuilderFactory.js +1 -0
  98. package/dist/src/model/queries/person/PersonQueryBuilderFactory.js.map +1 -1
  99. package/dist/src/model/queries/person/types.d.ts +4 -3
  100. package/dist/src/model/queries/person/types.d.ts.map +1 -1
  101. package/dist/src/model/queries/project/ProjectSecretsQuery.d.ts +1 -1
  102. package/dist/src/model/queries/project/ProjectSecretsQuery.d.ts.map +1 -1
  103. package/dist/src/model/service/IDPSignInManager.d.ts.map +1 -1
  104. package/dist/src/model/service/IDPSignInManager.js +8 -6
  105. package/dist/src/model/service/IDPSignInManager.js.map +1 -1
  106. package/dist/src/model/service/InviteManager.d.ts +1 -1
  107. package/dist/src/model/service/InviteManager.d.ts.map +1 -1
  108. package/dist/src/model/service/InviteManager.js +2 -3
  109. package/dist/src/model/service/InviteManager.js.map +1 -1
  110. package/dist/src/model/service/OtpAuthenticator.d.ts +1 -1
  111. package/dist/src/model/service/OtpAuthenticator.d.ts.map +1 -1
  112. package/dist/src/model/service/PasswordChangeManager.js +4 -5
  113. package/dist/src/model/service/PasswordChangeManager.js.map +1 -1
  114. package/dist/src/model/service/PasswordResetManager.d.ts +2 -4
  115. package/dist/src/model/service/PasswordResetManager.d.ts.map +1 -1
  116. package/dist/src/model/service/PasswordResetManager.js +2 -6
  117. package/dist/src/model/service/PasswordResetManager.js.map +1 -1
  118. package/dist/src/model/service/PersonAccessManager.d.ts +14 -0
  119. package/dist/src/model/service/PersonAccessManager.d.ts.map +1 -0
  120. package/dist/src/model/service/PersonAccessManager.js +42 -0
  121. package/dist/src/model/service/PersonAccessManager.js.map +1 -0
  122. package/dist/src/model/service/PersonManager.d.ts +7 -0
  123. package/dist/src/model/service/PersonManager.d.ts.map +1 -0
  124. package/dist/src/model/service/PersonManager.js +11 -0
  125. package/dist/src/model/service/PersonManager.js.map +1 -0
  126. package/dist/src/model/service/ProjectManager.d.ts +1 -1
  127. package/dist/src/model/service/ProjectManager.d.ts.map +1 -1
  128. package/dist/src/model/service/ProjectManager.js +2 -3
  129. package/dist/src/model/service/ProjectManager.js.map +1 -1
  130. package/dist/src/model/service/ProjectMemberManager.d.ts +2 -2
  131. package/dist/src/model/service/ProjectMemberManager.d.ts.map +1 -1
  132. package/dist/src/model/service/ProjectMemberManager.js +3 -16
  133. package/dist/src/model/service/ProjectMemberManager.js.map +1 -1
  134. package/dist/src/model/service/RolesManager.d.ts +11 -0
  135. package/dist/src/model/service/RolesManager.d.ts.map +1 -0
  136. package/dist/src/model/service/RolesManager.js +35 -0
  137. package/dist/src/model/service/RolesManager.js.map +1 -0
  138. package/dist/src/model/service/SignInManager.d.ts +2 -2
  139. package/dist/src/model/service/SignInManager.d.ts.map +1 -1
  140. package/dist/src/model/service/SignInManager.js +13 -8
  141. package/dist/src/model/service/SignInManager.js.map +1 -1
  142. package/dist/src/model/service/SignUpManager.d.ts +2 -2
  143. package/dist/src/model/service/SignUpManager.d.ts.map +1 -1
  144. package/dist/src/model/service/SignUpManager.js +2 -3
  145. package/dist/src/model/service/SignUpManager.js.map +1 -1
  146. package/dist/src/model/service/apiKey/ApiKeyManager.d.ts +3 -1
  147. package/dist/src/model/service/apiKey/ApiKeyManager.d.ts.map +1 -1
  148. package/dist/src/model/service/apiKey/ApiKeyManager.js +4 -1
  149. package/dist/src/model/service/apiKey/ApiKeyManager.js.map +1 -1
  150. package/dist/src/model/service/apiKey/ApiKeyService.d.ts +1 -1
  151. package/dist/src/model/service/apiKey/ApiKeyService.d.ts.map +1 -1
  152. package/dist/src/model/service/idp/IDPManager.d.ts +4 -4
  153. package/dist/src/model/service/idp/IDPManager.d.ts.map +1 -1
  154. package/dist/src/model/service/idp/IDPManager.js +7 -8
  155. package/dist/src/model/service/idp/IDPManager.js.map +1 -1
  156. package/dist/src/model/service/idp/providers/AppleProvider.d.ts +1 -1
  157. package/dist/src/model/service/idp/providers/AppleProvider.d.ts.map +1 -1
  158. package/dist/src/model/service/idp/providers/FacebookProvider.d.ts +1 -1
  159. package/dist/src/model/service/idp/providers/FacebookProvider.d.ts.map +1 -1
  160. package/dist/src/model/service/idp/providers/OIDCTypes.d.ts +3 -3
  161. package/dist/src/model/service/idp/providers/OIDCTypes.d.ts.map +1 -1
  162. package/dist/src/model/service/index.d.ts +2 -0
  163. package/dist/src/model/service/index.d.ts.map +1 -1
  164. package/dist/src/model/service/index.js +2 -0
  165. package/dist/src/model/service/index.js.map +1 -1
  166. package/dist/src/model/type/Variables.d.ts +1 -1
  167. package/dist/src/model/type/Variables.d.ts.map +1 -1
  168. package/dist/src/model/utils/Response.d.ts +2 -2
  169. package/dist/src/model/utils/Response.d.ts.map +1 -1
  170. package/dist/src/model/utils/email.d.ts +2 -0
  171. package/dist/src/model/utils/email.d.ts.map +1 -0
  172. package/dist/src/model/utils/email.js +8 -0
  173. package/dist/src/model/utils/email.js.map +1 -0
  174. package/dist/src/model/utils/tokenUtils.d.ts +1 -1
  175. package/dist/src/model/utils/tokenUtils.d.ts.map +1 -1
  176. package/dist/src/model/utils/typeUtils.d.ts +1 -1
  177. package/dist/src/model/utils/typeUtils.d.ts.map +1 -1
  178. package/dist/src/resolvers/ResolverFactory.d.ts +4 -1
  179. package/dist/src/resolvers/ResolverFactory.d.ts.map +1 -1
  180. package/dist/src/resolvers/ResolverFactory.js +3 -0
  181. package/dist/src/resolvers/ResolverFactory.js.map +1 -1
  182. package/dist/src/resolvers/errorUtils.d.ts +3 -3
  183. package/dist/src/resolvers/errorUtils.d.ts.map +1 -1
  184. package/dist/src/resolvers/errorUtils.js.map +1 -1
  185. package/dist/src/resolvers/membershipUtils.d.ts +4 -9
  186. package/dist/src/resolvers/membershipUtils.d.ts.map +1 -1
  187. package/dist/src/resolvers/membershipUtils.js +10 -18
  188. package/dist/src/resolvers/membershipUtils.js.map +1 -1
  189. package/dist/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js +1 -2
  190. package/dist/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.js.map +1 -1
  191. package/dist/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js +1 -2
  192. package/dist/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.js.map +1 -1
  193. package/dist/src/resolvers/mutation/identity/GlobalRolesMutationResolver.d.ts +11 -0
  194. package/dist/src/resolvers/mutation/identity/GlobalRolesMutationResolver.d.ts.map +1 -0
  195. package/dist/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js +44 -0
  196. package/dist/src/resolvers/mutation/identity/GlobalRolesMutationResolver.js.map +1 -0
  197. package/dist/src/resolvers/mutation/identity/index.d.ts +2 -0
  198. package/dist/src/resolvers/mutation/identity/index.d.ts.map +1 -0
  199. package/dist/src/resolvers/mutation/identity/index.js +18 -0
  200. package/dist/src/resolvers/mutation/identity/index.js.map +1 -0
  201. package/dist/src/resolvers/mutation/index.d.ts +1 -0
  202. package/dist/src/resolvers/mutation/index.d.ts.map +1 -1
  203. package/dist/src/resolvers/mutation/index.js +1 -0
  204. package/dist/src/resolvers/mutation/index.js.map +1 -1
  205. package/dist/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js +6 -7
  206. package/dist/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.js.map +1 -1
  207. package/dist/src/resolvers/mutation/person/ChangePasswordMutationResolver.js +2 -3
  208. package/dist/src/resolvers/mutation/person/ChangePasswordMutationResolver.js.map +1 -1
  209. package/dist/src/resolvers/mutation/person/DisablePersonMutationResolver.d.ts +11 -0
  210. package/dist/src/resolvers/mutation/person/DisablePersonMutationResolver.d.ts.map +1 -0
  211. package/dist/src/resolvers/mutation/person/DisablePersonMutationResolver.js +36 -0
  212. package/dist/src/resolvers/mutation/person/DisablePersonMutationResolver.js.map +1 -0
  213. package/dist/src/resolvers/mutation/person/InviteMutationResolver.d.ts.map +1 -1
  214. package/dist/src/resolvers/mutation/person/InviteMutationResolver.js +3 -4
  215. package/dist/src/resolvers/mutation/person/InviteMutationResolver.js.map +1 -1
  216. package/dist/src/resolvers/mutation/person/OtpMutationResolver.d.ts.map +1 -1
  217. package/dist/src/resolvers/mutation/person/OtpMutationResolver.js +3 -4
  218. package/dist/src/resolvers/mutation/person/OtpMutationResolver.js.map +1 -1
  219. package/dist/src/resolvers/mutation/person/ResetPasswordMutationResolver.d.ts.map +1 -1
  220. package/dist/src/resolvers/mutation/person/ResetPasswordMutationResolver.js +2 -10
  221. package/dist/src/resolvers/mutation/person/ResetPasswordMutationResolver.js.map +1 -1
  222. package/dist/src/resolvers/mutation/person/SignInMutationResolver.d.ts.map +1 -1
  223. package/dist/src/resolvers/mutation/person/SignInMutationResolver.js.map +1 -1
  224. package/dist/src/resolvers/mutation/person/SignOutMutationResolver.d.ts.map +1 -1
  225. package/dist/src/resolvers/mutation/person/SignOutMutationResolver.js +5 -2
  226. package/dist/src/resolvers/mutation/person/SignOutMutationResolver.js.map +1 -1
  227. package/dist/src/resolvers/mutation/project/CreateProjectMutationResolver.d.ts.map +1 -1
  228. package/dist/src/resolvers/mutation/project/CreateProjectMutationResolver.js +1 -2
  229. package/dist/src/resolvers/mutation/project/CreateProjectMutationResolver.js.map +1 -1
  230. package/dist/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js +1 -2
  231. package/dist/src/resolvers/mutation/project/SetProjectSecretMutationResolver.js.map +1 -1
  232. package/dist/src/resolvers/mutation/project/UpdateProjectMutationResolver.d.ts.map +1 -1
  233. package/dist/src/resolvers/mutation/project/UpdateProjectMutationResolver.js +1 -2
  234. package/dist/src/resolvers/mutation/project/UpdateProjectMutationResolver.js.map +1 -1
  235. package/dist/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js +1 -2
  236. package/dist/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.js.map +1 -1
  237. package/dist/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js +1 -2
  238. package/dist/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.js.map +1 -1
  239. package/dist/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js +1 -2
  240. package/dist/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.js.map +1 -1
  241. package/dist/src/resolvers/types/ProjectTypeResolver.d.ts.map +1 -1
  242. package/dist/src/resolvers/types/ProjectTypeResolver.js +5 -6
  243. package/dist/src/resolvers/types/ProjectTypeResolver.js.map +1 -1
  244. package/dist/src/schema/index.d.ts +431 -397
  245. package/dist/src/schema/index.d.ts.map +1 -1
  246. package/dist/src/schema/index.js +0 -188
  247. package/dist/src/schema/index.js.map +1 -1
  248. package/dist/src/schema/tenant.graphql.d.ts.map +1 -1
  249. package/dist/src/schema/tenant.graphql.js +97 -21
  250. package/dist/src/schema/tenant.graphql.js.map +1 -1
  251. package/dist/src/tsconfig.tsbuildinfo +1 -1
  252. package/dist/src/utils/Mailer.d.ts +1 -1
  253. package/dist/src/utils/Mailer.d.ts.map +1 -1
  254. package/dist/src/utils/array.d.ts +1 -1
  255. package/dist/src/utils/array.d.ts.map +1 -1
  256. package/dist/src/utils/batchQuery.d.ts +2 -2
  257. package/dist/src/utils/batchQuery.d.ts.map +1 -1
  258. package/dist/tests/cases/integration/db/updateRoles.test.d.ts +2 -0
  259. package/dist/tests/cases/integration/db/updateRoles.test.d.ts.map +1 -0
  260. package/dist/tests/cases/integration/db/updateRoles.test.js +67 -0
  261. package/dist/tests/cases/integration/db/updateRoles.test.js.map +1 -0
  262. package/dist/tests/cases/integration/mocked/confirmOtpMutation.test.js +1 -2
  263. package/dist/tests/cases/integration/mocked/confirmOtpMutation.test.js.map +1 -1
  264. package/dist/tests/cases/integration/mocked/gql/signUp.d.ts.map +1 -1
  265. package/dist/tests/cases/integration/mocked/gql/signUp.js +4 -0
  266. package/dist/tests/cases/integration/mocked/gql/signUp.js.map +1 -1
  267. package/dist/tests/cases/integration/mocked/gql/types.d.ts +1 -1
  268. package/dist/tests/cases/integration/mocked/gql/types.d.ts.map +1 -1
  269. package/dist/tests/cases/integration/mocked/signInMutation.test.js +36 -4
  270. package/dist/tests/cases/integration/mocked/signInMutation.test.js.map +1 -1
  271. package/dist/tests/cases/integration/mocked/signOutMutation.test.js +53 -0
  272. package/dist/tests/cases/integration/mocked/signOutMutation.test.js.map +1 -1
  273. package/dist/tests/cases/integration/mocked/signUpMutation.test.js +9 -0
  274. package/dist/tests/cases/integration/mocked/signUpMutation.test.js.map +1 -1
  275. package/dist/tests/cases/integration/mocked/sql/getApiKeySql.d.ts +11 -0
  276. package/dist/tests/cases/integration/mocked/sql/getApiKeySql.d.ts.map +1 -0
  277. package/dist/tests/cases/integration/mocked/sql/getApiKeySql.js +31 -0
  278. package/dist/tests/cases/integration/mocked/sql/getApiKeySql.js.map +1 -0
  279. package/dist/tests/cases/integration/mocked/sql/getPersonByEmailSql.d.ts.map +1 -1
  280. package/dist/tests/cases/integration/mocked/sql/getPersonByEmailSql.js +2 -1
  281. package/dist/tests/cases/integration/mocked/sql/getPersonByEmailSql.js.map +1 -1
  282. package/dist/tests/cases/integration/mocked/sql/getPersonByIdSql.js +1 -1
  283. package/dist/tests/cases/integration/mocked/sql/getPersonByIdentity.js +1 -1
  284. package/dist/tests/cases/integration/mocked/sql/getPersonByIdpSql.d.ts.map +1 -1
  285. package/dist/tests/cases/integration/mocked/sql/getPersonByIdpSql.js +2 -1
  286. package/dist/tests/cases/integration/mocked/sql/getPersonByIdpSql.js.map +1 -1
  287. package/dist/tests/cases/unit/authorization/membershipAwareAccessNode.test.js +27 -0
  288. package/dist/tests/cases/unit/authorization/membershipAwareAccessNode.test.js.map +1 -1
  289. package/dist/tests/src/mailer.d.ts +2 -2
  290. package/dist/tests/src/mailer.d.ts.map +1 -1
  291. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  292. package/graphql-tenant.codegen.yml +2 -1
  293. package/package.json +14 -14
  294. package/src/TenantContainer.ts +19 -2
  295. package/src/migrations/2023-01-20-135500-person-email-normalize.ts +28 -0
  296. package/src/migrations/2023-06-03-104000-person-disabled.ts +10 -0
  297. package/src/migrations/runner.ts +4 -0
  298. package/src/migrations/snapshot.ts +1 -0
  299. package/src/model/authorization/AclSchemaAccessNodeFactory.ts +16 -6
  300. package/src/model/authorization/PermissionActions.ts +5 -0
  301. package/src/model/authorization/PermissionsFactory.ts +11 -3
  302. package/src/model/commands/identity/PatchIdentityGlobalRoles.ts +28 -0
  303. package/src/model/commands/identity/index.ts +1 -0
  304. package/src/model/commands/membership/AddProjectMemberCommand.ts +9 -10
  305. package/src/model/commands/membership/RemoveProjectMemberCommand.ts +1 -1
  306. package/src/model/commands/membership/UpdateProjectMemberCommand.ts +2 -2
  307. package/src/model/commands/passwordReset/ResetPasswordCommand.ts +9 -16
  308. package/src/model/commands/person/CreatePersonCommand.ts +9 -4
  309. package/src/model/commands/person/DisablePersonCommand.ts +18 -0
  310. package/src/model/queries/apiKey/ApiKeyQuery.ts +64 -0
  311. package/src/model/queries/apiKey/index.ts +1 -1
  312. package/src/model/queries/idp/types.ts +2 -2
  313. package/src/model/queries/membership/ProjectMembersQuery.ts +3 -3
  314. package/src/model/queries/person/PersonQuery.ts +30 -3
  315. package/src/model/queries/person/PersonQueryBuilderFactory.ts +1 -0
  316. package/src/model/queries/person/types.ts +3 -2
  317. package/src/model/service/IDPSignInManager.ts +11 -6
  318. package/src/model/service/InviteManager.ts +2 -2
  319. package/src/model/service/PasswordChangeManager.ts +4 -4
  320. package/src/model/service/PasswordResetManager.ts +3 -5
  321. package/src/model/service/PersonAccessManager.ts +56 -0
  322. package/src/model/service/PersonManager.ts +14 -0
  323. package/src/model/service/ProjectManager.ts +3 -3
  324. package/src/model/service/ProjectMemberManager.ts +3 -15
  325. package/src/model/service/RolesManager.ts +40 -0
  326. package/src/model/service/SignInManager.ts +25 -7
  327. package/src/model/service/SignUpManager.ts +2 -2
  328. package/src/model/service/apiKey/ApiKeyManager.ts +8 -1
  329. package/src/model/service/idp/IDPManager.ts +8 -8
  330. package/src/model/service/index.ts +2 -0
  331. package/src/model/utils/Response.ts +1 -1
  332. package/src/model/utils/email.ts +5 -0
  333. package/src/resolvers/ResolverFactory.ts +10 -1
  334. package/src/resolvers/errorUtils.ts +1 -1
  335. package/src/resolvers/membershipUtils.ts +21 -21
  336. package/src/resolvers/mutation/apiKey/CreateApiKeyMutationResolver.ts +2 -2
  337. package/src/resolvers/mutation/apiKey/DisableApiKeyMutationResolver.ts +1 -1
  338. package/src/resolvers/mutation/identity/GlobalRolesMutationResolver.ts +69 -0
  339. package/src/resolvers/mutation/identity/index.ts +1 -0
  340. package/src/resolvers/mutation/index.ts +1 -0
  341. package/src/resolvers/mutation/mailTemplates/MailTemplateMutationResolver.ts +6 -6
  342. package/src/resolvers/mutation/person/ChangePasswordMutationResolver.ts +2 -2
  343. package/src/resolvers/mutation/person/DisablePersonMutationResolver.ts +48 -0
  344. package/src/resolvers/mutation/person/InviteMutationResolver.ts +5 -12
  345. package/src/resolvers/mutation/person/OtpMutationResolver.ts +4 -6
  346. package/src/resolvers/mutation/person/ResetPasswordMutationResolver.ts +2 -10
  347. package/src/resolvers/mutation/person/SignInMutationResolver.ts +1 -0
  348. package/src/resolvers/mutation/person/SignOutMutationResolver.ts +13 -3
  349. package/src/resolvers/mutation/project/CreateProjectMutationResolver.ts +2 -7
  350. package/src/resolvers/mutation/project/SetProjectSecretMutationResolver.ts +1 -1
  351. package/src/resolvers/mutation/project/UpdateProjectMutationResolver.ts +2 -7
  352. package/src/resolvers/mutation/projectMember/AddProjectMemberMutationResolver.ts +2 -2
  353. package/src/resolvers/mutation/projectMember/RemoveProjectMemberMutationResolver.ts +1 -1
  354. package/src/resolvers/mutation/projectMember/UpdateProjectMemberMutationResolver.ts +2 -2
  355. package/src/resolvers/types/ProjectTypeResolver.ts +2 -2
  356. package/src/schema/index.ts +321 -159
  357. package/src/schema/tenant.graphql.ts +97 -21
  358. package/tests/cases/integration/db/updateRoles.test.ts +74 -0
  359. package/tests/cases/integration/mocked/confirmOtpMutation.test.ts +1 -1
  360. package/tests/cases/integration/mocked/gql/signUp.ts +4 -0
  361. package/tests/cases/integration/mocked/signInMutation.test.ts +37 -3
  362. package/tests/cases/integration/mocked/signOutMutation.test.ts +58 -0
  363. package/tests/cases/integration/mocked/signUpMutation.test.ts +9 -0
  364. package/tests/cases/integration/mocked/sql/getApiKeySql.ts +33 -0
  365. package/tests/cases/integration/mocked/sql/getPersonByEmailSql.ts +2 -1
  366. package/tests/cases/integration/mocked/sql/getPersonByIdSql.ts +1 -1
  367. package/tests/cases/integration/mocked/sql/getPersonByIdentity.ts +1 -1
  368. package/tests/cases/integration/mocked/sql/getPersonByIdpSql.ts +2 -1
  369. package/tests/cases/unit/authorization/membershipAwareAccessNode.test.ts +36 -0
  370. package/dist/src/model/queries/apiKey/ApiKeyByTokenQuery.d.ts +0 -22
  371. package/dist/src/model/queries/apiKey/ApiKeyByTokenQuery.d.ts.map +0 -1
  372. package/dist/src/model/queries/apiKey/ApiKeyByTokenQuery.js +0 -33
  373. package/dist/src/model/queries/apiKey/ApiKeyByTokenQuery.js.map +0 -1
  374. package/src/model/queries/apiKey/ApiKeyByTokenQuery.ts +0 -49
@@ -6,7 +6,8 @@ config:
6
6
  generates:
7
7
  ./src/schema/index.ts:
8
8
  config:
9
- immutableTypes: "1"
9
+ immutableTypes: true
10
+ enumsAsTypes: true
10
11
  plugins:
11
12
  - "typescript"
12
13
  - "typescript-operations"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-tenant-api",
3
- "version": "1.3.0-alpha.7",
3
+ "version": "1.3.0-beta.1",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -10,19 +10,19 @@
10
10
  },
11
11
  "scripts": {
12
12
  "generate": "gql-gen --config graphql-tenant.codegen.yml",
13
- "test": "vitest --no-threads"
13
+ "test": "vitest --dir ./tests/cases --no-threads"
14
14
  },
15
15
  "dependencies": {
16
- "@contember/authorization": "^1.3.0-alpha.7",
17
- "@contember/config-loader": "^1.3.0-alpha.7",
18
- "@contember/database": "^1.3.0-alpha.7",
19
- "@contember/database-migrations": "^1.3.0-alpha.7",
20
- "@contember/dic": "^1.3.0-alpha.7",
21
- "@contember/graphql-utils": "^1.3.0-alpha.7",
22
- "@contember/logger": "^1.3.0-alpha.7",
23
- "@contember/schema": "^1.3.0-alpha.7",
24
- "@contember/schema-utils": "^1.3.0-alpha.7",
25
- "@contember/typesafe": "^1.3.0-alpha.7",
16
+ "@contember/authorization": "1.3.0-beta.1",
17
+ "@contember/config-loader": "1.3.0-beta.1",
18
+ "@contember/database": "1.3.0-beta.1",
19
+ "@contember/database-migrations": "1.3.0-beta.1",
20
+ "@contember/dic": "1.3.0-beta.1",
21
+ "@contember/graphql-utils": "1.3.0-beta.1",
22
+ "@contember/logger": "1.3.0-beta.1",
23
+ "@contember/schema": "1.3.0-beta.1",
24
+ "@contember/schema-utils": "1.3.0-beta.1",
25
+ "@contember/typesafe": "1.3.0-beta.1",
26
26
  "@graphql-tools/utils": "^8.6.13",
27
27
  "graphql-tag": "^2.12.5",
28
28
  "jose": "^4.10",
@@ -32,7 +32,7 @@
32
32
  "otpauth": "^7.0.6"
33
33
  },
34
34
  "devDependencies": {
35
- "@contember/database-tester": "^1.3.0-alpha.7",
35
+ "@contember/database-tester": "1.3.0-beta.1",
36
36
  "@graphql-codegen/cli": "^2.6.2",
37
37
  "@graphql-codegen/typescript": "^2.5.1",
38
38
  "@graphql-codegen/typescript-operations": "^2.4.2",
@@ -47,4 +47,4 @@
47
47
  "graphql": ">= 14.6.0",
48
48
  "pg": "^8.9.0"
49
49
  }
50
- }
50
+ }
@@ -4,9 +4,11 @@ import { Builder } from '@contember/dic'
4
4
  import {
5
5
  AclSchemaAccessNodeFactory,
6
6
  ApiKeyManager,
7
- ApiKeyService, AppleProvider,
7
+ ApiKeyService,
8
+ AppleProvider,
8
9
  DatabaseContext,
9
- DatabaseContextFactory, FacebookProvider,
10
+ DatabaseContextFactory,
11
+ FacebookProvider,
10
12
  Identity,
11
13
  IdentityFactory,
12
14
  IDPHandlerRegistry,
@@ -27,10 +29,12 @@ import {
27
29
  ProjectSchemaResolver,
28
30
  ProjectScopeFactory,
29
31
  Providers,
32
+ RolesManager,
30
33
  SecretsManager,
31
34
  SignInManager,
32
35
  SignUpManager,
33
36
  UserMailer,
37
+ PersonAccessManager,
34
38
  } from './model'
35
39
  import {
36
40
  AddIDPMutationResolver,
@@ -41,6 +45,7 @@ import {
41
45
  DisableApiKeyMutationResolver,
42
46
  DisableIDPMutationResolver,
43
47
  EnableIDPMutationResolver,
48
+ IdentityGlobalRolesMutationResolver,
44
49
  IdentityTypeResolver,
45
50
  IDPMutationResolver,
46
51
  InviteMutationResolver,
@@ -69,6 +74,8 @@ import { IDPManager } from './model/service/idp/IDPManager'
69
74
  import { IDPQueryResolver } from './resolvers/query/IDPQueryResolver'
70
75
  import { UpdateIDPMutationResolver } from './resolvers/mutation/idp/UpdateIDPMutationResolver'
71
76
  import { TenantCredentials, TenantMigrationsRunner } from './migrations'
77
+ import { DisablePersonMutationResolver } from './resolvers/mutation/person/DisablePersonMutationResolver'
78
+ import { PersonManager } from './model/service/PersonManager'
72
79
 
73
80
  export interface TenantContainer {
74
81
  projectMemberManager: ProjectMemberManager
@@ -153,6 +160,10 @@ export class TenantContainerFactory {
153
160
  new SecretsManager(providers))
154
161
  .addService('projectManager', ({ secretManager, apiKeyService }) =>
155
162
  new ProjectManager(secretManager, args.projectInitializer, apiKeyService))
163
+ .addService('personAccessManager', ({ apiKeyManager }) =>
164
+ new PersonAccessManager(apiKeyManager))
165
+ .addService('personManager', () =>
166
+ new PersonManager())
156
167
  .addService('passwordResetManager', ({ userMailer, projectManager }) =>
157
168
  new PasswordResetManager(userMailer, projectManager))
158
169
  .addService('idpRegistry', () => {
@@ -178,6 +189,8 @@ export class TenantContainerFactory {
178
189
  new OtpManager(otpAuthenticator))
179
190
  .addService('mailTemplateManager', () =>
180
191
  new MailTemplateManager())
192
+ .addService('rolesManager', () =>
193
+ new RolesManager())
181
194
 
182
195
  .addService('identityTypeResolver', ({ projectMemberManager, projectManager, permissionContextFactory }) =>
183
196
  new IdentityTypeResolver(projectMemberManager, projectManager, permissionContextFactory))
@@ -231,10 +244,14 @@ export class TenantContainerFactory {
231
244
  new EnableIDPMutationResolver(idpManager))
232
245
  .addService('createProjectMutationResolver', ({ projectManager }) =>
233
246
  new CreateProjectMutationResolver(projectManager))
247
+ .addService('disablePersonMutationResolver', ({ personAccessManager, personManager }) =>
248
+ new DisablePersonMutationResolver(personAccessManager, personManager))
234
249
  .addService('updateProjectMutationResolver', ({ projectManager }) =>
235
250
  new UpdateProjectMutationResolver(projectManager))
236
251
  .addService('setProjectSecretMutationResolver', ({ projectManager, secretManager }) =>
237
252
  new SetProjectSecretMutationResolver(projectManager, secretManager))
253
+ .addService('identityGlobalRolesMutationResolver', ({ rolesManager }) =>
254
+ new IdentityGlobalRolesMutationResolver(rolesManager))
238
255
  .addService('resolverContextFactory', ({ permissionContextFactory }) =>
239
256
  new TenantResolverContextFactory(permissionContextFactory))
240
257
  .addService('resolvers', container =>
@@ -0,0 +1,28 @@
1
+ import { MigrationBuilder } from '@contember/database-migrations'
2
+
3
+ const sql = `
4
+ WITH
5
+ normalized AS (
6
+ SELECT id, email, REGEXP_REPLACE(LOWER(email), '\\s', '', 'g') AS normalized
7
+ FROM person
8
+ ),
9
+ not_exist AS (
10
+ SELECT *
11
+ FROM normalized
12
+ WHERE NOT EXISTS(SELECT FROM person WHERE person.email = normalized.normalized)
13
+ ),
14
+ uniq AS (
15
+ SELECT DISTINCT ON (normalized) *
16
+ FROM not_exist
17
+ ORDER BY normalized
18
+ )
19
+ UPDATE person
20
+ SET email = uniq.normalized
21
+ FROM uniq
22
+ WHERE person.id = uniq.id;
23
+ `
24
+
25
+ export default async function (builder: MigrationBuilder) {
26
+ builder.sql(sql)
27
+ }
28
+
@@ -0,0 +1,10 @@
1
+ import { MigrationBuilder } from '@contember/database-migrations'
2
+
3
+ const sql = `
4
+ ALTER TABLE person
5
+ ADD disabled_at TIMESTAMP WITH TIME ZONE;
6
+ `
7
+
8
+ export default async function (builder: MigrationBuilder) {
9
+ builder.sql(sql)
10
+ }
@@ -33,6 +33,8 @@ import _20220707135000personemailoptuniq from './2022-07-07-135000-person-email-
33
33
  import _20220707141000persondisplayname from './2022-07-07-141000-person-display-name'
34
34
  import _20220714145000personloginoptions from './2022-07-14-145000-person-login-options'
35
35
  import _20221108projectupdatenotification from './2022-11-08-project-update-notification'
36
+ import _20230120135500personemailnormalize from './2023-01-20-135500-person-email-normalize'
37
+ import _20230603104000persondisabled from './2023-06-03-104000-person-disabled'
36
38
  import snapshot from './snapshot'
37
39
  import { computeTokenHash, Providers } from '../model'
38
40
  import { Logger } from '@contember/logger'
@@ -78,6 +80,8 @@ const migrations = {
78
80
  '2022-07-07-141000-person-display-name': _20220707141000persondisplayname,
79
81
  '2022-07-14-145000-person-login-options': _20220714145000personloginoptions,
80
82
  '2022-11-08-project-update-notification': _20221108projectupdatenotification,
83
+ '2023-01-20-135500-person-email-normalize': _20230120135500personemailnormalize,
84
+ '2023-06-03-104000-person-disabled': _20230603104000persondisabled,
81
85
  }
82
86
 
83
87
  export class TenantMigrationsRunner {
@@ -74,6 +74,7 @@ CREATE TABLE "person" (
74
74
  "otp_activated_at" timestamp with time zone,
75
75
  "name" "text",
76
76
  "idp_only" boolean DEFAULT false NOT NULL,
77
+ "disabled_at" timestamp with time zone,
77
78
  CONSTRAINT "idp_only_no_email" CHECK ((("idp_only" = false) OR (("idp_only" = true) AND ("email" IS NULL))))
78
79
  );
79
80
  CREATE TABLE "person_identity_provider" (
@@ -6,23 +6,33 @@ import { DirectPermissionsAccessNode } from './DirectPermissionsAccessNode'
6
6
 
7
7
  export class AclSchemaAccessNodeFactory {
8
8
  create(schema: Acl.Schema, memberships: readonly Acl.Membership[]): AccessNode {
9
- const membershipMatcher = new MembershipMatcher(memberships.map(it => ({
10
- ...it,
11
- matchRule: schema.roles[it.role]?.tenant?.manage ?? {},
12
- })))
13
9
 
14
- const verifier = ({ memberships }: { memberships: readonly Acl.Membership[] }) => {
15
- return memberships.every(it => membershipMatcher.matches(it))
10
+ const createVerifier = (getRule: (permissions: Acl.TenantPermissions) => Acl.MembershipMatchRule) => {
11
+ const membershipMatcher = new MembershipMatcher(memberships.map(it => ({
12
+ ...it,
13
+ matchRule: getRule(schema.roles[it.role]?.tenant ?? {}),
14
+ })))
15
+
16
+ return ({ memberships }: { memberships: readonly Acl.Membership[] }) => {
17
+ return memberships.every(it => membershipMatcher.matches(it))
18
+ }
16
19
  }
20
+
17
21
  const membershipRoles = memberships.map(it => schema.roles[it.role]).filter(it => !!it)
18
22
  const node = new DirectPermissionsAccessNode()
23
+
19
24
  if (membershipRoles.some(it => it.tenant?.invite)) {
25
+ const verifier = createVerifier(it => it.invite && it.invite !== true ? it.invite : it.manage ?? {})
20
26
  node.allow(PermissionActions.PERSON_INVITE([]), verifier)
21
27
  }
28
+
22
29
  if (membershipRoles.some(it => it.tenant?.unmanagedInvite)) {
30
+ const verifier = createVerifier(it => it.unmanagedInvite && it.unmanagedInvite !== true ? it.unmanagedInvite : it.manage ?? {})
23
31
  node.allow(PermissionActions.PERSON_INVITE_UNMANAGED([]), verifier)
24
32
  }
33
+
25
34
  if (membershipRoles.some(it => it.tenant?.manage)) {
35
+ const verifier = createVerifier(it => it.manage ?? {})
26
36
  node.allow(PermissionActions.PROJECT_ADD_MEMBER([]), verifier)
27
37
  node.allow(PermissionActions.PROJECT_VIEW_MEMBER([]), verifier)
28
38
  node.allow(PermissionActions.PROJECT_UPDATE_MEMBER([]), verifier)
@@ -13,6 +13,10 @@ namespace PermissionActions {
13
13
  }
14
14
 
15
15
  export const IDENTITY_VIEW_PERMISSIONS = Authorizator.createAction(Resources.identity, 'viewPermissions')
16
+ export const IDENTITY_ADD_GLOBAL_ROLES = (roles?: readonly string[]) => Authorizator.createAction(Resources.identity, 'addGlobalRoles', { roles })
17
+ export const IDENTITY_REMOVE_GLOBAL_ROLES = (roles?: readonly string[]) => Authorizator.createAction(Resources.identity, 'removeGlobalRoles', { roles })
18
+
19
+ export const PERSON_DISABLE = (roles?: readonly string[]) => Authorizator.createAction(Resources.person, 'disable', { roles })
16
20
 
17
21
  export const PERSON_SIGN_IN = Authorizator.createAction(Resources.person, 'signIn')
18
22
  export const PERSON_SIGN_UP = (roles?: readonly string[]) => Authorizator.createAction(Resources.person, 'signUp', { roles })
@@ -39,6 +43,7 @@ namespace PermissionActions {
39
43
  export const PROJECT_REMOVE_MEMBER = (memberships: readonly Acl.Membership[]) => Authorizator.createAction(Resources.project, 'removeMember', { memberships })
40
44
  export const PROJECT_UPDATE_MEMBER = (memberships: readonly Acl.Membership[]) => Authorizator.createAction(Resources.project, 'updateMember', { memberships })
41
45
 
46
+
42
47
  export const API_KEY_CREATE = Authorizator.createAction(Resources.apiKey, 'create')
43
48
  export const API_KEY_CREATE_GLOBAL = (roles?: readonly string[]) => Authorizator.createAction(Resources.apiKey, 'createGlobal', { roles })
44
49
  export const API_KEY_DISABLE = Authorizator.createAction(Resources.apiKey, 'disable')
@@ -4,7 +4,7 @@ import { TenantRole } from './Roles'
4
4
 
5
5
  const allowedRoles = new Set<string>([TenantRole.LOGIN, TenantRole.PROJECT_ADMIN])
6
6
 
7
- const projectAdminCreateRolesVerifier = ({ roles }: {roles?: readonly string[]}) => {
7
+ const projectAdminAllowedInputRoles = ({ roles }: {roles?: readonly string[]}) => {
8
8
  return roles === undefined || roles.every(it => allowedRoles.has(it))
9
9
  }
10
10
 
@@ -34,17 +34,25 @@ class PermissionsFactory {
34
34
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PROJECT_VIEW)
35
35
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.API_KEY_CREATE)
36
36
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.API_KEY_DISABLE)
37
- permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.API_KEY_CREATE_GLOBAL(), projectAdminCreateRolesVerifier)
38
- permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PERSON_SIGN_UP(), projectAdminCreateRolesVerifier)
37
+ permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.API_KEY_CREATE_GLOBAL(), projectAdminAllowedInputRoles)
38
+
39
+ permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PERSON_SIGN_UP(), projectAdminAllowedInputRoles)
40
+ permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.IDENTITY_ADD_GLOBAL_ROLES(), projectAdminAllowedInputRoles)
41
+ permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.IDENTITY_REMOVE_GLOBAL_ROLES(), projectAdminAllowedInputRoles)
39
42
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PERSON_CREATE_SESSION_KEY(), projectAdminUseRolesVerifier)
43
+ permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PERSON_DISABLE(), projectAdminUseRolesVerifier)
44
+
40
45
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PROJECT_VIEW_MEMBER([]))
41
46
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PROJECT_ADD_MEMBER([]))
42
47
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PROJECT_UPDATE_MEMBER([]))
43
48
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PROJECT_REMOVE_MEMBER([]))
49
+
44
50
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PERSON_INVITE([]))
45
51
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.PERSON_INVITE_UNMANAGED([]))
52
+
46
53
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.MAIL_TEMPLATE_ADD)
47
54
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.MAIL_TEMPLATE_REMOVE)
55
+
48
56
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.IDP_ADD)
49
57
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.IDP_UPDATE)
50
58
  permissions.allow(TenantRole.PROJECT_ADMIN, PermissionActions.IDP_DISABLE)
@@ -0,0 +1,28 @@
1
+ import { Command } from '../Command'
2
+ import { UpdateBuilder } from '@contember/database'
3
+
4
+ export class PatchIdentityGlobalRoles implements Command<boolean> {
5
+ constructor(
6
+ private readonly id: string,
7
+ private readonly add: readonly string[],
8
+ private readonly remove: readonly string[],
9
+ ) {
10
+ }
11
+
12
+ public async execute({ db, providers }: Command.Args): Promise<boolean> {
13
+ const result = await UpdateBuilder.create()
14
+ .table('identity')
15
+ .where({
16
+ id: this.id,
17
+ })
18
+ .values({
19
+ roles: it => it.raw(`(
20
+ SELECT JSONB_AGG(DISTINCT out_role)
21
+ FROM JSONB_ARRAY_ELEMENTS_TEXT(roles || ?::jsonb) t(out_role)
22
+ WHERE NOT(out_role = ANY (?::text[]))
23
+ )`, JSON.stringify(this.add), this.remove),
24
+ })
25
+ .execute(db)
26
+ return result > 0
27
+ }
28
+ }
@@ -1 +1,2 @@
1
1
  export * from './CreateIdentityCommand'
2
+ export * from './PatchIdentityGlobalRoles'
@@ -4,7 +4,7 @@ import { Response, ResponseError, ResponseOk } from '../../utils/Response'
4
4
  import { SelectBuilder } from '@contember/database'
5
5
  import { MembershipInput } from './types'
6
6
 
7
- type CommandResponse = Response<undefined, AddProjectMemberCommandError>
7
+ type CommandResponse = Response<null, AddProjectMemberCommandError>
8
8
 
9
9
  export class AddProjectMemberCommand implements Command<CommandResponse> {
10
10
  constructor(
@@ -24,7 +24,7 @@ export class AddProjectMemberCommand implements Command<CommandResponse> {
24
24
  .getResult(db)
25
25
  if (result.length > 0) {
26
26
  return new ResponseError(
27
- AddProjectMemberCommandError.alreadyMember,
27
+ 'ALREADY_MEMBER',
28
28
  `This identity is already a project member. Use updateProjectMember mutation to change memberships.`,
29
29
  )
30
30
  }
@@ -33,16 +33,16 @@ export class AddProjectMemberCommand implements Command<CommandResponse> {
33
33
  for (const membership of this.memberships) {
34
34
  await bus.execute(new CreateOrUpdateProjectMembershipCommand(this.projectId, this.identityId, membership))
35
35
  }
36
- return new ResponseOk(undefined)
36
+ return new ResponseOk(null)
37
37
  } catch (e) {
38
38
  if (!(e instanceof Error)) {
39
39
  throw e
40
40
  }
41
41
  switch ((e as any).constraint) {
42
42
  case 'project_membership_project':
43
- return new ResponseError(AddProjectMemberCommandError.projectNotFound, 'Project not found')
43
+ return new ResponseError('PROJECT_NOT_FOUND', 'Project not found')
44
44
  case 'project_membership_identity':
45
- return new ResponseError(AddProjectMemberCommandError.identityNotfound, 'Identity not found')
45
+ return new ResponseError('IDENTITY_NOT_FOUND', 'Identity not found')
46
46
  default:
47
47
  throw e
48
48
  }
@@ -50,8 +50,7 @@ export class AddProjectMemberCommand implements Command<CommandResponse> {
50
50
  }
51
51
  }
52
52
 
53
- export enum AddProjectMemberCommandError {
54
- alreadyMember,
55
- projectNotFound,
56
- identityNotfound,
57
- }
53
+ export type AddProjectMemberCommandError =
54
+ | 'ALREADY_MEMBER'
55
+ | 'PROJECT_NOT_FOUND'
56
+ | 'IDENTITY_NOT_FOUND'
@@ -17,7 +17,7 @@ export class RemoveProjectMemberCommand implements Command<RemoveProjectMemberRe
17
17
  .execute(db)
18
18
 
19
19
  if (result === 0) {
20
- return new ResponseError(RemoveProjectMemberErrorCode.NotMember, 'Not a project member')
20
+ return new ResponseError('NOT_MEMBER', 'Not a project member')
21
21
  }
22
22
  return new ResponseOk(null)
23
23
  }
@@ -23,7 +23,7 @@ export class UpdateProjectMemberCommand implements Command<UpdateProjectMemberRe
23
23
  })
24
24
  .getResult(db)
25
25
  if (result.length === 0) {
26
- return new ResponseError(UpdateProjectMemberErrorCode.NotMember, 'Not a project member')
26
+ return new ResponseError('NOT_MEMBER', 'Not a project member')
27
27
  }
28
28
 
29
29
  try {
@@ -44,7 +44,7 @@ export class UpdateProjectMemberCommand implements Command<UpdateProjectMemberRe
44
44
  }
45
45
  switch ((e as any).constraint) {
46
46
  case 'project_membership_project':
47
- return new ResponseError(UpdateProjectMemberErrorCode.ProjectNotFound, 'Project not found')
47
+ return new ResponseError('PROJECT_NOT_FOUND', 'Project not found')
48
48
  default:
49
49
  throw e
50
50
  }
@@ -23,20 +23,14 @@ export class ResetPasswordCommand implements Command<ResetPasswordCommandRespons
23
23
  .getResult(db)
24
24
  )[0] || null
25
25
  if (!result) {
26
- return new ResponseError(ResetPasswordCommandErrorCode.TOKEN_NOT_FOUND, 'Token was not found')
26
+ return new ResponseError('TOKEN_NOT_FOUND', 'Token was not found')
27
27
  }
28
28
  if (result.used_at) {
29
- return new ResponseError(
30
- ResetPasswordCommandErrorCode.TOKEN_USED,
31
- `Token was used at ${result.used_at.toISOString()}`,
32
- )
29
+ return new ResponseError('TOKEN_USED', `Token was used at ${result.used_at.toISOString()}`)
33
30
  }
34
31
  const now = providers.now()
35
32
  if (result.expires_at < now) {
36
- return new ResponseError(
37
- ResetPasswordCommandErrorCode.TOKEN_EXPIRED,
38
- `Token expired at ${result.expires_at.toISOString()}`,
39
- )
33
+ return new ResponseError('TOKEN_EXPIRED', `Token expired at ${result.expires_at.toISOString()}`)
40
34
  }
41
35
  const count = await UpdateBuilder.create()
42
36
  .table('person_password_reset')
@@ -52,13 +46,12 @@ export class ResetPasswordCommand implements Command<ResetPasswordCommandRespons
52
46
 
53
47
  await bus.execute(new ChangePasswordCommand(result.person_id, this.password))
54
48
 
55
- return new ResponseOk(undefined)
49
+ return new ResponseOk(null)
56
50
  }
57
51
  }
58
- export enum ResetPasswordCommandErrorCode {
59
- TOKEN_NOT_FOUND = 'TOKEN_NOT_FOUND',
60
- TOKEN_USED = 'TOKEN_USED',
61
- TOKEN_EXPIRED = 'TOKEN_EXPIRED',
62
- }
52
+ export type ResetPasswordCommandErrorCode =
53
+ | 'TOKEN_NOT_FOUND'
54
+ | 'TOKEN_USED'
55
+ | 'TOKEN_EXPIRED'
63
56
 
64
- export type ResetPasswordCommandResponse = Response<undefined, ResetPasswordCommandErrorCode>
57
+ export type ResetPasswordCommandResponse = Response<null, ResetPasswordCommandErrorCode>
@@ -1,7 +1,8 @@
1
1
  import { Command } from '../Command'
2
2
  import { PersonRow } from '../../queries'
3
- import { InsertBuilder } from '@contember/database'
3
+ import { InsertBuilder, Literal } from '@contember/database'
4
4
  import { MaybePassword } from '../../dtos/Password'
5
+ import { normalizeEmail } from '../../utils/email'
5
6
 
6
7
  export class CreatePersonCommand implements Command<Omit<PersonRow, 'roles'>> {
7
8
  constructor(private readonly data: {
@@ -16,12 +17,14 @@ export class CreatePersonCommand implements Command<Omit<PersonRow, 'roles'>> {
16
17
  const id = providers.uuid()
17
18
 
18
19
  const password_hash = await this.data.password.getHash(providers)
20
+ const email = this.data.email ? normalizeEmail(this.data.email) : null
21
+ const name = this.data.name ?? this.data.email?.split('@')[0] ?? null
19
22
  await InsertBuilder.create()
20
23
  .into('person')
21
24
  .values({
22
25
  id: id,
23
- email: this.data.email ?? null,
24
- name: this.data.name ?? this.data.email?.split('@')[0] ?? null,
26
+ email,
27
+ name: name,
25
28
  password_hash,
26
29
  identity_id: this.data.identityId,
27
30
  idp_only: this.data.idpOnly ?? false,
@@ -30,11 +33,13 @@ export class CreatePersonCommand implements Command<Omit<PersonRow, 'roles'>> {
30
33
 
31
34
  return {
32
35
  id,
33
- email: this.data.email,
36
+ email,
37
+ name,
34
38
  password_hash, identity_id:
35
39
  this.data.identityId,
36
40
  otp_uri: null,
37
41
  otp_activated_at: null,
42
+ disabled_at: null,
38
43
  }
39
44
  }
40
45
  }
@@ -0,0 +1,18 @@
1
+ import { Command } from '../Command'
2
+ import { UpdateBuilder } from '@contember/database'
3
+
4
+ export class DisablePersonCommand implements Command<void> {
5
+ constructor(private readonly personId: string) {}
6
+
7
+ async execute({ db, providers }: Command.Args): Promise<void> {
8
+ await UpdateBuilder.create()
9
+ .table('person')
10
+ .values({
11
+ disabled_at: new Date(),
12
+ })
13
+ .where({
14
+ id: this.personId,
15
+ })
16
+ .execute(db)
17
+ }
18
+ }
@@ -0,0 +1,64 @@
1
+ import { DatabaseQuery, DatabaseQueryable, Operator, SelectBuilder } from '@contember/database'
2
+ import { ApiKey } from '../../type'
3
+ import { computeTokenHash } from '../../utils'
4
+
5
+ export class ApiKeyByIdQuery extends DatabaseQuery<null | ApiKeyRow> {
6
+ constructor(private readonly apiKeyId: string) {
7
+ super()
8
+ }
9
+
10
+ async fetch({ db }: DatabaseQueryable): Promise<null | ApiKeyRow> {
11
+ const rows = await apiKeyBaseQuery
12
+ .where(
13
+ where => where.compare(['api_key', 'id'], Operator.eq, this.apiKeyId),
14
+ )
15
+ .getResult(db)
16
+
17
+ return this.fetchOneOrNull(rows)
18
+ }
19
+ }
20
+
21
+ export class ApiKeyByTokenQuery extends DatabaseQuery<null | ApiKeyRow> {
22
+ constructor(private readonly token: string) {
23
+ super()
24
+ }
25
+
26
+ async fetch({ db }: DatabaseQueryable): Promise<null | ApiKeyRow> {
27
+ const tokenHash = computeTokenHash(this.token)
28
+ const rows = await apiKeyBaseQuery
29
+ .where({ token_hash: tokenHash })
30
+ .getResult(db)
31
+
32
+ return this.fetchOneOrNull(rows)
33
+ }
34
+ }
35
+
36
+ export type ApiKeyRow = {
37
+ readonly id: string
38
+ readonly type: ApiKey.Type
39
+ readonly identity_id: string
40
+ readonly disabled_at: Date | null
41
+ readonly expires_at: Date | null
42
+ readonly expiration: number | null
43
+ readonly roles: string[]
44
+ readonly person_id: string | null
45
+ }
46
+
47
+ const apiKeyBaseQuery = SelectBuilder.create<null | ApiKeyRow>()
48
+ .select(['api_key', 'id'])
49
+ .select(['api_key', 'type'])
50
+ .select(['api_key', 'identity_id'])
51
+ .select(['api_key', 'disabled_at'])
52
+ .select(['api_key', 'expires_at'])
53
+ .select(['identity', 'roles'])
54
+ .select(['api_key', 'expiration'])
55
+ .select(['person', 'id'], 'person_id')
56
+ .from('api_key')
57
+ .join('identity', 'identity', joinClause =>
58
+ joinClause.compareColumns(['api_key', 'identity_id'], Operator.eq, ['identity', 'id']),
59
+ )
60
+ .leftJoin(
61
+ 'person', 'person', on => on.compareColumns(
62
+ ['person', 'identity_id'], Operator.eq, ['identity', 'id'],
63
+ ),
64
+ )
@@ -1 +1 @@
1
- export * from './ApiKeyByTokenQuery'
1
+ export * from './ApiKeyQuery'
@@ -4,7 +4,7 @@ export type IdentityProviderRow = {
4
4
  id: string
5
5
  slug: string
6
6
  type: string
7
- disabledAt: Date | unknown
7
+ disabledAt: Date | null
8
8
  configuration: Record<string, unknown>
9
9
  autoSignUp: boolean
10
10
  exclusive: boolean
@@ -13,6 +13,6 @@ export type IdentityProviderRow = {
13
13
  export type IdentityProviderDto =
14
14
  & {
15
15
  id: string
16
- disabledAt: Date | unknown
16
+ disabledAt: Date | null
17
17
  }
18
18
  & IdentityProviderData
@@ -24,7 +24,7 @@ export class ProjectMembersQuery extends DatabaseQuery<ProjectMembersQueryResult
24
24
  ))
25
25
  .match(qb => {
26
26
  const { email, memberType } = this.projectMemberInput.filter ?? {}
27
- if (email && memberType === MemberType.ApiKey) {
27
+ if (email && memberType === 'API_KEY') {
28
28
  throw new ImplementationException()
29
29
  }
30
30
  const personQuery = SelectBuilder.create()
@@ -34,9 +34,9 @@ export class ProjectMembersQuery extends DatabaseQuery<ProjectMembersQueryResult
34
34
  return qb.where(it => it.exists(personQuery.where({ email })))
35
35
  }
36
36
  switch (memberType) {
37
- case MemberType.ApiKey:
37
+ case 'API_KEY':
38
38
  return qb.where(it => it.not(it => it.exists(personQuery)))
39
- case MemberType.Person:
39
+ case 'PERSON':
40
40
  return qb.where(it => it.exists(personQuery))
41
41
  }
42
42
  return qb