@stamhoofd/backend 2.39.1 → 2.40.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 (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 +275 -273
  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 +58 -60
  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,43 +1,43 @@
1
- import { createMollieClient } from '@mollie/api-client';
1
+ import { createMollieClient, PaymentStatus as MolliePaymentStatus } from '@mollie/api-client';
2
2
  import { AutoEncoder, BooleanDecoder, Decoder, field } from '@simonbackx/simple-encoding';
3
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
4
- import { SimpleError } from "@simonbackx/simple-errors";
3
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
4
+ import { SimpleError } from '@simonbackx/simple-errors';
5
5
  import { BalanceItem, BalanceItemPayment, MolliePayment, MollieToken, Organization, PayconiqPayment, Payment } from '@stamhoofd/models';
6
6
  import { QueueHandler } from '@stamhoofd/queues';
7
- import { PaymentGeneral, PaymentMethod, PaymentProvider, PaymentStatus } from "@stamhoofd/structures";
7
+ import { PaymentGeneral, PaymentMethod, PaymentProvider, PaymentStatus } from '@stamhoofd/structures';
8
8
 
9
9
  import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
10
10
  import { BuckarooHelper } from '../../../helpers/BuckarooHelper';
11
11
  import { Context } from '../../../helpers/Context';
12
12
  import { StripeHelper } from '../../../helpers/StripeHelper';
13
13
 
14
- type Params = {id: string};
14
+ type Params = { id: string };
15
15
  class Query extends AutoEncoder {
16
16
  @field({ decoder: BooleanDecoder, optional: true })
17
- exchange = false
17
+ exchange = false;
18
18
 
19
19
  /**
20
20
  * If possible, cancel the payment if it is not yet paid/pending
21
21
  */
22
22
  @field({ decoder: BooleanDecoder, optional: true })
23
- cancel = false
23
+ cancel = false;
24
24
  }
25
- type Body = undefined
26
- type ResponseBody = PaymentGeneral | undefined
25
+ type Body = undefined;
26
+ type ResponseBody = PaymentGeneral | undefined;
27
27
 
28
28
  /**
29
29
  * 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
30
30
  */
31
31
 
32
32
  export class ExchangePaymentEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
33
- queryDecoder = Query as Decoder<Query>
33
+ queryDecoder = Query as Decoder<Query>;
34
34
 
35
35
  protected doesMatch(request: Request): [true, Params] | [false] {
36
- if (request.method != "POST") {
36
+ if (request.method !== 'POST') {
37
37
  return [false];
38
38
  }
39
39
 
40
- const params = Endpoint.parseParameters(request.url, "/payments/@id", {id: String});
40
+ const params = Endpoint.parseParameters(request.url, '/payments/@id', { id: String });
41
41
 
42
42
  if (params) {
43
43
  return [true, params as Params];
@@ -46,293 +46,304 @@ export class ExchangePaymentEndpoint extends Endpoint<Params, Query, Body, Respo
46
46
  }
47
47
 
48
48
  async handle(request: DecodedRequest<Params, Query, Body>) {
49
- const organization = await Context.setOptionalOrganizationScope()
49
+ const organization = await Context.setOptionalOrganizationScope();
50
50
  if (!request.query.exchange) {
51
- await Context.authenticate()
51
+ await Context.authenticate();
52
52
  }
53
-
53
+
54
54
  // Not method on payment because circular references (not supprted in ts)
55
- const payment = await ExchangePaymentEndpoint.pollStatus(request.params.id, organization, request.query.cancel)
55
+ const payment = await ExchangePaymentEndpoint.pollStatus(request.params.id, organization, request.query.cancel);
56
56
  if (!payment) {
57
57
  throw new SimpleError({
58
- code: "",
59
- message: "Deze link is ongeldig"
60
- })
58
+ code: '',
59
+ message: 'Deze link is ongeldig',
60
+ });
61
61
  }
62
62
 
63
63
  if (request.query.exchange) {
64
64
  return new Response(undefined);
65
65
  }
66
-
67
- return new Response(
68
- await AuthenticatedStructures.paymentGeneral(payment, true)
66
+
67
+ return new Response(
68
+ await AuthenticatedStructures.paymentGeneral(payment, true),
69
69
  );
70
70
  }
71
71
 
72
72
  static async handlePaymentStatusUpdate(payment: Payment, organization: Organization, status: PaymentStatus) {
73
73
  if (payment.status === status) {
74
74
  return;
75
- }
75
+ }
76
76
 
77
77
  if (status === PaymentStatus.Succeeded) {
78
- payment.status = PaymentStatus.Succeeded
79
- payment.paidAt = new Date()
78
+ payment.status = PaymentStatus.Succeeded;
79
+ payment.paidAt = new Date();
80
80
  await payment.save();
81
81
 
82
82
  // Prevent concurrency issues
83
- await QueueHandler.schedule("balance-item-update/"+organization.id, async () => {
84
- const unloaded = (await BalanceItemPayment.where({paymentId: payment.id})).map(r => r.setRelation(BalanceItemPayment.payment, payment))
83
+ await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
84
+ const unloaded = (await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment));
85
85
  const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
86
- unloaded
86
+ unloaded,
87
87
  );
88
88
 
89
89
  for (const balanceItemPayment of balanceItemPayments) {
90
90
  await balanceItemPayment.markPaid(organization);
91
91
  }
92
92
 
93
- await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem))
94
- })
93
+ await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
94
+ });
95
95
  return;
