@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,20 +1,19 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints'
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
2
  import { SimpleError } from '@simonbackx/simple-errors';
3
3
  import { Organization, RegisterCode } from '@stamhoofd/models';
4
- import {RegisterCode as RegisterCodeStruct } from "@stamhoofd/structures"
4
+ import { RegisterCode as RegisterCodeStruct } from '@stamhoofd/structures';
5
5
  type Params = { code: string };
6
6
  type Query = undefined;
7
7
  type Body = undefined;
8
8
  type ResponseBody = RegisterCodeStruct;
9
9
 
10
10
  export class CheckRegisterCodeEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
11
-
12
11
  protected doesMatch(request: Request): [true, Params] | [false] {
13
- if (request.method != "GET") {
12
+ if (request.method !== 'GET') {
14
13
  return [false];
15
14
  }
16
15
 
17
- const params = Endpoint.parseParameters(request.url, "/register-code/@code", {code: String});
16
+ const params = Endpoint.parseParameters(request.url, '/register-code/@code', { code: String });
18
17
 
19
18
  if (params) {
20
19
  return [true, params as Params];
@@ -23,23 +22,22 @@ export class CheckRegisterCodeEndpoint extends Endpoint<Params, Query, Body, Res
23
22
  }
24
23
 
25
24
  async handle(request: DecodedRequest<Params, Query, Body>) {
26
-
27
- const code = await RegisterCode.getByID(request.params.code)
25
+ const code = await RegisterCode.getByID(request.params.code);
28
26
  if (code) {
29
27
  return new Response(RegisterCodeStruct.create({
30
28
  code: code.code,
31
29
  description: code.description,
32
30
  customMessage: code.customMessage,
33
31
  organizationName: code.organizationId ? ((await Organization.getByID(code.organizationId))!.name) : null,
34
- value: code.value
35
- }))
32
+ value: code.value,
33
+ }));
36
34
  }
37
35
 
38
36
  throw new SimpleError({
39
- code: "invalid_code",
40
- message: "Invalid code",
41
- human: "Deze code is niet geldig",
42
- field: "registerCode"
43
- })
37
+ code: 'invalid_code',
38
+ message: 'Invalid code',
39
+ human: 'Deze code is niet geldig',
40
+ field: 'registerCode',
41
+ });
44
42
  }
45
43
  }
@@ -1,57 +1,56 @@
1
+ import { Request } from '@simonbackx/simple-endpoints';
2
+ import { Address, Country, CreateOrganization, NewUser, Organization as OrganizationStruct, Version } from '@stamhoofd/structures';
1
3
 
2
- import { Request } from "@simonbackx/simple-endpoints";
3
- import { Address, Country, CreateOrganization, NewUser, Organization as OrganizationStruct, Version } from "@stamhoofd/structures";
4
+ import { testServer } from '../../../../tests/helpers/TestServer';
5
+ import { CreateOrganizationEndpoint } from './CreateOrganizationEndpoint';
4
6
 
