@stamhoofd/backend 2.39.1 → 2.40.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 (198) hide show
  1. package/eslint.config.mjs +5 -0
  2. package/index.ts +81 -74
  3. package/jest.config.cjs +10 -0
  4. package/migrations.ts +16 -14
  5. package/package.json +11 -11
  6. package/src/crons/clear-excel-cache.test.ts +48 -50
  7. package/src/crons/clear-excel-cache.ts +18 -18
  8. package/src/crons/setup-steps.ts +2 -2
  9. package/src/crons.ts +325 -306
  10. package/src/decoders/StringArrayDecoder.ts +7 -7
  11. package/src/decoders/StringNullableDecoder.ts +1 -2
  12. package/src/email-recipient-loaders/members.ts +22 -22
  13. package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
  14. package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
  15. package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
  16. package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
  17. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
  18. package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
  19. package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
  20. package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
  21. package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
  22. package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
  23. package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
  24. package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
  25. package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
  26. package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
  27. package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
  28. package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
  29. package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
  30. package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
  31. package/src/endpoints/auth/SignupEndpoint.ts +37 -36
  32. package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
  33. package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
  34. package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
  35. package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
  36. package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
  37. package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
  38. package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
  39. package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
  40. package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
  41. package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
  42. package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
  43. package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
  44. package/src/endpoints/global/files/GetFileCache.ts +13 -13
  45. package/src/endpoints/global/files/UploadFile.ts +51 -54
  46. package/src/endpoints/global/files/UploadImage.ts +53 -53
  47. package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
  48. package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
  49. package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
  50. package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
  51. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
  52. package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
  53. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
  54. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
  55. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
  56. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
  57. package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
  58. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
  59. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
  60. package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
  61. package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
  62. package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
  63. package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
  64. package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
  65. package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
  66. package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
  67. package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
  68. package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
  69. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
  70. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
  71. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
  72. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
  73. package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
  74. package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
  75. package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
  76. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
  77. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
  78. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
  79. package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
  80. package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
  81. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
  82. package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
  83. package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
  84. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
  85. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
  86. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
  87. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
  88. package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
  89. package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
  90. package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
  91. package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
  92. package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
  93. package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
  94. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
  95. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
  96. package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
  97. package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
  98. package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
  99. package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
  100. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
  101. package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
  102. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
  103. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
  104. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
  105. package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
  106. package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
  107. package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
  108. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
  109. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
  110. package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
  111. package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
  112. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
  113. package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
  114. package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
  115. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
  116. package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
  117. package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
  118. package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
  119. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
  120. package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
  121. package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
  122. package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
  123. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
  124. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
  125. package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
  126. package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
  127. package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
  128. package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
  129. package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
  130. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
  131. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
  132. package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
  133. package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
  134. package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
  135. package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
  136. package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
  137. package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
  138. package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
  139. package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
  140. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
  141. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
  142. package/src/excel-loaders/members.ts +102 -103
  143. package/src/excel-loaders/payments.ts +155 -156
  144. package/src/helpers/AddressValidator.test.ts +32 -32
  145. package/src/helpers/AddressValidator.ts +128 -122
  146. package/src/helpers/AdminPermissionChecker.ts +339 -236
  147. package/src/helpers/AuthenticatedStructures.ts +233 -134
  148. package/src/helpers/BuckarooHelper.ts +134 -134
  149. package/src/helpers/CheckSettlements.ts +94 -88
  150. package/src/helpers/Context.ts +87 -86
  151. package/src/helpers/CookieHelper.ts +23 -22
  152. package/src/helpers/EmailResumer.ts +10 -10
  153. package/src/helpers/FileCache.ts +62 -62
  154. package/src/helpers/ForwardHandler.test.ts +122 -124
  155. package/src/helpers/ForwardHandler.ts +76 -70
  156. package/src/helpers/MemberUserSyncer.ts +101 -96
  157. package/src/helpers/MembershipCharger.ts +69 -69
  158. package/src/helpers/MembershipHelper.ts +11 -12
  159. package/src/helpers/OpenIDConnectHelper.ts +85 -82
  160. package/src/helpers/PeriodHelper.ts +65 -70
  161. package/src/helpers/StripeHelper.ts +146 -137
  162. package/src/helpers/StripePayoutChecker.ts +51 -52
  163. package/src/helpers/ViesHelper.ts +46 -44
  164. package/src/helpers/fetchToAsyncIterator.ts +14 -14
  165. package/src/helpers/xlsxAddressTransformerColumnFactory.ts +50 -52
  166. package/src/middleware/ContextMiddleware.ts +5 -5
  167. package/src/migrations/1646578856-validate-addresses.ts +6 -9
  168. package/src/seeds/0000000000-example.ts +3 -5
  169. package/src/seeds/1715028563-user-permissions.ts +16 -18
  170. package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
  171. package/src/seeds/1722344162-sync-member-users.ts +14 -15
  172. package/src/seeds/1722344162-update-membership.ts +6 -6
  173. package/src/seeds/1726055544-balance-item-paid.ts +4 -4
  174. package/src/seeds/1726055545-balance-item-pending.ts +4 -4
  175. package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
  176. package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
  177. package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
  178. package/src/seeds/1726847064-setup-steps.ts +16 -0
  179. package/src/sql-filters/balance-item-payments.ts +7 -7
  180. package/src/sql-filters/events.ts +14 -14
  181. package/src/sql-filters/members.ts +96 -96
  182. package/src/sql-filters/organizations.ts +139 -75
  183. package/src/sql-filters/payments.ts +28 -28
  184. package/src/sql-filters/registrations.ts +14 -14
  185. package/src/sql-sorters/events.ts +25 -25
  186. package/src/sql-sorters/members.ts +26 -26
  187. package/src/sql-sorters/organizations.ts +36 -36
  188. package/src/sql-sorters/payments.ts +26 -26
  189. package/tests/e2e/stock.test.ts +616 -621
  190. package/tests/e2e/tickets.test.ts +255 -260
  191. package/tests/helpers/StripeMocker.ts +177 -179
  192. package/tests/helpers/TestServer.ts +9 -9
  193. package/tests/jest.global.setup.ts +14 -13
  194. package/tests/jest.setup.ts +33 -32
  195. package/.eslintrc.js +0 -61
  196. package/jest.config.js +0 -11
  197. package/src/helpers/SetupStepsUpdater.ts +0 -359
  198. package/src/seeds/1724076679-setup-steps.ts +0 -16