96
96
  }
97
97
 
98
- const oldStatus = payment.status
98
+ const oldStatus = payment.status;
99
99
 
100
100
  // Save before updating balance items
101
- payment.status = status
102
- payment.paidAt = null
101
+ payment.status = status;
102
+ payment.paidAt = null;
103
103
  await payment.save();
104
104
 
105
105
  // If OLD status was succeeded, we need to revert the actions
106
106
  if (oldStatus === PaymentStatus.Succeeded) {
107
107
  // No longer succeeded
108
- await QueueHandler.schedule("balance-item-update/"+organization.id, async () => {
108
+ await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
109
109
  const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
110
- (await BalanceItemPayment.where({paymentId: payment.id})).map(r => r.setRelation(BalanceItemPayment.payment, payment))
110
+ (await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment)),
111
111
  );
112
112
 
113
113
  for (const balanceItemPayment of balanceItemPayments) {
114
114
  await balanceItemPayment.undoPaid(organization);
115
115
  }
116
116
 
117
- await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem))
118
- })
117
+ await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
118
+ });
119
119
  }
120
-
120
+
121
121
  // Moved to failed
122
122
  if (status == PaymentStatus.Failed) {
123
- await QueueHandler.schedule("balance-item-update/"+organization.id, async () => {
123
+ await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
124
124
  const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
125
- (await BalanceItemPayment.where({paymentId: payment.id})).map(r => r.setRelation(BalanceItemPayment.payment, payment))
125
+ (await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment)),
126
126
  );
127
127
 
128
128
  for (const balanceItemPayment of balanceItemPayments) {
129
129
  await balanceItemPayment.markFailed(organization);
130
130
  }
131
131
 
132
- await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem))
133
- })
132
+ await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
133
+ });
134
134
  }
135
135
 
136
136
  // If OLD status was FAILED, we need to revert the actions
137
137
  if (oldStatus === PaymentStatus.Failed) { // OLD FAILED!! -> NOW PENDING
138
- await QueueHandler.schedule("balance-item-update/"+organization.id, async () => {
138
+ await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
139
139
  const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
140
- (await BalanceItemPayment.where({paymentId: payment.id})).map(r => r.setRelation(BalanceItemPayment.payment, payment))
140
+ (await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment)),
141
141
  );
142
142
 
143
143
  for (const balanceItemPayment of balanceItemPayments) {
144
144
  await balanceItemPayment.undoFailed(organization);
145
145
  }
146
146
 
147
- await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem))
148
- })
147
+ await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
148
+ });
149
149
  }
150
150
  }
151
151
 
152
152
  /**
153
153
  * ID of payment is needed because of race conditions (need to fetch payment in a race condition save queue)
154
154
  */