5
- import { testServer } from "../../../../tests/helpers/TestServer";
6
- import { CreateOrganizationEndpoint } from "./CreateOrganizationEndpoint";
7
-
8
- describe("Endpoint.CreateOrganization", () => {
7
+ describe('Endpoint.CreateOrganization', () => {
9
8
  // Test endpoint
10
9
  const endpoint = new CreateOrganizationEndpoint();
11
10
 
12
- test("Can create a new organization", async () => {
13
- const r = Request.buildJson("POST", `/v${Version}/organizations`, "todo-host.be", CreateOrganization.create({
11
+ test('Can create a new organization', async () => {
12
+ const r = Request.buildJson('POST', `/v${Version}/organizations`, 'todo-host.be', CreateOrganization.create({
14
13
  organization: OrganizationStruct.create({
15
- name: "My endpoint test organization",
16
- uri: "my-endpoint-test-organization",
14
+ name: 'My endpoint test organization',
15
+ uri: 'my-endpoint-test-organization',
17
16
  address: Address.create({
18
- street: "My street",
19
- number: "1",
20
- postalCode: "9000",
21
- city: "Gent",
22
- country: Country.Belgium
17
+ street: 'My street',
18
+ number: '1',
19
+ postalCode: '9000',
20
+ city: 'Gent',
21
+ country: Country.Belgium,
23
22
  }),
24
-
23
+
25
24
  }),
26
25
  user: NewUser.create({
27
- email: "voorbeeld@stamhoofd.be",
28
- password: "My user password",
26
+ email: 'voorbeeld@stamhoofd.be',
27
+ password: 'My user password',
29
28
  }),
30
- }).encode({version: Version}));
29
+ }).encode({ version: Version }));
31
30
 
32
31
  const response = await testServer.test(endpoint, r);
33
32
  expect(response.body.token).not.toBeEmpty();
34
33
  });
35
34
 
36
- test("Creating an organization with an in-use URI throws", async () => {
37
- const r = Request.buildJson("POST", `/v${Version}/organizations`, "todo-host.be", CreateOrganization.create({
35
+ test('Creating an organization with an in-use URI throws', async () => {
36
+ const r = Request.buildJson('POST', `/v${Version}/organizations`, 'todo-host.be', CreateOrganization.create({
38
37
  organization: OrganizationStruct.create({
39
- name: "My endpoint test organization",
40
- uri: "my-endpoint-test-organization",
38
+ name: 'My endpoint test organization',
39
+ uri: 'my-endpoint-test-organization',
41
40
  address: Address.create({
42
- street: "My street",
43
- number: "1",
44
- postalCode: "9000",
45
- city: "Gent",
46
- country: Country.Belgium
41
+ street: 'My street',
42
+ number: '1',
43
+ postalCode: '9000',
44
+ city: 'Gent',
45
+ country: Country.Belgium,
47
46
  }),
48
-
47
+
49
48
  }),
50
49
  user: NewUser.create({
51
- email: "voorbeeld@stamhoofd.be",
52
- password: "My user password",
53
- })
54
- }).encode({version: Version}));
50
+ email: 'voorbeeld@stamhoofd.be',
51
+ password: 'My user password',
52
+ }),
53
+ }).encode({ version: Version }));
55
54
 
56
55
  await expect(testServer.test(endpoint, r)).rejects.toThrow(/name/);
57
56
  });
@@ -1,9 +1,9 @@
1
1
  import { Decoder } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
3
3
  import { SimpleError } from '@simonbackx/simple-errors';
4
4
  import { EmailVerificationCode, Organization, User } from '@stamhoofd/models';
5
- import { CreateOrganization, PermissionLevel, Permissions, SignupResponse, UserPermissions } from "@stamhoofd/structures";
6
- import { Formatter } from "@stamhoofd/utility";
5
+ import { CreateOrganization, PermissionLevel, Permissions, SignupResponse, UserPermissions } from '@stamhoofd/structures';
6
+ import { Formatter } from '@stamhoofd/utility';
7
7
 
8
8
  type Params = Record<string, never>;
9
9
  type Query = undefined;
@@ -14,11 +14,11 @@ export class CreateOrganizationEndpoint extends Endpoint<Params, Query, Body, Re
14
14
  bodyDecoder = CreateOrganization as Decoder<CreateOrganization>;
15
15
 
16
16
  protected doesMatch(request: Request): [true, Params] | [false] {
17
- if (request.method != "POST") {
17
+ if (request.method !== 'POST') {
18
18
  return [false];
19
19
  }
20
20
 
21
- const params = Endpoint.parseParameters(request.url, "/organizations", {});
21
+ const params = Endpoint.parseParameters(request.url, '/organizations', {});
22
22
 
23
23
  if (params) {
24
24
  return [true, params as Params];
@@ -29,48 +29,48 @@ export class CreateOrganizationEndpoint extends Endpoint<Params, Query, Body, Re
29
29
  async handle(request: DecodedRequest<Params, Query, Body>) {
30
30
  if (STAMHOOFD.userMode === 'platform') {
31
31
  throw new SimpleError({
32
- code: "invalid_field",
33
- message: "Not allowed",
34
- human: "Je kan geen vereniging aanmaken"
35
- })
32
+ code: 'invalid_field',
33
+ message: 'Not allowed',
34
+ human: 'Je kan geen vereniging aanmaken',
35
+ });
36
36
  }
37
37
 
38
38
  if (request.body.organization.name.length < 4) {
39
39
  if (request.body.organization.name.length == 0) {
40
40
  throw new SimpleError({
41
- code: "invalid_field",
42
- message: "Should not be empty",
43
- human: "Je bent de naam van je organisatie vergeten in te vullen",
44
- field: "organization.name"
45
- })
41
+ code: 'invalid_field',
42
+ message: 'Should not be empty',
43
+ human: 'Je bent de naam van je organisatie vergeten in te vullen',
44
+ field: 'organization.name',
45
+ });
46
46
  }
47
47
 
48
48
  throw new SimpleError({
49
- code: "invalid_field",
50
- message: "Field is too short",
51
- human: "Kijk de naam van je organisatie na, deze is te kort. Vul eventueel aan met de gemeente.",
52
- field: "organization.name"
53
- })
49
+ code: 'invalid_field',
50
+ message: 'Field is too short',
51
+ human: 'Kijk de naam van je organisatie na, deze is te kort. Vul eventueel aan met de gemeente.',
52
+ field: 'organization.name',
53
+ });
54
54
  }
55
55
 
56
56
  const uri = Formatter.slug(request.body.organization.name);
57
57
 
58
58
  if (uri.length > 100) {
59
59
  throw new SimpleError({
60
- code: "invalid_field",
61
- message: "Field is too long",
62
- human: "De naam van de vereniging is te lang. Probeer de naam wat te verkorten en probeer opnieuw.",
63
- field: "organization.name"
64
- })
60
+ code: 'invalid_field',
61
+ message: 'Field is too long',
62
+ human: 'De naam van de vereniging is te lang. Probeer de naam wat te verkorten en probeer opnieuw.',
63
+ field: 'organization.name',
64
+ });
65
65
  }
66
66
  const alreadyExists = await Organization.getByURI(uri);
67
67
 
68
68
  if (alreadyExists) {
69
69
  throw new SimpleError({
70
- code: "name_taken",
71
- message: "An organization with the same name already exists",
72
- human: "Er bestaat al een vereniging met dezelfde naam. Voeg bijvoorbeeld de naam van je gemeente toe.",
73
- field: "name",
70
+ code: 'name_taken',
71
+ message: 'An organization with the same name already exists',
72
+ human: 'Er bestaat al een vereniging met dezelfde naam. Voeg bijvoorbeeld de naam van je gemeente toe.',
73
+ field: 'name',
74
74
  });
75
75
  }
76
76
 
@@ -84,61 +84,52 @@ export class CreateOrganizationEndpoint extends Endpoint<Params, Query, Body, Re
84
84
  // let registerCodeModels: Model[] = []
85
85
  // let delayEmails: EmailInterfaceBase[] = []
86
86
 
87
- //if (request.body.registerCode) {
87
+ // if (request.body.registerCode) {
88
88
  // const applied = await RegisterCode.applyRegisterCode(organization, request.body.registerCode)
89
89
  // registerCodeModels = applied.models
90
90
  // delayEmails = applied.emails
91
- //}
91
+ // }
92
92
 
93
93
  organization.uri = uri;
94
- organization.meta = request.body.organization.meta
95
- organization.address = request.body.organization.address
96
- organization.privateMeta.acquisitionTypes = request.body.organization.privateMeta?.acquisitionTypes ?? []
94
+ organization.meta = request.body.organization.meta;
95
+ organization.address = request.body.organization.address;
96
+ organization.privateMeta.acquisitionTypes = request.body.organization.privateMeta?.acquisitionTypes ?? [];
97
97
 
98
98
  try {
99
99
  await organization.save();
100
- } catch (e) {
100
+ }
101
+ catch (e) {
101
102
  console.error(e);
102
103
  throw new SimpleError({
103
- code: "creating_organization",
104
- message: "Something went wrong while creating the organization. Please try again later or contact us.",
105
- statusCode: 500
104
+ code: 'creating_organization',
105
+ message: 'Something went wrong while creating the organization. Please try again later or contact us.',
106
+ statusCode: 500,
106
107
  });
107
108
  }
108
109
 
109
110
  const user = await User.register(
110
111
  organization,
111
- request.body.user
112
+ request.body.user,
112
113
  );
113
114
  if (!user) {
114
115
  // This user already exists, well that is pretty impossible
115
116
  throw new SimpleError({
116
- code: "creating_user",
117
- message: "Something went wrong while creating the user. Please contact us to resolve this issue.",
118
- statusCode: 500
117
+ code: 'creating_user',
118
+ message: 'Something went wrong while creating the user. Please contact us to resolve this issue.',
119
+ statusCode: 500,
119
120
  });
120
121
  }
121
122
 
122
123
  // Should prevent this extra save
123
- user.permissions = UserPermissions.create({})
124
- user.permissions.organizationPermissions.set(organization.id, Permissions.create({ level: PermissionLevel.Full }))
125
- await user.save()
124
+ user.permissions = UserPermissions.create({});
125
+ user.permissions.organizationPermissions.set(organization.id, Permissions.create({ level: PermissionLevel.Full }));
126
+ await user.save();
126
127
 
127
- // for (const model of registerCodeModels) {
128
- // await model.save()
129
- // }
130
-
131
- const code = await EmailVerificationCode.createFor(user, user.email)
132
- code.send(user, organization, request.i18n)
133
-
134
- // for (const email of delayEmails) {
135
- // Email.sendInternal(email, organization.i18n)
136
- // }
128
+ const code = await EmailVerificationCode.createFor(user, user.email);
129
+ code.send(user, organization, request.i18n).catch(console.error);
137
130
 
138
131
  return new Response(SignupResponse.create({
139
- token: code.token
132
+ token: code.token,
140
133
  }));
141
134
  }
142
-
143
-
144
135
  }