@@ -1,12 +1,12 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { RegistrationPeriod as RegistrationPeriodStruct } from "@stamhoofd/structures";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { RegistrationPeriod as RegistrationPeriodStruct } from '@stamhoofd/structures';
3
3
 
4
4
  import { RegistrationPeriod } from '@stamhoofd/models';
5
5
 
6
6
  type Params = Record<string, never>;
7
7
  type Query = undefined;
8
- type Body = undefined
9
- type ResponseBody = RegistrationPeriodStruct[]
8
+ type Body = undefined;
9
+ type ResponseBody = RegistrationPeriodStruct[];
10
10
 
11
11
  /**
12
12
  * One endpoint to create, patch and delete members and their registrations and payments
@@ -14,11 +14,11 @@ type ResponseBody = RegistrationPeriodStruct[]
14
14
 
15
15
  export class PatchRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
16
16
  protected doesMatch(request: Request): [true, Params] | [false] {
17
- if (request.method != "GET") {
17
+ if (request.method !== 'GET') {
18
18
  return [false];
19
19
  }
20
20
 
21
- const params = Endpoint.parseParameters(request.url, "/registration-periods", {});
21
+ const params = Endpoint.parseParameters(request.url, '/registration-periods', {});
22
22
 
23
23
  if (params) {
24
24
  return [true, params as Params];
@@ -27,11 +27,10 @@ export class PatchRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Bo
27
27
  }
28
28
 
29
29
  async handle(request: DecodedRequest<Params, Query, Body>) {
30
- const periods = await RegistrationPeriod.all()
30
+ const periods = await RegistrationPeriod.all();
31
31
 
32
32
  return new Response(
33
- periods.map(p => p.getStructure())
33
+ periods.map(p => p.getStructure()),
34
34
  );
35
35
  }
36
-
37
36
  }
@@ -1,6 +1,6 @@
1
1
  import { ConvertArrayToPatchableArray, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder, patchObject } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
3
- import { RegistrationPeriod as RegistrationPeriodStruct } from "@stamhoofd/structures";
2
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
3
+ import { RegistrationPeriod as RegistrationPeriodStruct } from '@stamhoofd/structures';
4
4
 
5
5
  import { SimpleError } from '@simonbackx/simple-errors';
6
6
  import { Platform, RegistrationPeriod } from '@stamhoofd/models';
@@ -9,8 +9,8 @@ import { PeriodHelper } from '../../../helpers/PeriodHelper';
9
9
 
10
10
  type Params = Record<string, never>;
11
11
  type Query = undefined;
12
- type Body = PatchableArrayAutoEncoder<RegistrationPeriodStruct>
13
- type ResponseBody = RegistrationPeriodStruct[]
12
+ type Body = PatchableArrayAutoEncoder<RegistrationPeriodStruct>;
13
+ type ResponseBody = RegistrationPeriodStruct[];
14
14
 
15
15
  /**
16
16
  * One endpoint to create, patch and delete members and their registrations and payments
@@ -18,14 +18,14 @@ type ResponseBody = RegistrationPeriodStruct[]
18
18
 
19
19
  export class PatchRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
20
20
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
21
- bodyDecoder = new PatchableArrayDecoder(RegistrationPeriodStruct as any, RegistrationPeriodStruct.patchType(), StringDecoder) as any as Decoder<ConvertArrayToPatchableArray<RegistrationPeriodStruct[]>>
21
+ bodyDecoder = new PatchableArrayDecoder(RegistrationPeriodStruct as any, RegistrationPeriodStruct.patchType(), StringDecoder) as any as Decoder<ConvertArrayToPatchableArray<RegistrationPeriodStruct[]>>;
22
22
 
23
23
  protected doesMatch(request: Request): [true, Params] | [false] {
24
- if (request.method != "PATCH") {
24
+ if (request.method !== 'PATCH') {
25
25
  return [false];
26
26
  }
27
27
 
28
- const params = Endpoint.parseParameters(request.url, "/registration-periods", {});
28
+ const params = Endpoint.parseParameters(request.url, '/registration-periods', {});
29
29
 
30
30
  if (params) {
31
31
  return [true, params as Params];
@@ -35,22 +35,23 @@ export class PatchRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Bo
35
35
 
36
36
  async handle(request: DecodedRequest<Params, Query, Body>) {
37
37
  const organization = await Context.setUserOrganizationScope();
38
- await Context.authenticate()
38
+ await Context.authenticate();
39
39
 
40
40
  // Fast throw first (more in depth checking for patches later)
41
41
  if (organization) {
42
42
  if (!await Context.auth.hasFullAccess(organization.id)) {
43
- throw Context.auth.error()
44
- }
45
- } else {
43
+ throw Context.auth.error();
44
+ }
45
+ }
46
+ else {
46
47
  if (!Context.auth.hasPlatformFullAccess()) {
47
- throw Context.auth.error()
48
- }
48
+ throw Context.auth.error();
49
+ }
49
50
  }
50
51
 
51
52
  const periods: RegistrationPeriod[] = [];
52
53
 
53
- for (const {put} of request.body.getPuts()) {
54
+ for (const { put } of request.body.getPuts()) {
54
55
  const period = new RegistrationPeriod();
55
56
  period.id = put.id;
56
57
  period.startDate = put.startDate;
@@ -68,9 +69,9 @@ export class PatchRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Bo
68
69
 
69
70
  if (!model || model.organizationId !== (organization?.id ?? null)) {
70
71
  throw new SimpleError({
71
- code: "not_found",
72
+ code: 'not_found',
72
73
  statusCode: 404,
73
- message: "Registration period not found",
74
+ message: 'Registration period not found',
74
75
  });
75
76
  }
76
77
 
@@ -101,9 +102,9 @@ export class PatchRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Bo
101
102
 
102
103
  if (!model || model.organizationId !== (organization?.id ?? null)) {
103
104
  throw new SimpleError({
104
- code: "not_found",
105
+ code: 'not_found',
105
106
  statusCode: 404,
106
- message: "Registration period not found",
107
+ message: 'Registration period not found',
107
108
  });
108
109
  }
109
110
 
@@ -111,11 +112,10 @@ export class PatchRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Bo
111
112
  }
112
113
 
113
114
  // Clear platform cache
114
- Platform.clearCache()
115
+ Platform.clearCache();
115
116
 
116
117
  return new Response(
117
- periods.map(p => p.getStructure())
118
+ periods.map(p => p.getStructure()),
118
119
  );
119
120
  }
120
-
121
121
  }
@@ -1,10 +1,10 @@
1
- import { AutoEncoder, Decoder,field, StringDecoder } from "@simonbackx/simple-encoding";
2
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
1
+ import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
2
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
3
3
  import { SimpleError } from '@simonbackx/simple-errors';
4
4
  import { Organization } from '@stamhoofd/models';
5
5
  import { Webshop } from '@stamhoofd/models';
6
- import { GetWebshopFromDomainResult, Webshop as WebshopStruct, WebshopPreview } from "@stamhoofd/structures";
7
- import { GoogleTranslateHelper, Sorter } from "@stamhoofd/utility";
6
+ import { GetWebshopFromDomainResult, Webshop as WebshopStruct, WebshopPreview } from '@stamhoofd/structures';
7
+ import { GoogleTranslateHelper, Sorter } from '@stamhoofd/utility';
8
8
  type Params = Record<string, never>;
9
9
 
10
10
  class Query extends AutoEncoder {
@@ -15,7 +15,7 @@ class Query extends AutoEncoder {
15
15
  uri: string | null;
16
16
  }
17
17
 
18
- type Body = undefined
18
+ type Body = undefined;
19
19
  type ResponseBody = GetWebshopFromDomainResult;
20
20
 
21
21
  /**
@@ -23,20 +23,20 @@ type ResponseBody = GetWebshopFromDomainResult;
23
23
  */
