@stamhoofd/backend 2.119.0 → 2.120.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/package.json +32 -22
  2. package/src/audit-logs/ModelLogger.ts +4 -2
  3. package/src/boot.ts +32 -14
  4. package/src/crons/balance-emails.ts +4 -2
  5. package/src/crons/clearExcelCache.test.ts +8 -8
  6. package/src/crons/update-cached-balances.ts +40 -14
  7. package/src/debug.ts +3 -2
  8. package/src/decoders/StringArrayDecoder.ts +1 -1
  9. package/src/decoders/StringNullableDecoder.ts +1 -1
  10. package/src/email-recipient-loaders/documents.ts +2 -1
  11. package/src/email-recipient-loaders/members.ts +2 -1
  12. package/src/email-recipient-loaders/orders.ts +2 -1
  13. package/src/email-recipient-loaders/payments.ts +6 -3
  14. package/src/email-recipient-loaders/receivable-balances.ts +2 -1
  15. package/src/email-recipient-loaders/registrations.ts +2 -1
  16. package/src/email-replacements/getEmailReplacementsForPayment.ts +2 -1
  17. package/src/endpoints/admin/members/ChargeMembersEndpoint.ts +3 -2
  18. package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +2 -1
  19. package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +2 -1
  20. package/src/endpoints/admin/organizations/ChargeOrganizationsEndpoint.ts +3 -2
  21. package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +3 -2
  22. package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +6 -4
  23. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +4 -2
  24. package/src/endpoints/admin/registrations/ChargeRegistrationsEndpoint.ts +3 -2
  25. package/src/endpoints/auth/CreateAdminEndpoint.ts +5 -3
  26. package/src/endpoints/auth/CreateTokenEndpoint.ts +4 -2
  27. package/src/endpoints/auth/DeleteTokenEndpoint.ts +2 -1
  28. package/src/endpoints/auth/DeleteUserEndpoint.ts +2 -1
  29. package/src/endpoints/auth/ForgotPasswordEndpoint.ts +3 -2
  30. package/src/endpoints/auth/GetOtherUserEndpoint.ts +3 -2
  31. package/src/endpoints/auth/GetUserEndpoint.ts +3 -2
  32. package/src/endpoints/auth/OpenIDConnectAuthTokenEndpoint.ts +2 -1
  33. package/src/endpoints/auth/OpenIDConnectCallbackEndpoint.ts +4 -2
  34. package/src/endpoints/auth/OpenIDConnectStartEndpoint.ts +3 -2
  35. package/src/endpoints/auth/PatchUserEndpoint.ts +6 -3
  36. package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +3 -2
  37. package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +3 -2
  38. package/src/endpoints/auth/SignupEndpoint.ts +3 -2
  39. package/src/endpoints/auth/VerifyEmailEndpoint.ts +3 -2
  40. package/src/endpoints/frontend/FrontendEnvironmentEndpoint.ts +3 -2
  41. package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +8 -5
  42. package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +5 -3
  43. package/src/endpoints/global/audit-logs/GetAuditLogsEndpoint.ts +7 -4
  44. package/src/endpoints/global/billing/ActivatePackagesEndpoint.ts +6 -4
  45. package/src/endpoints/global/billing/DeactivatePackageEndpoint.ts +2 -1
  46. package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +4 -2
  47. package/src/endpoints/global/email/CreateEmailEndpoint.ts +5 -3
  48. package/src/endpoints/global/email/GetAdminEmailsEndpoint.test.ts +2 -1
  49. package/src/endpoints/global/email/GetAdminEmailsEndpoint.ts +22 -19
  50. package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +4 -2
  51. package/src/endpoints/global/email/GetEmailEndpoint.ts +3 -2
  52. package/src/endpoints/global/email/GetUserEmailsEndpoint.test.ts +2 -1
  53. package/src/endpoints/global/email/GetUserEmailsEndpoint.ts +7 -4
  54. package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +4 -2
  55. package/src/endpoints/global/email/PatchEmailEndpoint.test.ts +11 -11
  56. package/src/endpoints/global/email/PatchEmailEndpoint.ts +6 -3
  57. package/src/endpoints/global/email-recipients/GetEmailRecipientsCountEndpoint.ts +3 -2
  58. package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.test.ts +2 -1
  59. package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.ts +7 -4
  60. package/src/endpoints/global/email-recipients/RetryEmailRecipientEndpoint.ts +4 -2
  61. package/src/endpoints/global/email-recipients/helpers/validateEmailRecipientFilter.ts +2 -1
  62. package/src/endpoints/global/events/GetEventNotificationsCountEndpoint.ts +3 -2
  63. package/src/endpoints/global/events/GetEventNotificationsEndpoint.ts +8 -5
  64. package/src/endpoints/global/events/GetEventsEndpoint.ts +7 -4
  65. package/src/endpoints/global/events/PatchEventNotificationsEndpoint.test.ts +4 -2
  66. package/src/endpoints/global/events/PatchEventNotificationsEndpoint.ts +4 -2
  67. package/src/endpoints/global/events/PatchEventsEndpoint.test.ts +4 -2
  68. package/src/endpoints/global/events/PatchEventsEndpoint.ts +4 -2
  69. package/src/endpoints/global/files/ExportToExcelEndpoint.ts +7 -4
  70. package/src/endpoints/global/files/GetFileCache.ts +5 -3
  71. package/src/endpoints/global/files/UploadFile.ts +9 -3
  72. package/src/endpoints/global/files/UploadImage.ts +4 -2
  73. package/src/endpoints/global/groups/GetGroupsEndpoint.test.ts +4 -2
  74. package/src/endpoints/global/groups/GetGroupsEndpoint.ts +7 -4
  75. package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +5 -3
  76. package/src/endpoints/global/members/GetMembersCountEndpoint.ts +3 -2
  77. package/src/endpoints/global/members/GetMembersEndpoint.test.ts +4 -2
  78. package/src/endpoints/global/members/GetMembersEndpoint.ts +8 -6
  79. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +257 -6
  80. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +114 -59
  81. package/src/endpoints/global/members/helpers/validateGroupFilter.ts +2 -1
  82. package/src/endpoints/global/members/shouldCheckIfMemberIsDuplicate.ts +3 -2
  83. package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +2 -1
  84. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +3 -2
  85. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +3 -2
  86. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +5 -3
  87. package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +5 -3
  88. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +8 -5
  89. package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +4 -2
  90. package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +2 -1
  91. package/src/endpoints/global/platform/GetPlatformEndpoint.ts +3 -2
  92. package/src/endpoints/global/platform/PatchPlatformEnpoint.test.ts +3 -2
  93. package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +6 -3
  94. package/src/endpoints/global/platform-memberships/GetPlatformMembershipsCountEndpoint.ts +47 -0
  95. package/src/endpoints/global/platform-memberships/GetPlatformMembershipsEndpoint.ts +206 -0
  96. package/src/endpoints/global/registration/GetRegistrationsCountEndpoint.ts +3 -2
  97. package/src/endpoints/global/registration/GetRegistrationsEndpoint.test.ts +2 -1
  98. package/src/endpoints/global/registration/GetRegistrationsEndpoint.ts +8 -5
  99. package/src/endpoints/global/registration/GetUserDetailedPayableBalanceEndpoint.ts +4 -2
  100. package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +4 -2
  101. package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +3 -2
  102. package/src/endpoints/global/registration/GetUserPayableBalanceEndpoint.ts +2 -1
  103. package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +5 -3
  104. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +9 -5
  105. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +50 -49
  106. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +7 -4
  107. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +7 -4
  108. package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +4 -2
  109. package/src/endpoints/global/sso/GetSSOEndpoint.ts +4 -2
  110. package/src/endpoints/global/sso/SetSSOEndpoint.ts +3 -2
  111. package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +4 -2
  112. package/src/endpoints/global/webshops/GetWebshopsCountEndpoint.ts +43 -0
  113. package/src/endpoints/global/webshops/GetWebshopsEndpoint.test.ts +808 -0
  114. package/src/endpoints/global/webshops/GetWebshopsEndpoint.ts +221 -0
  115. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemEndpoint.ts +3 -2
  116. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsCountEndpoint.ts +3 -2
  117. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsEndpoint.ts +5 -3
  118. package/src/endpoints/organization/dashboard/balance-items/PatchBalanceItemsEndpoint.ts +4 -2
  119. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceEndpoint.ts +4 -2
  120. package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableBalanceEndpoint.ts +4 -2
  121. package/src/endpoints/organization/dashboard/billing/GetPackagesEndpoint.ts +2 -1
  122. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +2 -1
  123. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesCountEndpoint.ts +3 -2
  124. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +7 -4
  125. package/src/endpoints/organization/dashboard/documents/GetDocumentsCountEndpoint.ts +3 -2
  126. package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +7 -4
  127. package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +4 -2
  128. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.test.ts +4 -2
  129. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.ts +4 -2
  130. package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +2 -1
  131. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.test.ts +36 -1
  132. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +13 -4
  133. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.test.ts +4 -2
  134. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +4 -2
  135. package/src/endpoints/organization/dashboard/invoices/GetInvoicesCountEndpoint.ts +3 -2
  136. package/src/endpoints/organization/dashboard/invoices/GetInvoicesEndpoint.ts +5 -3
  137. package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.ts +5 -3
  138. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +4 -2
  139. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +6 -3
  140. package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +4 -2
  141. package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +2 -1
  142. package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +2 -1
  143. package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +4 -2
  144. package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +3 -2
  145. package/src/endpoints/organization/dashboard/organization/GetUitpasClientIdEndpoint.ts +2 -1
  146. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +5 -3
  147. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +6 -3
  148. package/src/endpoints/organization/dashboard/organization/SearchUitpasOrganizersEndpoint.ts +5 -3
  149. package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +8 -6
  150. package/src/endpoints/organization/dashboard/organization/SetUitpasClientCredentialsEndpoint.ts +3 -2
  151. package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +2 -1
  152. package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +3 -2
  153. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +6 -4
  154. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +5 -3
  155. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint.ts +2 -1
  156. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesCountEndpoint.ts +3 -2
  157. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +5 -3
  158. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.test.ts +2 -1
  159. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +7 -4
  160. package/src/endpoints/organization/dashboard/registration-periods/MoveRegistrationPeriods.test.ts +4 -2
  161. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.test.ts +4 -2
  162. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +6 -3
  163. package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +6 -3
  164. package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +3 -2
  165. package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +2 -1
  166. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +4 -2
  167. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +2 -1
  168. package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +4 -2
  169. package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +2 -1
  170. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +3 -2
  171. package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +2 -1
  172. package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +3 -2
  173. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +2 -1
  174. package/src/endpoints/organization/dashboard/users/PatchApiUserEndpoint.ts +4 -2
  175. package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +3 -2
  176. package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +2 -1
  177. package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +4 -2
  178. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersCountEndpoint.ts +3 -2
  179. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +7 -4
  180. package/src/endpoints/organization/dashboard/webshops/{GetWebshopTicketsCountEndpoint → GetWebshopTicketsCountEndpoint.ts} +7 -7
  181. package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +9 -6
  182. package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +4 -2
  183. package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +4 -2
  184. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +4 -3
  185. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +4 -2
  186. package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +4 -2
  187. package/src/endpoints/organization/dashboard/webshops/SearchUitpasEventsEndpoint.ts +5 -3
  188. package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +2 -1
  189. package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +5 -3
  190. package/src/endpoints/organization/shared/GetDocumentHtml.ts +2 -1
  191. package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +3 -2
  192. package/src/endpoints/organization/shared/GetUitpasNumberDetailsEndpoint.ts +3 -2
  193. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +3 -2
  194. package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +3 -2
  195. package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +3 -2
  196. package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +3 -2
  197. package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +4 -2
  198. package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +3 -2
  199. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +7 -3
  200. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +3 -2
  201. package/src/endpoints/organization/webshops/RetrieveUitpasSocialTariffPriceEndpoint.ts +3 -2
  202. package/src/endpoints/system/HealthEndpoint.test.ts +44 -0
  203. package/src/endpoints/system/HealthEndpoint.ts +14 -6
  204. package/src/excel-loaders/balance-items.ts +4 -2
  205. package/src/excel-loaders/event-notifications.ts +4 -2
  206. package/src/excel-loaders/index.ts +1 -0
  207. package/src/excel-loaders/members.ts +4 -2
  208. package/src/excel-loaders/organizations.ts +3 -2
  209. package/src/excel-loaders/payments.ts +4 -2
  210. package/src/excel-loaders/platform-memberships.ts +202 -0
  211. package/src/excel-loaders/receivable-balances.ts +4 -2
  212. package/src/excel-loaders/registrations.ts +4 -2
  213. package/src/helpers/AddressValidator.test.ts +2 -1
  214. package/src/helpers/AddressValidator.ts +7 -4
  215. package/src/helpers/AdminPermissionChecker.ts +190 -92
  216. package/src/helpers/AuthenticatedStructures.ts +4 -2
  217. package/src/helpers/BuckarooHelper.ts +2 -1
  218. package/src/helpers/Context.ts +4 -2
  219. package/src/helpers/CookieHelper.ts +2 -2
  220. package/src/helpers/FileCache.ts +2 -2
  221. package/src/helpers/ForwardHandler.ts +2 -1
  222. package/src/helpers/GlobalHelper.ts +2 -0
  223. package/src/helpers/GroupBuilder.ts +2 -1
  224. package/src/helpers/GroupedThrottledQueue.test.ts +19 -19
  225. package/src/helpers/LimitedFilteredRequestHelper.ts +1 -1
  226. package/src/helpers/MemberCharger.ts +2 -1
  227. package/src/helpers/MemberUserSyncer.ts +6 -3
  228. package/src/helpers/OrganizationCharger.ts +2 -1
  229. package/src/helpers/PeriodHelper.ts +2 -1
  230. package/src/helpers/SQLTranslatedString.ts +3 -2
  231. package/src/helpers/ServiceFeeHelper.ts +1 -1
  232. package/src/helpers/SetupStepUpdater.ts +5 -4
  233. package/src/helpers/StripeHelper.ts +3 -2
  234. package/src/helpers/TagHelper.test.ts +5 -5
  235. package/src/helpers/TagHelper.ts +2 -1
  236. package/src/helpers/TemporaryMemberAccess.ts +2 -1
  237. package/src/helpers/ThrottledQueue.test.ts +20 -20
  238. package/src/helpers/ViesHelper.ts +4 -3
  239. package/src/helpers/XlsxTransformerColumnHelper.ts +4 -2
  240. package/src/helpers/email-html-helpers.ts +3 -2
  241. package/src/helpers/fetchToAsyncIterator.ts +1 -1
  242. package/src/helpers/outstandingBalanceJoin.ts +2 -1
  243. package/src/helpers/updateMemberDetailsUitpasNumber.ts +4 -3
  244. package/src/middleware/ContextMiddleware.ts +1 -1
  245. package/src/migrate.ts +21 -4
  246. package/src/seeds/0000000003-default-email-templates.ts +1 -1
  247. package/src/seeds/0000000004-single-organization.ts +2 -1
  248. package/src/seeds/1752848561-groups-registration-periods.ts +2 -1
  249. package/src/seeds/1754560914-groups-prices.test.ts +2 -1
  250. package/src/seeds/1754560914-groups-prices.ts +2 -1
  251. package/src/seeds/1755876819-remove-duplicate-members.ts +2 -1
  252. package/src/seeds/1765896674-document-update-year.test.ts +2 -1
  253. package/src/seeds/1773754928-force-save-members.ts +15 -0
  254. package/src/services/AuditLogService.ts +3 -2
  255. package/src/services/BalanceItemPaymentService.ts +2 -2
  256. package/src/services/BalanceItemService.ts +2 -1
  257. package/src/services/BootChecksService.test.ts +33 -0
  258. package/src/services/BootChecksService.ts +21 -0
  259. package/src/services/DatabaseCollationService.test.ts +18 -0
  260. package/src/services/DatabaseCollationService.ts +81 -0
  261. package/src/services/DocumentService.ts +1 -1
  262. package/src/services/EventNotificationService.ts +2 -1
  263. package/src/services/FileSignService.ts +1 -1
  264. package/src/services/MemberNumberService.ts +3 -1
  265. package/src/services/MemberRecordStore.ts +28 -19
  266. package/src/services/PaymentReallocationService.test.ts +2 -1
  267. package/src/services/PaymentReallocationService.ts +2 -1
  268. package/src/services/PaymentService.ts +5 -3
  269. package/src/services/RegistrationService.ts +65 -3
  270. package/src/services/SSOService.ts +8 -4
  271. package/src/services/STPackageService.ts +5 -3
  272. package/src/services/StartupHealthService.ts +15 -0
  273. package/src/services/uitpas/UitpasService.ts +6 -3
  274. package/src/sql-filters/audit-logs.ts +2 -1
  275. package/src/sql-filters/balance-item-payments.ts +2 -1
  276. package/src/sql-filters/balance-items.ts +2 -1
  277. package/src/sql-filters/base-registration-filter-compilers.ts +4 -2
  278. package/src/sql-filters/document-templates.ts +2 -1
  279. package/src/sql-filters/documents.ts +2 -1
  280. package/src/sql-filters/email-recipients.ts +2 -1
  281. package/src/sql-filters/emails.ts +2 -1
  282. package/src/sql-filters/event-notifications.ts +2 -1
  283. package/src/sql-filters/events.ts +2 -1
  284. package/src/sql-filters/groups.ts +2 -1
  285. package/src/sql-filters/invoiced-balance-items.ts +2 -1
  286. package/src/sql-filters/invoices.ts +2 -1
  287. package/src/sql-filters/member-responsibility-records.ts +2 -1
  288. package/src/sql-filters/members.ts +2 -1
  289. package/src/sql-filters/orders.ts +2 -1
  290. package/src/sql-filters/organization-registration-periods.ts +2 -1
  291. package/src/sql-filters/organizations.ts +2 -1
  292. package/src/sql-filters/payments.ts +2 -1
  293. package/src/sql-filters/platform-memberships.ts +67 -0
  294. package/src/sql-filters/receivable-balances.ts +2 -1
  295. package/src/sql-filters/registration-periods.ts +2 -1
  296. package/src/sql-filters/registrations.ts +2 -1
  297. package/src/sql-filters/tickets.ts +2 -1
  298. package/src/sql-filters/users.ts +2 -1
  299. package/src/sql-filters/webshops.ts +38 -0
  300. package/src/sql-sorters/audit-logs.ts +3 -2
  301. package/src/sql-sorters/balance-items.ts +3 -2
  302. package/src/sql-sorters/document-templates.ts +3 -2
  303. package/src/sql-sorters/documents.ts +3 -2
  304. package/src/sql-sorters/email-recipients.ts +3 -2
  305. package/src/sql-sorters/emails.ts +3 -2
  306. package/src/sql-sorters/event-notifications.ts +3 -2
  307. package/src/sql-sorters/events.ts +3 -2
  308. package/src/sql-sorters/groups.ts +3 -2
  309. package/src/sql-sorters/invoices.ts +3 -2
  310. package/src/sql-sorters/members.ts +3 -2
  311. package/src/sql-sorters/orders.ts +3 -2
  312. package/src/sql-sorters/organization-registration-periods.ts +3 -2
  313. package/src/sql-sorters/organizations.ts +3 -2
  314. package/src/sql-sorters/payments.ts +3 -2
  315. package/src/sql-sorters/platform-memberships.ts +40 -0
  316. package/src/sql-sorters/receivable-balances.ts +3 -2
  317. package/src/sql-sorters/registration-periods.ts +3 -2
  318. package/src/sql-sorters/registrations.ts +3 -2
  319. package/src/sql-sorters/tickets.ts +3 -2
  320. package/src/sql-sorters/webshops.ts +40 -0
  321. package/tests/actions/patchOrganizationMember.ts +5 -4
  322. package/tests/actions/patchPaymentStatus.ts +2 -2
  323. package/tests/actions/patchUserMember.ts +6 -4
  324. package/tests/e2e/api-rate-limits.test.ts +4 -5
  325. package/tests/e2e/bundle-discounts.test.ts +3 -2
  326. package/tests/e2e/charge-members.test.ts +7 -5
  327. package/tests/e2e/documents.test.ts +3 -2
  328. package/tests/e2e/private-files.test.ts +11 -13
  329. package/tests/e2e/register.test.ts +6 -5
  330. package/tests/e2e/stock.test.ts +6 -8
  331. package/tests/e2e/tickets.test.ts +4 -2
  332. package/tests/helpers/StripeMocker.ts +3 -3
  333. package/tests/init/initAdmin.ts +4 -2
  334. package/tests/init/initBundleDiscount.ts +3 -2
  335. package/tests/init/initPayconiq.ts +1 -1
  336. package/tests/init/initPermissionRole.ts +4 -2
  337. package/tests/init/initPlatformRecordCategory.ts +1 -1
  338. package/tests/init/initStripe.ts +1 -1
  339. package/tests/vitest.global.setup.ts +26 -0
  340. package/tests/{jest.setup.ts → vitest.setup.ts} +4 -3
  341. package/tsconfig.build.json +17 -0
  342. package/tsconfig.json +10 -41
  343. package/tsconfig.test.json +17 -0
  344. package/vitest.config.js +13 -0
  345. package/eslint.config.mjs +0 -5
  346. package/jest.config.cjs +0 -27
  347. package/tests/jest.global.setup.ts +0 -33
  348. package/tests/toMatchMap.ts +0 -68