@@ -1,52 +1,51 @@
1
- import { Request } from "@simonbackx/simple-endpoints";
1
+ import { Request } from '@simonbackx/simple-endpoints';
2
2
  import { GroupFactory, OrganizationFactory } from '@stamhoofd/models';
3
3
  import { Organization } from '@stamhoofd/structures';
4
4
 
5
- import { testServer } from "../../../../tests/helpers/TestServer";
5
+ import { testServer } from '../../../../tests/helpers/TestServer';
6
6
  import { GetOrganizationFromDomainEndpoint } from './GetOrganizationFromDomainEndpoint';
7
7
 
8
- describe("Endpoint.GetOrganizationFromDomain", () => {
8
+ describe('Endpoint.GetOrganizationFromDomain', () => {
9
9
  // Test endpoint
10
10
  const endpoint = new GetOrganizationFromDomainEndpoint();
11
11
 
12
- test("Get organization from default uri", async () => {
13
- const organization = await new OrganizationFactory({}).create()
14
- const groups = await new GroupFactory({ organization }).createMultiple(2)
12
+ test('Get organization from default uri', async () => {
13
+ const organization = await new OrganizationFactory({}).create();
14
+ const groups = await new GroupFactory({ organization }).createMultiple(2);
15
15
 
16
- const r = Request.buildJson("GET", "/v2/organization-from-domain");
16
+ const r = Request.buildJson('GET', '/v2/organization-from-domain');
17
17
  r.query = {
18
- "domain": organization.uri+".stamhoofd.dev",
19
- }
18
+ domain: organization.uri + '.stamhoofd.dev',
19
+ };
20
20
 
21
21
  const response = await testServer.test(endpoint, r);
22
22
  expect(response.body).toBeDefined();
23
23
 
24
24
  if (!(response.body instanceof Organization)) {
25
- throw new Error("Expected Organization")
25
+ throw new Error('Expected Organization');
26
26
  }
27
27
 
28
- expect(response.body.id).toEqual(organization.id)
29
- expect(response.body.groups.map(g => g.id).sort()).toEqual(groups.map(g => g.id).sort())
28
+ expect(response.body.id).toEqual(organization.id);
29
+ expect(response.body.groups.map(g => g.id).sort()).toEqual(groups.map(g => g.id).sort());
30
30
  });
31
31
 
32
- test("Get organization from custom domain", async () => {
33
- const organization = await new OrganizationFactory({ domain: "inschrijven.mijnscouts.be"}).create()
34
- const groups = await new GroupFactory({ organization }).createMultiple(2)
32
+ test('Get organization from custom domain', async () => {
33
+ const organization = await new OrganizationFactory({ domain: 'inschrijven.mijnscouts.be' }).create();
34
+ const groups = await new GroupFactory({ organization }).createMultiple(2);
35
35
 
36
- const r = Request.buildJson("GET", "/v2/organization-from-domain");
36
+ const r = Request.buildJson('GET', '/v2/organization-from-domain');
37
37
  r.query = {
38
- "domain": "inschrijven.mijnscouts.be",
39
- }
38
+ domain: 'inschrijven.mijnscouts.be',
39
+ };
40
40
 
41
41
  const response = await testServer.test(endpoint, r);
42
42
  expect(response.body).toBeDefined();
43
43
 
44
44
  if (!(response.body instanceof Organization)) {
45
- throw new Error("Expected Organization")
45
+ throw new Error('Expected Organization');
46
46
  }
47
47
 
48
- expect(response.body.id).toEqual(organization.id)
49
- expect(response.body.groups.map(g => g.id).sort()).toEqual(groups.map(g => g.id).sort())
48
+ expect(response.body.id).toEqual(organization.id);
49
+ expect(response.body.groups.map(g => g.id).sort()).toEqual(groups.map(g => g.id).sort());
50
50
  });
51
-
52
51
  });
@@ -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
- import { Organization as OrganizationStruct } from "@stamhoofd/structures";
6
- import { GoogleTranslateHelper } from "@stamhoofd/utility";
7
- import { AuthenticatedStructures } from "../../../helpers/AuthenticatedStructures";
5
+ import { Organization as OrganizationStruct } from '@stamhoofd/structures';
6
+ import { GoogleTranslateHelper } from '@stamhoofd/utility';
7
+ import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
8
8
  type Params = Record<string, never>;
9
9
 
10
10
  class Query extends AutoEncoder {
@@ -12,7 +12,7 @@ class Query extends AutoEncoder {
12
12
  domain: string;
13
13
  }
14
14
 
15
- type Body = undefined
15
+ type Body = undefined;
16
16
  type ResponseBody = OrganizationStruct;
17
17
 
18
18
  /**
@@ -20,15 +20,15 @@ type ResponseBody = OrganizationStruct;
20
20
  */
21
21
 
22
22
  export class GetOrganizationFromDomainEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
23
- queryDecoder = Query as Decoder<Query>
24
- registrationDomains = [... new Set(Object.values(STAMHOOFD.domains.registration ?? {}))]
23
+ queryDecoder = Query as Decoder<Query>;
24
+ registrationDomains = [...new Set(Object.values(STAMHOOFD.domains.registration ?? {}))];
25
25
 
26
26
  protected doesMatch(request: Request): [true, Params] | [false] {
27
- if (request.method != "GET") {
27
+ if (request.method !== 'GET') {
28
28
  return [false];
29
29
  }
30
30
 
31
- const params = Endpoint.parseParameters(request.url, "/organization-from-domain", {});
31
+ const params = Endpoint.parseParameters(request.url, '/organization-from-domain', {});
32
32
 
33
33
  if (params) {
34
34
  return [true, params as Params];
@@ -38,28 +38,28 @@ export class GetOrganizationFromDomainEndpoint extends Endpoint<Params, Query, B
38
38
 
39
39
  async handle(request: DecodedRequest<Params, Query, Body>) {
40
40
  // Clean up google translate domains -> make sure we can translate register pages
41
- request.query.domain = GoogleTranslateHelper.getDomainFromTranslateDomain(request.query.domain)
41
+ request.query.domain = GoogleTranslateHelper.getDomainFromTranslateDomain(request.query.domain);
42
42
 
43
43
  for (const domain of this.registrationDomains) {
44
- if (request.query.domain.endsWith("." + domain)) {
45
- const strippped = request.query.domain.substr(0, request.query.domain.length - ("." + domain).length )
46
- if (strippped.includes(".")) {
44
+ if (request.query.domain.endsWith('.' + domain)) {
45
+ const strippped = request.query.domain.substr(0, request.query.domain.length - ('.' + domain).length);
46
+ if (strippped.includes('.')) {
47
47
  throw new SimpleError({
48
- code: "invalid_domain",
49
- message: "This domain format is not supported",
50
- statusCode: 404
51
- })
48
+ code: 'invalid_domain',
49
+ message: 'This domain format is not supported',
50
+ statusCode: 404,
51
+ });
52
52
  }
53
53
 
54
54
  // Search for the URI
55
- const organization = await Organization.getByURI(strippped)
55
+ const organization = await Organization.getByURI(strippped);
56
56
 
57
57
  if (!organization) {
58
58
  throw new SimpleError({
59
- code: "unknown_organization",
60
- message: "No organization registered with this domain name",
61
- statusCode: 404
62
- })
59
+ code: 'unknown_organization',
60
+ message: 'No organization registered with this domain name',
61
+ statusCode: 404,
62
+ });
63
63
  }
64
64
  return new Response(await AuthenticatedStructures.organization(organization));
65
65
  }
@@ -67,14 +67,14 @@ export class GetOrganizationFromDomainEndpoint extends Endpoint<Params, Query, B
67
67
 
68
68
  // Check if we have an organization with a custom domain name
69
69
 
70
- const organization = await Organization.getByRegisterDomain(request.query.domain)
70
+ const organization = await Organization.getByRegisterDomain(request.query.domain);
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
  return new Response(await AuthenticatedStructures.organization(organization));
80
80
  }
@@ -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
- import { Organization as OrganizationStruct } from "@stamhoofd/structures";
6
- import { GoogleTranslateHelper } from "@stamhoofd/utility";
7
- import { AuthenticatedStructures } from "../../../helpers/AuthenticatedStructures";
5
+ import { Organization as OrganizationStruct } from '@stamhoofd/structures';
6
+ import { GoogleTranslateHelper } from '@stamhoofd/utility';
7
+ import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
8
8
  type Params = Record<string, never>;
9
9
 
10
10
  class Query extends AutoEncoder {
@@ -12,7 +12,7 @@ class Query extends AutoEncoder {
12
12
  uri: string;
13
13
  }
14
14
 
15
- type Body = undefined
15
+ type Body = undefined;
16
16
  type ResponseBody = OrganizationStruct;
17
17
 
18
18
  /**
@@ -20,14 +20,14 @@ type ResponseBody = OrganizationStruct;
20
20
  */
21
21
 
22
22
  export class GetOrganizationFromUriEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
23
- queryDecoder = Query as Decoder<Query>
23
+ queryDecoder = Query as Decoder<Query>;
24
24
 
25
25
  protected doesMatch(request: Request): [true, Params] | [false] {
26
- if (request.method != "GET") {
26
+ if (request.method !== 'GET') {
27
27
  return [false];
28
28
  }
29
29
 
30
- const params = Endpoint.parseParameters(request.url, "/organization-from-uri", {});
30
+ const params = Endpoint.parseParameters(request.url, '/organization-from-uri', {});
31
31
 
32
32
  if (params) {
33
33
  return [true, params as Params];
@@ -36,22 +36,22 @@ export class GetOrganizationFromUriEndpoint extends Endpoint<Params, Query, Body
36
36
  }
37
37
 
38
38
  async handle(request: DecodedRequest<Params, Query, Body>) {
39
- const organization = await Organization.getByURI(request.query.uri)
39
+ const organization = await Organization.getByURI(request.query.uri);
40
40
 
41
41
  if (!organization) {
42
42
  throw new SimpleError({
43
- code: "unknown_organization",
44
- message: "No organization registered with this uri",
45
- statusCode: 404
46
- })
43
+ code: 'unknown_organization',
44
+ message: 'No organization registered with this uri',
45
+ statusCode: 404,
46
+ });
47
47
  }
48
48
 
49
49
  if (!organization.active) {
50
50
  throw new SimpleError({
51
- code: "archived_organization",
52
- message: "This organization has been archived",
53
- statusCode: 404
54
- })
51
+ code: 'archived_organization',
52
+ message: 'This organization has been archived',
53
+ statusCode: 404,
54
+ });
55
55
  }
56
56
  return new Response(await AuthenticatedStructures.organization(organization));
57
57
  }