155
- static async pollStatus(paymentId: string, org: Organization|null, cancel = false): Promise<Payment | undefined> {
155
+ static async pollStatus(paymentId: string, org: Organization | null, cancel = false): Promise<Payment | undefined> {
156
156
  // Prevent polling the same payment multiple times at the same time: create a queue to prevent races
157
- QueueHandler.cancel("payments/"+paymentId); // Prevent creating more than one queue item for the same payment
158
- return await QueueHandler.schedule("payments/"+paymentId, async () => {
157
+ QueueHandler.cancel('payments/' + paymentId); // Prevent creating more than one queue item for the same payment
158
+ return await QueueHandler.schedule('payments/' + paymentId, async () => {
159
159
  // Get a new copy of the payment (is required to prevent concurreny bugs)
160
- const payment = await Payment.getByID(paymentId)
160
+ const payment = await Payment.getByID(paymentId);
161
161
  if (!payment) {
162
- return
162
+ return;
163
163
  }
164
164
 
165
165
  if (!payment.organizationId) {
166
- console.error('Payment without organization not supported', payment.id)
167
- return
166
+ console.error('Payment without organization not supported', payment.id);
167
+ return;
168
168
  }
169
169
 
170
- const organization = org ?? await Organization.getByID(payment.organizationId)
170
+ const organization = org ?? await Organization.getByID(payment.organizationId);
171
171
  if (!organization) {
172
- console.error('Organization not found for payment', payment.id)
173
- return
172
+ console.error('Organization not found for payment', payment.id);
173
+ return;
174
174
  }
175
175
 
176
- const testMode = organization.privateMeta.useTestPayments ?? STAMHOOFD.environment != 'production'
176
+ const testMode = organization.privateMeta.useTestPayments ?? STAMHOOFD.environment !== 'production';
177
177
 
178
178
  if (payment.status == PaymentStatus.Pending || payment.status == PaymentStatus.Created || (payment.provider === PaymentProvider.Buckaroo && payment.status == PaymentStatus.Failed)) {
179
179
  if (payment.provider === PaymentProvider.Stripe) {
180
180
  try {
181
- let status = await StripeHelper.getStatus(payment, cancel || this.shouldTryToCancel(payment.status, payment), testMode)
181
+ let status = await StripeHelper.getStatus(payment, cancel || this.shouldTryToCancel(payment.status, payment), testMode);
182
182
 
183
183
  if (this.isManualExpired(status, payment)) {
184
- console.error('Manually marking Stripe payment as expired', payment.id)
185
- status = PaymentStatus.Failed
184
+ console.error('Manually marking Stripe payment as expired', payment.id);
185
+ status = PaymentStatus.Failed;
186
186
  }
187
187
 
188
- await this.handlePaymentStatusUpdate(payment, organization, status)
189
- } catch (e) {
188
+ await this.handlePaymentStatusUpdate(payment, organization, status);
189
+ }
190
+ catch (e) {
190
191
  console.error('Payment check failed Stripe', payment.id, e);
191
192
  if (this.isManualExpired(payment.status, payment)) {
192
- console.error('Manually marking Stripe payment as expired', payment.id)
193
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
193
+ console.error('Manually marking Stripe payment as expired', payment.id);
194
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
194
195
  }
195
196
  }
196
- } else if (payment.provider === PaymentProvider.Mollie) {
197
+ }
198
+ else if (payment.provider === PaymentProvider.Mollie) {
197
199
  // check status via mollie
198
- const molliePayments = await MolliePayment.where({ paymentId: payment.id}, { limit: 1 })
200
+ const molliePayments = await MolliePayment.where({ paymentId: payment.id }, { limit: 1 });
199
201
  if (molliePayments.length == 1) {
200
- const molliePayment = molliePayments[0]
202
+ const molliePayment = molliePayments[0];
201
203
  // check status
202
- const token = await MollieToken.getTokenFor(organization.id)
203
-
204
+ const token = await MollieToken.getTokenFor(organization.id);
205
+
204
206
  if (token) {
205
207
  try {
206
208
  const mollieClient = createMollieClient({ accessToken: await token.getAccessToken() });
207
209
  const mollieData = await mollieClient.payments.get(molliePayment.mollieId, {
208
- testmode: organization.privateMeta.useTestPayments ?? STAMHOOFD.environment != 'production',
209
- })
210
+ testmode: organization.privateMeta.useTestPayments ?? STAMHOOFD.environment !== 'production',
211
+ });
210
212
 
211
- console.log(mollieData) // log to log files to check issues
213
+ console.log(mollieData); // log to log files to check issues
212
214
 
213
- const details = (mollieData.details as any)
215
+ const details = mollieData.details as any;
214
216
  if (details?.consumerName) {
215
- payment.ibanName = details.consumerName
217
+ payment.ibanName = details.consumerName;
216
218
  }
217
219
  if (details?.consumerAccount) {
218
- payment.iban = details.consumerAccount
220
+ payment.iban = details.consumerAccount;
219
221
  }
220
222
  if (details?.cardHolder) {
221
- payment.ibanName = details.cardHolder
223
+ payment.ibanName = details.cardHolder;
222
224
  }
223
225
  if (details?.cardNumber) {
224
- payment.iban = "xxxx xxxx xxxx "+details.cardNumber
226
+ payment.iban = 'xxxx xxxx xxxx ' + details.cardNumber;
225
227
  }
226
228
 
227
- if (mollieData.status == "paid") {
228
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Succeeded)
229
- } else if (mollieData.status == "failed" || mollieData.status == "expired" || mollieData.status == "canceled") {
230
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
231
- } else if (this.isManualExpired(payment.status, payment)) {
229
+ if (mollieData.status === MolliePaymentStatus.paid) {
230
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Succeeded);
231
+ }
232
+ else if (mollieData.status === MolliePaymentStatus.failed || mollieData.status === MolliePaymentStatus.expired || mollieData.status === MolliePaymentStatus.canceled) {
233
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
234
+ }
235
+ else if (this.isManualExpired(payment.status, payment)) {
232
236
  // Mollie still returning pending after 1 day: mark as failed
233
- console.error('Manually marking Mollie payment as expired', payment.id)
234
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
237
+ console.error('Manually marking Mollie payment as expired', payment.id);
238
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
235
239
  }
236
- } catch (e) {
240
+ }
241
+ catch (e) {
237
242
  console.error('Payment check failed Mollie', payment.id, e);
238
243
  if (this.isManualExpired(payment.status, payment)) {
239
- console.error('Manually marking Mollie payment as expired', payment.id)
240
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
244
+ console.error('Manually marking Mollie payment as expired', payment.id);
245
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
241
246
  }
242
247
  }
243
- } else {
244
- console.warn("Mollie payment is missing for organization "+organization.id+" while checking payment status...")
248
+ }
249
+ else {
250
+ console.warn('Mollie payment is missing for organization ' + organization.id + ' while checking payment status...');
245
251
 
246
252
  if (this.isManualExpired(payment.status, payment)) {
247
- console.error('Manually marking payment without mollie token as expired', payment.id)
248
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
253
+ console.error('Manually marking payment without mollie token as expired', payment.id);
254
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
249
255
  }
250
256
  }
251
- } else {
257
+ }
258
+ else {
252
259
  if (this.isManualExpired(payment.status, payment)) {
253
- console.error('Manually marking payment without mollie payments as expired', payment.id)
254
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
260
+ console.error('Manually marking payment without mollie payments as expired', payment.id);
261
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
255
262
  }
256
263
  }
257
- } else if (payment.provider == PaymentProvider.Buckaroo) {
258
- const helper = new BuckarooHelper(organization.privateMeta.buckarooSettings?.key ?? "", organization.privateMeta.buckarooSettings?.secret ?? "", organization.privateMeta.useTestPayments ?? STAMHOOFD.environment != 'production')
264
+ }
265
+ else if (payment.provider == PaymentProvider.Buckaroo) {
266
+ const helper = new BuckarooHelper(organization.privateMeta.buckarooSettings?.key ?? '', organization.privateMeta.buckarooSettings?.secret ?? '', organization.privateMeta.useTestPayments ?? STAMHOOFD.environment !== 'production');
259
267
  try {
260
- let status = await helper.getStatus(payment)
268
+ let status = await helper.getStatus(payment);
261
269
 
262
270
  if (this.isManualExpired(status, payment)) {
263
- console.error('Manually marking Buckaroo payment as expired', payment.id)
264
- status = PaymentStatus.Failed
271
+ console.error('Manually marking Buckaroo payment as expired', payment.id);
272
+ status = PaymentStatus.Failed;
265
273
  }
266
274
 
267
- await this.handlePaymentStatusUpdate(payment, organization, status)
268
- } catch (e) {
275
+ await this.handlePaymentStatusUpdate(payment, organization, status);
276
+ }
277
+ catch (e) {
269
278
  console.error('Payment check failed Buckaroo', payment.id, e);
270
279
  if (this.isManualExpired(payment.status, payment)) {
271
- console.error('Manually marking Buckaroo payment as expired', payment.id)
272
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
280
+ console.error('Manually marking Buckaroo payment as expired', payment.id);
281
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
273
282
  }
274
283
  }
275
-
276
- } else if (payment.provider == PaymentProvider.Payconiq) {
284
+ }
285
+ else if (payment.provider == PaymentProvider.Payconiq) {
277
286
  // Check status
278
287
 
279
- const payconiqPayments = await PayconiqPayment.where({ paymentId: payment.id}, { limit: 1 })
288
+ const payconiqPayments = await PayconiqPayment.where({ paymentId: payment.id }, { limit: 1 });
280
289
  if (payconiqPayments.length == 1) {
281
- const payconiqPayment = payconiqPayments[0]
290
+ const payconiqPayment = payconiqPayments[0];
282
291
 
283
292
  if (cancel) {
284
- console.error('Cancelling Payconiq payment on request', payment.id)
285
- await payconiqPayment.cancel(organization)
293
+ console.error('Cancelling Payconiq payment on request', payment.id);
294
+ await payconiqPayment.cancel(organization);
286
295
  }
287
296
 
288
- let status = await payconiqPayment.getStatus(organization)
297
+ let status = await payconiqPayment.getStatus(organization);
289
298
 
290
299
  if (!cancel && this.shouldTryToCancel(status, payment)) {
291
- console.error('Manually cancelling Payconiq payment', payment.id)
300
+ console.error('Manually cancelling Payconiq payment', payment.id);
292
301
  if (await payconiqPayment.cancel(organization)) {
293
- status = PaymentStatus.Failed
302
+ status = PaymentStatus.Failed;
294
303
  }
295
304
  }
296
305
 
297
306
  if (this.isManualExpired(status, payment)) {
298
- console.error('Manually marking Payconiq payment as expired', payment.id)
299
- status = PaymentStatus.Failed
307
+ console.error('Manually marking Payconiq payment as expired', payment.id);
308
+ status = PaymentStatus.Failed;
300
309
  }
301
310
 
302
- await this.handlePaymentStatusUpdate(payment, organization, status)
303
-
304
- } else {
305
- console.warn("Payconiq payment is missing for organization "+organization.id+" while checking payment status...")
311
+ await this.handlePaymentStatusUpdate(payment, organization, status);
312
+ }
313
+ else {
314
+ console.warn('Payconiq payment is missing for organization ' + organization.id + ' while checking payment status...');
306
315
 
307
316
  if (this.isManualExpired(payment.status, payment)) {
308
- console.error('Manually marking Payconiq payment as expired because not found', payment.id)
309
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
317
+ console.error('Manually marking Payconiq payment as expired because not found', payment.id);
318
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
310
319
  }
311
320
  }
312
- } else {
321
+ }
322
+ else {
313
323
  console.error('Invalid payment provider', payment.provider, 'for payment', payment.id);
314
324
  if (this.isManualExpired(payment.status, payment)) {
315
- console.error('Manually marking unknown payment as expired', payment.id)
316
- await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed)
325
+ console.error('Manually marking unknown payment as expired', payment.id);
326
+ await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
317
327
  }
318
328
  }
319
- } else {
329
+ }
330
+ else {
320
331
  // Do a manual update if needed
321
332
  if (payment.status === PaymentStatus.Succeeded) {
322
333
  if (payment.provider === PaymentProvider.Stripe) {
323
334
  // Update the status
324
- await StripeHelper.getStatus(payment, false, testMode)
335
+ await StripeHelper.getStatus(payment, false, testMode);
325
336
  }
326
337
  }
327
338
  }
328
- return payment
329
- })
339
+ return payment;
340
+ });
330
341
  }
