@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
package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
-
import { OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, SetupStepType } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, SetupStepType } from '@stamhoofd/structures';
|
|
3
3
|
|
|
4
|
-
import { AutoEncoder, BooleanDecoder, Decoder, EnumDecoder, field } from
|
|
5
|
-
import { SimpleError } from
|
|
6
|
-
import { OrganizationRegistrationPeriod } from
|
|
7
|
-
import { AuthenticatedStructures } from
|
|
8
|
-
import { Context } from
|
|
4
|
+
import { AutoEncoder, BooleanDecoder, Decoder, EnumDecoder, field } from '@simonbackx/simple-encoding';
|
|
5
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
|
+
import { OrganizationRegistrationPeriod } from '@stamhoofd/models';
|
|
7
|
+
import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures';
|
|
8
|
+
import { Context } from '../../../../helpers/Context';
|
|
9
9
|
|
|
10
10
|
type Params = { readonly id: string };
|
|
11
11
|
type Query = undefined;
|
|
12
12
|
|
|
13
13
|
class Body extends AutoEncoder {
|
|
14
|
-
@field({decoder: new EnumDecoder(SetupStepType)})
|
|
15
|
-
type: SetupStepType
|
|
14
|
+
@field({ decoder: new EnumDecoder(SetupStepType) })
|
|
15
|
+
type: SetupStepType;
|
|
16
16
|
|
|
17
|
-
@field({decoder: BooleanDecoder})
|
|
18
|
-
isReviewed: boolean
|
|
17
|
+
@field({ decoder: BooleanDecoder })
|
|
18
|
+
isReviewed: boolean;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
type ResponseBody = OrganizationRegistrationPeriodStruct
|
|
21
|
+
type ResponseBody = OrganizationRegistrationPeriodStruct;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Endpoint to mark a setup step as reviewed
|
|
@@ -28,11 +28,11 @@ export class SetupStepReviewEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
28
28
|
bodyDecoder = Body as Decoder<Body>;
|
|
29
29
|
|
|
30
30
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
31
|
-
if (request.method
|
|
31
|
+
if (request.method !== 'POST') {
|
|
32
32
|
return [false];
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const params = Endpoint.parseParameters(request.url,
|
|
35
|
+
const params = Endpoint.parseParameters(request.url, '/organization/registration-period/@id/setup-steps/review', { id: String });
|
|
36
36
|
|
|
37
37
|
if (params) {
|
|
38
38
|
return [true, params as Params];
|
|
@@ -42,10 +42,10 @@ export class SetupStepReviewEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
42
42
|
|
|
43
43
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
44
44
|
const organization = await Context.setOrganizationScope();
|
|
45
|
-
const { user } = await Context.authenticate()
|
|
45
|
+
const { user } = await Context.authenticate();
|
|
46
46
|
|
|
47
47
|
if (!await Context.auth.hasFullAccess(organization.id)) {
|
|
48
|
-
throw Context.auth.error()
|
|
48
|
+
throw Context.auth.error();
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const periodId = request.params.id;
|
|
@@ -55,22 +55,23 @@ export class SetupStepReviewEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
55
55
|
const organizationPeriod = await OrganizationRegistrationPeriod.getByID(periodId);
|
|
56
56
|
if (!organizationPeriod || organizationPeriod.organizationId !== organization.id) {
|
|
57
57
|
throw new SimpleError({
|
|
58
|
-
code:
|
|
59
|
-
message:
|
|
60
|
-
statusCode: 404
|
|
61
|
-
})
|
|
58
|
+
code: 'not_found',
|
|
59
|
+
message: 'Period not found',
|
|
60
|
+
statusCode: 404,
|
|
61
|
+
});
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const setupSteps = organizationPeriod.setupSteps;
|
|
65
65
|
|
|
66
|
-
if(isReviewed) {
|
|
66
|
+
if (isReviewed) {
|
|
67
67
|
setupSteps.markReviewed(stepType, {
|
|
68
68
|
userId: user.id,
|
|
69
|
-
userName: user.name ?? '?'
|
|
69
|
+
userName: user.name ?? '?',
|
|
70
70
|
});
|
|
71
|
-
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
72
73
|
setupSteps.resetReviewed(stepType);
|
|
73
|
-
}
|
|
74
|
+
}
|
|
74
75
|
|
|
75
76
|
await organizationPeriod.save();
|
|
76
77
|
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
|
|
2
1
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
2
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
3
|
import { StripeAccount } from '@stamhoofd/models';
|
|
5
|
-
import { PermissionLevel, StripeAccount as StripeAccountStruct } from
|
|
4
|
+
import { PermissionLevel, StripeAccount as StripeAccountStruct } from '@stamhoofd/structures';
|
|
6
5
|
import Stripe from 'stripe';
|
|
7
6
|
|
|
8
7
|
import { Context } from '../../../../helpers/Context';
|
|
9
8
|
import { StripeHelper } from '../../../../helpers/StripeHelper';
|
|
10
9
|
type Params = Record<string, never>;
|
|
11
10
|
type Body = undefined;
|
|
12
|
-
type Query = undefined
|
|
13
|
-
type ResponseBody = StripeAccountStruct
|
|
11
|
+
type Query = undefined;
|
|
12
|
+
type ResponseBody = StripeAccountStruct;
|
|
14
13
|
|
|
15
|
-
export class ConnectMollieEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
|
+
export class ConnectMollieEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
16
15
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
17
|
-
if (request.method
|
|
16
|
+
if (request.method !== 'POST') {
|
|
18
17
|
return [false];
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
const params = Endpoint.parseParameters(request.url,
|
|
20
|
+
const params = Endpoint.parseParameters(request.url, '/stripe/connect', {});
|
|
22
21
|
|
|
23
22
|
if (params) {
|
|
24
23
|
return [true, params as Params];
|
|
@@ -29,24 +28,24 @@ export class ConnectMollieEndpoint extends Endpoint<Params, Query, Body, Respons
|
|
|
29
28
|
|
|
30
29
|
async handle(_: DecodedRequest<Params, Query, Body>) {
|
|
31
30
|
const organization = await Context.setOrganizationScope();
|
|
32
|
-
await Context.authenticate()
|
|
31
|
+
await Context.authenticate();
|
|
33
32
|
|
|
34
33
|
// Fast throw first (more in depth checking for patches later)
|
|
35
34
|
if (!await Context.auth.canManagePaymentAccounts(organization.id, PermissionLevel.Full)) {
|
|
36
|
-
throw Context.auth.error()
|
|
35
|
+
throw Context.auth.error();
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
const models = await StripeAccount.where({ organizationId: organization.id, status:
|
|
38
|
+
const models = await StripeAccount.where({ organizationId: organization.id, status: 'active' });
|
|
40
39
|
|
|
41
|
-
const canCreateMultipleStripeAccounts = models.every(a => (a.meta.charges_enabled && a.meta.payouts_enabled) || (a.meta.details_submitted))
|
|
40
|
+
const canCreateMultipleStripeAccounts = models.every(a => (a.meta.charges_enabled && a.meta.payouts_enabled) || (a.meta.details_submitted));
|
|
42
41
|
if (models.length > 0 && !canCreateMultipleStripeAccounts) {
|
|
43
42
|
throw new SimpleError({
|
|
44
|
-
code:
|
|
45
|
-
message:
|
|
46
|
-
})
|
|
43
|
+
code: 'already_connected',
|
|
44
|
+
message: 'Je hebt al een Stripe account gekoppeld',
|
|
45
|
+
});
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
const type = STAMHOOFD.STRIPE_CONNECT_METHOD
|
|
48
|
+
const type = STAMHOOFD.STRIPE_CONNECT_METHOD;
|
|
50
49
|
|
|
51
50
|
const sharedData: Stripe.AccountCreateParams = {
|
|
52
51
|
capabilities: {
|
|
@@ -55,7 +54,7 @@ export class ConnectMollieEndpoint extends Endpoint<Params, Query, Body, Respons
|
|
|
55
54
|
bancontact_payments: { requested: true },
|
|
56
55
|
ideal_payments: { requested: true },
|
|
57
56
|
},
|
|
58
|
-
}
|
|
57
|
+
};
|
|
59
58
|
|
|
60
59
|
let expressData: Stripe.AccountCreateParams = {
|
|
61
60
|
country: organization.address.country,
|
|
@@ -68,9 +67,9 @@ export class ConnectMollieEndpoint extends Endpoint<Params, Query, Body, Respons
|
|
|
68
67
|
delay_days: 'minimum',
|
|
69
68
|
interval: 'weekly',
|
|
70
69
|
weekly_anchor: 'monday',
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
74
73
|
};
|
|
75
74
|
|
|
76
75
|
if (type !== 'express') {
|
|
@@ -78,22 +77,22 @@ export class ConnectMollieEndpoint extends Endpoint<Params, Query, Body, Respons
|
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
// Create a new Stripe account
|
|
81
|
-
const stripe = StripeHelper.getInstance()
|
|
80
|
+
const stripe = StripeHelper.getInstance();
|
|
82
81
|
const account = await stripe.accounts.create({
|
|
83
82
|
type,
|
|
84
83
|
...sharedData,
|
|
85
|
-
...expressData
|
|
84
|
+
...expressData,
|
|
86
85
|
});
|
|
87
86
|
|
|
88
87
|
// Save the Stripe account in the database
|
|
89
88
|
const model = new StripeAccount();
|
|
90
89
|
model.organizationId = organization.id;
|
|
91
90
|
model.accountId = account.id;
|
|
92
|
-
model.setMetaFromStripeAccount(account)
|
|
91
|
+
model.setMetaFromStripeAccount(account);
|
|
93
92
|
await model.save();
|
|
94
93
|
|
|
95
94
|
// Return information about the Stripe Account
|
|
96
|
-
|
|
95
|
+
|
|
97
96
|
return new Response(StripeAccountStruct.create(model));
|
|
98
97
|
}
|
|
99
98
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
2
|
import { StripeAccount } from '@stamhoofd/models';
|
|
4
3
|
import { PermissionLevel } from '@stamhoofd/structures';
|
|
@@ -9,16 +8,16 @@ import { SimpleError } from '@simonbackx/simple-errors';
|
|
|
9
8
|
|
|
10
9
|
type Params = { id: string };
|
|
11
10
|
type Body = undefined;
|
|
12
|
-
type Query = undefined
|
|
13
|
-
type ResponseBody = undefined
|
|
11
|
+
type Query = undefined;
|
|
12
|
+
type ResponseBody = undefined;
|
|
14
13
|
|
|
15
|
-
export class DeleteStripeAccountEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
|
+
export class DeleteStripeAccountEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
16
15
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
17
|
-
if (request.method
|
|
16
|
+
if (request.method !== 'DELETE') {
|
|
18
17
|
return [false];
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
const params = Endpoint.parseParameters(request.url,
|
|
20
|
+
const params = Endpoint.parseParameters(request.url, '/stripe/accounts/@id', { id: String });
|
|
22
21
|
|
|
23
22
|
if (params) {
|
|
24
23
|
return [true, params as Params];
|
|
@@ -29,39 +28,40 @@ export class DeleteStripeAccountEndpoint extends Endpoint<Params, Query, Body, R
|
|
|
29
28
|
|
|
30
29
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
31
30
|
const organization = await Context.setOrganizationScope();
|
|
32
|
-
await Context.authenticate()
|
|
31
|
+
await Context.authenticate();
|
|
33
32
|
|
|
34
33
|
// Fast throw first (more in depth checking for patches later)
|
|
35
34
|
if (!await Context.auth.canManagePaymentAccounts(organization.id, PermissionLevel.Full)) {
|
|
36
|
-
throw Context.auth.error()
|
|
35
|
+
throw Context.auth.error();
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
const model = await StripeAccount.getByID(request.params.id)
|
|
41
|
-
if (!model || model.organizationId
|
|
42
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
38
|
+
// Search account in database
|
|
39
|
+
const model = await StripeAccount.getByID(request.params.id);
|
|
40
|
+
if (!model || model.organizationId !== organization.id || model.status !== 'active') {
|
|
41
|
+
throw Context.auth.notFoundOrNoAccess('Account niet gevonden');
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
if (model.accountId === STAMHOOFD.STRIPE_ACCOUNT_ID) {
|
|
46
45
|
throw new SimpleError({
|
|
47
|
-
code:
|
|
48
|
-
message:
|
|
49
|
-
statusCode: 400
|
|
50
|
-
})
|
|
46
|
+
code: 'invalid_request',
|
|
47
|
+
message: 'Je kan het hoofdaccount van het platform niet verwijderen.',
|
|
48
|
+
statusCode: 400,
|
|
49
|
+
});
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
// For now we don't delete them in Stripe because this causes issues with data access
|
|
54
|
-
const stripe = StripeHelper.getInstance()
|
|
55
|
-
|
|
53
|
+
const stripe = StripeHelper.getInstance();
|
|
54
|
+
|
|
56
55
|
try {
|
|
57
56
|
await stripe.accounts.del(model.accountId);
|
|
58
|
-
}
|
|
59
|
-
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
console.error('Tried deleting account but failed', e);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
// If that succeeded
|
|
63
|
-
model.status =
|
|
64
|
-
await model.save()
|
|
63
|
+
model.status = 'deleted';
|
|
64
|
+
await model.save();
|
|
65
65
|
|
|
66
66
|
return new Response(undefined);
|
|
67
67
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
|
|
3
2
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
4
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
@@ -14,30 +13,30 @@ class Body extends AutoEncoder {
|
|
|
14
13
|
* The account id (internal id, not the stripe id)
|
|
15
14
|
*/
|
|
16
15
|
@field({ decoder: StringDecoder })
|
|
17
|
-
accountId: string
|
|
16
|
+
accountId: string;
|
|
18
17
|
|
|
19
18
|
@field({ decoder: StringDecoder })
|
|
20
|
-
returnUrl: string
|
|
19
|
+
returnUrl: string;
|
|
21
20
|
|
|
22
21
|
@field({ decoder: StringDecoder })
|
|
23
|
-
refreshUrl: string
|
|
22
|
+
refreshUrl: string;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
type Query = undefined
|
|
25
|
+
type Query = undefined;
|
|
27
26
|
class ResponseBody extends AutoEncoder {
|
|
28
27
|
@field({ decoder: StringDecoder })
|
|
29
|
-
url: string
|
|
28
|
+
url: string;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export class GetStripeAccountLinkEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
33
|
-
bodyDecoder = Body as Decoder<Body
|
|
32
|
+
bodyDecoder = Body as Decoder<Body>;
|
|
34
33
|
|
|
35
34
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
36
|
-
if (request.method
|
|
35
|
+
if (request.method !== 'POST') {
|
|
37
36
|
return [false];
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
const params = Endpoint.parseParameters(request.url,
|
|
39
|
+
const params = Endpoint.parseParameters(request.url, '/stripe/account-link', {});
|
|
41
40
|
|
|
42
41
|
if (params) {
|
|
43
42
|
return [true, params as Params];
|
|
@@ -48,21 +47,21 @@ export class GetStripeAccountLinkEndpoint extends Endpoint<Params, Query, Body,
|
|
|
48
47
|
|
|
49
48
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
50
49
|
const organization = await Context.setOrganizationScope();
|
|
51
|
-
await Context.authenticate()
|
|
50
|
+
await Context.authenticate();
|
|
52
51
|
|
|
53
52
|
// Fast throw first (more in depth checking for patches later)
|
|
54
53
|
if (!await Context.auth.canManagePaymentAccounts(organization.id, PermissionLevel.Full)) {
|
|
55
|
-
throw Context.auth.error()
|
|
54
|
+
throw Context.auth.error();
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
// Search account in database
|
|
59
|
-
const model = await StripeAccount.getByID(request.body.accountId)
|
|
60
|
-
if (!model || model.organizationId
|
|
61
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
58
|
+
const model = await StripeAccount.getByID(request.body.accountId);
|
|
59
|
+
if (!model || model.organizationId !== organization.id || model.status !== 'active') {
|
|
60
|
+
throw Context.auth.notFoundOrNoAccess('Account niet gevonden');
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
// Get account
|
|
65
|
-
const stripe = StripeHelper.getInstance()
|
|
64
|
+
const stripe = StripeHelper.getInstance();
|
|
66
65
|
const accountLink = await stripe.accountLinks.create({
|
|
67
66
|
account: model.accountId,
|
|
68
67
|
refresh_url: request.body.refreshUrl,
|
|
@@ -70,12 +69,12 @@ export class GetStripeAccountLinkEndpoint extends Endpoint<Params, Query, Body,
|
|
|
70
69
|
type: 'account_onboarding',
|
|
71
70
|
collection_options: {
|
|
72
71
|
fields: 'eventually_due',
|
|
73
|
-
future_requirements: 'include'
|
|
74
|
-
}
|
|
72
|
+
future_requirements: 'include',
|
|
73
|
+
},
|
|
75
74
|
});
|
|
76
75
|
|
|
77
76
|
return new Response(ResponseBody.create({
|
|
78
|
-
url: accountLink.url
|
|
77
|
+
url: accountLink.url,
|
|
79
78
|
}));
|
|
80
79
|
}
|
|
81
80
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
2
|
import { StripeAccount } from '@stamhoofd/models';
|
|
4
3
|
import { PermissionLevel, StripeAccount as StripeAccountStruct } from '@stamhoofd/structures';
|
|
@@ -7,16 +6,16 @@ import { Context } from '../../../../helpers/Context';
|
|
|
7
6
|
|
|
8
7
|
type Params = Record<string, never>;
|
|
9
8
|
type Body = undefined;
|
|
10
|
-
type Query = undefined
|
|
11
|
-
type ResponseBody = StripeAccountStruct[]
|
|
9
|
+
type Query = undefined;
|
|
10
|
+
type ResponseBody = StripeAccountStruct[];
|
|
12
11
|
|
|
13
|
-
export class GetStripeAccountLinkEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
12
|
+
export class GetStripeAccountLinkEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
13
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
15
|
-
if (request.method
|
|
14
|
+
if (request.method !== 'GET') {
|
|
16
15
|
return [false];
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
const params = Endpoint.parseParameters(request.url,
|
|
18
|
+
const params = Endpoint.parseParameters(request.url, '/stripe/accounts', {});
|
|
20
19
|
|
|
21
20
|
if (params) {
|
|
22
21
|
return [true, params as Params];
|
|
@@ -27,14 +26,14 @@ export class GetStripeAccountLinkEndpoint extends Endpoint<Params, Query, Body,
|
|
|
27
26
|
|
|
28
27
|
async handle(_: DecodedRequest<Params, Query, Body>) {
|
|
29
28
|
const organization = await Context.setOrganizationScope();
|
|
30
|
-
await Context.authenticate()
|
|
29
|
+
await Context.authenticate();
|
|
31
30
|
|
|
32
31
|
// Fast throw first (more in depth checking for patches later)
|
|
33
32
|
if (!await Context.auth.canManagePaymentAccounts(organization.id, PermissionLevel.Read)) {
|
|
34
|
-
throw Context.auth.error()
|
|
33
|
+
throw Context.auth.error();
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
const models = await StripeAccount.where({ organizationId: organization.id, status: 'active' })
|
|
36
|
+
const models = await StripeAccount.where({ organizationId: organization.id, status: 'active' });
|
|
38
37
|
return new Response(models.map(m => StripeAccountStruct.create(m)));
|
|
39
38
|
}
|
|
40
39
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
|
|
3
2
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
4
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
@@ -14,24 +13,24 @@ class Body extends AutoEncoder {
|
|
|
14
13
|
* The account id (internal id, not the stripe id)
|
|
15
14
|
*/
|
|
16
15
|
@field({ decoder: StringDecoder })
|
|
17
|
-
accountId: string
|
|
16
|
+
accountId: string;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
type Query = undefined
|
|
19
|
+
type Query = undefined;
|
|
21
20
|
class ResponseBody extends AutoEncoder {
|
|
22
21
|
@field({ decoder: StringDecoder })
|
|
23
|
-
url: string
|
|
22
|
+
url: string;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
export class GetStripeLoginLinkEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
27
|
-
bodyDecoder = Body as Decoder<Body
|
|
26
|
+
bodyDecoder = Body as Decoder<Body>;
|
|
28
27
|
|
|
29
28
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
30
|
-
if (request.method
|
|
29
|
+
if (request.method !== 'POST') {
|
|
31
30
|
return [false];
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
const params = Endpoint.parseParameters(request.url,
|
|
33
|
+
const params = Endpoint.parseParameters(request.url, '/stripe/login-link', {});
|
|
35
34
|
|
|
36
35
|
if (params) {
|
|
37
36
|
return [true, params as Params];
|
|
@@ -42,34 +41,34 @@ export class GetStripeLoginLinkEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
42
41
|
|
|
43
42
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
44
43
|
const organization = await Context.setOrganizationScope();
|
|
45
|
-
await Context.authenticate()
|
|
44
|
+
await Context.authenticate();
|
|
46
45
|
|
|
47
46
|
// Fast throw first (more in depth checking for patches later)
|
|
48
47
|
if (!await Context.auth.canManagePaymentAccounts(organization.id, PermissionLevel.Full)) {
|
|
49
|
-
throw Context.auth.error()
|
|
48
|
+
throw Context.auth.error();
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
// Search account in database
|
|
53
|
-
const model = await StripeAccount.getByID(request.body.accountId)
|
|
54
|
-
if (!model || model.organizationId
|
|
52
|
+
const model = await StripeAccount.getByID(request.body.accountId);
|
|
53
|
+
if (!model || model.organizationId !== organization.id || model.status !== 'active') {
|
|
55
54
|
throw new SimpleError({
|
|
56
|
-
code:
|
|
57
|
-
message:
|
|
58
|
-
statusCode: 400
|
|
59
|
-
})
|
|
55
|
+
code: 'not_found',
|
|
56
|
+
message: 'Account niet gevonden',
|
|
57
|
+
statusCode: 400,
|
|
58
|
+
});
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
if (model.meta.type === 'standard') {
|
|
63
62
|
return new Response(ResponseBody.create({
|
|
64
|
-
url: 'https://dashboard.stripe.com/'
|
|
63
|
+
url: 'https://dashboard.stripe.com/',
|
|
65
64
|
}));
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
const stripe = StripeHelper.getInstance()
|
|
67
|
+
const stripe = StripeHelper.getInstance();
|
|
69
68
|
const accountLink = await stripe.accounts.createLoginLink(model.accountId);
|
|
70
69
|
|
|
71
70
|
return new Response(ResponseBody.create({
|
|
72
|
-
url: accountLink.url
|
|
71
|
+
url: accountLink.url,
|
|
73
72
|
}));
|
|
74
73
|
}
|
|
75
74
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
2
|
import { StripeAccount } from '@stamhoofd/models';
|
|
4
3
|
import { PermissionLevel, StripeAccount as StripeAccountStruct } from '@stamhoofd/structures';
|
|
@@ -8,16 +7,16 @@ import { StripeHelper } from '../../../../helpers/StripeHelper';
|
|
|
8
7
|
|
|
9
8
|
type Params = { id: string };
|
|
10
9
|
type Body = undefined;
|
|
11
|
-
type Query = undefined
|
|
12
|
-
type ResponseBody = StripeAccountStruct
|
|
10
|
+
type Query = undefined;
|
|
11
|
+
type ResponseBody = StripeAccountStruct;
|
|
13
12
|
|
|
14
|
-
export class UpdateStripeAccountEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
13
|
+
export class UpdateStripeAccountEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
15
14
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
16
|
-
if (request.method
|
|
15
|
+
if (request.method !== 'POST') {
|
|
17
16
|
return [false];
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
const params = Endpoint.parseParameters(request.url,
|
|
19
|
+
const params = Endpoint.parseParameters(request.url, '/stripe/accounts/@id', { id: String });
|
|
21
20
|
|
|
22
21
|
if (params) {
|
|
23
22
|
return [true, params as Params];
|
|
@@ -28,24 +27,24 @@ export class UpdateStripeAccountEndpoint extends Endpoint<Params, Query, Body, R
|
|
|
28
27
|
|
|
29
28
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
30
29
|
const organization = await Context.setOrganizationScope();
|
|
31
|
-
await Context.authenticate()
|
|
30
|
+
await Context.authenticate();
|
|
32
31
|
|
|
33
32
|
// Fast throw first (more in depth checking for patches later)
|
|
34
33
|
if (!await Context.auth.canManagePaymentAccounts(organization.id, PermissionLevel.Read)) {
|
|
35
|
-
throw Context.auth.error()
|
|
34
|
+
throw Context.auth.error();
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
const model = await StripeAccount.getByID(request.params.id)
|
|
40
|
-
if (!model || model.organizationId
|
|
41
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
37
|
+
// Search account in database
|
|
38
|
+
const model = await StripeAccount.getByID(request.params.id);
|
|
39
|
+
if (!model || model.organizationId !== organization.id) {
|
|
40
|
+
throw Context.auth.notFoundOrNoAccess('Account niet gevonden');
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
// Get account
|
|
45
|
-
const stripe = StripeHelper.getInstance()
|
|
44
|
+
const stripe = StripeHelper.getInstance();
|
|
46
45
|
const account = await stripe.accounts.retrieve(model.accountId);
|
|
47
|
-
model.setMetaFromStripeAccount(account)
|
|
48
|
-
await model.save()
|
|
46
|
+
model.setMetaFromStripeAccount(account);
|
|
47
|
+
await model.save();
|
|
49
48
|
|
|
50
49
|
return new Response(StripeAccountStruct.create(model));
|
|
51
50
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { Decoder } 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 { Token, User } from '@stamhoofd/models';
|
|
5
|
-
import { ApiUser, ApiUserWithToken, UserPermissions } from
|
|
5
|
+
import { ApiUser, ApiUserWithToken, UserPermissions } from '@stamhoofd/structures';
|
|
6
6
|
|
|
7
7
|
import { Context } from '../../../../helpers/Context';
|
|
8
8
|
type Params = Record<string, never>;
|
|
9
9
|
type Query = undefined;
|
|
10
|
-
type Body = ApiUser
|
|
11
|
-
type ResponseBody = ApiUser
|
|
10
|
+
type Body = ApiUser;
|
|
11
|
+
type ResponseBody = ApiUser;
|
|
12
12
|
|
|
13
13
|
export class CreateAdminEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
|
-
bodyDecoder = ApiUser as Decoder<ApiUser
|
|
14
|
+
bodyDecoder = ApiUser as Decoder<ApiUser>;
|
|
15
15
|
|
|
16
16
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
17
|
-
if (request.method
|
|
17
|
+
if (request.method !== 'POST') {
|
|
18
18
|
return [false];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const params = Endpoint.parseParameters(request.url,
|
|
21
|
+
const params = Endpoint.parseParameters(request.url, '/api-keys', {});
|
|
22
22
|
|
|
23
23
|
if (params) {
|
|
24
24
|
return [true, params as Params];
|
|
@@ -28,22 +28,22 @@ export class CreateAdminEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
28
28
|
|
|
29
29
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
30
30
|
const organization = await Context.setOrganizationScope();
|
|
31
|
-
await Context.authenticate()
|
|
31
|
+
await Context.authenticate();
|
|
32
32
|
|
|
33
33
|
// Fast throw first (more in depth checking for patches later)
|
|
34
34
|
if (!await Context.auth.canManageAdmins(organization.id)) {
|
|
35
|
-
throw Context.auth.error()
|
|
35
|
+
throw Context.auth.error();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const admin = new User();
|
|
39
39
|
admin.organizationId = organization.id;
|
|
40
40
|
admin.firstName = request.body.name;
|
|
41
|
-
admin.lastName = null
|
|
42
|
-
admin.email = 'creating.api'
|
|
43
|
-
admin.verified = true
|
|
41
|
+
admin.lastName = null;
|
|
42
|
+
admin.email = 'creating.api';
|
|
43
|
+
admin.verified = true;
|
|
44
44
|
|
|
45
45
|
if (!admin.isApiUser) {
|
|
46
|
-
throw new Error('Unexpectedly created normal user while trying to create API-user')
|
|
46
|
+
throw new Error('Unexpectedly created normal user while trying to create API-user');
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// Merge permissions
|
|
@@ -51,15 +51,15 @@ export class CreateAdminEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
51
51
|
throw new SimpleError({
|
|
52
52
|
code: 'missing_field',
|
|
53
53
|
message: 'When creating API-users, you are required to specify permissions in the request',
|
|
54
|
-
field: 'permissions'
|
|
55
|
-
})
|
|
54
|
+
field: 'permissions',
|
|
55
|
+
});
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
admin.permissions = UserPermissions.limitedAdd(null, request.body.permissions, organization.id)
|
|
58
|
+
admin.permissions = UserPermissions.limitedAdd(null, request.body.permissions, organization.id);
|
|
59
59
|
await admin.save();
|
|
60
60
|
|
|
61
61
|
// Set id
|
|
62
|
-
admin.email = admin.id + '.api'
|
|
62
|
+
admin.email = admin.id + '.api';
|
|
63
63
|
await admin.save();
|
|
64
64
|
|
|
65
65
|
const createdToken = await Token.createApiToken(admin);
|
|
@@ -67,7 +67,7 @@ export class CreateAdminEndpoint extends Endpoint<Params, Query, Body, ResponseB
|
|
|
67
67
|
return new Response(ApiUserWithToken.create({
|
|
68
68
|
...(await Token.getAPIUserWithToken(admin)),
|
|
69
69
|
token: createdToken.accessToken,
|
|
70
|
-
expiresAt: createdToken.accessTokenValidUntil
|
|
70
|
+
expiresAt: createdToken.accessTokenValidUntil,
|
|
71
71
|
}));
|
|
72
72
|
}
|
|
73
73
|
}
|