@stamhoofd/backend 1.0.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 (150) hide show
  1. package/.env.template.json +63 -0
  2. package/.eslintrc.js +61 -0
  3. package/README.md +40 -0
  4. package/index.ts +172 -0
  5. package/jest.config.js +11 -0
  6. package/migrations.ts +33 -0
  7. package/package.json +48 -0
  8. package/src/crons.ts +845 -0
  9. package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +42 -0
  10. package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +320 -0
  11. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +171 -0
  12. package/src/endpoints/auth/CreateAdminEndpoint.ts +137 -0
  13. package/src/endpoints/auth/CreateTokenEndpoint.test.ts +68 -0
  14. package/src/endpoints/auth/CreateTokenEndpoint.ts +200 -0
  15. package/src/endpoints/auth/DeleteTokenEndpoint.ts +31 -0
  16. package/src/endpoints/auth/ForgotPasswordEndpoint.ts +70 -0
  17. package/src/endpoints/auth/GetUserEndpoint.test.ts +64 -0
  18. package/src/endpoints/auth/GetUserEndpoint.ts +57 -0
  19. package/src/endpoints/auth/PatchApiUserEndpoint.ts +90 -0
  20. package/src/endpoints/auth/PatchUserEndpoint.ts +122 -0
  21. package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +37 -0
  22. package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +41 -0
  23. package/src/endpoints/auth/SignupEndpoint.ts +107 -0
  24. package/src/endpoints/auth/VerifyEmailEndpoint.ts +89 -0
  25. package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +95 -0
  26. package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +31 -0
  27. package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +101 -0
  28. package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +53 -0
  29. package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +57 -0
  30. package/src/endpoints/global/files/UploadFile.ts +147 -0
  31. package/src/endpoints/global/files/UploadImage.ts +119 -0
  32. package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +76 -0
  33. package/src/endpoints/global/members/GetMembersCountEndpoint.ts +43 -0
  34. package/src/endpoints/global/members/GetMembersEndpoint.ts +429 -0
  35. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +734 -0
  36. package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +45 -0
  37. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +105 -0
  38. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +146 -0
  39. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +52 -0
  40. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +80 -0
  41. package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +49 -0
  42. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +58 -0
  43. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +62 -0
  44. package/src/endpoints/global/payments/ExchangeSTPaymentEndpoint.ts +153 -0
  45. package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +134 -0
  46. package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +44 -0
  47. package/src/endpoints/global/platform/GetPlatformEnpoint.ts +39 -0
  48. package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +63 -0
  49. package/src/endpoints/global/registration/GetPaymentRegistrations.ts +68 -0
  50. package/src/endpoints/global/registration/GetUserBalanceEndpoint.ts +39 -0
  51. package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +80 -0
  52. package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +41 -0
  53. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +134 -0
  54. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +521 -0
  55. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +37 -0
  56. package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +115 -0
  57. package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +187 -0
  58. package/src/endpoints/organization/dashboard/billing/ActivatePackagesEndpoint.ts +424 -0
  59. package/src/endpoints/organization/dashboard/billing/DeactivatePackageEndpoint.ts +67 -0
  60. package/src/endpoints/organization/dashboard/billing/GetBillingStatusEndpoint.ts +39 -0
  61. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +57 -0
  62. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +50 -0
  63. package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +50 -0
  64. package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +129 -0
  65. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +114 -0
  66. package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +50 -0
  67. package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +234 -0
  68. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +62 -0
  69. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +85 -0
  70. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +80 -0
  71. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +54 -0
  72. package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +49 -0
  73. package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +63 -0
  74. package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +61 -0
  75. package/src/endpoints/organization/dashboard/organization/ApplyRegisterCodeEndpoint.test.ts +64 -0
  76. package/src/endpoints/organization/dashboard/organization/ApplyRegisterCodeEndpoint.ts +84 -0
  77. package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +43 -0
  78. package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +42 -0
  79. package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +43 -0
  80. package/src/endpoints/organization/dashboard/organization/GetRegisterCodeEndpoint.ts +65 -0
  81. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +281 -0
  82. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +338 -0
  83. package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +196 -0
  84. package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +50 -0
  85. package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +48 -0
  86. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +207 -0
  87. package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +202 -0
  88. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +233 -0
  89. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +66 -0
  90. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +210 -0
  91. package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +93 -0
  92. package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +59 -0
  93. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +78 -0
  94. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +40 -0
  95. package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +69 -0
  96. package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +52 -0
  97. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +73 -0
  98. package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +60 -0
  99. package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +47 -0
  100. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +41 -0
  101. package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +217 -0
  102. package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +51 -0
  103. package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +47 -0
  104. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +83 -0
  105. package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +68 -0
  106. package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +69 -0
  107. package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +125 -0
  108. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +204 -0
  109. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +278 -0
  110. package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +80 -0
  111. package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +60 -0
  112. package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +379 -0
  113. package/src/endpoints/organization/shared/GetDocumentHtml.ts +54 -0
  114. package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +45 -0
  115. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +78 -0
  116. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +34 -0
  117. package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +44 -0
  118. package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +82 -0
  119. package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +59 -0
  120. package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +51 -0
  121. package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +40 -0
  122. package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +124 -0
  123. package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +130 -0
  124. package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +50 -0
  125. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +450 -0
  126. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +335 -0
  127. package/src/helpers/AddressValidator.test.ts +40 -0
  128. package/src/helpers/AddressValidator.ts +256 -0
  129. package/src/helpers/AdminPermissionChecker.ts +1031 -0
  130. package/src/helpers/AuthenticatedStructures.ts +158 -0
  131. package/src/helpers/BuckarooHelper.ts +279 -0
  132. package/src/helpers/CheckSettlements.ts +215 -0
  133. package/src/helpers/Context.ts +202 -0
  134. package/src/helpers/CookieHelper.ts +45 -0
  135. package/src/helpers/ForwardHandler.test.ts +216 -0
  136. package/src/helpers/ForwardHandler.ts +140 -0
  137. package/src/helpers/OpenIDConnectHelper.ts +284 -0
  138. package/src/helpers/StripeHelper.ts +293 -0
  139. package/src/helpers/StripePayoutChecker.ts +188 -0
  140. package/src/middleware/ContextMiddleware.ts +16 -0
  141. package/src/migrations/1646578856-validate-addresses.ts +60 -0
  142. package/src/seeds/0000000000-example.ts +13 -0
  143. package/src/seeds/1715028563-user-permissions.ts +52 -0
  144. package/tests/e2e/stock.test.ts +2120 -0
  145. package/tests/e2e/tickets.test.ts +926 -0
  146. package/tests/helpers/StripeMocker.ts +362 -0
  147. package/tests/helpers/TestServer.ts +21 -0
  148. package/tests/jest.global.setup.ts +29 -0
  149. package/tests/jest.setup.ts +59 -0
  150. package/tsconfig.json +42 -0