24
24
 
25
25
  export class GetWebshopFromDomainEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
26
- queryDecoder = Query as Decoder<Query>
26
+ queryDecoder = Query as Decoder<Query>;
27
27
  webshopDomains = [
28
28
  ...new Set([
29
- ...Object.values(STAMHOOFD.domains.webshop),
30
- ...Object.values(STAMHOOFD.domains.marketing)
31
- ])
32
- ]
29
+ ...Object.values(STAMHOOFD.domains.webshop),
30
+ ...Object.values(STAMHOOFD.domains.marketing),
31
+ ]),
32
+ ];
33
33
 
34
34
  protected doesMatch(request: Request): [true, Params] | [false] {
35
- if (request.method != "GET") {
35
+ if (request.method !== 'GET') {
36
36
  return [false];
37
37
  }
38
38
 
39
- const params = Endpoint.parseParameters(request.url, "/webshop-from-domain", {});
39
+ const params = Endpoint.parseParameters(request.url, '/webshop-from-domain', {});
40
40
 
41
41
  if (params) {
42
42
  return [true, params as Params];
@@ -47,141 +47,141 @@ export class GetWebshopFromDomainEndpoint extends Endpoint<Params, Query, Body,
47
47
  async handle(request: DecodedRequest<Params, Query, Body>) {
48
48
  // check if the domain ends on .stamhoofd.be
49
49
  if (!STAMHOOFD.domains.webshop) {
50
- throw new Error("Expected environment variable HOSTNAME_WEBSHOP")
50
+ throw new Error('Expected environment variable HOSTNAME_WEBSHOP');
51
51
  }
52
52
 
53
53
  // Clean up google translate domains -> make sure we can translate register pages
54
- request.query.domain = GoogleTranslateHelper.getDomainFromTranslateDomain(request.query.domain)
54
+ request.query.domain = GoogleTranslateHelper.getDomainFromTranslateDomain(request.query.domain);
55
55
 
56
56
  if (request.query.uri) {
57
57
  for (const domain of this.webshopDomains) {
58
58
  if (request.query.domain === domain) {
59
59
  // Search webshop
60
- const webshop = await Webshop.getByURI(request.query.uri)
60
+ const webshop = await Webshop.getByURI(request.query.uri);
61
61
 
62
62
  if (!webshop) {
63
63
  throw new SimpleError({
64
- code: "unknown_webshop",
65
- message: "No webshop registered with this name",
66
- statusCode: 404
67
- })
64
+ code: 'unknown_webshop',
65
+ message: 'No webshop registered with this name',
66
+ statusCode: 404,
67
+ });
68
68
  }
69
69
 
70
- const organization = await Organization.getByID(webshop.organizationId)
70
+ const organization = await Organization.getByID(webshop.organizationId);
71
71
 
72
72
  if (!organization) {
73
73
  throw new SimpleError({
74
- code: "unknown_organization",
75
- message: "No organization registered with this domain name",
76
- statusCode: 404
77
- })
74
+ code: 'unknown_organization',
75
+ message: 'No organization registered with this domain name',
76
+ statusCode: 404,
77
+ });
78
78
  }
79
79
 
80
80
  return new Response(GetWebshopFromDomainResult.create({
81
81
  organization: organization.getBaseStructure(),
82
- webshop: WebshopStruct.create(webshop)
82
+ webshop: WebshopStruct.create(webshop),
83
83
  }));
84
84
  }
85
85
  }
86
86
  }
