@stamhoofd/backend 2.119.0 → 2.120.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 (348) hide show
  1. package/package.json +32 -22
  2. package/src/audit-logs/ModelLogger.ts +4 -2
  3. package/src/boot.ts +40 -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 +211 -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 +11 -9
  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 +7 -5
  206. package/src/excel-loaders/index.ts +1 -0
  207. package/src/excel-loaders/members.ts +6 -4
  208. package/src/excel-loaders/organizations.ts +8 -7
  209. package/src/excel-loaders/payments.ts +5 -3
  210. package/src/excel-loaders/platform-memberships.ts +262 -0
  211. package/src/excel-loaders/receivable-balances.ts +7 -5
  212. package/src/excel-loaders/registrations.ts +9 -7
  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 +5 -4
  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 +72 -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,9 +1,13 @@
1
- import { OneToManyRelation } from '@simonbackx/simple-database';
2
- import { AutoEncoderPatchType, ConvertArrayToPatchableArray, Decoder, isEmptyPatch, isPatchableArray, PatchableArray, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
3
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { OneToManyRelation } from '@simonbackx/simple-database';
2
+ import type { AutoEncoderPatchType, ConvertArrayToPatchableArray, Decoder, PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
3
+ import { isEmptyPatch, isPatchableArray, PatchableArray, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
4
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
5
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
4
6
  import { SimpleError } from '@simonbackx/simple-errors';
5
- import { AuditLog, BalanceItem, Document, Group, Member, MemberFactory, MemberPlatformMembership, MemberResponsibilityRecord, MemberWithRegistrations, MemberWithUsersAndRegistrations, MemberWithUsersRegistrationsAndGroups, mergeTwoMembers, Organization, Platform, RateLimiter, Registration, RegistrationPeriod, User } from '@stamhoofd/models';
6
- import { AuditLogReplacement, AuditLogReplacementType, AuditLogSource, AuditLogType, EmergencyContact, GroupType, MemberDetails, MemberResponsibility, MembersBlob, MemberWithRegistrationsBlob, Parent, PermissionLevel, PlatformMembershipTypeBehaviour, SetupStepType } from '@stamhoofd/structures';
7
+ import type { MemberWithUsersRegistrationsAndGroups, Registration } from '@stamhoofd/models';
8
+ import { AuditLog, BalanceItem, Document, Group, Member, MemberFactory, MemberPlatformMembership, MemberResponsibilityRecord, mergeTwoMembers, Organization, Platform, RateLimiter, RegistrationPeriod, User } from '@stamhoofd/models';
9
+ import type { MemberResponsibility, MembersBlob } from '@stamhoofd/structures';
10
+ import { AuditLogReplacement, AuditLogReplacementType, AuditLogSource, AuditLogType, EmergencyContact, GroupType, MemberDetails, MemberWithRegistrationsBlob, Parent, PermissionLevel, PlatformMembershipTypeBehaviour, SetupStepType } from '@stamhoofd/structures';
7
11
  import { Formatter } from '@stamhoofd/utility';
8
12
 
9
13
  import { Email } from '@stamhoofd/email';
@@ -56,6 +60,18 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
56
60
  return [false];
57
61
  }
58
62
 
63
+ private static throwDuplicateMemberNumberError(error: unknown): never {
64
+ if (error && typeof error === 'object' && 'code' in error && error.code === 'ER_DUP_ENTRY' && 'message' in error && typeof error.message === 'string' && error.message.includes('memberNumber')) {
65
+ throw new SimpleError({
66
+ code: 'invalid_field',
67
+ message: 'Member number already in use',
68
+ human: $t('%1Oe'),
69
+ field: 'details.memberNumber',
70
+ });
71
+ }
72
+ throw error;
73
+ }
74
+
59
75
  async handle(request: DecodedRequest<Params, Query, Body>) {
60
76
  const organization = await Context.setOptionalOrganizationScope();
61
77
  await Context.authenticate();
@@ -129,7 +145,12 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
129
145
  }
130
146
  }
131
147
 
132
- await member.save();
148
+ try {
149
+ await member.save();
150
+ }
151
+ catch (error) {
152
+ PatchOrganizationMembersEndpoint.throwDuplicateMemberNumberError(error);
153
+ }
133
154
  members.push(member);
134
155
  updateMembershipMemberIds.add(member.id);
135
156
 
@@ -148,9 +169,7 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
148
169
  throw Context.auth.memberNotFoundOrNoAccess();
149
170
  }
