@stamhoofd/backend 2.39.1 → 2.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.mjs +5 -0
- package/index.ts +81 -74
- package/jest.config.cjs +10 -0
- package/migrations.ts +16 -14
- package/package.json +11 -11
- package/src/crons/clear-excel-cache.test.ts +48 -50
- package/src/crons/clear-excel-cache.ts +18 -18
- package/src/crons/setup-steps.ts +2 -2
- package/src/crons.ts +325 -306
- package/src/decoders/StringArrayDecoder.ts +7 -7
- package/src/decoders/StringNullableDecoder.ts +1 -2
- package/src/email-recipient-loaders/members.ts +22 -22
- package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
- package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
- package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
- package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
- package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
- package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
- package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
- package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
- package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
- package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
- package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
- package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
- package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
- package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
- package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
- package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
- package/src/endpoints/auth/SignupEndpoint.ts +37 -36
- package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
- package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
- package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
- package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
- package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
- package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
- package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
- package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
- package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
- package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
- package/src/endpoints/global/files/GetFileCache.ts +13 -13
- package/src/endpoints/global/files/UploadFile.ts +51 -54
- package/src/endpoints/global/files/UploadImage.ts +53 -53
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
- package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
- package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
- package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
- package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
- package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
- package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
- package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
- package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
- package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
- package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
- package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
- package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
- package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
- package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
- package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
- package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
- package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
- package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
- package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
- package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
- package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
- package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
- package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
- package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
- package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
- package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
- package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
- package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
- package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
- package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
- package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
- package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
- package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
- package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
- package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
- package/src/excel-loaders/members.ts +275 -273
- package/src/excel-loaders/payments.ts +155 -156
- package/src/helpers/AddressValidator.test.ts +32 -32
- package/src/helpers/AddressValidator.ts +128 -122
- package/src/helpers/AdminPermissionChecker.ts +339 -236
- package/src/helpers/AuthenticatedStructures.ts +233 -134
- package/src/helpers/BuckarooHelper.ts +134 -134
- package/src/helpers/CheckSettlements.ts +94 -88
- package/src/helpers/Context.ts +87 -86
- package/src/helpers/CookieHelper.ts +23 -22
- package/src/helpers/EmailResumer.ts +10 -10
- package/src/helpers/FileCache.ts +62 -62
- package/src/helpers/ForwardHandler.test.ts +122 -124
- package/src/helpers/ForwardHandler.ts +76 -70
- package/src/helpers/MemberUserSyncer.ts +101 -96
- package/src/helpers/MembershipCharger.ts +69 -69
- package/src/helpers/MembershipHelper.ts +11 -12
- package/src/helpers/OpenIDConnectHelper.ts +85 -82
- package/src/helpers/PeriodHelper.ts +65 -70
- package/src/helpers/StripeHelper.ts +146 -137
- package/src/helpers/StripePayoutChecker.ts +51 -52
- package/src/helpers/ViesHelper.ts +46 -44
- package/src/helpers/fetchToAsyncIterator.ts +14 -14
- package/src/helpers/xlsxAddressTransformerColumnFactory.ts +58 -60
- package/src/middleware/ContextMiddleware.ts +5 -5
- package/src/migrations/1646578856-validate-addresses.ts +6 -9
- package/src/seeds/0000000000-example.ts +3 -5
- package/src/seeds/1715028563-user-permissions.ts +16 -18
- package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
- package/src/seeds/1722344162-sync-member-users.ts +14 -15
- package/src/seeds/1722344162-update-membership.ts +6 -6
- package/src/seeds/1726055544-balance-item-paid.ts +4 -4
- package/src/seeds/1726055545-balance-item-pending.ts +4 -4
- package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
- package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
- package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
- package/src/seeds/1726847064-setup-steps.ts +16 -0
- package/src/sql-filters/balance-item-payments.ts +7 -7
- package/src/sql-filters/events.ts +14 -14
- package/src/sql-filters/members.ts +96 -96
- package/src/sql-filters/organizations.ts +139 -75
- package/src/sql-filters/payments.ts +28 -28
- package/src/sql-filters/registrations.ts +14 -14
- package/src/sql-sorters/events.ts +25 -25
- package/src/sql-sorters/members.ts +26 -26
- package/src/sql-sorters/organizations.ts +36 -36
- package/src/sql-sorters/payments.ts +26 -26
- package/tests/e2e/stock.test.ts +616 -621
- package/tests/e2e/tickets.test.ts +255 -260
- package/tests/helpers/StripeMocker.ts +177 -179
- package/tests/helpers/TestServer.ts +9 -9
- package/tests/jest.global.setup.ts +14 -13
- package/tests/jest.setup.ts +33 -32
- package/.eslintrc.js +0 -61
- package/jest.config.js +0 -11
- package/src/helpers/SetupStepsUpdater.ts +0 -359
- package/src/seeds/1724076679-setup-steps.ts +0 -16
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Decoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { SimpleError, SimpleErrors } from '@simonbackx/simple-errors';
|
|
4
|
-
import { DNSRecord, DNSRecordType, Organization as OrganizationStruct,OrganizationDomains } from
|
|
4
|
+
import { DNSRecord, DNSRecordType, Organization as OrganizationStruct, OrganizationDomains } from '@stamhoofd/structures';
|
|
5
5
|
import NodeRSA from 'node-rsa';
|
|
6
6
|
|
|
7
7
|
import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures';
|
|
@@ -11,21 +11,21 @@ import { Formatter } from '@stamhoofd/utility';
|
|
|
11
11
|
type Params = Record<string, never>;
|
|
12
12
|
type Query = undefined;
|
|
13
13
|
type Body = OrganizationDomains;
|
|
14
|
-
type ResponseBody = OrganizationStruct
|
|
14
|
+
type ResponseBody = OrganizationStruct;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* One endpoint to create, patch and delete groups. Usefull because on organization setup, we need to create multiple groups at once. Also, sometimes we need to link values and update multiple groups at once
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
export class SetOrganizationDomainEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
21
|
-
bodyDecoder = OrganizationDomains as Decoder<OrganizationDomains
|
|
21
|
+
bodyDecoder = OrganizationDomains as Decoder<OrganizationDomains>;
|
|
22
22
|
|
|
23
23
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
24
|
-
if (request.method
|
|
24
|
+
if (request.method !== 'POST') {
|
|
25
25
|
return [false];
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const params = Endpoint.parseParameters(request.url,
|
|
28
|
+
const params = Endpoint.parseParameters(request.url, '/organization/domain', {});
|
|
29
29
|
|
|
30
30
|
if (params) {
|
|
31
31
|
return [true, params as Params];
|
|
@@ -35,162 +35,161 @@ export class SetOrganizationDomainEndpoint extends Endpoint<Params, Query, Body,
|
|
|
35
35
|
|
|
36
36
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
37
37
|
const organization = await Context.setOrganizationScope();
|
|
38
|
-
await Context.authenticate()
|
|
38
|
+
await Context.authenticate();
|
|
39
39
|
|
|
40
40
|
if (!await Context.auth.canManageOrganizationDomain(organization.id)) {
|
|
41
|
-
throw Context.auth.error()
|
|
41
|
+
throw Context.auth.error();
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const errors = new SimpleErrors()
|
|
44
|
+
const errors = new SimpleErrors();
|
|
45
45
|
|
|
46
46
|
// check if changed
|
|
47
47
|
if (
|
|
48
|
-
(organization.privateMeta.pendingRegisterDomain ?? organization.registerDomain) !== request.body.registerDomain
|
|
49
|
-
||
|
|
50
|
-
(organization.privateMeta.pendingMailDomain ?? organization.privateMeta.mailDomain) !== request.body.mailDomain // changed pending domain
|
|
48
|
+
(organization.privateMeta.pendingRegisterDomain ?? organization.registerDomain) !== request.body.registerDomain // changed register domain
|
|
49
|
+
|| (organization.privateMeta.pendingMailDomain ?? organization.privateMeta.mailDomain) !== request.body.mailDomain // changed pending domain
|
|
51
50
|
) {
|
|
52
|
-
console.log(
|
|
51
|
+
console.log('Domains changed');
|
|
53
52
|
|
|
54
53
|
// Validate domains
|
|
55
|
-
|
|
54
|
+
|
|
56
55
|
if (request.body.registerDomain !== null && !request.body.registerDomain.match(/^([a-zA-Z0-9-]+\.)?[a-zA-Z0-9-]+\.[a-zA-Z]+$/)) {
|
|
57
56
|
throw new SimpleError({
|
|
58
|
-
code:
|
|
59
|
-
message:
|
|
60
|
-
human:
|
|
61
|
-
field:
|
|
62
|
-
})
|
|
57
|
+
code: 'invalid_domain',
|
|
58
|
+
message: 'registerDomain is invalid',
|
|
59
|
+
human: 'De subdomeinnaam voor jouw registratiepagina is ongeldig',
|
|
60
|
+
field: 'registerDomain',
|
|
61
|
+
});
|
|
63
62
|
}
|
|
64
|
-
|
|
65
|
-
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
|
|
63
|
+
|
|
66
64
|
if (request.body.mailDomain !== null && !request.body.mailDomain.match(/^([a-zA-Z0-9-]+\.)?[a-zA-Z0-9-]+\.[a-zA-Z]+$/)) {
|
|
67
65
|
throw new SimpleError({
|
|
68
|
-
code:
|
|
69
|
-
message:
|
|
70
|
-
human:
|
|
71
|
-
field:
|
|
72
|
-
})
|
|
66
|
+
code: 'invalid_domain',
|
|
67
|
+
message: 'mailDomain is invalid',
|
|
68
|
+
human: 'De domeinnaam voor e-mails is ongeldig',
|
|
69
|
+
field: 'mailDomain',
|
|
70
|
+
});
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
const oldMailDomain = organization.privateMeta.mailDomain
|
|
73
|
+
const oldMailDomain = organization.privateMeta.mailDomain;
|
|
76
74
|
|
|
77
|
-
organization.privateMeta.pendingRegisterDomain = request.body.registerDomain?.toLowerCase() ?? null
|
|
78
|
-
organization.privateMeta.pendingMailDomain = request.body.mailDomain?.toLowerCase() ?? null
|
|
75
|
+
organization.privateMeta.pendingRegisterDomain = request.body.registerDomain?.toLowerCase() ?? null;
|
|
76
|
+
organization.privateMeta.pendingMailDomain = request.body.mailDomain?.toLowerCase() ?? null;
|
|
79
77
|
|
|
80
78
|
// We don't keep the current register domain because we have no way to validate the old DNS-records
|
|
81
79
|
if (organization.privateMeta.pendingRegisterDomain === null || organization.registerDomain !== organization.privateMeta.pendingRegisterDomain) {
|
|
82
|
-
organization.registerDomain = null
|
|
80
|
+
organization.registerDomain = null;
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
// We don't keep the current mail domain because we have no way to validate the old DNS-records
|
|
86
84
|
if (organization.privateMeta.pendingMailDomain === null || organization.privateMeta.mailDomain !== organization.privateMeta.pendingMailDomain) {
|
|
87
|
-
organization.privateMeta.mailDomain = null
|
|
85
|
+
organization.privateMeta.mailDomain = null;
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
// Always temporary disable mail domain until validated
|
|
91
|
-
organization.privateMeta.mailDomainActive = false
|
|
89
|
+
organization.privateMeta.mailDomainActive = false;
|
|
92
90
|
|
|
93
91
|
// Reset notification counters
|
|
94
|
-
organization.serverMeta.DNSRecordWarningCount = 0
|
|
95
|
-
organization.serverMeta.firstInvalidDNSRecords = undefined
|
|
96
|
-
organization.serverMeta.didSendDomainSetupMail = false
|
|
92
|
+
organization.serverMeta.DNSRecordWarningCount = 0;
|
|
93
|
+
organization.serverMeta.firstInvalidDNSRecords = undefined;
|
|
94
|
+
organization.serverMeta.didSendDomainSetupMail = false;
|
|
97
95
|
|
|
98
96
|
// Generate new DNS-records
|
|
99
|
-
organization.privateMeta.dnsRecords = []
|
|
97
|
+
organization.privateMeta.dnsRecords = [];
|
|
100
98
|
|
|
101
99
|
if (organization.privateMeta.pendingMailDomain !== null) {
|
|
102
|
-
const defaultFromDomain = Formatter.slug(STAMHOOFD.platformName) +
|
|
100
|
+
const defaultFromDomain = Formatter.slug(STAMHOOFD.platformName) + '.' + organization.privateMeta.pendingMailDomain;
|
|
103
101
|
if (organization.privateMeta.pendingRegisterDomain === null || !organization.privateMeta.pendingRegisterDomain.endsWith('.' + organization.privateMeta.pendingMailDomain)) {
|
|
104
102
|
// We set a custom domainname for webshops already
|
|
105
103
|
// This is not used at this moment
|
|
106
104
|
organization.privateMeta.mailFromDomain = defaultFromDomain;
|
|
107
|
-
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
108
107
|
// CNAME domain: for SPF + MX + A record
|
|
109
108
|
organization.privateMeta.mailFromDomain = organization.privateMeta.pendingRegisterDomain;
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
if (organization.privateMeta.mailFromDomain !== organization.privateMeta.pendingRegisterDomain) {
|
|
112
|
+
organization.privateMeta.dnsRecords.push(DNSRecord.create({
|
|
113
|
+
type: DNSRecordType.CNAME,
|
|
114
|
+
name: organization.privateMeta.mailFromDomain + '.',
|
|
115
|
+
// Use shops for mail domain, to allow reuse
|
|
116
|
+
value: STAMHOOFD.domains.webshopCname + '.',
|
|
117
|
+
}));
|
|
118
|
+
|
|
119
|
+
if (STAMHOOFD.domains.registration && organization.privateMeta.pendingRegisterDomain) {
|
|
113
120
|
organization.privateMeta.dnsRecords.push(DNSRecord.create({
|
|
114
121
|
type: DNSRecordType.CNAME,
|
|
115
|
-
name: organization.privateMeta.
|
|
116
|
-
// Use
|
|
117
|
-
value: STAMHOOFD.domains.
|
|
118
|
-
}))
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
type: DNSRecordType.CNAME,
|
|
123
|
-
name: organization.privateMeta.pendingRegisterDomain+".",
|
|
124
|
-
// Use registration domain
|
|
125
|
-
value: STAMHOOFD.domains.registrationCname + "."
|
|
126
|
-
}))
|
|
127
|
-
}
|
|
128
|
-
} else {
|
|
122
|
+
name: organization.privateMeta.pendingRegisterDomain + '.',
|
|
123
|
+
// Use registration domain
|
|
124
|
+
value: STAMHOOFD.domains.registrationCname + '.',
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
129
|
organization.privateMeta.dnsRecords.push(DNSRecord.create({
|
|
130
130
|
type: DNSRecordType.CNAME,
|
|
131
|
-
name: organization.privateMeta.mailFromDomain+
|
|
131
|
+
name: organization.privateMeta.mailFromDomain + '.',
|
|
132
132
|
// Use registration domain
|
|
133
|
-
value: STAMHOOFD.domains.registrationCname +
|
|
134
|
-
}))
|
|
133
|
+
value: STAMHOOFD.domains.registrationCname + '.',
|
|
134
|
+
}));
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
if (request.body.mailDomain !== null) {
|
|
139
|
+
let priv: string;
|
|
140
|
+
let pub: string;
|
|
139
141
|
|
|
140
|
-
|
|
141
|
-
let pub: string
|
|
142
|
-
|
|
143
|
-
if (!organization.serverMeta.privateDKIMKey || !organization.serverMeta.publicDKIMKey ) {
|
|
142
|
+
if (!organization.serverMeta.privateDKIMKey || !organization.serverMeta.publicDKIMKey) {
|
|
144
143
|
const key = new NodeRSA({ b: request.body.useDkim1024bit ? 1024 : 2048 });
|
|
145
|
-
const privArr = (key.exportKey('private') as string).split(
|
|
146
|
-
priv = privArr.splice(1, privArr.length - 2).join(
|
|
144
|
+
const privArr = (key.exportKey('private') as string).split('\n');
|
|
145
|
+
priv = privArr.splice(1, privArr.length - 2).join('');
|
|
147
146
|
|
|
148
|
-
const pubArr = (key.exportKey('public') as string).split(
|
|
149
|
-
pub = pubArr.splice(1, pubArr.length - 2).join(
|
|
147
|
+
const pubArr = (key.exportKey('public') as string).split('\n');
|
|
148
|
+
pub = pubArr.splice(1, pubArr.length - 2).join('');
|
|
150
149
|
|
|
151
|
-
organization.serverMeta.privateDKIMKey = priv
|
|
152
|
-
organization.serverMeta.publicDKIMKey = pub
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
150
|
+
organization.serverMeta.privateDKIMKey = priv;
|
|
151
|
+
organization.serverMeta.publicDKIMKey = pub;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
priv = organization.serverMeta.privateDKIMKey;
|
|
155
|
+
pub = organization.serverMeta.publicDKIMKey;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
// DKIM records
|
|
159
159
|
organization.privateMeta.dnsRecords.push(DNSRecord.create({
|
|
160
160
|
type: DNSRecordType.TXT,
|
|
161
|
-
name:
|
|
162
|
-
value:
|
|
163
|
-
}))
|
|
164
|
-
}
|
|
161
|
+
name: 'stamhoofd._domainkey.' + request.body.mailDomain + '.',
|
|
162
|
+
value: 'v=DKIM1; k=rsa; p=' + pub + '',
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
165
166
|
if (oldMailDomain) {
|
|
166
|
-
organization.deleteAWSMailIdenitity(oldMailDomain).catch(console.error)
|
|
167
|
+
organization.deleteAWSMailIdenitity(oldMailDomain).catch(console.error);
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
if (organization.serverMeta.privateDKIMKey && organization.serverMeta.publicDKIMKey
|
|
170
|
+
if (organization.serverMeta.privateDKIMKey && organization.serverMeta.publicDKIMKey) {
|
|
170
171
|
// Allow creation of new keys for new domains
|
|
171
|
-
console.log(
|
|
172
|
-
console.log(
|
|
173
|
-
console.log(
|
|
172
|
+
console.log('Backup DKIM keys for ' + organization.id);
|
|
173
|
+
console.log('Private: ' + organization.serverMeta.privateDKIMKey);
|
|
174
|
+
console.log('Public: ' + organization.serverMeta.publicDKIMKey);
|
|
174
175
|
|
|
175
176
|
// Delete keys if mail domain is deleted -> to allow new keys
|
|
176
|
-
organization.serverMeta.privateDKIMKey = undefined
|
|
177
|
-
organization.serverMeta.publicDKIMKey = undefined
|
|
177
|
+
organization.serverMeta.privateDKIMKey = undefined;
|
|
178
|
+
organization.serverMeta.publicDKIMKey = undefined;
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
181
|
|
|
181
|
-
await organization.save()
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
await organization.save();
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
184
185
|
// Validate DNS-records if not empty
|
|
185
|
-
console.log(
|
|
186
|
-
await organization.updateDNSRecords()
|
|
186
|
+
console.log('Validating domains');
|
|
187
|
+
await organization.updateDNSRecords();
|
|
187
188
|
}
|
|
188
189
|
|
|
189
|
-
console.log(
|
|
190
|
-
|
|
191
|
-
errors.throwIfNotEmpty()
|
|
190
|
+
console.log('Done.');
|
|
191
|
+
|
|
192
|
+
errors.throwIfNotEmpty();
|
|
192
193
|
return new Response(await AuthenticatedStructures.organization(organization));
|
|
193
194
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
195
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Decoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
3
|
-
import { OpenIDClientConfiguration } from
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
|
+
import { OpenIDClientConfiguration } from '@stamhoofd/structures';
|
|
4
4
|
|
|
5
5
|
import { Context } from '../../../../helpers/Context';
|
|
6
6
|
import { OpenIDConnectHelper } from '../../../../helpers/OpenIDConnectHelper';
|
|
@@ -8,21 +8,21 @@ import { OpenIDConnectHelper } from '../../../../helpers/OpenIDConnectHelper';
|
|
|
8
8
|
type Params = Record<string, never>;
|
|
9
9
|
type Query = undefined;
|
|
10
10
|
type Body = OpenIDClientConfiguration;
|
|
11
|
-
type ResponseBody = OpenIDClientConfiguration
|
|
11
|
+
type ResponseBody = OpenIDClientConfiguration;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* One endpoint to create, patch and delete groups. Usefull because on organization setup, we need to create multiple groups at once. Also, sometimes we need to link values and update multiple groups at once
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
export class SetOrganizationSSOEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
18
|
-
bodyDecoder = OpenIDClientConfiguration as Decoder<OpenIDClientConfiguration
|
|
18
|
+
bodyDecoder = OpenIDClientConfiguration as Decoder<OpenIDClientConfiguration>;
|
|
19
19
|
|
|
20
20
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
21
|
-
if (request.method
|
|
21
|
+
if (request.method !== 'POST') {
|
|
22
22
|
return [false];
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const params = Endpoint.parseParameters(request.url,
|
|
25
|
+
const params = Endpoint.parseParameters(request.url, '/organization/sso', {});
|
|
26
26
|
|
|
27
27
|
if (params) {
|
|
28
28
|
return [true, params as Params];
|
|
@@ -32,18 +32,18 @@ export class SetOrganizationSSOEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
32
32
|
|
|
33
33
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
34
34
|
const organization = await Context.setOrganizationScope();
|
|
35
|
-
await Context.authenticate()
|
|
35
|
+
await Context.authenticate();
|
|
36
36
|
|
|
37
37
|
if (!await Context.auth.canManageSSOSettings(organization.id)) {
|
|
38
|
-
throw Context.auth.error()
|
|
38
|
+
throw Context.auth.error();
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Validate configuration
|
|
42
|
-
const helper = new OpenIDConnectHelper(organization, request.body)
|
|
43
|
-
await helper.getClient()
|
|
42
|
+
const helper = new OpenIDConnectHelper(organization, request.body);
|
|
43
|
+
await helper.getClient();
|
|
44
44
|
|
|
45
|
-
organization.serverMeta.ssoConfiguration = request.body
|
|
46
|
-
await organization.save()
|
|
45
|
+
organization.serverMeta.ssoConfiguration = request.body;
|
|
46
|
+
await organization.save();
|
|
47
47
|
|
|
48
48
|
return new Response(request.body);
|
|
49
49
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
-
import { SimpleError } from
|
|
3
|
-
import { BalanceItem, Group, Member } from
|
|
4
|
-
import { BalanceItemWithPayments } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
3
|
+
import { BalanceItem, Group, Member } from '@stamhoofd/models';
|
|
4
|
+
import { BalanceItemWithPayments } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
|
-
import { Context } from
|
|
6
|
+
import { Context } from '../../../../helpers/Context';
|
|
7
7
|
|
|
8
8
|
type Params = { id: string };
|
|
9
|
-
type Query = undefined
|
|
10
|
-
type Body = undefined
|
|
11
|
-
type ResponseBody = BalanceItemWithPayments[]
|
|
9
|
+
type Query = undefined;
|
|
10
|
+
type Body = undefined;
|
|
11
|
+
type ResponseBody = BalanceItemWithPayments[];
|
|
12
12
|
|
|
13
13
|
export class GetMemberBalanceEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
14
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
15
|
-
if (request.method
|
|
15
|
+
if (request.method !== 'GET') {
|
|
16
16
|
return [false];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const params = Endpoint.parseParameters(request.url,
|
|
19
|
+
const params = Endpoint.parseParameters(request.url, '/organization/members/@id/balance', { id: String });
|
|
20
20
|
|
|
21
21
|
if (params) {
|
|
22
22
|
return [true, params as Params];
|
|
@@ -26,23 +26,23 @@ export class GetMemberBalanceEndpoint extends Endpoint<Params, Query, Body, Resp
|
|
|
26
26
|
|
|
27
27
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
28
28
|
const organization = await Context.setOrganizationScope();
|
|
29
|
-
await Context.authenticate()
|
|
29
|
+
await Context.authenticate();
|
|
30
30
|
|
|
31
31
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
32
|
-
throw Context.auth.error()
|
|
33
|
-
}
|
|
32
|
+
throw Context.auth.error();
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
const member = (await Member.getWithRegistrations(request.params.id))
|
|
35
|
+
const member = (await Member.getWithRegistrations(request.params.id));
|
|
36
36
|
|
|
37
37
|
if (!member || !await Context.auth.hasFinancialMemberAccess(member)) {
|
|
38
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
38
|
+
throw Context.auth.notFoundOrNoAccess('Geen lid gevonden, of je hebt geen toegang tot dit lid');
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Get all balance items for this member or users
|
|
42
|
-
const balanceItems = await BalanceItem.balanceItemsForUsersAndMembers(organization.id, member.users.map(u => u.id), [member.id])
|
|
42
|
+
const balanceItems = await BalanceItem.balanceItemsForUsersAndMembers(organization.id, member.users.map(u => u.id), [member.id]);
|
|
43
43
|
|
|
44
44
|
return new Response(
|
|
45
|
-
await BalanceItem.getStructureWithPayments(balanceItems)
|
|
45
|
+
await BalanceItem.getStructureWithPayments(balanceItems),
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -11,14 +11,14 @@ type Body = undefined;
|
|
|
11
11
|
type ResponseBody = CountResponse;
|
|
12
12
|
|
|
13
13
|
export class GetPaymentsCountEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
|
-
queryDecoder = CountFilteredRequest as Decoder<CountFilteredRequest
|
|
14
|
+
queryDecoder = CountFilteredRequest as Decoder<CountFilteredRequest>;
|
|
15
15
|
|
|
16
16
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
17
|
-
if (request.method
|
|
17
|
+
if (request.method !== 'GET') {
|
|
18
18
|
return [false];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const params = Endpoint.parseParameters(request.url,
|
|
21
|
+
const params = Endpoint.parseParameters(request.url, '/payments/count', {});
|
|
22
22
|
|
|
23
23
|
if (params) {
|
|
24
24
|
return [true, params as Params];
|
|
@@ -28,16 +28,16 @@ export class GetPaymentsCountEndpoint extends Endpoint<Params, Query, Body, Resp
|
|
|
28
28
|
|
|
29
29
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
30
30
|
await Context.setOrganizationScope();
|
|
31
|
-
await Context.authenticate()
|
|
32
|
-
const query = await GetPaymentsEndpoint.buildQuery(request.query)
|
|
33
|
-
|
|
31
|
+
await Context.authenticate();
|
|
32
|
+
const query = await GetPaymentsEndpoint.buildQuery(request.query);
|
|
33
|
+
|
|
34
34
|
const count = await query
|
|
35
35
|
.count();
|
|
36
36
|
|
|
37
37
|
return new Response(
|
|
38
38
|
CountResponse.create({
|
|
39
|
-
count
|
|
40
|
-
})
|
|
39
|
+
count,
|
|
40
|
+
}),
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
43
|
}
|