@@ -1,8 +1,11 @@
1
1
  import { Database } from '@simonbackx/simple-database';
2
- import { ArrayDecoder, AutoEncoder, Decoder, field, ObjectData, StringDecoder } from '@simonbackx/simple-encoding';
2
+ import type { Decoder } from '@simonbackx/simple-encoding';
3
+ import { ArrayDecoder, AutoEncoder, field, ObjectData, StringDecoder } from '@simonbackx/simple-encoding';
3
4
  import { SimpleError } from '@simonbackx/simple-errors';
4
5
  import { City, PostalCode, Street } from '@stamhoofd/models';
5
- import { Address, Country, ValidatedAddress } from '@stamhoofd/structures';
6
+ import type { Address } from '@stamhoofd/structures';
7
+ import { ValidatedAddress } from '@stamhoofd/structures';
8
+ import { Country } from '@stamhoofd/types/Country';
6
9
  import { sleep, StringCompare } from '@stamhoofd/utility';
7
10
  import axios from 'axios';
8
11
  import { v4 as uuidv4 } from 'uuid';
@@ -26,7 +29,7 @@ export class AddressValidatorStatic {
26
29
  }
27
30
 
28
31
  const numbers = stripped.slice(0, 4);
29
- if (!/[0-9]{4}/.test(numbers)) {
32
+ if (!/\d{4}/.test(numbers)) {
30
33
  throw new SimpleError({
31
34
  code: 'invalid_field',
32
35
  message: 'Invalid postal code format (NL)',
@@ -44,7 +47,7 @@ export class AddressValidatorStatic {
44
47
 
45
48
  if (postalCode.length == 0) {
46
49
  const numbers = address.city.substring(0, 4);
47
- if (!/[0-9]{4}/.test(numbers)) {
50
+ if (!/\d{4}/.test(numbers)) {
48
51
  postalCode = numbers;
49
52
  address.city = address.city.substring(4).trim();
50
53
  }
@@ -1,8 +1,12 @@
1
- import { AutoEncoderPatchType, PatchMap } from '@simonbackx/simple-encoding';
1
+ import type { AutoEncoderPatchType } from '@simonbackx/simple-encoding';
2
+ import { PatchMap } from '@simonbackx/simple-encoding';
2
3
  import { isSimpleError, isSimpleErrors, SimpleError } from '@simonbackx/simple-errors';
3
- import { BalanceItem, CachedBalance, Document, Email, EmailTemplate, Event, EventNotification, Group, Member, MemberPlatformMembership, MemberWithRegistrations, MemberWithUsers, MemberWithUsersAndRegistrations, MemberWithUsersRegistrationsAndGroups, Order, Organization, OrganizationRegistrationPeriod, Payment, Registration, User, Webshop } from '@stamhoofd/models';
4
- import { AccessRight, EmailTemplate as EmailTemplateStruct, EventPermissionChecker, FinancialSupportSettings, GroupCategory, GroupStatus, GroupType, MemberWithRegistrationsBlob, PermissionLevel, PermissionsResourceType, Platform as PlatformStruct, ReceivableBalanceType, RecordSettings, ResourcePermissions, UitpasNumberDetails, UitpasSocialTariff, UitpasSocialTariffStatus } from '@stamhoofd/structures';
4
+ import type { BalanceItem, Document, Email, EmailTemplate, MemberWithUsers, MemberWithUsersAndRegistrations, MemberWithUsersRegistrationsAndGroups, Order, OrganizationRegistrationPeriod, User } from '@stamhoofd/models';
5
+ import { CachedBalance, Event, EventNotification, Group, Member, MemberPlatformMembership, Organization, Payment, Registration, Webshop } from '@stamhoofd/models';
6
+ import type { GroupCategory, MemberWithRegistrationsBlob, Platform as PlatformStruct, RecordAnswer, RecordSettings, ResourcePermissions } from '@stamhoofd/structures';
7
+ import { AccessRight, EmailTemplate as EmailTemplateStruct, EventPermissionChecker, FinancialSupportSettings, GroupStatus, GroupType, PermissionLevel, PermissionsResourceType, ReceivableBalanceType, UitpasNumberDetails, UitpasSocialTariff, UitpasSocialTariffStatus } from '@stamhoofd/structures';
5
8
  import { Formatter } from '@stamhoofd/utility';
9
+ import type { RecordCacheEntry } from '../services/MemberRecordStore.js';
6
10
  import { MemberRecordStore } from '../services/MemberRecordStore.js';
7
11
  import { addTemporaryMemberAccess, hasTemporaryMemberAccess } from './TemporaryMemberAccess.js';
8
12
 
@@ -11,7 +15,7 @@ import { addTemporaryMemberAccess, hasTemporaryMemberAccess } from './TemporaryM
11
15
  * This helps when dependencies of permissions change, such as parent categories for groups
12
16
  */
13
17
  export class AdminPermissionChecker {
14
- organization: Organization | null;
18
+ readonly organization: Organization | null;
15
19
  user: User;
16
20
  /**
17
21
  * The member that is linked to this user = is this user
@@ -21,6 +25,7 @@ export class AdminPermissionChecker {
21
25
 
22
26
  organizationCache: Map<string, Organization | Promise<Organization | undefined>> = new Map();
23
27
  groupsCache: Map<string, Group | null | Promise<Group | null>> = new Map();
28
+ webshopsCache: Map<string, Webshop | null | Promise<Webshop | null>> = new Map();
24
29
 
25
30
  constructor(user: User, platform: PlatformStruct, organization?: Organization) {
26
31
  this.user = user;
@@ -74,7 +79,6 @@ export class AdminPermissionChecker {
74
79
  return await cache;
75
80
  }
76
81
 
77
- console.log('Get group', groupId);
78
82
  const promise = Group.select()
79
83
  .where('id', groupId)
80
84
  .first(false);
@@ -106,7 +110,6 @@ export class AdminPermissionChecker {
106
110
  }
107
111
 
108
112
  if (remainingIds.length > 0) {
109
- console.log('Get groups', remainingIds);
110
113
  const promise = Group.select()
111
114
  .where('id', remainingIds)
112
115
  .fetch();
@@ -125,6 +128,22 @@ export class AdminPermissionChecker {
125
128
  return cached;
126
129
  }
127
130
 
131
+ async getWebshop(webshopId: string): Promise<Webshop | null> {
132
+ const cache = this.webshopsCache.get(webshopId);
133
+ if (cache !== undefined) {
134
+ return await cache;
135
+ }
136
+
137
+ const promise = Webshop.select()
138
+ .where('id', webshopId)
139
+ .first(false);
140
+
141
+ this.webshopsCache.set(webshopId, promise);
142
+ const webshop = await promise;
143
+ this.webshopsCache.set(webshopId, webshop);
144
+ return webshop;
145
+ }
146
+
128
147
  cacheGroup(group: Group) {
129
148
  this.groupsCache.set(group.id, group);
130
149
  }
@@ -799,7 +818,7 @@ export class AdminPermissionChecker {
799
818
  }
800
819
 
801
820
  if (template.webshopId) {
802
- const webshop = await Webshop.getByID(template.webshopId);
821
+ const webshop = await this.getWebshop(template.webshopId);
803
822
  if (!webshop || !(await this.canAccessWebshop(webshop, PermissionLevel.Full))) {
804
823
  return false;
805
824
  }
@@ -808,7 +827,7 @@ export class AdminPermissionChecker {
808
827
  }
809
828
 
810
829
  if (template.groupId) {
811
- const group = await Group.getByID(template.groupId);
830
+ const group = await this.getGroup(template.groupId);
812
831
  if (!group || !(await this.canAccessGroup(group, PermissionLevel.Full))) {
813
832
  return false;
814
833
  }
@@ -1255,8 +1274,33 @@ export class AdminPermissionChecker {
1255
1274
  return false;
1256
1275
  }
1257
1276
 
1277
+ private async getSingleRecord(id: string): Promise<RecordCacheEntry | null> {
1278
+ // For userMode organization the records should not be cached
1279
+ if (STAMHOOFD.userMode === 'organization') {
1280
+ if (this.organization) {
1281
+ for (const recordCategory of this.organization.meta.recordsConfiguration.recordCategories) {
1282
+ for (const record of recordCategory.getAllRecords()) {
1283
+ if (id === record.id) {
1284
+ return {
1285
+ record,
1286
+ rootCategoryId: recordCategory.id,
1287
+ organizationId: this.organization.id
1288
+ }
1289
+ }
1290
+ }
1291
+ }
1292
+ return null;
1293
+ }
1294
+ // should never get called if no organization
1295
+ console.error('getRecord called without an organization');
1296
+ return null;
1297
+ }
1298
+
1299
+ return MemberRecordStore.getRecord(id);
1300
+ }
1301
+
1258
1302
  async canFilterMembersOnRecordId(recordId: string): Promise<{ canAccess: false; record: RecordSettings | null } | { canAccess: true; record: RecordSettings }> {
1259
- const record = await MemberRecordStore.getRecord(recordId);
1303
+ const record = await this.getSingleRecord(recordId);
1260
1304
  if (!record) {
1261
1305
  return {
1262
1306
  canAccess: false,
@@ -1322,87 +1366,142 @@ export class AdminPermissionChecker {
1322
1366
  };
1323
1367
  }
1324
1368
 
1325
- async checkRecordAccess(member: MemberWithUsersRegistrationsAndGroups, recordId: string, level: PermissionLevel = PermissionLevel.Read): Promise<{ canAccess: false; record: RecordSettings | null } | { canAccess: true; record: RecordSettings }> {
1326
- const record = await MemberRecordStore.getRecord(recordId);
1327
- if (!record) {
1328
- return {
1329
- canAccess: false,
1330
- record: null,
1331
- };
1369
+ private async loopRecordAnswerSettingsAccess<T extends RecordAnswer | AutoEncoderPatchType<RecordAnswer>>({member, level, recordAnswers, callback }:
1370
+ {
1371
+ member: MemberWithUsersRegistrationsAndGroups,
1372
+ level: PermissionLevel,
1373
+ recordAnswers: PatchMap<string, T | null | undefined> | Map<string, T>
1374
+ callback: (result: { canAccess: false; record: RecordSettings | null } | { canAccess: true; record: RecordSettings }, entry: [keys: string, value: T | null | undefined]) => void
1375
+ }): Promise<void>
1376
+ {
1377
+ if (STAMHOOFD.userMode !== 'platform') {
1378
+ let organization = this.organization;
1379
+
1380
+ if (!organization) {
1381
+ // normally this should not happen
1382
+ console.error('loopRecordAnswerSettingsAccess called without an organization set');
1383
+ let organizationId = member.organizationId;
1384
+
1385
+ if (!organizationId) {
1386
+ if (member.registrations.length === 0) {
1387
+ // no access to any records (theoretically a global admin should have access, but normally this case should not happen)
1388
+ for (const entry of recordAnswers.entries()) {
1389
+ callback({canAccess: false, record: null}, entry);
1390
+ }
1391
+ return;
1392
+ }
1393
+
1394
+ // in userMode organization a member can only be linked to 1 organization
1395
+ organizationId = member.registrations[0].organizationId;
1396
+ }
1397
+
1398
+ organization = await this.getOrganization(organizationId);
1399
+ }
1400
+
1401
+ const organizationId = organization.id;
1402
+ const map = new Map<string, RecordCacheEntry>()
1403
+
1404
+ // create map
1405
+ for (const category of organization.meta.recordsConfiguration.recordCategories) {
1406
+ const rootCategoryId = category.id;
1407
+
1408
+ for (const record of category.getAllRecords()) {
1409
+ map.set(record.id, {
1410
+ record,
1411
+ organizationId,
1412
+ rootCategoryId,
1413
+ });
1414
+ }
1415
+ }
1416
+
1417
+ for (const entry of recordAnswers.entries()) {
1418
+ const key = entry[0];
1419
+ const cachedRecordEntry = map.get(key);
1420
+ if (cachedRecordEntry) {
1421
+ const canAccess = await this.checkRecordAccess({
1422
+ member,
1423
+ record: cachedRecordEntry.record,
1424
+ organizationId: cachedRecordEntry.organizationId,
1425
+ rootCategoryId: cachedRecordEntry.rootCategoryId,
1426
+ level
1427
+ });
1428
+ callback({canAccess, record: cachedRecordEntry.record}, entry);
1429
+ } else {
1430
+ callback({canAccess: false, record: null}, entry);
1431
+ }
1432
+ }
1433
+
1434
+ return;
1332
1435
  }
1333
1436
 
1334
- if (!this.checkScope(record.organizationId)) {
1335
- return {
1336
- canAccess: false,
1337
- record: record.record,
1338
- };
1437
+ // userMode platform
1438
+ for (const entry of recordAnswers.entries()) {
1439
+ const key = entry[0];
1440
+ const cachedRecordEntry = await MemberRecordStore.getRecord(key);
1441
+ if (cachedRecordEntry) {
1442
+ const canAccess = await this.checkRecordAccess({
1443
+ member,
1444
+ record: cachedRecordEntry.record,
1445
+ organizationId: cachedRecordEntry.organizationId,
1446
+ rootCategoryId: cachedRecordEntry.rootCategoryId,
1447
+ level
1448
+ });
1449
+ callback({canAccess, record: cachedRecordEntry.record}, entry);
1450
+ } else {
1451
+ callback({canAccess: false, record: null}, entry);
1452
+ }
1453
+ }
1454
+ }
1455
+
1456
+ private async checkRecordAccess({member, level, record, organizationId, rootCategoryId}: {member: MemberWithUsersRegistrationsAndGroups, record: RecordSettings, organizationId: string | null, rootCategoryId: string, level: PermissionLevel}): Promise<boolean> {
1457
+ if (!this.checkScope(organizationId)) {
1458
+ return false
1339
1459
  }
1340
1460
 
1341
1461
  const isUserManager = this.isUserManager(member);
1342
1462
  if (isUserManager) {
1343
- if (record.record.checkPermissionForUserManager(level)) {
1344
- return {
1345
- canAccess: true,
1346
- record: record.record,
1347
- };
1463
+ if (record.checkPermissionForUserManager(level)) {
1464
+ return true;
1348
1465
  }
1349
1466
  }
1350
1467
 
1351
1468
  if (!this.user.permissions) {
1352
- return {
1353
- canAccess: false,
1354
- record: record.record,
1355
- };
1469
+ return false;
1356
1470
  }
1357
1471
 
1358
- if (record.organizationId) {
1359
- const organizationPermissions = await this.getOrganizationPermissions(record.organizationId);
1360
- if (organizationPermissions && organizationPermissions.hasResourceAccess(PermissionsResourceType.RecordCategories, record.rootCategoryId, level)) {
1361
- return {
1362
- canAccess: true,
1363
- record: record.record,
1364
- };
1472
+ if (organizationId) {
1473
+ const organizationPermissions = await this.getOrganizationPermissions(organizationId);
1474
+ if (organizationPermissions && organizationPermissions.hasResourceAccess(PermissionsResourceType.RecordCategories, rootCategoryId, level)) {
1475
+ return true;
1365
1476
  }
1366
1477
  }
1367
1478
  else {
1368
1479
  // Also check current scoped organization
1369
1480
  if (this.organization) {
1370
1481
  const organizationPermissions = await this.getOrganizationPermissions(this.organization.id);
1371
- if (organizationPermissions && organizationPermissions.hasResourceAccess(PermissionsResourceType.RecordCategories, record.rootCategoryId, level)) {
1372
- return {
1373
- canAccess: true,
1374
- record: record.record,
1375
- };
1482
+ if (organizationPermissions && organizationPermissions.hasResourceAccess(PermissionsResourceType.RecordCategories, rootCategoryId, level)) {
1483
+ return true;
1376
1484
  }
1377
1485
  }
1378
1486
  }
1379
1487
 
1380
1488
  // 2. Check platform permissions
1381
- if (this.platformPermissions?.hasResourceAccess(PermissionsResourceType.RecordCategories, record.rootCategoryId, level)) {
1382
- return {
1383
- canAccess: true,
1384
- record: record.record,
1385
- };
1489
+ if (this.platformPermissions?.hasResourceAccess(PermissionsResourceType.RecordCategories, rootCategoryId, level)) {
1490
+ return true;
1386
1491
  }
1387
1492
 
1388
1493
  // All member access, means also having access to record categories of non-registered members
1389
1494
  if (this.canAccessAllPlatformMembers(level)) { // needs to be full to also inherit record category access
1390
- return {
1391
- canAccess: true,
1392
- record: record.record,
1393
- };
1495
+ return true;
1394
1496
  }
1395
1497
 
1396
1498
  if (hasTemporaryMemberAccess(this.user.id, member.id, PermissionLevel.Full)) {
1397
1499
  // You created this member, so temporary can read all records in order to set the member up correctly
1398
- return {
1399
- canAccess: true,
1400
- record: record.record,
1401
- };
1500
+ return true;
1402
1501
  }
1403
1502
 
1404
1503
  // It is possible that this is a platform admin (or an admin that has access to multiple organizations), and inherits automatic permissions for tags. So'll need to loop all the organizations where this member has an active registration for
1405
- if (!record.organizationId && !this.organization) {
1504
+ if (!organizationId && !this.organization) {
1406
1505
  const checkedOrganizations = new Map<string, boolean>();
1407
1506
  for (const registration of member.registrations) {
1408
1507
  const permissions = checkedOrganizations.get(registration.organizationId);
@@ -1410,22 +1509,16 @@ export class AdminPermissionChecker {
1410
1509
  // Checking the organization permissions is faster (and less data lookups required), so we do that first before doing the more expensive registration access check
1411
1510
  if (permissions !== undefined) {
1412
1511
  if (permissions === true && await this.canAccessRegistration(registration, level)) {
1413
- return {
1414
- canAccess: true,
1415
- record: record.record,
1416
- };
1512
+ return true;
1417
1513
  }
1418
1514
  continue;
1419
1515
  }
1420
1516
 
1421
1517
  const organizationPermissions = await this.getOrganizationPermissions(registration.organizationId);
1422
- if (organizationPermissions && organizationPermissions.hasResourceAccess(PermissionsResourceType.RecordCategories, record.rootCategoryId, level)) {
1518
+ if (organizationPermissions && organizationPermissions.hasResourceAccess(PermissionsResourceType.RecordCategories, rootCategoryId, level)) {
1423
1519
  checkedOrganizations.set(registration.organizationId, true);
1424
1520
  if (await this.canAccessRegistration(registration, level)) {
1425
- return {
1426
- canAccess: true,
1427
- record: record.record,
1428
- };
1521
+ return true;
1429
1522
  }
1430
1523
  }
1431
1524
  else {
@@ -1434,10 +1527,7 @@ export class AdminPermissionChecker {
1434
1527
  }
1435
1528
  }
1436
1529
 
1437
- return {
1438
- canAccess: false,
1439
- record: record.record,
1440
- };
1530
+ return false;
1441
1531
  }
1442
1532
 
1443
1533
  /**
@@ -1458,18 +1548,22 @@ export class AdminPermissionChecker {
1458
1548
  async filterMemberData(member: MemberWithUsersRegistrationsAndGroups, data: MemberWithRegistrationsBlob, options?: { forAdminCartCalculation?: boolean }): Promise<MemberWithRegistrationsBlob> {
1459
1549
  const cloned = data.clone();
1460
1550
 
1461
- for (const [key, value] of cloned.details.recordAnswers.entries()) {
1462
- const { canAccess, record } = await this.checkRecordAccess(member, key, PermissionLevel.Read);
1463
- if (!canAccess) {
1464
- cloned.details.recordAnswers.delete(key);
1465
- }
1466
- else {
1467
- if (value) {
1468
- // Force update
1469
- value.settings = record;
1551
+ await this.loopRecordAnswerSettingsAccess({
1552
+ member,
1553
+ level: PermissionLevel.Read,
1554
+ recordAnswers: cloned.details.recordAnswers,
1555
+ callback: ({ canAccess, record }, [key, value]) => {
1556
+ if (!canAccess) {
1557
+ cloned.details.recordAnswers.delete(key);
1558
+ }
1559
+ else {
1560
+ if (value) {
1561
+ // Force update
1562
+ value.settings = record;
1563
+ }
1470
1564
  }
1471
1565
  }
1472
- }
1566
+ });
1473
1567
 
1474
1568
  const isUserManager = this.isUserManager(member);
1475
1569
  if (isUserManager) {
@@ -1597,21 +1691,25 @@ export class AdminPermissionChecker {
1597
1691
  });
1598
1692
  }
1599
1693
 
1600
- for (const [key, value] of data.details.recordAnswers.entries()) {
1601
- const { canAccess, record } = await this.checkRecordAccess(member, key, PermissionLevel.Write);
1602
- if (!canAccess) {
1603
- throw new SimpleError({
1604
- code: 'permission_denied',
1605
- message: $t('%Ff', { name: record?.name ?? 'deze vraag' }),
1606
- statusCode: 400,
1607
- });
1608
- }
1694
+ await this.loopRecordAnswerSettingsAccess({
1695
+ member,
1696
+ level: PermissionLevel.Write,
1697
+ recordAnswers: data.details.recordAnswers,
1698
+ callback: ({canAccess, record}, [_key, value]) => {
1699
+ if (!canAccess) {
1700
+ throw new SimpleError({
1701
+ code: 'permission_denied',
1702
+ message: $t('%Ff', { name: record?.name ?? 'deze vraag' }),
1703
+ statusCode: 400,
1704
+ });
1705
+ }
1609
1706
 
1610
- // Force set the value settings
1611
- if (value) {
1612
- value.settings = record;
1707
+ // Force set the value settings
1708
+ if (value) {
1709
+ value.settings = record;
1710
+ }
1613
1711
  }
1614
- }
1712
+ })
1615
1713
  }
1616
1714
 
1617
1715
  const isUserManager = this.isUserManager(member);
@@ -1,6 +1,8 @@
1
1
  import { SimpleError } from '@simonbackx/simple-errors';
2
- import { AuditLog, BalanceItem, CachedBalance, Document, Event, EventNotification, Group, Invoice, Member, MemberPlatformMembership, MemberResponsibilityRecord, MemberWithUsersRegistrationsAndGroups, Order, Organization, OrganizationRegistrationPeriod, Payment, Registration, RegistrationPeriod, Ticket, User, Webshop } from '@stamhoofd/models';
3
- import { AuditLogReplacement, AuditLogReplacementType, AuditLog as AuditLogStruct, DetailedReceivableBalance, Document as DocumentStruct, EventNotification as EventNotificationStruct, Event as EventStruct, GenericBalance, Group as GroupStruct, GroupType, InvoicedBalanceItem, InvoiceStruct, MemberPlatformMembership as MemberPlatformMembershipStruct, MembersBlob, MemberWithRegistrationsBlob, NamedObject, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, Organization as OrganizationStruct, PaymentCustomer, PaymentGeneral, PermissionLevel, Platform, PrivateOrder, PrivateWebshop, ReceivableBalanceObject, ReceivableBalanceObjectContact, ReceivableBalance as ReceivableBalanceStruct, ReceivableBalanceType, RegistrationsBlob, RegistrationWithMemberBlob, TicketPrivate, UserWithMembers, WebshopPreview, Webshop as WebshopStruct, BalanceItem as BalanceItemStruct } from '@stamhoofd/structures';
2
+ import type { AuditLog, Document, EventNotification, MemberWithUsersRegistrationsAndGroups, Order, Ticket} from '@stamhoofd/models';
3
+ import { BalanceItem, CachedBalance, Event, Group, Invoice, Member, MemberPlatformMembership, MemberResponsibilityRecord, Organization, OrganizationRegistrationPeriod, Payment, Registration, RegistrationPeriod, User, Webshop } from '@stamhoofd/models';
4
+ import type { PaymentGeneral} from '@stamhoofd/structures';
5
+ import { AuditLogReplacement, AuditLogReplacementType, AuditLog as AuditLogStruct, DetailedReceivableBalance, Document as DocumentStruct, EventNotification as EventNotificationStruct, Event as EventStruct, GenericBalance, Group as GroupStruct, GroupType, InvoicedBalanceItem, InvoiceStruct, MemberPlatformMembership as MemberPlatformMembershipStruct, MembersBlob, MemberWithRegistrationsBlob, NamedObject, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, Organization as OrganizationStruct, PaymentCustomer, PermissionLevel, Platform, PrivateOrder, PrivateWebshop, ReceivableBalanceObject, ReceivableBalanceObjectContact, ReceivableBalance as ReceivableBalanceStruct, ReceivableBalanceType, RegistrationsBlob, RegistrationWithMemberBlob, TicketPrivate, UserWithMembers, WebshopPreview, Webshop as WebshopStruct, BalanceItem as BalanceItemStruct } from '@stamhoofd/structures';
4
6
  import { Sorter } from '@stamhoofd/utility';
5
7
 
6
8
  import { SQL } from '@stamhoofd/sql';
@@ -1,5 +1,6 @@
1
1
  import { SimpleError } from '@simonbackx/simple-errors';
2
- import { BuckarooPayment, Payment } from '@stamhoofd/models';
2
+ import type { Payment } from '@stamhoofd/models';
3
+ import { BuckarooPayment } from '@stamhoofd/models';
3
4
  import { PaymentMethod, PaymentStatus } from '@stamhoofd/structures';
4
5
  import axios from 'axios';
5
6
  import crypto from 'crypto';
@@ -1,10 +1,12 @@
1
1
  import { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { isSimpleError, SimpleError } from '@simonbackx/simple-errors';
3
3
  import { I18n } from '@stamhoofd/backend-i18n';
4
- import { Organization, Platform, RateLimiter, Token, User } from '@stamhoofd/models';
4
+ import type { User } from '@stamhoofd/models';
5
+ import { Organization, Platform, RateLimiter, Token } from '@stamhoofd/models';
5
6
  import { AsyncLocalStorage } from 'async_hooks';
6
7
 
7
- import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
8
+ import type { Decoder} from '@simonbackx/simple-encoding';
9
+ import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
8
10
  import { ApiUserRateLimits } from '@stamhoofd/structures';
9
11
  import { AdminPermissionChecker } from './AdminPermissionChecker.js';
10
12
 
@@ -1,6 +1,6 @@
1
- import { Response } from '@simonbackx/simple-endpoints';
1
+ import type { Response } from '@simonbackx/simple-endpoints';
2
2
  import cookie from 'cookie';
3
- import http from 'http';
3
+ import type http from 'http';
4
4
 
5
5
  export type ObjectWithHeaders = {
6
6
  headers: http.IncomingHttpHeaders;
@@ -3,8 +3,8 @@ import { Formatter } from '@stamhoofd/utility';
3
3
  import basex from 'base-x';
4
4
  import crypto from 'crypto';
5
5
  import fs from 'node:fs';
6
- import { Writable } from 'node:stream';
7
- import { Readable } from 'stream';
6
+ import type { Writable } from 'node:stream';
7
+ import type { Readable } from 'stream';
8
8
 
9
9
  const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';
10
10
  const baseEncoder = basex(ALPHABET);
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
2
 
3
- import { Email, EmailAddress, EmailInterface, EmailInterfaceRecipient } from '@stamhoofd/email';
3
+ import type { EmailInterface, EmailInterfaceRecipient } from '@stamhoofd/email';
4
+ import { Email, EmailAddress } from '@stamhoofd/email';
4
5
  import { Organization, Platform } from '@stamhoofd/models';
5
6
  import { Formatter } from '@stamhoofd/utility';
6
7
  import { simpleParser } from 'mailparser';
@@ -9,7 +9,9 @@ export class GlobalHelper {
9
9
  await I18n.load();
10
10
  this.loadGlobalTranslateFunction();
11
11
  await FileSignService.load();
12
+
12
13
  MemberRecordStore.init();
14
+
13
15
  BalanceItemService.listen();
14
16
  }
15
17
 
@@ -1,5 +1,6 @@
1
1
  import { GroupCategory, GroupCategorySettings, GroupGenderType, GroupSettings, Group as GroupStruct, OrganizationGenderType, OrganizationType, OrganizationTypeHelper, TranslatedString, UmbrellaOrganization } from '@stamhoofd/structures';
2
- import { Group, Organization, OrganizationRegistrationPeriod, RegistrationPeriod } from '@stamhoofd/models';
2
+ import type { Organization} from '@stamhoofd/models';
3
+ import { Group, OrganizationRegistrationPeriod, RegistrationPeriod } from '@stamhoofd/models';
3
4
 
4
5
  export class GroupBuilder {
5
6
  organization: Organization;