331
342
 
332
343
  static isManualExpired(status: PaymentStatus, payment: Payment) {
333
344
  if ((status == PaymentStatus.Pending || status === PaymentStatus.Created) && payment.method !== PaymentMethod.DirectDebit) {
334
345
  // If payment is not succeeded after one day, mark as failed
335
- if (payment.createdAt < new Date(new Date().getTime() - 60*1000*60*24)) {
346
+ if (payment.createdAt < new Date(new Date().getTime() - 60 * 1000 * 60 * 24)) {
336
347
  return true;
337
348
  }
338
349
  }
@@ -344,11 +355,11 @@ export class ExchangePaymentEndpoint extends Endpoint<Params, Query, Body, Respo
344
355
  */
345
356
  static shouldTryToCancel(status: PaymentStatus, payment: Payment) {
346
357
  if ((status == PaymentStatus.Pending || status === PaymentStatus.Created) && payment.method !== PaymentMethod.DirectDebit) {
347
- let timeout = STAMHOOFD.environment === 'development' ? 60*1000*2 : 60*1000*30;
358
+ let timeout = STAMHOOFD.environment === 'development' ? 60 * 1000 * 2 : 60 * 1000 * 30;
348
359
 
349
360
  // If payconiq and not yet 'identified' (scanned), cancel after 5 minutes
350
361
  if (payment.provider === PaymentProvider.Payconiq && status === PaymentStatus.Created) {
351
- timeout = STAMHOOFD.environment === 'development' ? 60*1000*1 : 60*1000*5;
362
+ timeout = STAMHOOFD.environment === 'development' ? 60 * 1000 * 1 : 60 * 1000 * 5;
352
363
  }
353
364
 
354
365
  if (payment.createdAt < new Date(new Date().getTime() - timeout)) {
@@ -1,21 +1,21 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { SimpleError } from "@simonbackx/simple-errors";
3
- import { signInternal } from "@stamhoofd/backend-env";
4
- import { Document } from "@stamhoofd/models";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { SimpleError } from '@simonbackx/simple-errors';
3
+ import { signInternal } from '@stamhoofd/backend-env';
4
+ import { Document } from '@stamhoofd/models';
5
5
 
6
- import { Context } from "../../../helpers/Context";
6
+ import { Context } from '../../../helpers/Context';
7
7
  type Params = { id: string };
8
8
  type Query = undefined;
9
- type Body = undefined
10
- type ResponseBody = Buffer
9
+ type Body = undefined;
10
+ type ResponseBody = Buffer;
11
11
 
12
12
  export class GetDocumentHtml 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, "/documents/@id/html", { id: String});
18
+ const params = Endpoint.parseParameters(request.url, '/documents/@id/html', { id: String });
19
19
 
20
20
  if (params) {
21
21
  return [true, params as Params];
@@ -24,31 +24,31 @@ export class GetDocumentHtml extends Endpoint<Params, Query, Body, ResponseBody>
24
24
  }
25
25
 
26
26
  async handle(request: DecodedRequest<Params, Query, Body>) {
27
- const organization = await Context.setOrganizationScope()
28
- await Context.authenticate()
27
+ const organization = await Context.setOrganizationScope();
28
+ await Context.authenticate();
29
29
 
30
- const document = await Document.getByID(request.params.id)
30
+ const document = await Document.getByID(request.params.id);
31
31
  if (!document || !(await Context.auth.canAccessDocument(document))) {
32
32
  throw new SimpleError({
33
- code: "not_found",
34
- message: "Onbekend document"
35
- })
33
+ code: 'not_found',
34
+ message: 'Onbekend document',
35
+ });
36
36
  }
37
37
 
38
38
  const html = await document.getRenderedHtml(organization);
39
39
  if (!html) {
40
40
  throw new SimpleError({
41
- code: "failed_generating",
42
- 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."
43
- })
41
+ code: 'failed_generating',
42
+ 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.',
43
+ });
44
44
  }
45
45
 
46
- const response = new Response(Buffer.from(html, 'utf8'))
47
- response.headers["content-type"] = "text/plain; charset=utf-8" // avoid JS execution
48
- response.headers["content-length"] = Buffer.byteLength(html, 'utf8').toString()
49
- response.headers["x-cache-id"] = 'document-' + document.id;
50
- response.headers["x-cache-timestamp"] = document.updatedAt.getTime().toString();
51
- response.headers["x-cache-signature"] = signInternal('document-' + document.id, document.updatedAt.getTime().toString(), html)
52
- return response
46
+ const response = new Response(Buffer.from(html, 'utf8'));
47
+ response.headers['content-type'] = 'text/plain; charset=utf-8'; // avoid JS execution
48
+ response.headers['content-length'] = Buffer.byteLength(html, 'utf8').toString();
49
+ response.headers['x-cache-id'] = 'document-' + document.id;
50
+ response.headers['x-cache-timestamp'] = document.updatedAt.getTime().toString();
51
+ response.headers['x-cache-signature'] = signInternal('document-' + document.id, document.updatedAt.getTime().toString(), html);
52
+ return response;
53
53
  }