150
171
 
151
- if (!(await Context.auth.canAccessMember(member, PermissionLevel.Write))) {
152
- await PatchOrganizationMembersEndpoint.checkSecurityCode(member, securityCode, 'patch');
153
- }
172
+ await PatchOrganizationMembersEndpoint.checkCanAccessMember(member, securityCode, 'patch');
154
173
 
155
174
  patch = await Context.auth.filterMemberPatch(member, patch);
156
175
  const originalDetails = member.details.clone();
@@ -202,7 +221,12 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
202
221
  }
203
222
  }
204
223
 
205
- await member.save();
224
+ try {
225
+ await member.save();
226
+ }
227
+ catch (error) {
228
+ PatchOrganizationMembersEndpoint.throwDuplicateMemberNumberError(error);
229
+ }
206
230
 
207
231
  // If parents changed or emergeny contacts: fetch family and merge data
208
232
  if (patch.details && (!isEmptyPatch(patch.details?.parents) || !isEmptyPatch(patch.details?.emergencyContacts))) {
@@ -732,8 +756,10 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
732
756
  ] }).catch(console.error);
733
757
  }
734
758
 
759
+ const r = await AuthenticatedStructures.membersBlob(members);
760
+
735
761
  return new Response(
736
- await AuthenticatedStructures.membersBlob(members),
762
+ r,
737
763
  );
738
764
  }
739
765
 
@@ -929,73 +955,98 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
929
955
  }
930
956
  }
931
957
 
