@stamhoofd/backend 2.39.0 → 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.
- 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 +102 -103
- 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 +50 -52
- 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,22 +1,22 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
-
import { SimpleError } from
|
|
3
|
-
import { DocumentTemplate, Token } from
|
|
4
|
-
import { DocumentTemplatePrivate } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
3
|
+
import { DocumentTemplate, Token } from '@stamhoofd/models';
|
|
4
|
+
import { DocumentTemplatePrivate } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
|
-
import { Context } from
|
|
6
|
+
import { Context } from '../../../../helpers/Context';
|
|
7
7
|
|
|
8
8
|
type Params = Record<string, never>;
|
|
9
9
|
type Query = undefined;
|
|
10
|
-
type Body = undefined
|
|
11
|
-
type ResponseBody = DocumentTemplatePrivate[]
|
|
10
|
+
type Body = undefined;
|
|
11
|
+
type ResponseBody = DocumentTemplatePrivate[];
|
|
12
12
|
|
|
13
13
|
export class GetDocumentTemplatesEndpoint 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/document-templates', {});
|
|
20
20
|
|
|
21
21
|
if (params) {
|
|
22
22
|
return [true, params as Params];
|
|
@@ -26,25 +26,25 @@ export class GetDocumentTemplatesEndpoint extends Endpoint<Params, Query, Body,
|
|
|
26
26
|
|
|
27
27
|
async handle(_: 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.canManageDocuments(organization.id)) {
|
|
32
|
-
throw Context.auth.error()
|
|
32
|
+
throw Context.auth.error();
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const templates = await DocumentTemplate.where(
|
|
36
|
-
{
|
|
37
|
-
organizationId: organization.id
|
|
38
|
-
},
|
|
39
|
-
{
|
|
36
|
+
{
|
|
37
|
+
organizationId: organization.id,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
40
|
sort: [{
|
|
41
|
-
column:
|
|
42
|
-
direction:
|
|
43
|
-
}]
|
|
44
|
-
}
|
|
45
|
-
)
|
|
41
|
+
column: 'createdAt',
|
|
42
|
+
direction: 'ASC',
|
|
43
|
+
}],
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
46
|
return new Response(
|
|
47
|
-
templates.map(t => t.getPrivateStructure())
|
|
47
|
+
templates.map(t => t.getPrivateStructure()),
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
-
import { SimpleError } from
|
|
3
|
-
import { Document, DocumentTemplate } from
|
|
4
|
-
import { Document as DocumentStruct } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
3
|
+
import { Document, DocumentTemplate } from '@stamhoofd/models';
|
|
4
|
+
import { Document as DocumentStruct } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
|
-
import { Context } from
|
|
6
|
+
import { Context } from '../../../../helpers/Context';
|
|
7
7
|
|
|
8
8
|
type Params = { id: string };
|
|
9
9
|
type Query = undefined;
|
|
10
|
-
type Body = undefined
|
|
11
|
-
type ResponseBody = DocumentStruct[]
|
|
10
|
+
type Body = undefined;
|
|
11
|
+
type ResponseBody = DocumentStruct[];
|
|
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
|
|
@@ -16,11 +16,11 @@ type ResponseBody = DocumentStruct[]
|
|
|
16
16
|
|
|
17
17
|
export class GetDocumentsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
18
18
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
19
|
-
if (request.method
|
|
19
|
+
if (request.method !== 'GET') {
|
|
20
20
|
return [false];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const params = Endpoint.parseParameters(request.url,
|
|
23
|
+
const params = Endpoint.parseParameters(request.url, '/organization/document-templates/@id/documents', { id: String });
|
|
24
24
|
|
|
25
25
|
if (params) {
|
|
26
26
|
return [true, params as Params];
|
|
@@ -30,21 +30,21 @@ export class GetDocumentsEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
30
30
|
|
|
31
31
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
32
32
|
const organization = await Context.setOrganizationScope();
|
|
33
|
-
await Context.authenticate()
|
|
33
|
+
await Context.authenticate();
|
|
34
34
|
|
|
35
35
|
if (!await Context.auth.canManageDocuments(organization.id)) {
|
|
36
|
-
throw Context.auth.error()
|
|
37
|
-
}
|
|
36
|
+
throw Context.auth.error();
|
|
37
|
+
}
|
|
38
38
|
|
|
39
|
-
const template = await DocumentTemplate.getByID(request.params.id)
|
|
39
|
+
const template = await DocumentTemplate.getByID(request.params.id);
|
|
40
40
|
if (!template || !await Context.auth.canAccessDocumentTemplate(template)) {
|
|
41
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
41
|
+
throw Context.auth.notFoundOrNoAccess('Onbekend document');
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const documents = await Document.where({ templateId: template.id });
|
|
45
45
|
|
|
46
46
|
return new Response(
|
|
47
|
-
documents.map(t => t.getStructure())
|
|
47
|
+
documents.map(t => t.getStructure()),
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
3
|
-
import { SimpleError } from
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
4
|
import { Document, DocumentTemplate, Group, Member, Registration, Token } from '@stamhoofd/models';
|
|
5
|
-
import { Document as DocumentStruct, DocumentStatus, DocumentTemplatePrivate, PermissionLevel } from
|
|
5
|
+
import { Document as DocumentStruct, DocumentStatus, DocumentTemplatePrivate, PermissionLevel } from '@stamhoofd/structures';
|
|
6
6
|
|
|
7
7
|
import { Context } from '../../../../helpers/Context';
|
|
8
8
|
|
|
9
9
|
type Params = Record<string, never>;
|
|
10
10
|
type Query = undefined;
|
|
11
|
-
type Body = PatchableArrayAutoEncoder<DocumentStruct
|
|
12
|
-
type ResponseBody = DocumentStruct[]
|
|
11
|
+
type Body = PatchableArrayAutoEncoder<DocumentStruct>;
|
|
12
|
+
type ResponseBody = DocumentStruct[];
|
|
13
13
|
|
|
14
14
|
export class PatchDocumentEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
15
|
-
bodyDecoder = new PatchableArrayDecoder(DocumentStruct as Decoder<DocumentStruct>, DocumentStruct.patchType() as Decoder<AutoEncoderPatchType<DocumentStruct>>, StringDecoder)
|
|
15
|
+
bodyDecoder = new PatchableArrayDecoder(DocumentStruct as Decoder<DocumentStruct>, DocumentStruct.patchType() as Decoder<AutoEncoderPatchType<DocumentStruct>>, StringDecoder);
|
|
16
16
|
|
|
17
17
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
18
|
-
if (request.method
|
|
18
|
+
if (request.method !== 'PATCH') {
|
|
19
19
|
return [false];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const params = Endpoint.parseParameters(request.url,
|
|
22
|
+
const params = Endpoint.parseParameters(request.url, '/organization/documents', {});
|
|
23
23
|
|
|
24
24
|
if (params) {
|
|
25
25
|
return [true, params as Params];
|
|
@@ -29,101 +29,101 @@ export class PatchDocumentEndpoint extends Endpoint<Params, Query, Body, Respons
|
|
|
29
29
|
|
|
30
30
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
31
31
|
const organization = await Context.setOrganizationScope();
|
|
32
|
-
await Context.authenticate()
|
|
32
|
+
await Context.authenticate();
|
|
33
33
|
|
|
34
|
-
if (!await Context.auth.canManageDocuments(organization.id
|
|
35
|
-
throw Context.auth.error()
|
|
34
|
+
if (!await Context.auth.canManageDocuments(organization.id, PermissionLevel.Write)) {
|
|
35
|
+
throw Context.auth.error();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const updatedDocuments: DocumentStruct[] = []
|
|
38
|
+
const updatedDocuments: DocumentStruct[] = [];
|
|
39
39
|
|
|
40
40
|
for (const patch of request.body.getPatches()) {
|
|
41
|
-
const document = await Document.getByID(patch.id)
|
|
41
|
+
const document = await Document.getByID(patch.id);
|
|
42
42
|
if (!document || !(await Context.auth.canAccessDocument(document, PermissionLevel.Write))) {
|
|
43
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
43
|
+
throw Context.auth.notFoundOrNoAccess('Onbekend document');
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
if (patch.data) {
|
|
47
|
-
document.data.patchOrPut(patch.data)
|
|
48
|
-
}
|
|
47
|
+
document.data.patchOrPut(patch.data);
|
|
48
|
+
}
|
|
49
49
|
|
|
50
50
|
if (patch.status && (document.status !== DocumentStatus.MissingData || patch.status === DocumentStatus.Deleted)) {
|
|
51
|
-
document.status = patch.status
|
|
51
|
+
document.status = patch.status;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
if (document.status === DocumentStatus.Draft || document.status === DocumentStatus.Published) {
|
|
55
|
-
const template = await DocumentTemplate.getByID(document.templateId)
|
|
55
|
+
const template = await DocumentTemplate.getByID(document.templateId);
|
|
56
56
|
if (!template) {
|
|
57
57
|
throw new SimpleError({
|
|
58
|
-
code:
|
|
59
|
-
message:
|
|
60
|
-
human:
|
|
61
|
-
})
|
|
58
|
+
code: 'not_found',
|
|
59
|
+
message: 'Document not found',
|
|
60
|
+
human: 'Document niet gevonden',
|
|
61
|
+
});
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
document.status = template.status
|
|
64
|
+
document.status = template.status;
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
await document.updateData();
|
|
68
68
|
await document.save();
|
|
69
69
|
|
|
70
70
|
// Return in response
|
|
71
|
-
updatedDocuments.push(document.getStructure())
|
|
71
|
+
updatedDocuments.push(document.getStructure());
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
for (const {put} of request.body.getPuts()) {
|
|
74
|
+
for (const { put } of request.body.getPuts()) {
|
|
75
75
|
// Create a new document
|
|
76
|
-
const template = await DocumentTemplate.getByID(put.templateId)
|
|
76
|
+
const template = await DocumentTemplate.getByID(put.templateId);
|
|
77
77
|
if (!template || !await Context.auth.canAccessDocumentTemplate(template, PermissionLevel.Write)) {
|
|
78
78
|
throw new SimpleError({
|
|
79
|
-
code:
|
|
80
|
-
message:
|
|
81
|
-
human:
|
|
82
|
-
})
|
|
79
|
+
code: 'not_found',
|
|
80
|
+
message: 'Document template not found',
|
|
81
|
+
human: 'Document template niet gevonden',
|
|
82
|
+
});
|
|
83
83
|
}
|
|
84
84
|
const document = new Document();
|
|
85
|
-
document.organizationId = organization.id
|
|
86
|
-
document.templateId = template.id
|
|
87
|
-
document.status = put.status
|
|
88
|
-
document.data = put.data
|
|
85
|
+
document.organizationId = organization.id;
|
|
86
|
+
document.templateId = template.id;
|
|
87
|
+
document.status = put.status;
|
|
88
|
+
document.data = put.data;
|
|
89
89
|
|
|
90
90
|
if (document.status === DocumentStatus.Draft || document.status === DocumentStatus.Published) {
|
|
91
|
-
document.status = template.status
|
|
91
|
+
document.status = template.status;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
if (put.registrationId) {
|
|
95
|
-
const registration = await Registration.getByID(put.registrationId)
|
|
95
|
+
const registration = await Registration.getByID(put.registrationId);
|
|
96
96
|
if (!registration) {
|
|
97
97
|
throw new SimpleError({
|
|
98
|
-
code:
|
|
99
|
-
message:
|
|
100
|
-
human:
|
|
101
|
-
})
|
|
98
|
+
code: 'not_found',
|
|
99
|
+
message: 'Registration not found',
|
|
100
|
+
human: 'Inschrijving niet gevonden',
|
|
101
|
+
});
|
|
102
102
|
}
|
|
103
|
-
document.registrationId = put.registrationId
|
|
104
|
-
put.memberId = registration.memberId
|
|
103
|
+
document.registrationId = put.registrationId;
|
|
104
|
+
put.memberId = registration.memberId;
|
|
105
105
|
}
|
|
106
106
|
if (put.memberId) {
|
|
107
|
-
const member = await Member.getWithRegistrations(put.memberId)
|
|
107
|
+
const member = await Member.getWithRegistrations(put.memberId);
|
|
108
108
|
if (!member || !await Context.auth.canAccessMember(member, PermissionLevel.Read)) {
|
|
109
109
|
throw new SimpleError({
|
|
110
|
-
code:
|
|
111
|
-
message:
|
|
112
|
-
human:
|
|
113
|
-
})
|
|
110
|
+
code: 'not_found',
|
|
111
|
+
message: 'Member not found',
|
|
112
|
+
human: 'Lid niet gevonden',
|
|
113
|
+
});
|
|
114
114
|
}
|
|
115
|
-
document.memberId = put.memberId
|
|
115
|
+
document.memberId = put.memberId;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
await document.updateData();
|
|
119
119
|
await document.save();
|
|
120
120
|
|
|
121
121
|
// Return in response
|
|
122
|
-
updatedDocuments.push(document.getStructure())
|
|
122
|
+
updatedDocuments.push(document.getStructure());
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
return new Response(
|
|
126
|
-
updatedDocuments
|
|
126
|
+
updatedDocuments,
|
|
127
127
|
);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
3
|
-
import { SimpleError } from
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
4
|
import { DocumentTemplate, Token } from '@stamhoofd/models';
|
|
5
|
-
import { DocumentTemplatePrivate, PermissionLevel } from
|
|
5
|
+
import { DocumentTemplatePrivate, PermissionLevel } from '@stamhoofd/structures';
|
|
6
6
|
|
|
7
7
|
import { Context } from '../../../../helpers/Context';
|
|
8
8
|
|
|
9
9
|
type Params = Record<string, never>;
|
|
10
10
|
type Query = undefined;
|
|
11
|
-
type Body = PatchableArrayAutoEncoder<DocumentTemplatePrivate
|
|
12
|
-
type ResponseBody = DocumentTemplatePrivate[]
|
|
11
|
+
type Body = PatchableArrayAutoEncoder<DocumentTemplatePrivate>;
|
|
12
|
+
type ResponseBody = DocumentTemplatePrivate[];
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* 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
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
export class PatchDocumentTemplateEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
19
|
-
bodyDecoder = new PatchableArrayDecoder(DocumentTemplatePrivate as Decoder<DocumentTemplatePrivate>, DocumentTemplatePrivate.patchType() as Decoder<AutoEncoderPatchType<DocumentTemplatePrivate>>, StringDecoder)
|
|
19
|
+
bodyDecoder = new PatchableArrayDecoder(DocumentTemplatePrivate as Decoder<DocumentTemplatePrivate>, DocumentTemplatePrivate.patchType() as Decoder<AutoEncoderPatchType<DocumentTemplatePrivate>>, StringDecoder);
|
|
20
20
|
|
|
21
21
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
22
|
-
if (request.method
|
|
22
|
+
if (request.method !== 'PATCH') {
|
|
23
23
|
return [false];
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const params = Endpoint.parseParameters(request.url,
|
|
26
|
+
const params = Endpoint.parseParameters(request.url, '/organization/document-templates', {});
|
|
27
27
|
|
|
28
28
|
if (params) {
|
|
29
29
|
return [true, params as Params];
|
|
@@ -33,82 +33,82 @@ export class PatchDocumentTemplateEndpoint extends Endpoint<Params, Query, Body,
|
|
|
33
33
|
|
|
34
34
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
35
35
|
const organization = await Context.setOrganizationScope();
|
|
36
|
-
await Context.authenticate()
|
|
36
|
+
await Context.authenticate();
|
|
37
37
|
|
|
38
38
|
if (!await Context.auth.canManageDocuments(organization.id, PermissionLevel.Write)) {
|
|
39
|
-
throw Context.auth.error()
|
|
39
|
+
throw Context.auth.error();
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const updatedTemplates: DocumentTemplatePrivate[] = []
|
|
42
|
+
const updatedTemplates: DocumentTemplatePrivate[] = [];
|
|
43
43
|
|
|
44
|
-
for (const {put} of request.body.getPuts()) {
|
|
44
|
+
for (const { put } of request.body.getPuts()) {
|
|
45
45
|
// Creating new templates
|
|
46
|
-
const template = new DocumentTemplate()
|
|
47
|
-
template.privateSettings = put.privateSettings
|
|
48
|
-
template.settings = put.settings
|
|
49
|
-
template.status = put.status
|
|
50
|
-
template.html = put.html
|
|
51
|
-
template.updatesEnabled = put.updatesEnabled
|
|
52
|
-
template.organizationId = organization.id
|
|
46
|
+
const template = new DocumentTemplate();
|
|
47
|
+
template.privateSettings = put.privateSettings;
|
|
48
|
+
template.settings = put.settings;
|
|
49
|
+
template.status = put.status;
|
|
50
|
+
template.html = put.html;
|
|
51
|
+
template.updatesEnabled = put.updatesEnabled;
|
|
52
|
+
template.organizationId = organization.id;
|
|
53
53
|
await template.save();
|
|
54
54
|
|
|
55
55
|
// todo: Generate documents (maybe in background)
|
|
56
|
-
template.buildAll().catch(console.error)
|
|
56
|
+
template.buildAll().catch(console.error);
|
|
57
57
|
|
|
58
58
|
// Return in response
|
|
59
|
-
updatedTemplates.push(template.getPrivateStructure())
|
|
59
|
+
updatedTemplates.push(template.getPrivateStructure());
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
for (const patch of request.body.getPatches()) {
|
|
63
|
-
const template = await DocumentTemplate.getByID(patch.id)
|
|
63
|
+
const template = await DocumentTemplate.getByID(patch.id);
|
|
64
64
|
if (!template || !await Context.auth.canAccessDocumentTemplate(template, PermissionLevel.Full)) {
|
|
65
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
65
|
+
throw Context.auth.notFoundOrNoAccess('Onbekende template');
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
if (patch.privateSettings) {
|
|
69
|
-
template.privateSettings.patchOrPut(patch.privateSettings)
|
|
69
|
+
template.privateSettings.patchOrPut(patch.privateSettings);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
if (patch.settings) {
|
|
73
|
-
template.settings.patchOrPut(patch.settings)
|
|
73
|
+
template.settings.patchOrPut(patch.settings);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
if (patch.status) {
|
|
77
|
-
template.status = patch.status
|
|
77
|
+
template.status = patch.status;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
if (patch.updatesEnabled !== undefined) {
|
|
81
|
-
template.updatesEnabled = patch.updatesEnabled
|
|
81
|
+
template.updatesEnabled = patch.updatesEnabled;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
if (patch.html) {
|
|
85
|
-
template.html = patch.html
|
|
85
|
+
template.html = patch.html;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
await template.save();
|
|
89
89
|
|
|
90
90
|
// Update documents
|
|
91
|
-
await template.buildAll()
|
|
91
|
+
await template.buildAll();
|
|
92
92
|
|
|
93
93
|
// Return in response
|
|
94
|
-
updatedTemplates.push(template.getPrivateStructure())
|
|
94
|
+
updatedTemplates.push(template.getPrivateStructure());
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
for (const id of request.body.getDeletes()) {
|
|
98
|
-
const template = await DocumentTemplate.getByID(id)
|
|
98
|
+
const template = await DocumentTemplate.getByID(id);
|
|
99
99
|
if (!template || !await Context.auth.canAccessDocumentTemplate(template, PermissionLevel.Full)) {
|
|
100
100
|
throw new SimpleError({
|
|
101
|
-
code:
|
|
102
|
-
message:
|
|
103
|
-
human:
|
|
104
|
-
})
|
|
101
|
+
code: 'not_found',
|
|
102
|
+
message: 'Template not found',
|
|
103
|
+
human: 'Template niet gevonden',
|
|
104
|
+
});
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
await template.delete()
|
|
107
|
+
await template.delete();
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
return new Response(
|
|
111
|
-
updatedTemplates
|
|
111
|
+
updatedTemplates,
|
|
112
112
|
);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArrayDecoder, StringDecoder } 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 } from '@simonbackx/simple-errors';
|
|
4
4
|
import { EmailAddress } from '@stamhoofd/email';
|
|
5
5
|
import { EmailInformation } from '@stamhoofd/structures';
|
|
@@ -8,18 +8,18 @@ import { Context } from '../../../../helpers/Context';
|
|
|
8
8
|
|
|
9
9
|
type Params = Record<string, never>;
|
|
10
10
|
type Query = undefined;
|
|
11
|
-
type Body = string[]
|
|
11
|
+
type Body = string[];
|
|
12
12
|
type ResponseBody = EmailInformation[];
|
|
13
13
|
|
|
14
14
|
export class CheckEmailBouncesEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
15
|
-
bodyDecoder = new ArrayDecoder(StringDecoder)
|
|
15
|
+
bodyDecoder = new ArrayDecoder(StringDecoder);
|
|
16
16
|
|
|
17
17
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
18
|
-
if (request.method
|
|
18
|
+
if (request.method !== 'POST') {
|
|
19
19
|
return [false];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const params = Endpoint.parseParameters(request.url,
|
|
22
|
+
const params = Endpoint.parseParameters(request.url, '/email/check-bounces', {});
|
|
23
23
|
|
|
24
24
|
if (params) {
|
|
25
25
|
return [true, params as Params];
|
|
@@ -29,22 +29,22 @@ export class CheckEmailBouncesEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
29
29
|
|
|
30
30
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
31
31
|
const organization = await Context.setOrganizationScope();
|
|
32
|
-
await Context.authenticate()
|
|
32
|
+
await Context.authenticate();
|
|
33
33
|
|
|
34
34
|
if (!await Context.auth.canAccessEmailBounces(organization.id)) {
|
|
35
|
-
throw Context.auth.error()
|
|
36
|
-
}
|
|
35
|
+
throw Context.auth.error();
|
|
36
|
+
}
|
|
37
37
|
|
|
38
38
|
if (request.body.length > 10000) {
|
|
39
39
|
throw new SimpleError({
|
|
40
|
-
code:
|
|
41
|
-
message:
|
|
42
|
-
human:
|
|
43
|
-
field:
|
|
44
|
-
})
|
|
40
|
+
code: 'too_many_recipients',
|
|
41
|
+
message: 'Too many recipients',
|
|
42
|
+
human: 'Je kan maar maximaal 10.000 adressen tergelijk controleren.',
|
|
43
|
+
field: 'recipients',
|
|
44
|
+
});
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const emails = await EmailAddress.getByEmails(request.body, organization.id)
|
|
47
|
+
const emails = await EmailAddress.getByEmails(request.body, organization.id);
|
|
48
48
|
return new Response(emails.map(e => EmailInformation.create(e)));
|
|
49
49
|
}
|
|
50
50
|
}
|