54
54
  }
@@ -1,23 +1,23 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { SimpleError } from "@simonbackx/simple-errors";
3
- import { Payment } from "@stamhoofd/models";
4
- import { PaymentGeneral } from "@stamhoofd/structures";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { SimpleError } from '@simonbackx/simple-errors';
3
+ import { Payment } from '@stamhoofd/models';
4
+ import { PaymentGeneral } from '@stamhoofd/structures';
5
5
 
6
- import { AuthenticatedStructures } from "../../../helpers/AuthenticatedStructures";
7
- import { Context } from "../../../helpers/Context";
6
+ import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
7
+ import { Context } from '../../../helpers/Context';
8
8
 
9
9
  type Params = { id: string };
10
- type Query = undefined
11
- type Body = undefined
12
- type ResponseBody = PaymentGeneral
10
+ type Query = undefined;
11
+ type Body = undefined;
12
+ type ResponseBody = PaymentGeneral;
13
13
 
14
14
  export class GetPaymentEndpoint 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
- const params = Endpoint.parseParameters(request.url, "/payments/@id", { id: String});
20
+ const params = Endpoint.parseParameters(request.url, '/payments/@id', { id: String });
21
21
 
22
22
  if (params) {
23
23
  return [true, params as Params];
@@ -26,20 +26,20 @@ export class GetPaymentEndpoint extends Endpoint<Params, Query, Body, ResponseBo
26
26
  }
27
27
 
28
28
  async handle(request: DecodedRequest<Params, Query, Body>) {
29
- await Context.setOptionalOrganizationScope()
30
- await Context.authenticate()
29
+ await Context.setOptionalOrganizationScope();
30
+ await Context.authenticate();
31
31
 
32
32
  const payment = await Payment.getByID(request.params.id);
33
33
  if (!payment) {
34
34
  throw new SimpleError({
35
- code: "not_found",
36
- message: "Payment not found",
37
- human: "Je hebt geen toegang tot deze betaling"
38
- })
35
+ code: 'not_found',
36
+ message: 'Payment not found',
37
+ human: 'Je hebt geen toegang tot deze betaling',
38
+ });
39
39
  }
40
40
 
41
41
  return new Response(
42
- await AuthenticatedStructures.paymentGeneral(payment, true)
42
+ await AuthenticatedStructures.paymentGeneral(payment, true),
43
43
  );
44
44
  }
45
45
  }