932
- static async checkSecurityCode(member: MemberWithUsersRegistrationsAndGroups, securityCode: string | null | undefined, type: 'put' | 'patch') {
933
- if ((type === 'put' && await member.isSafeToMergeDuplicateWithoutSecurityCode()) || await Context.auth.canAccessMember(member, PermissionLevel.Write)) {
934
- console.log('checkSecurityCode: without security code: allowed for ' + member.id);
958
+ private static async checkSecurityCode(member: MemberWithUsersRegistrationsAndGroups, securityCode: string) {
959
+ try {
960
+ securityCodeLimiter.track(member.details.name, 1);
935
961
  }
936
- else if (securityCode) {
937
- try {
938
- securityCodeLimiter.track(member.details.name, 1);
939
- }
940
- catch (e) {
941
- Email.sendWebmaster({
942
- subject: $t(`%E9`),
943
- text: $t(`%EA`) + ' ' + member.details.name + ' ' + $t(`%1G`) + ' ' + member.id + ')' + '\n\n' + e.message + '\n\nStamhoofd',
944
- });
962
+ catch (e) {
963
+ Email.sendWebmaster({
964
+ subject: $t(`%E9`),
965
+ text: $t(`%EA`) + ' ' + member.details.name + ' ' + $t(`%1G`) + ' ' + member.id + ')' + '\n\n' + e.message + '\n\nStamhoofd',
966
+ });
945
967
 
968
+ throw new SimpleError({
969
+ code: 'too_many_tries',
970
+ message: 'Too many securityCodes limited',
971
+ human: $t(`%EB`),
972
+ field: 'details.securityCode',
973
+ });
974
+ }
975
+
976
+ // Entered the security code, so we can link the user to the member
977
+ if (STAMHOOFD.environment !== 'development') {
978
+ if (!member.details.securityCode || securityCode !== member.details.securityCode) {
946
979
  throw new SimpleError({
947
- code: 'too_many_tries',
948
- message: 'Too many securityCodes limited',
949
- human: $t(`%EB`),
980
+ code: 'invalid_field',
950
981
  field: 'details.securityCode',
982
+ message: 'Invalid security code',
983
+ human: Context.i18n.$t('%2i'),
984
+ statusCode: 400,
951
985
  });
952
986
  }
987
+ }
953
988
 
954
- // Entered the security code, so we can link the user to the member
955
- if (STAMHOOFD.environment !== 'development') {
956
- if (!member.details.securityCode || securityCode !== member.details.securityCode) {
957
- throw new SimpleError({
958
- code: 'invalid_field',
959
- field: 'details.securityCode',
960
- message: 'Invalid security code',
961
- human: Context.i18n.$t('%2i'),
962
- statusCode: 400,
963
- });
964
- }
965
- }
989
+ console.log('checkSecurityCode: security code is correct - for ' + member.id);
966
990
 
967
- console.log('checkSecurityCode: security code is correct - for ' + member.id);
991
+ // Grant temporary access to this member without needing to enter the security code again
992
+ await Context.auth.temporarilyGrantMemberAccess(member, PermissionLevel.Full);
968
993
 
969
- // Grant temporary access to this member without needing to enter the security code again
970
- await Context.auth.temporarilyGrantMemberAccess(member, PermissionLevel.Full);
994
+ const log = new AuditLog();
995
+
996
+ // a member has multiple organizations, so this is difficult to determine - for now it is only visible in the admin panel
997
+ log.organizationId = member.organizationId;
971
998
 
972
- const log = new AuditLog();
999
+ log.type = AuditLogType.MemberSecurityCodeUsed;
1000
+ log.source = AuditLogSource.Anonymous;
973
1001
 
974
- // a member has multiple organizations, so this is difficult to determine - for now it is only visible in the admin panel
975
- log.organizationId = member.organizationId;
1002
+ if (Context.user) {
1003
+ log.userId = Context.user.id;
1004
+ log.source = AuditLogSource.User;
1005
+ }
976
1006
 
977
- log.type = AuditLogType.MemberSecurityCodeUsed;
978
- log.source = AuditLogSource.Anonymous;
1007
+ log.objectId = member.id;
1008
+ log.replacements = new Map([
1009
+ ['m', AuditLogReplacement.create({
1010
+ value: member.details.name,
1011
+ type: AuditLogReplacementType.Member,
1012
+ id: member.id,
1013
+ })],
1014
+ ]);
1015
+ await log.save();
1016
+ }
979
1017
 
980
- if (Context.user) {
981
- log.userId = Context.user.id;
982
- log.source = AuditLogSource.User;
1018
+ static async checkCanAccessMember(member: MemberWithUsersRegistrationsAndGroups, securityCode: string | null | undefined, type: 'put' | 'patch') {
1019
+ // do not check security code for user mode organization (throw error if not allowed)
1020
+ if (STAMHOOFD.userMode === 'organization') {
1021
+ if ((type === 'put' && await member.isSafeToMergeDuplicateWithoutSecurityCode()) || await Context.auth.canAccessMember(member, PermissionLevel.Write)) {
1022
+ console.log('checkSecurityCode: allowed for ' + member.id);
1023
+ return;
1024
+ }
1025
+
1026
+ if (type === 'patch') {
1027
+ throw Context.auth.memberNotFoundOrNoAccess();
983
1028
  }
984
1029
 
985
- log.objectId = member.id;
986
- log.replacements = new Map([
987
- ['m', AuditLogReplacement.create({
988
- value: member.details.name,
989
- type: AuditLogReplacementType.Member,
990
- id: member.id,
991
- })],
992
- ]);
993
- await log.save();
1030
+ throw new SimpleError({
1031
+ code: 'known_member_missing_rights',
1032
+ message: 'Creating known member without sufficient access rights',
1033
+ // different message for userMode organization because security codes are not available in that mode
1034
+ human: $t(`%1Oz`, { member: member.details.firstName }),
1035
+ statusCode: 400,
1036
+ });
1037
+ }
1038
+
1039
+ if ((type === 'put' && await member.isSafeToMergeDuplicateWithoutSecurityCode()) || await Context.auth.canAccessMember(member, PermissionLevel.Write)) {
1040
+ console.log('checkSecurityCode: without security code: allowed for ' + member.id);
1041
+ }
1042
+ else if (securityCode) {
1043
+ await this.checkSecurityCode(member, securityCode);
994
1044
  }
995
1045
  else {
996
1046
  if (type === 'patch') {
997
1047
  throw Context.auth.memberNotFoundOrNoAccess();
998
1048
  }
1049
+
999
1050
  throw new SimpleError({
1000
1051
  code: 'known_member_missing_rights',
1001
1052
  message: 'Creating known member without sufficient access rights',
@@ -1027,7 +1078,11 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
1027
1078
  // Check for duplicates and prevent creating a duplicate member by a user
1028
1079
  const duplicate = await this.findExistingMember(member);
1029
1080
  if (duplicate) {
1030
- await this.checkSecurityCode(duplicate, securityCode, type);
1081
+ console.error('duplicate detection');
1082
+ console.error(member.details.parents);
1083
+ console.error(duplicate.details.parents);
1084
+
1085
+ await this.checkCanAccessMember(duplicate, securityCode, type);
1031
1086
 
1032
1087
  // Merge data
1033
1088
  // NOTE: We use mergeTwoMembers instead of mergeMultipleMembers, because we should never safe 'member' , because that one does not exist in the database
@@ -1,5 +1,6 @@
1
1
  import { SimpleError } from '@simonbackx/simple-errors';
2
- import { FilterWrapperMarker, PermissionLevel, StamhoofdFilter, unwrapFilter, WrapperFilter } from '@stamhoofd/structures';
2
+ import type { StamhoofdFilter, WrapperFilter } from '@stamhoofd/structures';
3
+ import { FilterWrapperMarker, PermissionLevel, unwrapFilter } from '@stamhoofd/structures';
3
4
  import { Context } from '../../../../helpers/Context.js';
4
5
 
5
6
  export async function validateGroupFilter({ filter, permissionLevel, key }: { filter: StamhoofdFilter; permissionLevel: PermissionLevel; key: string | null }) {
@@ -1,5 +1,6 @@
1
- import { AutoEncoderPatchType } from '@simonbackx/simple-encoding';
2
- import { MemberDetails, MemberWithRegistrationsBlob } from '@stamhoofd/structures';
1
+ import type { AutoEncoderPatchType } from '@simonbackx/simple-encoding';
2
+ import type { MemberDetails} from '@stamhoofd/structures';
3
+ import { MemberWithRegistrationsBlob } from '@stamhoofd/structures';
3
4
 
4
5
  /**
5
6
  * Returns true when either the firstname, lastname or birthday has changed
@@ -1,4 +1,5 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
2
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
2
3
  import { SimpleError } from '@simonbackx/simple-errors';
3
4
  import { Organization, RegisterCode } from '@stamhoofd/models';
4
5
  import { RegisterCode as RegisterCodeStruct } from '@stamhoofd/structures';
@@ -1,5 +1,6 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import { Address, Country, CreateOrganization, NewUser, Organization as OrganizationStruct, Version } from '@stamhoofd/structures';
2
+ import { Address, CreateOrganization, NewUser, Organization as OrganizationStruct, Version } from '@stamhoofd/structures';
3
+ import { Country } from '@stamhoofd/types/Country';
3
4
 
4
5
  import { testServer } from '../../../../tests/helpers/TestServer.js';
5
6
  import { CreateOrganizationEndpoint } from './CreateOrganizationEndpoint.js';
@@ -29,7 +30,7 @@ describe.skip('Endpoint.CreateOrganization', () => {
29
30
  }).encode({ version: Version }));
30
31
 
31
32
  const response = await testServer.test(endpoint, r);
32
- expect(response.body.token).not.toBeEmpty();
33
+ expect(response.body.token).not.toEqual([]);
33
34
  });
34
35
 
35
36
  test('Creating an organization with an in-use URI throws', async () => {
@@ -1,5 +1,6 @@
1
- import { Decoder } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { Decoder } from '@simonbackx/simple-encoding';
2
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
4
  import { SimpleError } from '@simonbackx/simple-errors';
4
5
  import { AuditLog, EmailVerificationCode, Organization, OrganizationRegistrationPeriod, RegistrationPeriod, User } from '@stamhoofd/models';
5
6
  import { AuditLogSource, AuditLogType, CreateOrganization, PermissionLevel, Permissions, RegistrationPeriodSettings, SignupResponse, UserPermissions } from '@stamhoofd/structures';
@@ -1,8 +1,10 @@
1
- import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { Decoder} from '@simonbackx/simple-encoding';
2
+ import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
4
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
5
  import { SimpleError } from '@simonbackx/simple-errors';
4
6
  import { Organization } from '@stamhoofd/models';
5
- import { Organization as OrganizationStruct } from '@stamhoofd/structures';
7
+ import type { Organization as OrganizationStruct } from '@stamhoofd/structures';
6
8
  import { GoogleTranslateHelper } from '@stamhoofd/utility';
7
9
  import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures.js';
8
10
  type Params = Record<string, never>;
@@ -1,8 +1,10 @@
1
- import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { Decoder} from '@simonbackx/simple-encoding';
2
+ import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
4
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
5
  import { SimpleError } from '@simonbackx/simple-errors';
4
6
  import { Organization } from '@stamhoofd/models';
5
- import { Organization as OrganizationStruct } from '@stamhoofd/structures';
7
+ import type { Organization as OrganizationStruct } from '@stamhoofd/structures';
6
8
  import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures.js';
7
9
  type Params = Record<string, never>;
8
10
 
@@ -1,8 +1,11 @@
1
- import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { Decoder} from '@simonbackx/simple-encoding';
2
+ import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
4
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
5
  import { Organization } from '@stamhoofd/models';
4
- import { scalarToSQLExpression, SQL, SQLMatch, SQLWhere, SQLWhereLike } from '@stamhoofd/sql';
5
- import { Organization as OrganizationStruct } from '@stamhoofd/structures';
6
+ import type { SQLWhere} from '@stamhoofd/sql';
7
+ import { scalarToSQLExpression, SQL, SQLMatch, SQLWhereLike } from '@stamhoofd/sql';
8
+ import type { Organization as OrganizationStruct } from '@stamhoofd/structures';
6
9
  import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures.js';
7
10
 
8
11
  type Params = Record<string, never>;
@@ -33,7 +36,7 @@ export class SearchOrganizationEndpoint extends Endpoint<Params, Query, Body, Re
33
36
 
34
37
  async handle(request: DecodedRequest<Params, Query, Body>) {
35
38
  // Escape query
36
- const query = request.query.query.replace(/([-+><()~*"@\s]+)/g, ' ').replace(/[^\w\d]+$/, '').trim();
39
+ const query = request.query.query.replace(/[-+><()~*"@\s]+/g, ' ').replace(/\W+$/, '').trim();
37
40
  if (query.length === 0) {
38
41
  // Do not try searching...
39
42
  return new Response([]);
@@ -1,5 +1,7 @@
1
- import { AnyDecoder, AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { Decoder} from '@simonbackx/simple-encoding';
2
+ import { AnyDecoder, AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
4
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
5
  import { SimpleError } from '@simonbackx/simple-errors';
4
6
  import { Organization, StripeAccount, StripeCheckoutSession, StripePaymentIntent } from '@stamhoofd/models';
5
7
  import { isDebouncedError, QueueHandler } from '@stamhoofd/queues';
@@ -1,4 +1,5 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
2
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
2
3
  import { User } from '@stamhoofd/models';
3
4
  import { OrganizationAdmins } from '@stamhoofd/structures';
4
5
 
@@ -1,6 +1,7 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
2
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
2
3
  import { Platform } from '@stamhoofd/models';
3
- import { Platform as PlatformStruct } from '@stamhoofd/structures';
4
+ import type { Platform as PlatformStruct } from '@stamhoofd/structures';
4
5
 
5
6
  import { Context } from '../../../helpers/Context.js';
6
7
 
@@ -1,8 +1,9 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import { Organization, OrganizationFactory, Platform, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
2
+ import type { Organization} from '@stamhoofd/models';
3
+ import { OrganizationFactory, Platform, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
3
4
  import { PermissionLevel, Permissions, PlatformConfig, Platform as PlatformStruct, Version } from '@stamhoofd/structures';
4
5
 
5
- import { AutoEncoderPatchType } from '@simonbackx/simple-encoding';
6
+ import type { AutoEncoderPatchType } from '@simonbackx/simple-encoding';
6
7
  import { TestUtils } from '@stamhoofd/test-utils';
7
8
  import { testServer } from '../../../../tests/helpers/TestServer.js';
8
9
  import { PatchPlatformEndpoint } from './PatchPlatformEnpoint.js';
@@ -1,7 +1,10 @@
1
- import { AutoEncoderPatchType, Decoder, isPatchableArray, patchObject } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
1
+ import type { AutoEncoderPatchType, Decoder} from '@simonbackx/simple-encoding';
2
+ import { isPatchableArray, patchObject } from '@simonbackx/simple-encoding';
3
+ import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
4
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
5
  import { Organization, Platform, RegistrationPeriod } from '@stamhoofd/models';
4
- import { MemberResponsibility, PlatformConfig, PlatformPremiseType, Platform as PlatformStruct } from '@stamhoofd/structures';
6
+ import type { MemberResponsibility, PlatformConfig, PlatformPremiseType} from '@stamhoofd/structures';
7
+ import { Platform as PlatformStruct } from '@stamhoofd/structures';
5
8
 
6
9
  import { SimpleError } from '@simonbackx/simple-errors';
7
10
  import { QueueHandler } from '@stamhoofd/queues';
@@ -0,0 +1,47 @@
1
+ import type { Decoder } from '@simonbackx/simple-encoding';
2
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
3
+ import { Endpoint, Response } from '@simonbackx/simple-endpoints';
4
+ import { CountFilteredRequest, CountResponse } from '@stamhoofd/structures';
5
+ import { Context } from '../../../helpers/Context.js';
6
+ import { GetPlatformMembershipsEndpoint } from './GetPlatformMembershipsEndpoint.js';
7
+
8
+ type Params = Record<string, never>;
9
+ type Query = CountFilteredRequest;
10
+ type Body = undefined;
11
+ type ResponseBody = CountResponse
12
+
13
+ export class GetPlatformMembershipsCountEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
14
+ queryDecoder = CountFilteredRequest as Decoder<CountFilteredRequest>;
15
+
16
+ protected doesMatch(request: Request): [true, Params] | [false] {
17
+ if (request.method !== 'GET') {
18
+ return [false];
19
+ }
20
+
21
+ const params = Endpoint.parseParameters(request.url, '/platform-memberships/count', {});
22
+
23
+ if (params) {
24
+ return [true, params as Params];
25
+ }
26
+ return [false];
27
+ }
28
+
29
+ async handle(request: DecodedRequest<Params, Query, Body>) {
30
+ await Context.authenticate();
31
+
32
+ if (!Context.auth.hasPlatformFullAccess()) {
33
+ throw Context.auth.error();
34
+ }
35
+
36
+ const query = await GetPlatformMembershipsEndpoint.buildQuery(request.query);
37
+
38
+ const count = await query
39
+ .count();
40
+
41
+ return new Response(
42
+ CountResponse.create({
43
+ count,
44
+ }),
45
+ );
46
+ }
47
+ }