@stamhoofd/backend 2.143.1 → 2.145.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 (111) hide show
  1. package/package.json +19 -19
  2. package/src/crons/fake-settlements.test.ts +13 -11
  3. package/src/crons/fake-settlements.ts +22 -38
  4. package/src/crons/mollie-chargebacks.ts +31 -29
  5. package/src/crons/mollie-refunds.ts +61 -59
  6. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +16 -5
  7. package/src/endpoints/auth/CreateTokenEndpoint.test.ts +210 -4
  8. package/src/endpoints/auth/CreateTokenEndpoint.ts +9 -20
  9. package/src/endpoints/auth/DeleteTokenEndpoint.test.ts +29 -0
  10. package/src/endpoints/auth/DeleteTokenEndpoint.ts +2 -1
  11. package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -11
  12. package/src/endpoints/auth/MFA.security.test.ts +9 -7
  13. package/src/endpoints/auth/MFA.test.ts +42 -15
  14. package/src/endpoints/auth/PatchUserEndpoint.ts +3 -2
  15. package/src/endpoints/auth/VerifyEmailEndpoint.ts +5 -4
  16. package/src/endpoints/global/email/GetAdminEmailsEndpoint.test.ts +4 -3
  17. package/src/endpoints/global/email/GetUserEmailsEndpoint.test.ts +6 -5
  18. package/src/endpoints/global/email/PatchEmailEndpoint.test.ts +5 -4
  19. package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.test.ts +5 -4
  20. package/src/endpoints/global/events/PatchEventNotificationsEndpoint.test.ts +2 -1
  21. package/src/endpoints/global/events/PatchEventsEndpoint.test.ts +2 -1
  22. package/src/endpoints/global/files/UploadFile.test.ts +2 -1
  23. package/src/endpoints/global/files/UploadFile.ts +53 -25
  24. package/src/endpoints/global/files/UploadImage.test.ts +2 -1
  25. package/src/endpoints/global/files/UploadImage.ts +32 -6
  26. package/src/endpoints/global/files/upload-security.test.ts +3 -2
  27. package/src/endpoints/global/groups/GetGroupsEndpoint.test.ts +4 -3
  28. package/src/endpoints/global/members/GetMembersEndpoint.test.ts +26 -25
  29. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +57 -56
  30. package/src/endpoints/global/members/SendMemberSecurityCodeEndpoint.test.ts +4 -3
  31. package/src/endpoints/global/platform/GetPlatformEndpoint.test.ts +6 -4
  32. package/src/endpoints/global/platform/PatchPlatformEnpoint.test.ts +6 -6
  33. package/src/endpoints/global/platform/SignOutPlatformAdminsEndpoint.test.ts +9 -8
  34. package/src/endpoints/global/registration/GetRegistrationsEndpoint.test.ts +14 -13
  35. package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +24 -23
  36. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +4 -3
  37. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.test.ts +2 -1
  38. package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.test.ts +2 -1
  39. package/src/endpoints/global/webshops/GetWebshopsEndpoint.test.ts +20 -19
  40. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemBreakdownEndpoint.test.ts +2 -1
  41. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsEndpoint.test.ts +2 -1
  42. package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.test.ts +3 -2
  43. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.test.ts +4 -3
  44. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.test.ts +5 -4
  45. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.test.ts +5 -4
  46. package/src/endpoints/organization/dashboard/invoices/GetInvoicesEndpoint.test.ts +2 -1
  47. package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.test.ts +2 -1
  48. package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.ts +0 -1
  49. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +23 -22
  50. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +4 -4
  51. package/src/endpoints/organization/dashboard/payments/GetPaymentBreakdownEndpoint.test.ts +2 -1
  52. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.test.ts +4 -3
  53. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +2 -2
  54. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint.test.ts +2 -1
  55. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.test.ts +5 -4
  56. package/src/endpoints/organization/dashboard/registration-periods/MoveRegistrationPeriods.test.ts +7 -6
  57. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.test.ts +9 -8
  58. package/src/endpoints/organization/dashboard/settlements/SettlementsExportEndpoint.test.ts +3 -2
  59. package/src/endpoints/organization/dashboard/settlements/SettlementsSyncEndpoint.test.ts +2 -1
  60. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.test.ts +5 -4
  61. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +2 -1
  62. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.test.ts +3 -2
  63. package/src/endpoints/organization/dashboard/users/PatchApiUserEndpoint.test.ts +6 -5
  64. package/src/endpoints/organization/dashboard/users/SignOutOrganizationAdminsEndpoint.test.ts +16 -15
  65. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.test.ts +2 -1
  66. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.test.ts +2 -1
  67. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.test.ts +2 -1
  68. package/src/endpoints/organization/dashboard/webshops/WebshopReservedPathSegments.test.ts +2 -1
  69. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +4 -3
  70. package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +6 -5
  71. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +94 -8
  72. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +18 -18
  73. package/src/helpers/ApplicationFeeInvoicer.ts +1 -1
  74. package/src/helpers/Context.ts +14 -21
  75. package/src/helpers/ContextStorage.ts +5 -0
  76. package/src/helpers/MollieSettlementSync.test.ts +94 -41
  77. package/src/helpers/MollieSettlementSync.ts +174 -78
  78. package/src/helpers/StripeSettlementSync.test.ts +0 -85
  79. package/src/helpers/StripeSettlementSync.ts +47 -70
  80. package/src/helpers/TwoFactorHelper.ts +21 -22
  81. package/src/helpers/streamForBreakdown.ts +1 -1
  82. package/src/services/AdminSessionService.ts +5 -3
  83. package/src/services/InvoiceService.ts +2 -2
  84. package/src/services/MollieService.ts +168 -126
  85. package/src/services/PaymentService.ts +2 -2
  86. package/src/services/SSOService.test.ts +25 -1
  87. package/src/services/SSOService.ts +17 -6
  88. package/src/services/SessionService.test.ts +319 -0
  89. package/src/services/SessionService.ts +357 -0
  90. package/src/services/SettlementService.test.ts +13 -85
  91. package/src/services/SettlementService.ts +5 -113
  92. package/src/services/WebshopCrowdfundingService.test.ts +4 -3
  93. package/src/sql-filters/balance-items.ts +10 -0
  94. package/src/sql-filters/registrations.ts +59 -1
  95. package/tests/actions/patchUserMember.ts +2 -1
  96. package/tests/e2e/api-rate-limits.test.ts +2 -1
  97. package/tests/e2e/bundle-discounts.test.ts +4 -3
  98. package/tests/e2e/charge-members.test.ts +6 -5
  99. package/tests/e2e/documents.test.ts +4 -3
  100. package/tests/e2e/private-files.test.ts +9 -8
  101. package/tests/e2e/register.test.ts +4 -3
  102. package/tests/e2e/stock.test.ts +4 -3
  103. package/tests/e2e/tickets.test.ts +4 -3
  104. package/tests/helpers/ExportSlice.ts +2 -1
  105. package/tests/helpers/MollieMocker.ts +173 -38
  106. package/tests/init/initAdmin.ts +2 -1
  107. package/tests/init/initPlatformAdmin.ts +2 -1
  108. package/src/helpers/ViesHelper.test.ts +0 -401
  109. package/src/helpers/ViesHelper.ts +0 -215
  110. package/src/services/PeppolDirectoryService.test.ts +0 -139
  111. package/src/services/PeppolDirectoryService.ts +0 -111