@@ -0,0 +1,362 @@
1
+ import { Request } from "@simonbackx/simple-endpoints";
2
+ import { StripeAccount } from "@stamhoofd/models";
3
+ import nock from "nock";
4
+ import qs from 'qs';
5
+ import { v4 as uuidv4 } from "uuid";
6
+
7
+ import { StripeWebookEndpoint } from "../../src/endpoints/global/payments/StripeWebhookEndpoint";
8
+ import { StripeHelper } from "../../src/helpers/StripeHelper";
9
+ import { testServer } from "./TestServer";
10
+
11
+ export class StripeMocker {
12
+ paymentIntents: {id: string}[] = []
13
+ charges: {id: string}[] = [];
14
+ #forceFailure = false;
15
+
16
+ reset() {
17
+ this.paymentIntents = [];
18
+ this.charges = [];
19
+ this.#forceFailure = false;
20
+ }
21
+
22
+ forceFailure() {
23
+ this.#forceFailure = true;
24
+ }
25
+
26
+ start() {
27
+ nock('https://api.stripe.com')
28
+ .persist()
29
+ .get(/v1\/.*/)
30
+ .reply((uri, body) => {
31
+ const [match, resource, id] = uri.match(/\/?v1\/(\w+)(?:\/?(\w+)){0,2}/) || [null];
32
+
33
+ if (!match) {
34
+ return [500];
35
+ }
36
+
37
+ if (resource === 'payment_intents') {
38
+ return this.#getPaymentIntent(id);
39
+ }
40
+
41
+ if (resource === 'charges') {
42
+ return this.#getCharge(id);
43
+ }
44
+
45
+ return [500];
46
+ });
47
+
48
+ nock('https://api.stripe.com')
49
+ .persist()
50
+ .post(/v1\/.*/)
51
+ .reply((uri, body: string) => {
52
+ const [match, resource, id] = uri.match(/\/?v1\/(\w+)(?:\/?(\w+)){0,2}/) || [null];
53
+
54
+ if (!match) {
55
+ return [500];
56
+ }
57
+
58
+ if (this.#forceFailure ) {
59
+ return [400];
60
+ }
61
+
62
+ if (resource === 'payment_methods') {
63
+ // Ignore: this is just creating a saved payment method for Bancontact/iDEAL
64
+ return [200, {
65
+ object: 'payment_method',
66
+ id: this.createId('pm')
67
+ }]
68
+ }
69
+
70
+ if (resource === 'payment_intents') {
71
+ return this.#createPaymentIntent();
72
+ }
73
+
74
+ return [500];
75
+ });
76
+
77
+
78
+ }
79
+
80
+ clear() {
81
+ this.paymentIntents = [];
82
+ this.charges = [];
83
+ }
84
+
85
+ createId(prefix: string) {
86
+ return prefix + '_' + uuidv4().replaceAll('-', '');
87
+ }
88
+
89
+ #getPaymentIntent(id: string) {
90
+ const intent = this.paymentIntents.find(i => i.id === id);
91
+ if (!intent) {
92
+ return [404]
93
+ }
94
+ return [200, intent];
95
+ }
96
+
97
+ #getCharge(id: string) {
98
+ const intent = this.charges.find(i => i.id === id);
99
+ if (!intent) {
100
+ return [404]
101
+ }
102
+ return [200, intent];
103
+ }
104
+
105
+ #createPaymentIntent() {
106
+ const intent = {
107
+ object: 'payment_intent',
108
+ id: this.createId('pi'),
109
+ status: 'requires_action',
110
+ next_action: {
111
+ redirect_to_url: {
112
+ url: 'https://paymenturl'
113
+ }
114
+ }
115
+ };
116
+ this.paymentIntents.push(intent);
117
+ return [200, intent];
118
+ }
119
+
120
+ getLastIntent() {
121
+ return this.paymentIntents[this.paymentIntents.length - 1]
122
+ }
123
+
124
+ async succeedPayment(intent) {
125
+ const charge = {
126
+ id: this.createId('ch'),
127
+ payment_method_details: {
128
+ bancontact: {
129
+ iban_last4: 1234,
130
+ verified_name: 'John Doe'
131
+ }
132
+ }
133
+ };
134
+
135
+ this.charges.push(charge);
136
+
137
+ intent.status = 'succeeded';
138
+ intent.latest_charge = charge.id;
139
+
140
+ await this.#sendWebhook({
141
+ type: 'payment_intent.succeeded',
142
+ data: {
143
+ object: intent
144
+ }
145
+ })
146
+ }
147
+
148
+ async failPayment(intent) {
149
+ intent.status = 'canceled';
150
+
151
+ await this.#sendWebhook({
152
+ type: 'payment_intent.payment_failed',
153
+ data: {
154
+ object: intent
155
+ }
156
+ })
157
+ }
158
+
159
+ async #sendWebhook(payload: {[key: string]: unknown}) {
160
+ payload.id = this.createId('wh');
161
+
162
+ const stripe = StripeHelper.getInstance()
163
+ const endpoint = new StripeWebookEndpoint()
164
+
165
+ const r = Request.buildJson("POST", `/stripe/webhooks`, undefined, payload);
166
+ r.headers['stripe-signature'] = stripe.webhooks.generateTestHeaderString({
167
+ payload: JSON.stringify(payload),
168
+ secret: STAMHOOFD.STRIPE_ENDPOINT_SECRET
169
+ })
170
+ await testServer.test(endpoint, r);
171
+ }
172
+
173
+ decodeBody(body: string) {
174
+ return qs.parse(body, {
175
+ allowPrototypes: true,
176
+ decoder(value: unknown) {
177
+ // Convert numbers to numbers and bools to bools
178
+ if (typeof value === 'string' && /^(\d+|\d*\.\d+)$/.test(value)) {
179
+ return parseFloat(value);
180
+ }
181
+
182
+ const keywords = {
183
+ true: true,
184
+ false: false,
185
+ null: null
186
+ };
187
+ if (typeof value === 'string' && value in keywords) {
188
+ return keywords[value];
189
+ }
190
+
191
+ if (typeof value === 'string') {
192
+ return decodeURIComponent(value);
193
+ }
194
+
195
+ return value;
196
+ }
197
+ });
198
+ }
199
+
200
+ async createStripeAccount(organizationId: string): Promise<StripeAccount> {
201
+ const account = new StripeAccount()
202
+ account.organizationId = organizationId
203
+ account.accountId = this.createId('acct');
204
+ account.setMetaFromStripeAccount(defaultBlobData)
205
+ await account.save();
206
+ return account;
207
+ }
208
+
209
+ stop() {
210
+ nock.cleanAll()
211
+ }
212
+ }
213
+
214
+ const defaultBlobData = {
215
+ "business_profile": {
216
+ "annual_revenue": null,
217
+ "estimated_worker_count": null,
218
+ "mcc": "8641",
219
+ "name": "Demo vereniging",
220
+ "support_address": null,
221
+ "support_email": null,
222
+ "support_phone": null,
223
+ "support_url": null,
224
+ "url": "www.stamhoofd.be"
225
+ },
226
+ "capabilities": {
227
+ "bancontact_payments": "active",
228
+ "card_payments": "active",
229
+ "ideal_payments": "active",
230
+ "transfers": "active"
231
+ },
232
+ "charges_enabled": true,
233
+ "country": "BE",
234
+ "created": 0,
235
+ "default_currency": "eur",
236
+ "details_submitted": true,
237
+ "email": "tests@stamhoofd.be",
238
+ "external_accounts": {
239
+ "data": [
240
+ {
241
+ "account": "acct_test",
242
+ "account_holder_name": null,
243
+ "account_holder_type": null,
244
+ "account_type": null,
245
+ "available_payout_methods": [
246
+ "standard"
247
+ ],
248
+ "bank_name": "KBC BANK NV",
249
+ "country": "BE",
250
+ "currency": "eur",
251
+ "default_for_currency": true,
252
+ "fingerprint": "xxxxxxxxxxxx",
253
+ "future_requirements": {
254
+ "currently_due": [],
255
+ "errors": [],
256
+ "past_due": [],
257
+ "pending_verification": []
258
+ },
259
+ "id": "ba_xxxxxxxxxxx",
260
+ "last4": "1111",
261
+ "metadata": {},
262
+ "object": "bank_account",
263
+ "requirements": {
264
+ "currently_due": [],
265
+ "errors": [],
266
+ "past_due": [],
267
+ "pending_verification": []
268
+ },
269
+ "routing_number": "KREDBEBB",
270
+ "status": "new"
271
+ }
272
+ ],
273
+ "has_more": false,
274
+ "object": "list",
275
+ "total_count": 1,
276
+ "url": "/v1/accounts/acct_test/external_accounts"
277
+ },
278
+ "future_requirements": {
279
+ "alternatives": [],
280
+ "current_deadline": null,
281
+ "currently_due": [],
282
+ "disabled_reason": null,
283
+ "errors": [],
284
+ "eventually_due": [],
285
+ "past_due": [],
286
+ "pending_verification": []
287
+ },
288
+ "id": "acct_text",
289
+ "login_links": {
290
+ "data": [],
291
+ "has_more": false,
292
+ "object": "list",
293
+ "total_count": 0,
294
+ "url": "/v1/accounts/acct_test/login_links"
295
+ },
296
+ "metadata": {},
297
+ "object": "account",
298
+ "payouts_enabled": true,
299
+ "requirements": {
300
+ "alternatives": [],
301
+ "current_deadline": null,
302
+ "currently_due": [],
303
+ "disabled_reason": null,
304
+ "errors": [],
305
+ "eventually_due": [],
306
+ "past_due": [],
307
+ "pending_verification": []
308
+ },
309
+ "settings": {
310
+ "bacs_debit_payments": {
311
+ "display_name": null,
312
+ "service_user_number": null
313
+ },
314
+ "branding": {
315
+ "icon": "file_test",
316
+ "logo": null,
317
+ "primary_color": "#000000",
318
+ "secondary_color": "#000000"
319
+ },
320
+ "card_issuing": {
321
+ "tos_acceptance": {
322
+ "date": null,
323
+ "ip": null
324
+ }
325
+ },
326
+ "card_payments": {
327
+ "decline_on": {
328
+ "avs_failure": false,
329
+ "cvc_failure": false
330
+ },
331
+ "statement_descriptor_prefix": null,
332
+ "statement_descriptor_prefix_kana": null,
333
+ "statement_descriptor_prefix_kanji": null
334
+ },
335
+ "dashboard": {
336
+ "display_name": "Stamhoofd",
337
+ "timezone": "Etc/UTC"
338
+ },
339
+ "invoices": {
340
+ "default_account_tax_ids": null
341
+ },
342
+ "payments": {
343
+ "statement_descriptor": "WWW.STAMHOOFD.BE",
344
+ "statement_descriptor_kana": null,
345
+ "statement_descriptor_kanji": null
346
+ },
347
+ "payouts": {
348
+ "debit_negative_balances": true,
349
+ "schedule": {
350
+ "delay_days": 7,
351
+ "interval": "weekly",
352
+ "weekly_anchor": "monday"
353
+ },
354
+ "statement_descriptor": null
355
+ },
356
+ "sepa_debit_payments": {}
357
+ },
358
+ "tos_acceptance": {
359
+ "date": 0
360
+ },
361
+ "type": "express"
362
+ };
@@ -0,0 +1,21 @@
1
+ import { TestServer } from "@simonbackx/simple-endpoints";
2
+ import { VersionMiddleware } from "@stamhoofd/backend-middleware";
3
+ import { Version } from "@stamhoofd/structures";
4
+
5
+ import { ContextMiddleware } from "../../src/middleware/ContextMiddleware";
6
+
7
+ export const testServer = new TestServer();
8
+
9
+ // Contexts
10
+ testServer.addRequestMiddleware(ContextMiddleware)
11
+
12
+ // Add version headers and minimum version
13
+ const versionMiddleware = new VersionMiddleware({
14
+ latestVersions: {
15
+ android: STAMHOOFD.LATEST_ANDROID_VERSION,
16
+ ios: STAMHOOFD.LATEST_IOS_VERSION,
17
+ web: Version
18
+ },
19
+ minimumVersion: 1 //168
20
+ })
21
+ testServer.addRequestMiddleware(versionMiddleware)
@@ -0,0 +1,29 @@
1
+ require('@stamhoofd/backend-env').load({path: __dirname+'/../../.env.test.json'})
2
+
3
+ import { Database, Migration } from "@simonbackx/simple-database";
4
+ import path from "path";
5
+ const emailPath = require.resolve("@stamhoofd/email")
6
+ const modelsPath = require.resolve("@stamhoofd/models")
7
+ import nock from "nock";
8
+
9
+ // Disable network requests
10
+ nock.disableNetConnect()
11
+
12
+ // Set timezone!
13
+ process.env.TZ = "UTC";
14
+
15
+ // Quick check
16
+ if (new Date().getTimezoneOffset() != 0) {
17
+ throw new Error("Process should always run in UTC timezone");
18
+ }
19
+
20
+ export default async () => {
21
+ // External migrations
22
+ await Migration.runAll(path.dirname(modelsPath) + "/migrations");
23
+ await Migration.runAll(path.dirname(emailPath) + "/migrations");
24
+
25
+ // Internal
26
+ await Migration.runAll(__dirname + "/src/migrations");
27
+
28
+ await Database.end();
29
+ };
@@ -0,0 +1,59 @@
1
+ require('@stamhoofd/backend-env').load({path: __dirname+'/../../.env.test.json'})
2
+
3
+ import { Column,Database } from "@simonbackx/simple-database";
4
+ import { Request } from '@simonbackx/simple-endpoints';
5
+ import { I18n } from "@stamhoofd/backend-i18n";
6
+ import { Email } from "@stamhoofd/email";
7
+ import { Version } from '@stamhoofd/structures';
8
+ import { sleep } from "@stamhoofd/utility";
9
+ import nock from "nock";
10
+
11
+ // Set version of saved structures
12
+ Column.setJSONVersion(Version);
13
+
14
+ // Disable network requests
15
+ nock.disableNetConnect()
16
+
17
+ // Automatically set endpoint default version to latest one (only in tests!)
18
+ Request.defaultVersion = Version
19
+
20
+ // Set timezone!
21
+ process.env.TZ = "UTC";
22
+
23
+ // Quick check
24
+ if (new Date().getTimezoneOffset() != 0) {
25
+ throw new Error("Process should always run in UTC timezone");
26
+ }
27
+
28
+ console.log = jest.fn();
29
+
30
+ beforeAll(async () => {
31
+ await Database.delete("DELETE FROM `tokens`");
32
+ await Database.delete("DELETE FROM `users`");
33
+ await Database.delete("DELETE FROM `registrations`");
34
+ await Database.delete("DELETE FROM `members`");
35
+ await Database.delete("DELETE FROM `postal_codes`");
36
+ await Database.delete("DELETE FROM `cities`");
37
+ await Database.delete("DELETE FROM `provinces`");
38
+
39
+ await Database.delete("DELETE FROM `webshop_orders`");
40
+ await Database.delete("DELETE FROM `webshops`");
41
+ await Database.delete("DELETE FROM `groups`");
42
+ await Database.delete("DELETE FROM `email_addresses`");
43
+
44
+ await Database.delete("DELETE FROM `organizations`");
45
+
46
+ await Database.delete("DELETE FROM `payments`");
47
+ await Database.delete("OPTIMIZE TABLE organizations;"); // fix breaking of indexes due to deletes (mysql bug?)
48
+
49
+ await I18n.load()
50
+ });
51
+
52
+ afterAll(async () => {
53
+ // Wait for email queue etc
54
+ while (Email.currentQueue.length > 0) {
55
+ console.info("Emails still in queue. Waiting...")
56
+ await sleep(100)
57
+ }
58
+ await Database.end();
59
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2019", // needs to be es2019 to support optional chaining. Node.js doesn't support optional chaining yet, so we need the transpiling
4
+ "module": "commonjs",
5
+ "jsx": "preserve",
6
+ "importHelpers": true,
7
+ "moduleResolution": "node",
8
+ "experimentalDecorators": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "sourceMap": true,
12
+ "strictNullChecks": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "outDir": "dist",
16
+ "lib": [
17
+ "es2019",
18
+ "ES2021.String",
19
+ "DOM" // axios fix
20
+ ],
21
+ "types": [
22
+ "node",
23
+ "jest",
24
+ "@stamhoofd/backend-i18n",
25
+ ]
26
+ },
27
+ "include": [
28
+ "src/**/*.ts",
29
+ "tests/**/*.ts",
30
+ "index.ts",
31
+ "migrations.ts",
32
+ "../../../*.d.ts",
33
+ "../../*.d.ts"
34
+ ],
35
+ "exclude": [
36
+ "node_modules",
37
+ "dist"
38
+ ],
39
+ "ts-node": {
40
+ "files": true
41
+ }
42
+ }