87
-
87
+
88
88
  // If ends with the legacy webshop domain
89
- if (STAMHOOFD.domains.legacyWebshop && request.query.domain.endsWith("." + STAMHOOFD.domains.legacyWebshop)) {
90
- const strippped = request.query.domain.substr(0, request.query.domain.length - ("." + STAMHOOFD.domains.legacyWebshop).length )
91
- if (strippped.includes(".")) {
89
+ if (STAMHOOFD.domains.legacyWebshop && request.query.domain.endsWith('.' + STAMHOOFD.domains.legacyWebshop)) {
90
+ const strippped = request.query.domain.substr(0, request.query.domain.length - ('.' + STAMHOOFD.domains.legacyWebshop).length);
91
+ if (strippped.includes('.')) {
92
92
  throw new SimpleError({
93
- code: "invalid_domain",
94
- message: "This domain format is not supported",
95
- statusCode: 404
96
- })
93
+ code: 'invalid_domain',
94
+ message: 'This domain format is not supported',
95
+ statusCode: 404,
96
+ });
97
97
  }
98
98
 
99
99
  // Search for the URI
100
- const organization = await Organization.getByURI(strippped)
100
+ const organization = await Organization.getByURI(strippped);
101
101
 
102
102
  if (!organization) {
103
103
  throw new SimpleError({
104
- code: "unknown_organization",
105
- message: "No organization registered with this domain name",
106
- statusCode: 404
107
- })
104
+ code: 'unknown_organization',
105
+ message: 'No organization registered with this domain name',
106
+ statusCode: 404,
107
+ });
108
108
  }