@@ -1,10 +1,11 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization, RegistrationPeriod } from '@stamhoofd/models';
3
- import { EmailTemplate, GroupFactory, OrganizationFactory, Platform, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
2
+ import type { Organization, RegistrationPeriod, Token } from '@stamhoofd/models';
3
+ import { EmailTemplate, GroupFactory, OrganizationFactory, Platform, RegistrationPeriodFactory, UserFactory } from '@stamhoofd/models';
4
4
  import { EmailTemplateType, PermissionLevel, PermissionRoleDetailed, Permissions, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
5
5
  import { TestUtils } from '@stamhoofd/test-utils';
6
6
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
7
7
  import { GetEmailTemplatesEndpoint } from './GetEmailTemplatesEndpoint.js';
8
+ import { SessionService } from '../../../../services/SessionService.js';
8
9
 
9
10
  const baseUrl = `/v${Version}/email-templates`;
10
11
 
@@ -66,7 +67,7 @@ describe('Endpoint.GetEmailTemplatesEndpoint', () => {
66
67
  const organization = await new OrganizationFactory({ period }).create();
67
68
  const group = await new GroupFactory({ organization }).create();
68
69
 
69
- const token = await Token.createToken(user);
70
+ const token = await SessionService.createSession(user);
70
71
 
71
72
  const template = new EmailTemplate();
72
73
  template.subject = 'test template 1';
@@ -99,7 +100,7 @@ describe('Endpoint.GetEmailTemplatesEndpoint', () => {
99
100
  }),
100
101
  }).create();
101
102
 
102
- const token = await Token.createToken(user);
103
+ const token = await SessionService.createSession(user);
103
104
 
104
105
  const template = new EmailTemplate();
105
106
  template.subject = 'saved template';
@@ -1,14 +1,15 @@
1
1
  import type { PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
2
2
  import { PatchableArray, PatchMap } from '@simonbackx/simple-encoding';
3
3
  import { Request } from '@simonbackx/simple-endpoints';
4
- import type { Organization, RegistrationPeriod } from '@stamhoofd/models';
5
- import { EmailTemplate, GroupFactory, OrganizationFactory, Platform, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
4
+ import type { Organization, RegistrationPeriod, Token } from '@stamhoofd/models';
5
+ import { EmailTemplate, GroupFactory, OrganizationFactory, Platform, RegistrationPeriodFactory, UserFactory } from '@stamhoofd/models';
6
6
  import { EmailContent, EmailTemplate as EmailTemplateStruct, EmailTemplateType, PermissionLevel, PermissionRoleDetailed, Permissions, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
7
7
  import { Language } from '@stamhoofd/types/Language';
8
8
  import { STExpect, TestUtils } from '@stamhoofd/test-utils';
9
9
  import { v4 as uuidv4 } from 'uuid';
10
10
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
11
11
  import { PatchEmailTemplatesEndpoint } from './PatchEmailTemplatesEndpoint.js';
12
+ import { SessionService } from '../../../../services/SessionService.js';
12
13
 
13
14
  const baseUrl = `/v${Version}/email-templates`;
14
15
 
@@ -64,7 +65,7 @@ describe('Endpoint.PatchEmailTemplatesEndpoint', () => {
64
65
  const organization = await new OrganizationFactory({ period }).create();
65
66
  const group = await new GroupFactory({ organization }).create();
66
67
 
67
- const token = await Token.createToken(user);
68
+ const token = await SessionService.createSession(user);
68
69
 
69
70
  const template = new EmailTemplate();
70
71
  template.subject = 'test template 1';
@@ -99,7 +100,7 @@ describe('Endpoint.PatchEmailTemplatesEndpoint', () => {
99
100
  level: PermissionLevel.Full,
100
101
  }),
101
102
  }).create();
102
- const token = await Token.createToken(user);
103
+ const token = await SessionService.createSession(user);
103
104
  return { organization, token };
104
105
  };
105
106
 
@@ -6,6 +6,7 @@ import { LimitedFilteredRequest, PermissionLevel, Permissions } from '@stamhoofd
6
6
  import { STExpect } from '@stamhoofd/test-utils';
7
7
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
8
8
  import { GetInvoicesEndpoint } from './GetInvoicesEndpoint.js';
9
+ import { SessionService } from '../../../../services/SessionService.js';
9
10
 
10
11
  describe('Endpoint.GetInvoicesEndpoint', () => {
11
12
  const endpoint = new GetInvoicesEndpoint();
@@ -38,7 +39,7 @@ describe('Endpoint.GetInvoicesEndpoint', () => {
38
39
  };
39
40
 
40
41
  const getInvoices = async ({ filter, organization, user }: { filter: StamhoofdFilter | null; organization: Organization; user: User }) => {
41
- const token = await Token.createToken(user);
42
+ const token = await SessionService.createSession(user);
42
43
 
43
44
  const request = Request.get({
44
45
  path: '/invoices',
@@ -8,6 +8,7 @@ import { PaymentMethod, PaymentStatus, PermissionLevel, Permissions } from '@sta
8
8
  import { STExpect } from '@stamhoofd/test-utils';
9
9
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
10
10
  import { PatchInvoicesEndpoint } from './PatchInvoicesEndpoint.js';
11
+ import { SessionService } from '../../../../services/SessionService.js';
11
12
 
12
13
  describe('Endpoint.PatchInvoicesEndpoint', () => {
13
14
  const endpoint = new PatchInvoicesEndpoint();
@@ -56,7 +57,7 @@ describe('Endpoint.PatchInvoicesEndpoint', () => {
56
57
  };
57
58
 
58
59
  const patchInvoices = async ({ body, organization, user }: { body: PatchableArrayAutoEncoder<InvoiceStruct>; organization: Organization; user: User }) => {
59
- const token = await Token.createToken(user);
60
+ const token = await SessionService.createSession(user);
60
61
  const request = Request.buildJson('PATCH', '/invoices', organization.getApiHost(), body);
61
62
  request.headers.authorization = 'Bearer ' + token.accessToken;
62
63
  return await testServer.test<InvoiceStruct[]>(endpoint, request);
@@ -8,7 +8,6 @@ import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStruct
8
8
  import { Context } from '../../../../helpers/Context.js';
9
9
  import { Invoice } from '@stamhoofd/models';
10
10
  import { SimpleError } from '@simonbackx/simple-errors';
11
- import { ViesHelper } from '../../../../helpers/ViesHelper.js';
12
11
  import { InvoiceService } from '../../../../services/InvoiceService.js';
13
12
 
14
13
  type Params = Record<string, never>;
@@ -1,7 +1,8 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization, User, Webshop } from '@stamhoofd/models';
3
- import { GroupFactory, OrganizationFactory, OrganizationRegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory, WebshopFactory } from '@stamhoofd/models';
2
+ import type { Organization, User, Webshop, Token } from '@stamhoofd/models';
3
+ import { GroupFactory, OrganizationFactory, OrganizationRegistrationPeriod, RegistrationPeriodFactory, UserFactory, WebshopFactory } from '@stamhoofd/models';
4
4
  import { AccessRight, Address, Company, MemberResponsibility, OrganizationMetaData, OrganizationPrivateMetaData, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, Organization as OrganizationStruct, PeppolEndointId, PermissionLevel, PermissionRoleDetailed, PermissionRoleForResponsibility, Permissions, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
5
+ import { SessionService } from '../../../../services/SessionService.js';
5
6
 
6
7
  import type { AutoEncoderPatchType, PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
7
8
  import { PatchableArray, PatchMap } from '@simonbackx/simple-encoding';
@@ -29,7 +30,7 @@ describe('Endpoint.PatchOrganization', () => {
29
30
  const organization = await new OrganizationFactory({}).create();
30
31
  const user = await new UserFactory({ organization, permissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
31
32
  // const groups = await new GroupFactory({ organization }).createMultiple(2)
32
- const token = await Token.createToken(user);
33
+ const token = await SessionService.createSession(user);
33
34
 
34
35
  const r = Request.buildJson('PATCH', '/v2/organization', organization.getApiHost(), {
35
36
  id: organization.id,
@@ -51,7 +52,7 @@ describe('Endpoint.PatchOrganization', () => {
51
52
  test("Can't change organization as a normal user", async () => {
52
53
  const organization = await new OrganizationFactory({}).create();
53
54
  const user = await new UserFactory({ organization }).create();
54
- const token = await Token.createToken(user);
55
+ const token = await SessionService.createSession(user);
55
56
 
56
57
  const r = Request.buildJson('PATCH', '/organization', organization.getApiHost(), {
57
58
  id: organization.id,
@@ -65,7 +66,7 @@ describe('Endpoint.PatchOrganization', () => {
65
66
  test("Can't change organization as a user with read access", async () => {
66
67
  const organization = await new OrganizationFactory({}).create();
67
68
  const user = await new UserFactory({ organization, permissions: Permissions.create({ level: PermissionLevel.Read }) }).create();
68
- const token = await Token.createToken(user);
69
+ const token = await SessionService.createSession(user);
69
70
 
70
71
  const r = Request.buildJson('PATCH', '/organization', organization.getApiHost(), {
71
72
  id: organization.id,
@@ -169,7 +170,7 @@ describe('Endpoint.PatchOrganization', () => {
169
170
  })
170
171
  .create();
171
172
 
172
- const token = await Token.createToken(user);
173
+ const token = await SessionService.createSession(user);
173
174
 
174
175
  // act
175
176
  const response = await patchOrganization({
@@ -275,7 +276,7 @@ describe('Endpoint.PatchOrganization', () => {
275
276
  })
276
277
  .create();
277
278
 
278
- const token = await Token.createToken(user);
279
+ const token = await SessionService.createSession(user);
279
280
 
280
281
  // act
281
282
  const response = await patchOrganization({
@@ -336,7 +337,7 @@ describe('Endpoint.PatchOrganization', () => {
336
337
  })
337
338
  .create();
338
339
 
339
- token = await Token.createToken(user);
340
+ token = await SessionService.createSession(user);
340
341
  });
341
342
 
342
343
  test('should throw if put roles', async () => {
@@ -687,7 +688,7 @@ describe('Endpoint.PatchOrganization', () => {
687
688
  })
688
689
  .create();
689
690
 
690
- const userWithReadAccessToken = await Token.createToken(userWithReadAccess);
691
+ const userWithReadAccessToken = await SessionService.createSession(userWithReadAccess);
691
692
 
692
693
  const userWithWriteAccess = await new UserFactory({
693
694
  organization,
@@ -702,7 +703,7 @@ describe('Endpoint.PatchOrganization', () => {
702
703
  })
703
704
  .create();
704
705
 
705
- const userWithWriteAccessToken = await Token.createToken(userWithReadAccess);
706
+ const userWithWriteAccessToken = await SessionService.createSession(userWithReadAccess);
706
707
 
707
708
  const otherWebshop = await new WebshopFactory({ organizationId: organization.id }).create();
708
709
 
@@ -719,7 +720,7 @@ describe('Endpoint.PatchOrganization', () => {
719
720
  })
720
721
  .create();
721
722
 
722
- const userWithFullAccessForOtherWebshopToken = await Token.createToken(userWithReadAccess);
723
+ const userWithFullAccessForOtherWebshopToken = await SessionService.createSession(userWithReadAccess);
723
724
 
724
725
  usersWithoutFullAccess = [
725
726
  { user: userWithReadAccess, token: userWithReadAccessToken },
@@ -1002,7 +1003,7 @@ describe('Endpoint.PatchOrganization', () => {
1002
1003
  })
1003
1004
  .create();
1004
1005
 
1005
- token = await Token.createToken(user);
1006
+ token = await SessionService.createSession(user);
1006
1007
  });
1007
1008
 
1008
1009
  test('should not be able to put roles', async () => {
@@ -1299,7 +1300,7 @@ describe('Endpoint.PatchOrganization', () => {
1299
1300
  .query({ participant: `iso6523-actorid-upis::${schemeID}:${id}` })
1300
1301
  .reply(200, {
1301
1302
  'total-result-count': 1,
1302
- matches: [{
1303
+ 'matches': [{
1303
1304
  participantID: { scheme: 'iso6523-actorid-upis', value: `${schemeID}:${id}` },
1304
1305
  entities: [{ name: [{ name: entityName }] }],
1305
1306
  }],
@@ -1326,7 +1327,7 @@ describe('Endpoint.PatchOrganization', () => {
1326
1327
  const scope = mockDirectoryFound('0208', '0123456789');
1327
1328
  const organization = await new OrganizationFactory({}).create();
1328
1329
  const user = await new UserFactory({ organization, permissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1329
- const token = await Token.createToken(user);
1330
+ const token = await SessionService.createSession(user);
1330
1331
 
1331
1332
  const patch = OrganizationStruct.patch({
1332
1333
  id: organization.id,
@@ -1354,7 +1355,7 @@ describe('Endpoint.PatchOrganization', () => {
1354
1355
  await organization.save();
1355
1356
 
1356
1357
  const user = await new UserFactory({ organization, permissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1357
- const token = await Token.createToken(user);
1358
+ const token = await SessionService.createSession(user);
1358
1359
 
1359
1360
  const patch = OrganizationStruct.patch({
1360
1361
  id: organization.id,
@@ -1375,7 +1376,7 @@ describe('Endpoint.PatchOrganization', () => {
1375
1376
  const scope = mockDirectoryFound('0088', '5412345000013');
1376
1377
  const organization = await new OrganizationFactory({}).create();
1377
1378
  const user = await new UserFactory({ globalPermissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1378
- const token = await Token.createToken(user);
1379
+ const token = await SessionService.createSession(user);
1379
1380
 
1380
1381
  const patch = OrganizationStruct.patch({
1381
1382
  id: organization.id,
@@ -1404,7 +1405,7 @@ describe('Endpoint.PatchOrganization', () => {
1404
1405
  mockDirectoryFound('0088', '5412345000013', 'Directory Name');
1405
1406
  const organization = await new OrganizationFactory({}).create();
1406
1407
  const user = await new UserFactory({ globalPermissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1407
- const token = await Token.createToken(user);
1408
+ const token = await SessionService.createSession(user);
1408
1409
 
1409
1410
  const patch = OrganizationStruct.patch({
1410
1411
  id: organization.id,
@@ -1425,7 +1426,7 @@ describe('Endpoint.PatchOrganization', () => {
1425
1426
  test('a KBO custom PEPPOL endpoint id that does not match the company number is rejected', async () => {
1426
1427
  const organization = await new OrganizationFactory({}).create();
1427
1428
  const user = await new UserFactory({ globalPermissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1428
- const token = await Token.createToken(user);
1429
+ const token = await SessionService.createSession(user);
1429
1430
 
1430
1431
  const patch = OrganizationStruct.patch({
1431
1432
  id: organization.id,
@@ -1447,11 +1448,11 @@ describe('Endpoint.PatchOrganization', () => {
1447
1448
  nock('https://directory.peppol.eu')
1448
1449
  .get('/search/1.0/json')
1449
1450
  .query({ participant: 'iso6523-actorid-upis::0088:5412345000013' })
1450
- .reply(200, { 'total-result-count': 0, matches: [] } as nock.Body);
1451
+ .reply(200, { 'total-result-count': 0, 'matches': [] } as nock.Body);
1451
1452
 
1452
1453
  const organization = await new OrganizationFactory({}).create();
1453
1454
  const user = await new UserFactory({ globalPermissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1454
- const token = await Token.createToken(user);
1455
+ const token = await SessionService.createSession(user);
1455
1456
 
1456
1457
  const patch = OrganizationStruct.patch({
1457
1458
  id: organization.id,
@@ -1483,7 +1484,7 @@ describe('Endpoint.PatchOrganization', () => {
1483
1484
  await organization.save();
1484
1485
 
1485
1486
  const user = await new UserFactory({ organization, permissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1486
- const token = await Token.createToken(user);
1487
+ const token = await SessionService.createSession(user);
1487
1488
 
1488
1489
  const newPeriod = await new RegistrationPeriodFactory({}).create();
1489
1490
 
@@ -1510,7 +1511,7 @@ describe('Endpoint.PatchOrganization', () => {
1510
1511
  await organization.save();
1511
1512
 
1512
1513
  const user = await new UserFactory({ organization, permissions: Permissions.create({ level: PermissionLevel.Full }) }).create();
1513
- const token = await Token.createToken(user);
1514
+ const token = await SessionService.createSession(user);
1514
1515
 
1515
1516
  const otherOrganization = await new OrganizationFactory({ }).create();
1516
1517
  const newPeriod = await new RegistrationPeriodFactory({ organization: otherOrganization }).create();
@@ -15,7 +15,7 @@ import { MemberUserSyncer } from '../../../../helpers/MemberUserSyncer.js';
15
15
  import { RecordAnswerHelper } from '../../../../helpers/RecordAnswerHelper.js';
16
16
  import { SetupStepUpdater } from '../../../../helpers/SetupStepUpdater.js';
17
17
  import { TagHelper } from '../../../../helpers/TagHelper.js';
18
- import { ViesHelper } from '../../../../helpers/ViesHelper.js';
18
+ import { ViesService } from '@stamhoofd/vies';
19
19
  import { UitpasService } from '../../../../services/uitpas/UitpasService.js';
20
20
  import { VATService } from '../../../../services/VATService.js';
21
21
  import { isAbortedError, isCanceledError } from '@stamhoofd/queues';
@@ -697,7 +697,7 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
697
697
 
698
698
  // Changed VAT number
699
699
  const prepatched = original.patch(patch);
700
- await ViesHelper.checkCompany(prepatched, patch);
700
+ await ViesService.checkCompany(prepatched, patch);
701
701
  }
702
702
 
703
703
  let c = 0;
@@ -717,7 +717,7 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
717
717
  this.requirePeppolPermission();
718
718
  }
719
719
 
720
- await ViesHelper.checkCompany(put, put);
720
+ await ViesService.checkCompany(put, null, { forceValidation: true });
721
721
  }
722
722
  } else {
723
723
  if (companies.length > 5) {
@@ -734,7 +734,7 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
734
734
  this.requirePeppolPermission();
735
735
  }
736
736
 
737
- await ViesHelper.checkCompany(company, company);
737
+ await ViesService.checkCompany(company, null, { forceValidation: true });
738
738
  }
739
739
  }
740
740
  }
@@ -12,6 +12,7 @@ import { exportSlice } from '../../../../../tests/helpers/ExportSlice.js';
12
12
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
13
13
  import { GetPaymentEndpoint } from '../../shared/GetPaymentEndpoint.js';
14
14
  import { GetPaymentBreakdownEndpoint } from './GetPaymentBreakdownEndpoint.js';
15
+ import { SessionService } from '../../../../services/SessionService.js';
15
16
 
16
17
  /**
17
18
  * What was ordered: the name of the product, its unit price, how many, and optionally one chosen
@@ -23,7 +24,7 @@ describe('Endpoint.GetPaymentBreakdownEndpoint', () => {
23
24
  const endpoint = new GetPaymentBreakdownEndpoint();
24
25
 
25
26
  const getBreakdown = async ({ filter, path, search, narrowFilter, organization, user }: { filter?: StamhoofdFilter; path?: BreakdownPathItem[]; search?: string; narrowFilter?: StamhoofdFilter; organization: Organization; user: User }) => {
26
- const token = await Token.createToken(user);
27
+ const token = await SessionService.createSession(user);
27
28
 
28
29
  const request = Request.get({
29
30
  path: '/payments/breakdown',
@@ -1,12 +1,13 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization, User } from '@stamhoofd/models';
3
- import { BalanceItem, BalanceItemFactory, BalanceItemPayment, OrderFactory, OrganizationFactory, Payment, StripeAccount, Token, UserFactory, WebshopFactory } from '@stamhoofd/models';
2
+ import type { Organization, User, BalanceItem } from '@stamhoofd/models';
3
+ import { BalanceItemFactory, BalanceItemPayment, OrderFactory, OrganizationFactory, Payment, StripeAccount, Token, UserFactory, WebshopFactory } from '@stamhoofd/models';
4
4
  import type { PaginatedResponse, PaymentGeneral, StamhoofdFilter } from '@stamhoofd/structures';
5
5
  import { BalanceItemRelation, BalanceItemRelationType, BalanceItemType, LimitedFilteredRequest, PaymentMethod, PaymentProvider, PaymentStatus, PermissionLevel, Permissions, TranslatedString } from '@stamhoofd/structures';
6
6
  import { v4 as uuidv4 } from 'uuid';
7
7
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
8
8
  import { SettlementService } from '../../../../services/SettlementService.js';
9
9
  import { GetPaymentsEndpoint } from './GetPaymentsEndpoint.js';
10
+ import { SessionService } from '../../../../services/SessionService.js';
10
11
 
11
12
  // These tests exercise the balance-item filters reused inside the payments query (balanceItemPayments ->
12
13
  // balanceItem -> ...), which is the path where balance_items is joined into another query.
@@ -14,7 +15,7 @@ describe('Endpoint.GetPaymentsEndpoint', () => {
14
15
  const endpoint = new GetPaymentsEndpoint();
15
16
 
16
17
  const getPayments = async ({ filter, organization, user }: { filter: StamhoofdFilter | null; organization: Organization; user: User }) => {
17
- const token = await Token.createToken(user);
18
+ const token = await SessionService.createSession(user);
18
19
 
19
20
  const request = Request.get({
20
21
  path: '/payments',
@@ -12,7 +12,7 @@ import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStruct
12
12
  import { Context } from '../../../../helpers/Context.js';
13
13
  import { BalanceItemService } from '../../../../services/BalanceItemService.js';
14
14
  import { PaymentService } from '../../../../services/PaymentService.js';
15
- import { ViesHelper } from '../../../../helpers/ViesHelper.js';
15
+ import { ViesService } from '@stamhoofd/vies';
16
16
 
17
17
  type Params = Record<string, never>;
18
18
  type Query = undefined;
@@ -112,7 +112,7 @@ export class PatchPaymentsEndpoint extends Endpoint<Params, Query, Body, Respons
112
112
  }
113
113
 
114
114
  if (put.customer?.company) {
115
- await ViesHelper.checkCompany(put.customer.company, put.customer.company);
115
+ await ViesService.checkCompany(put.customer.company, null, { forceValidation: true });
116
116
  }
117
117
  payment.type = put.type;
118
118
 
@@ -6,6 +6,7 @@ import { PaymentMethod, PaymentStatus, PermissionLevel, Permissions, ReceivableB
6
6
  import { TestUtils } from '@stamhoofd/test-utils';
7
7
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
8
8
  import { GetReceivableBalanceEndpoint } from './GetReceivableBalanceEndpoint.js';
9
+ import { SessionService } from '../../../../services/SessionService.js';
9
10
 
10
11
  describe('Endpoint.GetReceivableBalanceEndpoint', () => {
11
12
  const endpoint = new GetReceivableBalanceEndpoint();
@@ -56,7 +57,7 @@ describe('Endpoint.GetReceivableBalanceEndpoint', () => {
56
57
  };
57
58
 
58
59
  const getReceivableBalance = async ({ type, id, organization, user }: { type: ReceivableBalanceType; id: string; organization: Organization; user: User }) => {
59
- const token = await Token.createToken(user);
60
+ const token = await SessionService.createSession(user);
60
61
 
61
62
  const request = Request.get({
62
63
  path: `/receivable-balances/${type}/${id}`,
@@ -1,9 +1,10 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization, RegistrationPeriod } from '@stamhoofd/models';
3
- import { GroupFactory, OrganizationFactory, OrganizationRegistrationPeriodFactory, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
2
+ import type { Organization, RegistrationPeriod, Token } from '@stamhoofd/models';
3
+ import { GroupFactory, OrganizationFactory, OrganizationRegistrationPeriodFactory, RegistrationPeriodFactory, UserFactory } from '@stamhoofd/models';
4
4
  import { GroupType, LimitedFilteredRequest, PermissionLevel, Permissions } from '@stamhoofd/structures';
5
5
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
6
6
  import { GetOrganizationRegistrationPeriodsEndpoint } from './GetOrganizationRegistrationPeriodsEndpoint.js';
7
+ import { SessionService } from '../../../../services/SessionService.js';
7
8
 
8
9
  const baseUrl = `/organization/registration-periods`;
9
10
 
@@ -61,7 +62,7 @@ describe('Endpoint.GetOrganizationRegistrationPeriods', () => {
61
62
  }),
62
63
  })
63
64
  .create();
64
- const token = await Token.createToken(user);
65
+ const token = await SessionService.createSession(user);
65
66
 
66
67
  const otherOrganization = await initOrganization(registrationPeriod1);
67
68
 
@@ -145,7 +146,7 @@ describe('Endpoint.GetOrganizationRegistrationPeriods', () => {
145
146
  })
146
147
  .create();
147
148
 
148
- const token = await Token.createToken(user);
149
+ const token = await SessionService.createSession(user);
149
150
 
150
151
  const group1 = await new GroupFactory({
151
152
  organization,
@@ -1,8 +1,9 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization, OrganizationRegistrationPeriod, RegistrationPeriod } from '@stamhoofd/models';
3
- import { GroupFactory, MemberFactory, OrganizationFactory, OrganizationRegistrationPeriodFactory, Registration, RegistrationFactory, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
2
+ import type { Organization, OrganizationRegistrationPeriod, RegistrationPeriod, Token } from '@stamhoofd/models';
3
+ import { GroupFactory, MemberFactory, OrganizationFactory, OrganizationRegistrationPeriodFactory, Registration, RegistrationFactory, RegistrationPeriodFactory, UserFactory } from '@stamhoofd/models';
4
4
  import { Group, GroupCategory, GroupCategorySettings, GroupType, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, OrganizationRegistrationPeriodSettings, PermissionLevel, Permissions, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
5
5
  import { PatchOrganizationRegistrationPeriodsEndpoint } from './PatchOrganizationRegistrationPeriodsEndpoint.js';
6
+ import { SessionService } from '../../../../services/SessionService.js';
6
7
 
7
8
  import type { PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
8
9
  import { PatchableArray } from '@simonbackx/simple-encoding';
@@ -37,7 +38,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriodsEndpoint.MoveRegistration
37
38
  level: PermissionLevel.Full,
38
39
  }),
39
40
  }).create();
40
- token = await Token.createToken(user);
41
+ token = await SessionService.createSession(user);
41
42
 
42
43
  const allGroupsUser = await new UserFactory({
43
44
  organization,
@@ -52,7 +53,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriodsEndpoint.MoveRegistration
52
53
  ]]),
53
54
  }),
54
55
  }).create();
55
- allGroupsToken = await Token.createToken(allGroupsUser);
56
+ allGroupsToken = await SessionService.createSession(allGroupsUser);
56
57
  });
57
58
 
58
59
  const patchOrganizationRegistrationPeriods = async ({ patch, organization, token }: { patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> | OrganizationRegistrationPeriodStruct[]; organization: Organization; token: Token }) => {
@@ -317,7 +318,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriodsEndpoint.MoveRegistration
317
318
  level: PermissionLevel.Full,
318
319
  }),
319
320
  }).create();
320
- token = await Token.createToken(user);
321
+ token = await SessionService.createSession(user);
321
322
  });
322
323
 
323
324
  const patchOrganizationRegistrationPeriods = async ({ patch, organization, token }: { patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> | OrganizationRegistrationPeriodStruct[]; organization: Organization; token: Token }) => {
@@ -506,7 +507,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriodsEndpoint.MoveCategoryToPe
506
507
  level: PermissionLevel.Full,
507
508
  }),
508
509
  }).create();
509
- token = await Token.createToken(user);
510
+ token = await SessionService.createSession(user);
510
511
  });
511
512
 
512
513
  const patchOrganizationRegistrationPeriods = async ({ patch }: { patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> }) => {
@@ -1,7 +1,8 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization } from '@stamhoofd/models';
3
- import { Group, GroupFactory, OrganizationFactory, OrganizationRegistrationPeriod, OrganizationRegistrationPeriodFactory, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
2
+ import type { Organization, Token } from '@stamhoofd/models';
3
+ import { Group, GroupFactory, OrganizationFactory, OrganizationRegistrationPeriod, OrganizationRegistrationPeriodFactory, RegistrationPeriodFactory, UserFactory } from '@stamhoofd/models';
4
4
  import { GroupCategory, GroupSettings, Group as GroupStruct, GroupType, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, PermissionLevel, Permissions, TranslatedString, Version } from '@stamhoofd/structures';
5
+ import { SessionService } from '../../../../services/SessionService.js';
5
6
 
6
7
  import type { PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
7
8
  import { PatchableArray } from '@simonbackx/simple-encoding';
@@ -45,7 +46,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriods', () => {
45
46
  permissions: Permissions.create({ level: PermissionLevel.Full }),
46
47
  }).create();
47
48
 
48
- const token = await Token.createToken(user);
49
+ const token = await SessionService.createSession(user);
49
50
 
50
51
  const patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> = new PatchableArray();
51
52
 
@@ -77,7 +78,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriods', () => {
77
78
  permissions: Permissions.create({ level: PermissionLevel.Full }),
78
79
  }).create();
79
80
 
80
- const token = await Token.createToken(user);
81
+ const token = await SessionService.createSession(user);
81
82
 
82
83
  const patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> = new PatchableArray();
83
84
 
@@ -107,7 +108,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriods', () => {
107
108
  permissions: Permissions.create({ level: PermissionLevel.Full }),
108
109
  }).create();
109
110
 
110
- const token = await Token.createToken(user);
111
+ const token = await SessionService.createSession(user);
111
112
 
112
113
  const patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> = new PatchableArray();
113
114
 
@@ -142,7 +143,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriods', () => {
142
143
  permissions: Permissions.create({ level: PermissionLevel.Full }),
143
144
  }).create();
144
145
 
145
- const token = await Token.createToken(user);
146
+ const token = await SessionService.createSession(user);
146
147
 
147
148
  const patch: PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct> = new PatchableArray();
148
149
 
@@ -171,7 +172,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriods', () => {
171
172
  permissions: Permissions.create({ level: PermissionLevel.Full }),
172
173
  }).create();
173
174
 
174
- const token = await Token.createToken(user);
175
+ const token = await SessionService.createSession(user);
175
176
 
176
177
  // A waiting list group and a regular group that references it. The regular group is
177
178
  // listed BEFORE the waiting list, reproducing the ordering produced by Group.defaultSort
@@ -237,7 +238,7 @@ describe('Endpoint.PatchOrganizationRegistrationPeriods', () => {
237
238
  permissions: Permissions.create({ level: PermissionLevel.Full }),
238
239
  }).create();
239
240
 
240
- const token = await Token.createToken(user);
241
+ const token = await SessionService.createSession(user);
241
242
 
242
243
  // create group
243
244
  const group = await new GroupFactory({ organization: otherOrganization }).create();
@@ -11,6 +11,7 @@ import { v4 as uuidv4 } from 'uuid';
11
11
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
12
12
  import { initMembershipOrganization } from '../../../../../tests/init/initMembershipOrganization.js';
13
13
  import { initPlatformAdmin } from '../../../../../tests/init/initPlatformAdmin.js';
14
+ import { SessionService } from '../../../../services/SessionService.js';
14
15
  import { SettlementService } from '../../../../services/SettlementService.js';
15
16
  import { SettlementsExportEndpoint } from './SettlementsExportEndpoint.js';
16
17
 
@@ -34,7 +35,7 @@ describe('Endpoint.SettlementsExport', () => {
34
35
  organization,
35
36
  permissions: Permissions.create({ level: PermissionLevel.Full }),
36
37
  }).create();
37
- return { user, token: await TokenModel.createToken(user) };
38
+ return { user, token: await SessionService.createSession(user) };
38
39
  };
39
40
 
40
41
  const post = async (organization: Organization, token: Token, { start = new Date(2026, 0, 1), end = new Date(2026, 1, 1) } = {}) => {
@@ -115,7 +116,7 @@ describe('Endpoint.SettlementsExport', () => {
115
116
 
116
117
  test('A user without finance access cannot export settlements', async () => {
117
118
  const user = await new UserFactory({ organization: membershipOrganization }).create();
118
- const token = await TokenModel.createToken(user);
119
+ const token = await SessionService.createSession(user);
119
120
 
120
121
  await expect(post(membershipOrganization, token)).rejects.toThrow(
121
122
  STExpect.simpleError({ code: 'permission_denied' }),
@@ -14,6 +14,7 @@ import { SettlementSyncRunner } from '../../../../helpers/SettlementSyncRunner.j
14
14
  import { testServer } from '../../../../../tests/helpers/TestServer.js';
15
15
  import { initMembershipOrganization } from '../../../../../tests/init/initMembershipOrganization.js';
16
16
  import { initPlatformAdmin } from '../../../../../tests/init/initPlatformAdmin.js';
17
+ import { SessionService } from '../../../../services/SessionService.js';
17
18
  import { GetSettlementsSyncStatusEndpoint } from './GetSettlementsSyncStatusEndpoint.js';
18
19
  import { SettlementsSyncEndpoint } from './SettlementsSyncEndpoint.js';
19
20
 
@@ -174,7 +175,7 @@ describe('Endpoint.SettlementsSync', () => {
174
175
 
175
176
  test('A user without platform full access cannot run the sync', async () => {
176
177
  const user = await new UserFactory({ organization: membershipOrganization }).create();
177
- const token = await TokenModel.createToken(user);
178
+ const token = await SessionService.createSession(user);
178
179
 
179
180
  await expect(post(membershipOrganization, token)).rejects.toThrow(
180
181
  STExpect.simpleError({ code: 'permission_denied' }),