@stamhoofd/backend 2.39.1 → 2.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,41 +1,41 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Group, Organization } from '@stamhoofd/models';
|
|
3
|
-
import { GroupsWithOrganizations } from
|
|
3
|
+
import { GroupsWithOrganizations } from '@stamhoofd/structures';
|
|
4
4
|
|
|
5
|
-
import { AutoEncoder, Decoder, field, StringDecoder } from
|
|
6
|
-
import { Formatter } from
|
|
7
|
-
import { StringArrayDecoder } from
|
|
8
|
-
import { AuthenticatedStructures } from
|
|
9
|
-
import { Context } from
|
|
10
|
-
import { SimpleError } from
|
|
5
|
+
import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
|
|
6
|
+
import { Formatter } from '@stamhoofd/utility';
|
|
7
|
+
import { StringArrayDecoder } from '../../../decoders/StringArrayDecoder';
|
|
8
|
+
import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
|
|
9
|
+
import { Context } from '../../../helpers/Context';
|
|
10
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
11
11
|
type Params = Record<string, never>;
|
|
12
12
|
|
|
13
13
|
class Query extends AutoEncoder {
|
|
14
14
|
@field({ decoder: new StringArrayDecoder(StringDecoder) })
|
|
15
|
-
ids: string[]
|
|
15
|
+
ids: string[];
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* List of organizations the requester already knows and doesn't need to be included in the response
|
|
19
19
|
*/
|
|
20
20
|
@field({ decoder: new StringArrayDecoder(StringDecoder), optional: true })
|
|
21
|
-
excludeOrganizationIds: string[] = []
|
|
21
|
+
excludeOrganizationIds: string[] = [];
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
type Body = undefined
|
|
25
|
-
type ResponseBody = GroupsWithOrganizations
|
|
24
|
+
type Body = undefined;
|
|
25
|
+
type ResponseBody = GroupsWithOrganizations;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Get the members of the user
|
|
29
29
|
*/
|
|
30
30
|
export class GetGroupsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
31
|
-
queryDecoder = Query as Decoder<Query
|
|
31
|
+
queryDecoder = Query as Decoder<Query>;
|
|
32
32
|
|
|
33
33
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
34
|
-
if (request.method
|
|
34
|
+
if (request.method !== 'GET') {
|
|
35
35
|
return [false];
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const params = Endpoint.parseParameters(request.url,
|
|
38
|
+
const params = Endpoint.parseParameters(request.url, '/groups', {});
|
|
39
39
|
|
|
40
40
|
if (params) {
|
|
41
41
|
return [true, params as Params];
|
|
@@ -46,34 +46,34 @@ export class GetGroupsEndpoint extends Endpoint<Params, Query, Body, ResponseBod
|
|
|
46
46
|
|
|
47
47
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
48
48
|
await Context.setOptionalOrganizationScope();
|
|
49
|
-
await Context.optionalAuthenticate()
|
|
49
|
+
await Context.optionalAuthenticate();
|
|
50
50
|
|
|
51
51
|
if (request.query.ids.length === 0) {
|
|
52
52
|
return new Response(
|
|
53
53
|
GroupsWithOrganizations.create({
|
|
54
54
|
groups: [],
|
|
55
|
-
organizations: []
|
|
56
|
-
})
|
|
55
|
+
organizations: [],
|
|
56
|
+
}),
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
if (request.query.ids.length > 100) {
|
|
61
61
|
throw new SimpleError({
|
|
62
|
-
code:
|
|
63
|
-
message: "You can't request more than 100 groups at once"
|
|
64
|
-
})
|
|
62
|
+
code: 'too_many_ids',
|
|
63
|
+
message: "You can't request more than 100 groups at once",
|
|
64
|
+
});
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const groups = await Group.getByIDs(...request.query.ids)
|
|
67
|
+
const groups = await Group.getByIDs(...request.query.ids);
|
|
68
68
|
const organizationIds = Formatter.uniqueArray(groups.map(g => g.organizationId).filter(id => !request.query.excludeOrganizationIds.includes(id)));
|
|
69
69
|
|
|
70
70
|
const organizations = organizationIds.length > 0 ? (await Organization.getByIDs(...organizationIds)) : [];
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
return new Response(
|
|
73
73
|
GroupsWithOrganizations.create({
|
|
74
74
|
groups: await AuthenticatedStructures.groups(groups),
|
|
75
|
-
organizations: await AuthenticatedStructures.organizations(organizations)
|
|
76
|
-
})
|
|
75
|
+
organizations: await AuthenticatedStructures.organizations(organizations),
|
|
76
|
+
}),
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
-
import { Member, MemberWithRegistrations } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { Member, MemberWithRegistrations } from '@stamhoofd/models';
|
|
3
3
|
|
|
4
|
-
import { MembersBlob } from
|
|
5
|
-
import { AuthenticatedStructures } from
|
|
6
|
-
import { Context } from
|
|
4
|
+
import { MembersBlob } from '@stamhoofd/structures';
|
|
5
|
+
import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
|
|
6
|
+
import { Context } from '../../../helpers/Context';
|
|
7
7
|
type Params = { id: string };
|
|
8
|
-
type Query = undefined
|
|
9
|
-
type Body = undefined
|
|
10
|
-
type ResponseBody = MembersBlob
|
|
8
|
+
type Query = undefined;
|
|
9
|
+
type Body = undefined;
|
|
10
|
+
type ResponseBody = MembersBlob;
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* 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,11 +15,11 @@ type ResponseBody = MembersBlob
|
|
|
15
15
|
|
|
16
16
|
export class GetMemberFamilyEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
17
17
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
18
|
-
if (request.method
|
|
18
|
+
if (request.method !== 'GET') {
|
|
19
19
|
return [false];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const params = Endpoint.parseParameters(request.url,
|
|
22
|
+
const params = Endpoint.parseParameters(request.url, '/organization/members/@id/family', { id: String });
|
|
23
23
|
|
|
24
24
|
if (params) {
|
|
25
25
|
return [true, params as Params];
|
|
@@ -29,24 +29,25 @@ export class GetMemberFamilyEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
29
29
|
|
|
30
30
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
31
31
|
const organization = await Context.setOptionalOrganizationScope();
|
|
32
|
-
await Context.authenticate()
|
|
32
|
+
await Context.authenticate();
|
|
33
33
|
|
|
34
34
|
// Fast throw first (more in depth checking for patches later)
|
|
35
35
|
if (organization) {
|
|
36
36
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
37
|
-
throw Context.auth.error()
|
|
38
|
-
}
|
|
39
|
-
}
|
|
37
|
+
throw Context.auth.error();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
40
41
|
if (!Context.auth.hasSomePlatformAccess()) {
|
|
41
|
-
throw Context.auth.error()
|
|
42
|
+
throw Context.auth.error();
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
const members = (await Member.getFamilyWithRegistrations(request.params.id))
|
|
46
|
+
const members = (await Member.getFamilyWithRegistrations(request.params.id));
|
|
46
47
|
|
|
47
|
-
let foundMember = false
|
|
48
|
+
let foundMember = false;
|
|
48
49
|
|
|
49
|
-
const validatedMembers: MemberWithRegistrations[] = []
|
|
50
|
+
const validatedMembers: MemberWithRegistrations[] = [];
|
|
50
51
|
|
|
51
52
|
for (const member of members) {
|
|
52
53
|
if (member.id === request.params.id) {
|
|
@@ -54,23 +55,23 @@ export class GetMemberFamilyEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
54
55
|
|
|
55
56
|
// Check access to this member (this will automatically give access to the family)
|
|
56
57
|
if (!await Context.auth.canAccessMember(member)) {
|
|
57
|
-
throw Context.auth.error(
|
|
58
|
+
throw Context.auth.error('Je hebt geen toegang tot dit lid');
|
|
58
59
|
}
|
|
59
|
-
validatedMembers.push(member)
|
|
60
|
+
validatedMembers.push(member);
|
|
60
61
|
continue;
|
|
61
62
|
}
|
|
62
63
|
if (await Context.auth.canAccessMember(member)) {
|
|
63
64
|
// Remove from result
|
|
64
|
-
validatedMembers.push(member)
|
|
65
|
+
validatedMembers.push(member);
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
if (!foundMember) {
|
|
69
|
-
throw Context.auth.error(
|
|
70
|
+
throw Context.auth.error('Je hebt geen toegang tot dit lid');
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
return new Response(
|
|
73
|
-
await AuthenticatedStructures.membersBlob(validatedMembers)
|
|
74
|
+
await AuthenticatedStructures.membersBlob(validatedMembers),
|
|
74
75
|
);
|
|
75
76
|
}
|
|
76
77
|
}
|
|
@@ -11,14 +11,14 @@ type Body = undefined;
|
|
|
11
11
|
type ResponseBody = CountResponse;
|
|
12
12
|
|
|
13
13
|
export class GetMembersCountEndpoint 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, '/members/count', {});
|
|
22
22
|
|
|
23
23
|
if (params) {
|
|
24
24
|
return [true, params as Params];
|
|
@@ -28,16 +28,16 @@ export class GetMembersCountEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
28
28
|
|
|
29
29
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
30
30
|
await Context.setOptionalOrganizationScope();
|
|
31
|
-
await Context.authenticate()
|
|
32
|
-
const query = await GetMembersEndpoint.buildQuery(request.query)
|
|
33
|
-
|
|
31
|
+
await Context.authenticate();
|
|
32
|
+
const query = await GetMembersEndpoint.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
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
2
1
|
import { Decoder } from '@simonbackx/simple-encoding';
|
|
3
2
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
4
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
5
4
|
import { Member, Platform } from '@stamhoofd/models';
|
|
6
|
-
import { SQL, compileToSQLFilter, compileToSQLSorter } from
|
|
5
|
+
import { SQL, compileToSQLFilter, compileToSQLSorter } from '@stamhoofd/sql';
|
|
7
6
|
import { CountFilteredRequest, Country, LimitedFilteredRequest, MembersBlob, PaginatedResponse, PermissionLevel, StamhoofdFilter, assertSort, getSortFilter } from '@stamhoofd/structures';
|
|
8
7
|
import { DataValidator } from '@stamhoofd/utility';
|
|
9
8
|
|
|
10
|
-
import parsePhoneNumber from
|
|
9
|
+
import parsePhoneNumber from 'libphonenumber-js/max';
|
|
11
10
|
import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
|
|
12
11
|
import { Context } from '../../../helpers/Context';
|
|
13
12
|
import { memberFilterCompilers } from '../../../sql-filters/members';
|
|
@@ -16,20 +15,20 @@ import { memberSorters } from '../../../sql-sorters/members';
|
|
|
16
15
|
type Params = Record<string, never>;
|
|
17
16
|
type Query = LimitedFilteredRequest;
|
|
18
17
|
type Body = undefined;
|
|
19
|
-
type ResponseBody = PaginatedResponse<MembersBlob, LimitedFilteredRequest
|
|
18
|
+
type ResponseBody = PaginatedResponse<MembersBlob, LimitedFilteredRequest>;
|
|
20
19
|
|
|
21
|
-
const sorters = memberSorters
|
|
22
|
-
const filterCompilers = memberFilterCompilers
|
|
20
|
+
const sorters = memberSorters;
|
|
21
|
+
const filterCompilers = memberFilterCompilers;
|
|
23
22
|
|
|
24
23
|
export class GetMembersEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
25
|
-
queryDecoder = LimitedFilteredRequest as Decoder<LimitedFilteredRequest
|
|
24
|
+
queryDecoder = LimitedFilteredRequest as Decoder<LimitedFilteredRequest>;
|
|
26
25
|
|
|
27
26
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
28
|
-
if (request.method
|
|
27
|
+
if (request.method !== 'GET') {
|
|
29
28
|
return [false];
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
const params = Endpoint.parseParameters(request.url,
|
|
31
|
+
const params = Endpoint.parseParameters(request.url, '/members', {});
|
|
33
32
|
|
|
34
33
|
if (params) {
|
|
35
34
|
return [true, params as Params];
|
|
@@ -37,18 +36,18 @@ export class GetMembersEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
37
36
|
return [false];
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
static async buildQuery(q: CountFilteredRequest|LimitedFilteredRequest) {
|
|
41
|
-
const organization = Context.organization
|
|
42
|
-
let scopeFilter: StamhoofdFilter|undefined = undefined;
|
|
39
|
+
static async buildQuery(q: CountFilteredRequest | LimitedFilteredRequest) {
|
|
40
|
+
const organization = Context.organization;
|
|
41
|
+
let scopeFilter: StamhoofdFilter | undefined = undefined;
|
|
43
42
|
|
|
44
43
|
if (!organization && !Context.auth.canAccessAllPlatformMembers()) {
|
|
45
|
-
const tags = Context.auth.getPlatformAccessibleOrganizationTags(PermissionLevel.Read)
|
|
46
|
-
if (tags
|
|
47
|
-
throw Context.auth.error()
|
|
44
|
+
const tags = Context.auth.getPlatformAccessibleOrganizationTags(PermissionLevel.Read);
|
|
45
|
+
if (tags !== 'all' && tags.length === 0) {
|
|
46
|
+
throw Context.auth.error();
|
|
48
47
|
}
|
|
49
|
-
|
|
48
|
+
|
|
50
49
|
if (tags !== 'all') {
|
|
51
|
-
const platform = await Platform.getShared()
|
|
50
|
+
const platform = await Platform.getShared();
|
|
52
51
|
|
|
53
52
|
// Add organization scope filter
|
|
54
53
|
scopeFilter = {
|
|
@@ -56,27 +55,27 @@ export class GetMembersEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
56
55
|
$elemMatch: {
|
|
57
56
|
organization: {
|
|
58
57
|
tags: {
|
|
59
|
-
$in: tags
|
|
60
|
-
}
|
|
58
|
+
$in: tags,
|
|
59
|
+
},
|
|
61
60
|
},
|
|
62
61
|
periodId: platform.periodId,
|
|
63
62
|
group: {
|
|
64
63
|
defaultAgeGroupId: {
|
|
65
|
-
$neq: null
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
64
|
+
$neq: null,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
70
69
|
};
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
if (organization) {
|
|
75
74
|
// Add organization scope filter
|
|
76
|
-
const groups = await Context.auth.getAccessibleGroups(organization.id)
|
|
75
|
+
const groups = await Context.auth.getAccessibleGroups(organization.id);
|
|
77
76
|
|
|
78
77
|
if (groups.length === 0) {
|
|
79
|
-
throw Context.auth.error()
|
|
78
|
+
throw Context.auth.error();
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
if (groups === 'all') {
|
|
@@ -86,173 +85,177 @@ export class GetMembersEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
86
85
|
registrations: {
|
|
87
86
|
$elemMatch: {
|
|
88
87
|
organizationId: organization.id,
|
|
89
|
-
}
|
|
90
|
-
}
|
|
88
|
+
},
|
|
89
|
+
},
|
|
91
90
|
};
|
|
92
|
-
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
93
|
// Can only access current period
|
|
94
94
|
scopeFilter = {
|
|
95
95
|
registrations: {
|
|
96
96
|
$elemMatch: {
|
|
97
97
|
organizationId: organization.id,
|
|
98
98
|
periodId: organization.periodId,
|
|
99
|
-
}
|
|
100
|
-
}
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
104
105
|
scopeFilter = {
|
|
105
106
|
registrations: {
|
|
106
107
|
$elemMatch: {
|
|
107
108
|
organizationId: organization.id,
|
|
108
109
|
periodId: organization.periodId,
|
|
109
110
|
groupId: {
|
|
110
|
-
$in: groups
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
111
|
+
$in: groups,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
114
115
|
};
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
|
-
|
|
118
|
+
|
|
118
119
|
const query = SQL
|
|
119
120
|
.select(
|
|
120
|
-
SQL.column('members', 'id')
|
|
121
|
+
SQL.column('members', 'id'),
|
|
121
122
|
)
|
|
122
123
|
.from(
|
|
123
|
-
SQL.table('members')
|
|
124
|
+
SQL.table('members'),
|
|
124
125
|
);
|
|
125
|
-
|
|
126
|
+
|
|
126
127
|
if (scopeFilter) {
|
|
127
|
-
query.where(compileToSQLFilter(scopeFilter, filterCompilers))
|
|
128
|
+
query.where(compileToSQLFilter(scopeFilter, filterCompilers));
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
if (q.filter) {
|
|
131
|
-
query.where(compileToSQLFilter(q.filter, filterCompilers))
|
|
132
|
+
query.where(compileToSQLFilter(q.filter, filterCompilers));
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
if (q.search) {
|
|
135
|
-
let searchFilter: StamhoofdFilter|null = null
|
|
136
|
+
let searchFilter: StamhoofdFilter | null = null;
|
|
136
137
|
|
|
137
138
|
// is phone?
|
|
138
139
|
if (!searchFilter && q.search.match(/^\+?[0-9\s-]+$/)) {
|
|
139
140
|
// Try to format as phone so we have 1:1 space matches
|
|
140
141
|
try {
|
|
141
|
-
const phoneNumber = parsePhoneNumber(q.search, (Context.i18n.country as Country) || Country.Belgium)
|
|
142
|
+
const phoneNumber = parsePhoneNumber(q.search, (Context.i18n.country as Country) || Country.Belgium);
|
|
142
143
|
if (phoneNumber && phoneNumber.isValid()) {
|
|
143
144
|
const formatted = phoneNumber.formatInternational();
|
|
144
145
|
searchFilter = {
|
|
145
146
|
$or: [
|
|
146
147
|
{
|
|
147
148
|
phone: {
|
|
148
|
-
$eq: formatted
|
|
149
|
-
}
|
|
149
|
+
$eq: formatted,
|
|
150
|
+
},
|
|
150
151
|
},
|
|
151
152
|
{
|
|
152
153
|
parentPhone: {
|
|
153
|
-
$eq: formatted
|
|
154
|
-
}
|
|
154
|
+
$eq: formatted,
|
|
155
|
+
},
|
|
155
156
|
},
|
|
156
157
|
{
|
|
157
158
|
unverifiedPhone: {
|
|
158
|
-
$eq: formatted
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
]
|
|
162
|
-
}
|
|
163
|
-
|
|
159
|
+
$eq: formatted,
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
164
|
}
|
|
165
|
-
}
|
|
166
|
-
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
console.error('Failed to parse phone number', q.search, e);
|
|
167
168
|
}
|
|
168
169
|
}
|
|
169
170
|
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
// Is lidnummer?
|
|
172
|
+
if (!searchFilter && (q.search.match(/^[0-9]{4}-[0-9]{6}-[0-9]{1,2}$/) || q.search.match(/^[0-9]{10}$/))) {
|
|
172
173
|
searchFilter = {
|
|
173
174
|
memberNumber: {
|
|
174
|
-
$eq: q.search
|
|
175
|
-
}
|
|
176
|
-
}
|
|
175
|
+
$eq: q.search,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
// Two search modes:
|
|
180
181
|
// e-mail or name based searching
|
|
181
182
|
if (searchFilter) {
|
|
182
183
|
// already done
|
|
183
|
-
}
|
|
184
|
+
}
|
|
185
|
+
else if (q.search.includes('@')) {
|
|
184
186
|
const isCompleteAddress = DataValidator.isEmailValid(q.search);
|
|
185
187
|
|
|
186
188
|
// Member email address contains, or member parent contains
|
|
187
189
|
searchFilter = {
|
|
188
|
-
|
|
190
|
+
$or: [
|
|
189
191
|
{
|
|
190
192
|
email: {
|
|
191
|
-
[(isCompleteAddress ? '$eq' : '$contains')]: q.search
|
|
192
|
-
}
|
|
193
|
+
[(isCompleteAddress ? '$eq' : '$contains')]: q.search,
|
|
194
|
+
},
|
|
193
195
|
},
|
|
194
196
|
{
|
|
195
197
|
parentEmail: {
|
|
196
|
-
[(isCompleteAddress ? '$eq' : '$contains')]: q.search
|
|
197
|
-
}
|
|
198
|
+
[(isCompleteAddress ? '$eq' : '$contains')]: q.search,
|
|
199
|
+
},
|
|
198
200
|
},
|
|
199
201
|
{
|
|
200
202
|
unverifiedEmail: {
|
|
201
|
-
[(isCompleteAddress ? '$eq' : '$contains')]: q.search
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
]
|
|
205
|
-
} as any as StamhoofdFilter
|
|
206
|
-
}
|
|
203
|
+
[(isCompleteAddress ? '$eq' : '$contains')]: q.search,
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
} as any as StamhoofdFilter;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
207
210
|
searchFilter = {
|
|
208
211
|
name: {
|
|
209
|
-
$contains: q.search
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
+
$contains: q.search,
|
|
213
|
+
},
|
|
214
|
+
};
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
// todo: Address search detection
|
|
215
218
|
|
|
216
219
|
if (searchFilter) {
|
|
217
|
-
query.where(compileToSQLFilter(searchFilter, filterCompilers))
|
|
220
|
+
query.where(compileToSQLFilter(searchFilter, filterCompilers));
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
if (q instanceof LimitedFilteredRequest) {
|
|
222
225
|
if (q.pageFilter) {
|
|
223
|
-
query.where(compileToSQLFilter(q.pageFilter, filterCompilers))
|
|
226
|
+
query.where(compileToSQLFilter(q.pageFilter, filterCompilers));
|
|
224
227
|
}
|
|
225
228
|
|
|
226
|
-
q.sort = assertSort(q.sort, [{key: 'id'}])
|
|
227
|
-
query.orderBy(compileToSQLSorter(q.sort, sorters))
|
|
228
|
-
query.limit(q.limit)
|
|
229
|
+
q.sort = assertSort(q.sort, [{ key: 'id' }]);
|
|
230
|
+
query.orderBy(compileToSQLSorter(q.sort, sorters));
|
|
231
|
+
query.limit(q.limit);
|
|
229
232
|
}
|
|
230
|
-
|
|
231
|
-
return query
|
|
233
|
+
|
|
234
|
+
return query;
|
|
232
235
|
}
|
|
233
236
|
|
|
234
237
|
static async buildData(requestQuery: LimitedFilteredRequest) {
|
|
235
|
-
const query = await GetMembersEndpoint.buildQuery(requestQuery)
|
|
236
|
-
const data = await query.fetch()
|
|
237
|
-
|
|
238
|
+
const query = await GetMembersEndpoint.buildQuery(requestQuery);
|
|
239
|
+
const data = await query.fetch();
|
|
240
|
+
|
|
238
241
|
const memberIds = data.map((r) => {
|
|
239
242
|
if (typeof r.members.id === 'string') {
|
|
240
|
-
return r.members.id
|
|
243
|
+
return r.members.id;
|
|
241
244
|
}
|
|
242
|
-
throw new Error('Expected string')
|
|
245
|
+
throw new Error('Expected string');
|
|
243
246
|
});
|
|
244
247
|
|
|
245
|
-
const _members = await Member.getBlobByIds(...memberIds)
|
|
248
|
+
const _members = await Member.getBlobByIds(...memberIds);
|
|
246
249
|
// Make sure members is in same order as memberIds
|
|
247
|
-
const members = memberIds.map(id => _members.find(m => m.id === id)!)
|
|
250
|
+
const members = memberIds.map(id => _members.find(m => m.id === id)!);
|
|
248
251
|
|
|
249
252
|
for (const member of members) {
|
|
250
253
|
if (!await Context.auth.canAccessMember(member, PermissionLevel.Read)) {
|
|
251
|
-
throw Context.auth.error()
|
|
254
|
+
throw Context.auth.error();
|
|
252
255
|
}
|
|
253
256
|
}
|
|
254
257
|
|
|
255
|
-
let next: LimitedFilteredRequest|undefined;
|
|
258
|
+
let next: LimitedFilteredRequest | undefined;
|
|
256
259
|
|
|
257
260
|
if (memberIds.length >= requestQuery.limit) {
|
|
258
261
|
const lastObject = members[members.length - 1];
|
|
@@ -263,8 +266,8 @@ export class GetMembersEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
263
266
|
pageFilter: nextFilter,
|
|
264
267
|
sort: requestQuery.sort,
|
|
265
268
|
limit: requestQuery.limit,
|
|
266
|
-
search: requestQuery.search
|
|
267
|
-
})
|
|
269
|
+
search: requestQuery.search,
|
|
270
|
+
});
|
|
268
271
|
|
|
269
272
|
if (JSON.stringify(nextFilter) === JSON.stringify(requestQuery.pageFilter)) {
|
|
270
273
|
console.error('Found infinite loading loop for', requestQuery);
|
|
@@ -274,13 +277,13 @@ export class GetMembersEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
274
277
|
|
|
275
278
|
return new PaginatedResponse<MembersBlob, LimitedFilteredRequest>({
|
|
276
279
|
results: await AuthenticatedStructures.membersBlob(members),
|
|
277
|
-
next
|
|
280
|
+
next,
|
|
278
281
|
});
|
|
279
282
|
}
|
|
280
283
|
|
|
281
284
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
282
285
|
await Context.setOptionalOrganizationScope();
|
|
283
|
-
await Context.authenticate()
|
|
286
|
+
await Context.authenticate();
|
|
284
287
|
|
|
285
288
|
const maxLimit = Context.auth.hasSomePlatformAccess() ? 1000 : 100;
|
|
286
289
|
|
|
@@ -288,20 +291,20 @@ export class GetMembersEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
288
291
|
throw new SimpleError({
|
|
289
292
|
code: 'invalid_field',
|
|
290
293
|
field: 'limit',
|
|
291
|
-
message: 'Limit can not be more than ' + maxLimit
|
|
292
|
-
})
|
|
294
|
+
message: 'Limit can not be more than ' + maxLimit,
|
|
295
|
+
});
|
|
293
296
|
}
|
|
294
297
|
|
|
295
298
|
if (request.query.limit < 1) {
|
|
296
299
|
throw new SimpleError({
|
|
297
300
|
code: 'invalid_field',
|
|
298
301
|
field: 'limit',
|
|
299
|
-
message: 'Limit can not be less than 1'
|
|
300
|
-
})
|
|
302
|
+
message: 'Limit can not be less than 1',
|
|
303
|
+
});
|
|
301
304
|
}
|
|
302
|
-
|
|
305
|
+
|
|
303
306
|
return new Response(
|
|
304
|
-
await GetMembersEndpoint.buildData(request.query)
|
|
307
|
+
await GetMembersEndpoint.buildData(request.query),
|
|
305
308
|
);
|
|
306
309
|
}
|
|
307
310
|
}
|