109
109
 
110
110
  // Search webshop
111
- const webshop = await Webshop.getByLegacyURI(organization.id, request.query.uri ?? "")
111
+ const webshop = await Webshop.getByLegacyURI(organization.id, request.query.uri ?? '');
112
112
 
113
113
  if (!webshop) {
114
114
  // Return organization, so we know the locale + can do some custom logic
115
115
  return new Response(GetWebshopFromDomainResult.create({
116
116
  organization: organization.getBaseStructure(),
117
117
  webshop: null,
118
- webshops: []
118
+ webshops: [],
119
119
  }));
120
120
  }
121
121
 
122
122
  return new Response(GetWebshopFromDomainResult.create({
123
123
  organization: organization.getBaseStructure(),
124
- webshop: WebshopStruct.create(webshop)
124
+ webshop: WebshopStruct.create(webshop),
125
125
  }));
126
126
  }
127
127
 
128
128
  // Check if we have an organization with a custom domain name
129
129
 
130
- const webshop = await Webshop.getByDomain(request.query.domain, request.query.uri)
130
+ const webshop = await Webshop.getByDomain(request.query.domain, request.query.uri);
131
131
 
132
132
  if (!webshop) {
133
133
  // If uri is empty, check if we have multiple webshops with the same domain
134
134
  // Check organization
135
135
  if (!request.query.uri) {
136
- const webshops = await Webshop.getByDomainOnly(request.query.domain)
137
- const organizationId = Sorter.getMostOccuringElement(webshops.map(w => w.organizationId))
136
+ const webshops = await Webshop.getByDomainOnly(request.query.domain);
137
+ const organizationId = Sorter.getMostOccuringElement(webshops.map(w => w.organizationId));
138
138
 
139
139
  if (webshops.length == 0 || !organizationId) {
140
140
  throw new SimpleError({
141
- code: "unknown_webshop",
142
- message: "No webshop registered with this domain name",
143
- statusCode: 404
144
- })
141
+ code: 'unknown_webshop',
142
+ message: 'No webshop registered with this domain name',
143
+ statusCode: 404,
144
+ });
145
145
  }
146
146
 
147
- const organization = await Organization.getByID(organizationId)
147
+ const organization = await Organization.getByID(organizationId);
148
148
 
149
149
  if (!organization) {
150
150
  throw new SimpleError({
151
- code: "unknown_webshop",
152
- message: "No webshop registered with this domain name",
153
- statusCode: 404
154
- })
151
+ code: 'unknown_webshop',
152
+ message: 'No webshop registered with this domain name',
153
+ statusCode: 404,
154
+ });
155
155
  }
156
156
 
157
157
  // Return organization, and the known webshops on this domain
158
158
  return new Response(GetWebshopFromDomainResult.create({
159
159
  organization: organization.getBaseStructure(),
160
160
  webshop: null,
161
- webshops: webshops.map(w => WebshopPreview.create(w)).filter(w => w.isClosed(0) === false).sort((a, b) => Sorter.byStringValue(a.meta.name, b.meta.name))
161
+ webshops: webshops.map(w => WebshopPreview.create(w)).filter(w => w.isClosed(0) === false).sort((a, b) => Sorter.byStringValue(a.meta.name, b.meta.name)),
162
162
  }));
163
163
  }
164
-
164
+
165
165
  throw new SimpleError({
166
- code: "unknown_webshop",
167
- message: "No webshop registered with this domain name",
168
- statusCode: 404
169
- })
166
+ code: 'unknown_webshop',
167
+ message: 'No webshop registered with this domain name',
168
+ statusCode: 404,
169
+ });
170
170
  }
171
171
 
172
- const organization = await Organization.getByID(webshop.organizationId)
172
+ const organization = await Organization.getByID(webshop.organizationId);
173
173
 
174
174
  if (!organization) {
175
175
  throw new SimpleError({
176
- code: "unknown_organization",
177
- message: "No organization registered with this domain name",
178
- statusCode: 404
179
- })
176
+ code: 'unknown_organization',
177
+ message: 'No organization registered with this domain name',
178
+ statusCode: 404,
179
+ });
180
180
  }
181
181
 
182
182
  return new Response(GetWebshopFromDomainResult.create({
183
183
  organization: organization.getBaseStructure(),
184
- webshop: WebshopStruct.create(webshop)
184
+ webshop: WebshopStruct.create(webshop),
185
185
  }));
186
186
  }
187
187
  }
@@ -1,8 +1,8 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { OrganizationBillingStatus } from "@stamhoofd/structures";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { OrganizationBillingStatus } from '@stamhoofd/structures';
3
3
 
4
- import { Context } from "../../../../helpers/Context";
5
- import { GetUserBilingStatusEndpoint } from "../../../global/registration/GetUserBillingStatusEndpoint";
4
+ import { Context } from '../../../../helpers/Context';
5
+ import { GetUserBilingStatusEndpoint } from '../../../global/registration/GetUserBillingStatusEndpoint';
6
6
 
7
7
  type Params = Record<string, never>;
8
8
  type Query = undefined;
@@ -11,11 +11,11 @@ type Body = undefined;
11
11
 
12
12
  export class GetDetailedBillingStatusEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
13
13
  protected doesMatch(request: Request): [true, Params] | [false] {
14
- if (request.method != "GET") {
14
+ if (request.method !== 'GET') {
15
15
  return [false];
16
16
  }
17
17
 
18
- const params = Endpoint.parseParameters(request.url, "/organization/billing/status", {});
18
+ const params = Endpoint.parseParameters(request.url, '/organization/billing/status', {});
19
19
 
20
20
  if (params) {
21
21
  return [true, params as Params];
@@ -25,13 +25,13 @@ export class GetDetailedBillingStatusEndpoint extends Endpoint<Params, Query, Bo
25
25
 
26
26
  async handle(_: DecodedRequest<Params, Query, Body>) {
27
27
  const organization = await Context.setOrganizationScope();
28
- await Context.authenticate()
28
+ await Context.authenticate();
29
29
 
30
30
  // If the user has permission, we'll also search if he has access to the organization's key
31
31
  if (!await Context.auth.canManageFinances(organization.id)) {
32
- throw Context.auth.error()
32
+ throw Context.auth.error();
33
33
  }
34
-
34
+
35
35
  return new Response(await GetUserBilingStatusEndpoint.getBillingStatusForObjects([organization.id], null));
36
36
  }
37
37
  }
@@ -1,10 +1,10 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { OrganizationDetailedBillingStatus, PaymentStatus } from "@stamhoofd/structures";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { OrganizationDetailedBillingStatus, PaymentStatus } from '@stamhoofd/structures';
3
3
 
4
- import { BalanceItem, Payment } from "@stamhoofd/models";
5
- import { SQL } from "@stamhoofd/sql";
6
- import { Context } from "../../../../helpers/Context";
7
- import { GetUserDetailedBilingStatusEndpoint } from "../../../global/registration/GetUserDetailedBillingStatusEndpoint";
4
+ import { BalanceItem, Payment } from '@stamhoofd/models';
5
+ import { SQL } from '@stamhoofd/sql';
6
+ import { Context } from '../../../../helpers/Context';
7
+ import { GetUserDetailedBilingStatusEndpoint } from '../../../global/registration/GetUserDetailedBillingStatusEndpoint';
8
8
 
9
9
  type Params = Record<string, never>;
10
10
  type Query = undefined;
@@ -13,13 +13,13 @@ type Body = undefined;
13
13
 
14
14
  export class GetOrganizationDetailedBillingStatusEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
15
15
  protected doesMatch(request: Request): [true, Params] | [false] {
16
- if (request.method != "GET") {
16
+ if (request.method !== 'GET') {
17
17
  return [false];
18
18
  }
19
19
 
20
20
  if (request.getVersion() <= 334) {
21
21
  // Deprecated
22
- const params = Endpoint.parseParameters(request.url, "/billing/status/detailed", {});
22
+ const params = Endpoint.parseParameters(request.url, '/billing/status/detailed', {});
23
23
 
24
24
  if (params) {
25
25
  return [true, params as Params];
@@ -27,7 +27,7 @@ export class GetOrganizationDetailedBillingStatusEndpoint extends Endpoint<Param
27
27
  return [false];
28
28
  }
29
29
 
30
- const params = Endpoint.parseParameters(request.url, "/organization/billing/status/detailed", {});
30
+ const params = Endpoint.parseParameters(request.url, '/organization/billing/status/detailed', {});
31
31
 
32
32
  if (params) {
33
33
  return [true, params as Params];
@@ -37,21 +37,21 @@ export class GetOrganizationDetailedBillingStatusEndpoint extends Endpoint<Param
37
37
 
38
38
  async handle(_: DecodedRequest<Params, Query, Body>) {
39
39
  const organization = await Context.setOrganizationScope();
40
- await Context.authenticate()
40
+ await Context.authenticate();
41
41
 
42
42
  // If the user has permission, we'll also search if he has access to the organization's key
43
43
  if (!await Context.auth.canManageFinances(organization.id)) {
44
- throw Context.auth.error()
44
+ throw Context.auth.error();
45
45
  }
46
-
46
+
47
47
  const balanceItemModels = await BalanceItem.balanceItemsForOrganization(organization.id);
48
48
 
49
49
  const paymentModels = await Payment.select()
50
50
  .where('payingOrganizationId', organization.id)
51
51
  .andWhere(
52
- SQL.whereNot('status', PaymentStatus.Failed)
52
+ SQL.whereNot('status', PaymentStatus.Failed),
53
53
  )
54
- .fetch()
54
+ .fetch();
55
55
 
56
56
  return new Response(await GetUserDetailedBilingStatusEndpoint.getDetailedBillingStatus(balanceItemModels, paymentModels));
57
57
  }
@@ -1,13 +1,13 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { SimpleError } from "@simonbackx/simple-errors";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { SimpleError } from '@simonbackx/simple-errors';
3
3
  import { DocumentTemplate } from '@stamhoofd/models';
4
4
 
5
- import { Context } from "../../../../helpers/Context";
5
+ import { Context } from '../../../../helpers/Context';
6
6
 
7
7
  type Params = { id: string };
8
8
  type Query = undefined;
9
9
  type Body = undefined;
10
- type ResponseBody = Buffer
10
+ type ResponseBody = Buffer;
11
11
 
12
12
  /**
13
13
  * One endpoint to create, patch and delete groups. Usefull because on organization setup, we need to create multiple groups at once. Also, sometimes we need to link values and update multiple groups at once
@@ -15,11 +15,11 @@ type ResponseBody = Buffer
15
15
 
16
16
  export class GetDocumentTemplateXMLEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
17
17
  protected doesMatch(request: Request): [true, Params] | [false] {
18
- if (request.method != "GET") {
18
+ if (request.method !== 'GET') {
19
19
  return [false];
20
20
  }
21
21
 
22
- const params = Endpoint.parseParameters(request.url, "/organization/document-templates/@id/xml", { id: String});
22
+ const params = Endpoint.parseParameters(request.url, '/organization/document-templates/@id/xml', { id: String });
23
23
 
24
24
  if (params) {
25
25
  return [true, params as Params];
@@ -29,29 +29,29 @@ export class GetDocumentTemplateXMLEndpoint extends Endpoint<Params, Query, Body
29
29
 
30
30
  async handle(request: DecodedRequest<Params, Query, Body>) {
31
31
  const organization = await Context.setOrganizationScope();
32
- await Context.authenticate()
32
+ await Context.authenticate();
33
33
 
34
34
  if (!await Context.auth.canManageDocuments(organization.id)) {
35
- throw Context.auth.error()
35
+ throw Context.auth.error();
36
36
  }
37
37
 
38
- const template = await DocumentTemplate.getByID(request.params.id)
38
+ const template = await DocumentTemplate.getByID(request.params.id);
39
39
  if (!template || !await Context.auth.canAccessDocumentTemplate(template)) {
40
- throw Context.auth.notFoundOrNoAccess("Onbekend document")
40
+ throw Context.auth.notFoundOrNoAccess('Onbekend document');
41
41
  }
42
42
 
43
43
  // Update documents
44
44
  const xml = await template.getRenderedXml(organization);
45
45
  if (!xml) {
46
46
  throw new SimpleError({
47
- code: "failed_generating",
48
- message: "Er ging iets mis bij het aanmaken van het document. Probeer later opieuw en neem contact met ons op als het probleem blijft herhalen."
49
- })
47
+ code: 'failed_generating',
48
+ message: 'Er ging iets mis bij het aanmaken van het document. Probeer later opieuw en neem contact met ons op als het probleem blijft herhalen.',
49
+ });
50
50
  }
51
51
 
52
- const response = new Response(Buffer.from(xml, 'utf8'))
53
- response.headers["content-type"] = "text/plain; charset=utf-8" // avoid JS execution
54
- response.headers["content-length"] = Buffer.byteLength(xml, 'utf8').toString()
55
- return response
52
+ const response = new Response(Buffer.from(xml, 'utf8'));
53
+ response.headers['content-type'] = 'text/plain; charset=utf-8'; // avoid JS execution
54
+ response.headers['content-length'] = Buffer.byteLength(xml, 'utf8').toString();
55
+ return response;
56
56
  }
57
57
  }