@stamhoofd/backend 2.39.1 → 2.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.mjs +5 -0
- package/index.ts +81 -74
- package/jest.config.cjs +10 -0
- package/migrations.ts +16 -14
- package/package.json +11 -11
- package/src/crons/clear-excel-cache.test.ts +48 -50
- package/src/crons/clear-excel-cache.ts +18 -18
- package/src/crons/setup-steps.ts +2 -2
- package/src/crons.ts +325 -306
- package/src/decoders/StringArrayDecoder.ts +7 -7
- package/src/decoders/StringNullableDecoder.ts +1 -2
- package/src/email-recipient-loaders/members.ts +22 -22
- package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
- package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
- package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
- package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
- package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
- package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
- package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
- package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
- package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
- package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
- package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
- package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
- package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
- package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
- package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
- package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
- package/src/endpoints/auth/SignupEndpoint.ts +37 -36
- package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
- package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
- package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
- package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
- package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
- package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
- package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
- package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
- package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
- package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
- package/src/endpoints/global/files/GetFileCache.ts +13 -13
- package/src/endpoints/global/files/UploadFile.ts +51 -54
- package/src/endpoints/global/files/UploadImage.ts +53 -53
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
- package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
- package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
- package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
- package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
- package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
- package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
- package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
- package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
- package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
- package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
- package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
- package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
- package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
- package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
- package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
- package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
- package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
- package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
- package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
- package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
- package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
- package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
- package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
- package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
- package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
- package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
- package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
- package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
- package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
- package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
- package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
- package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
- package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
- package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
- package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
- package/src/excel-loaders/members.ts +275 -273
- package/src/excel-loaders/payments.ts +155 -156
- package/src/helpers/AddressValidator.test.ts +32 -32
- package/src/helpers/AddressValidator.ts +128 -122
- package/src/helpers/AdminPermissionChecker.ts +339 -236
- package/src/helpers/AuthenticatedStructures.ts +233 -134
- package/src/helpers/BuckarooHelper.ts +134 -134
- package/src/helpers/CheckSettlements.ts +94 -88
- package/src/helpers/Context.ts +87 -86
- package/src/helpers/CookieHelper.ts +23 -22
- package/src/helpers/EmailResumer.ts +10 -10
- package/src/helpers/FileCache.ts +62 -62
- package/src/helpers/ForwardHandler.test.ts +122 -124
- package/src/helpers/ForwardHandler.ts +76 -70
- package/src/helpers/MemberUserSyncer.ts +101 -96
- package/src/helpers/MembershipCharger.ts +69 -69
- package/src/helpers/MembershipHelper.ts +11 -12
- package/src/helpers/OpenIDConnectHelper.ts +85 -82
- package/src/helpers/PeriodHelper.ts +65 -70
- package/src/helpers/StripeHelper.ts +146 -137
- package/src/helpers/StripePayoutChecker.ts +51 -52
- package/src/helpers/ViesHelper.ts +46 -44
- package/src/helpers/fetchToAsyncIterator.ts +14 -14
- package/src/helpers/xlsxAddressTransformerColumnFactory.ts +58 -60
- package/src/middleware/ContextMiddleware.ts +5 -5
- package/src/migrations/1646578856-validate-addresses.ts +6 -9
- package/src/seeds/0000000000-example.ts +3 -5
- package/src/seeds/1715028563-user-permissions.ts +16 -18
- package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
- package/src/seeds/1722344162-sync-member-users.ts +14 -15
- package/src/seeds/1722344162-update-membership.ts +6 -6
- package/src/seeds/1726055544-balance-item-paid.ts +4 -4
- package/src/seeds/1726055545-balance-item-pending.ts +4 -4
- package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
- package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
- package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
- package/src/seeds/1726847064-setup-steps.ts +16 -0
- package/src/sql-filters/balance-item-payments.ts +7 -7
- package/src/sql-filters/events.ts +14 -14
- package/src/sql-filters/members.ts +96 -96
- package/src/sql-filters/organizations.ts +139 -75
- package/src/sql-filters/payments.ts +28 -28
- package/src/sql-filters/registrations.ts +14 -14
- package/src/sql-sorters/events.ts +25 -25
- package/src/sql-sorters/members.ts +26 -26
- package/src/sql-sorters/organizations.ts +36 -36
- package/src/sql-sorters/payments.ts +26 -26
- package/tests/e2e/stock.test.ts +616 -621
- package/tests/e2e/tickets.test.ts +255 -260
- package/tests/helpers/StripeMocker.ts +177 -179
- package/tests/helpers/TestServer.ts +9 -9
- package/tests/jest.global.setup.ts +14 -13
- package/tests/jest.setup.ts +33 -32
- package/.eslintrc.js +0 -61
- package/jest.config.js +0 -11
- package/src/helpers/SetupStepsUpdater.ts +0 -359
- package/src/seeds/1724076679-setup-steps.ts +0 -16
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { ArrayDecoder, AutoEncoderPatchType, Data, Decoder, PatchableArray, 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 { BalanceItem, BalanceItemPayment, Order, Payment, Token, Webshop } from '@stamhoofd/models';
|
|
5
5
|
import { QueueHandler } from '@stamhoofd/queues';
|
|
6
|
-
import { BalanceItemRelation, BalanceItemRelationType, BalanceItemStatus, BalanceItemType, OrderStatus, PaymentMethod, PaymentStatus, PermissionLevel, PrivateOrder, PrivatePayment,Webshop as WebshopStruct } from
|
|
6
|
+
import { BalanceItemRelation, BalanceItemRelationType, BalanceItemStatus, BalanceItemType, OrderStatus, PaymentMethod, PaymentStatus, PermissionLevel, PrivateOrder, PrivatePayment, Webshop as WebshopStruct } from '@stamhoofd/structures';
|
|
7
7
|
|
|
8
8
|
import { Context } from '../../../../helpers/Context';
|
|
9
9
|
|
|
10
10
|
type Params = { id: string };
|
|
11
11
|
type Query = undefined;
|
|
12
|
-
type Body = AutoEncoderPatchType<PrivateOrder>[] | PatchableArrayAutoEncoder<PrivateOrder
|
|
13
|
-
type ResponseBody = PrivateOrder[]
|
|
12
|
+
type Body = AutoEncoderPatchType<PrivateOrder>[] | PatchableArrayAutoEncoder<PrivateOrder>;
|
|
13
|
+
type ResponseBody = PrivateOrder[];
|
|
14
14
|
|
|
15
15
|
class VersionSpecificDecoder<A, B> implements Decoder<A | B> {
|
|
16
16
|
oldDecoder: Decoder<A>;
|
|
@@ -25,13 +25,13 @@ class VersionSpecificDecoder<A, B> implements Decoder<A | B> {
|
|
|
25
25
|
|
|
26
26
|
decode(data: Data): A | B {
|
|
27
27
|
// Set the version of the decoding context of "data"
|
|
28
|
-
const v = data.context.version
|
|
28
|
+
const v = data.context.version;
|
|
29
29
|
|
|
30
30
|
if (v >= this.version) {
|
|
31
31
|
return this.newerDecoder.decode(data);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
return this.oldDecoder.decode(data);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -41,15 +41,15 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
41
41
|
new ArrayDecoder(PrivateOrder.patchType() as Decoder<AutoEncoderPatchType<PrivateOrder>>),
|
|
42
42
|
159,
|
|
43
43
|
// After or at version 159, accept a patchable array
|
|
44
|
-
new PatchableArrayDecoder(PrivateOrder as Decoder<PrivateOrder>, PrivateOrder.patchType() as Decoder<AutoEncoderPatchType<PrivateOrder>>, StringDecoder)
|
|
44
|
+
new PatchableArrayDecoder(PrivateOrder as Decoder<PrivateOrder>, PrivateOrder.patchType() as Decoder<AutoEncoderPatchType<PrivateOrder>>, StringDecoder),
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
48
|
-
if (request.method
|
|
48
|
+
if (request.method !== 'PATCH') {
|
|
49
49
|
return [false];
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const params = Endpoint.parseParameters(request.url,
|
|
52
|
+
const params = Endpoint.parseParameters(request.url, '/webshop/@id/orders', { id: String });
|
|
53
53
|
|
|
54
54
|
if (params) {
|
|
55
55
|
return [true, params as Params];
|
|
@@ -59,22 +59,23 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
59
59
|
|
|
60
60
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
61
61
|
const organization = await Context.setOrganizationScope();
|
|
62
|
-
await Context.authenticate()
|
|
62
|
+
await Context.authenticate();
|
|
63
63
|
|
|
64
64
|
// Fast throw first (more in depth checking for patches later)
|
|
65
65
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
66
|
-
throw Context.auth.error()
|
|
66
|
+
throw Context.auth.error();
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
let body: PatchableArrayAutoEncoder<PrivateOrder> = new PatchableArray()
|
|
69
|
+
let body: PatchableArrayAutoEncoder<PrivateOrder> = new PatchableArray();
|
|
70
70
|
|
|
71
71
|
// Migrate old syntax
|
|
72
72
|
if (Array.isArray(request.body)) {
|
|
73
73
|
for (const p of request.body) {
|
|
74
74
|
body.addPatch(p);
|
|
75
75
|
}
|
|
76
|
-
}
|
|
77
|
-
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
body = request.body;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
if (body.changes.length == 0) {
|
|
@@ -82,100 +83,103 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
// Need to happen in the queue because we are updating the webshop stock
|
|
85
|
-
const orders = await QueueHandler.schedule(
|
|
86
|
-
const webshop = await Webshop.getByID(request.params.id)
|
|
86
|
+
const orders = await QueueHandler.schedule('webshop-stock/' + request.params.id, async () => {
|
|
87
|
+
const webshop = await Webshop.getByID(request.params.id);
|
|
87
88
|
if (!webshop || !await Context.auth.canAccessWebshop(webshop, PermissionLevel.Write)) {
|
|
88
|
-
throw Context.auth.notFoundOrNoAccess()
|
|
89
|
+
throw Context.auth.notFoundOrNoAccess();
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
const orders = body.getPatches().length > 0
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
const orders = body.getPatches().length > 0
|
|
93
|
+
? await Order.where({
|
|
94
|
+
webshopId: webshop.id,
|
|
95
|
+
id: {
|
|
96
|
+
sign: 'IN',
|
|
97
|
+
value: body.getPatches().map(o => o.id),
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
: [];
|
|
98
101
|
|
|
99
102
|
// We use a getter because we need to have an up to date webshop struct
|
|
100
103
|
// otherwise we won't validate orders on the latest webshop with the latest stock information
|
|
101
104
|
const webshopGetter = {
|
|
102
105
|
get struct() {
|
|
103
106
|
return WebshopStruct.create(webshop);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
106
109
|
|
|
107
110
|
// TODO: handle order creation here
|
|
108
111
|
for (const put of body.getPuts()) {
|
|
109
|
-
const struct = put.put
|
|
110
|
-
const model = new Order()
|
|
111
|
-
model.webshopId = webshop.id
|
|
112
|
-
model.organizationId = webshop.organizationId
|
|
113
|
-
model.status = struct.status
|
|
114
|
-
model.data = struct.data
|
|
112
|
+
const struct = put.put;
|
|
113
|
+
const model = new Order();
|
|
114
|
+
model.webshopId = webshop.id;
|
|
115
|
+
model.organizationId = webshop.organizationId;
|
|
116
|
+
model.status = struct.status;
|
|
117
|
+
model.data = struct.data;
|
|
115
118
|
|
|
116
119
|
// For now, we don't invalidate tickets, because they will get invalidated at scan time (the order status is checked)
|
|
117
|
-
// This allows you to revalidate a ticket without needing to generate a new one (e.g. when accidentally canceling an order)
|
|
120
|
+
// This allows you to revalidate a ticket without needing to generate a new one (e.g. when accidentally canceling an order)
|
|
118
121
|
// -> the user doesn't need to download the ticket again
|
|
119
122
|
// + added benefit: we can inform the user that the ticket was canceled, instead of throwing an 'invalid ticket' error
|
|
120
123
|
|
|
121
124
|
if (model.status === OrderStatus.Deleted) {
|
|
122
|
-
model.data.removePersonalData()
|
|
125
|
+
model.data.removePersonalData();
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
const order = model.setRelation(Order.webshop, webshop.setRelation(Webshop.organization, organization))
|
|
128
|
+
const order = model.setRelation(Order.webshop, webshop.setRelation(Webshop.organization, organization));
|
|
126
129
|
|
|
127
130
|
// TODO: validate before updating stock
|
|
128
131
|
order.data.validate(webshopGetter.struct, organization.meta, request.i18n, true);
|
|
129
|
-
|
|
132
|
+
|
|
130
133
|
try {
|
|
131
|
-
await order.updateStock()
|
|
132
|
-
const totalPrice = order.data.totalPrice
|
|
134
|
+
await order.updateStock();
|
|
135
|
+
const totalPrice = order.data.totalPrice;
|
|
133
136
|
|
|
134
137
|
if (totalPrice == 0) {
|
|
135
138
|
// Force unknown payment method
|
|
136
|
-
order.data.paymentMethod = PaymentMethod.Unknown
|
|
139
|
+
order.data.paymentMethod = PaymentMethod.Unknown;
|
|
137
140
|
|
|
138
141
|
// Mark this order as paid
|
|
139
|
-
await order.markPaid(null, organization, webshop)
|
|
140
|
-
await order.save()
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
payment
|
|
144
|
-
payment.
|
|
145
|
-
payment.
|
|
146
|
-
payment.
|
|
147
|
-
payment.
|
|
142
|
+
await order.markPaid(null, organization, webshop);
|
|
143
|
+
await order.save();
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const payment = new Payment();
|
|
147
|
+
payment.organizationId = organization.id;
|
|
148
|
+
payment.method = struct.data.paymentMethod;
|
|
149
|
+
payment.status = PaymentStatus.Created;
|
|
150
|
+
payment.price = totalPrice;
|
|
151
|
+
payment.paidAt = null;
|
|
148
152
|
|
|
149
153
|
// Determine the payment provider (always null because no online payments here)
|
|
150
|
-
payment.provider = null
|
|
154
|
+
payment.provider = null;
|
|
151
155
|
|
|
152
|
-
await payment.save()
|
|
156
|
+
await payment.save();
|
|
153
157
|
|
|
154
|
-
order.paymentId = payment.id
|
|
155
|
-
order.setRelation(Order.payment, payment)
|
|
158
|
+
order.paymentId = payment.id;
|
|
159
|
+
order.setRelation(Order.payment, payment);
|
|
156
160
|
|
|
157
161
|
// Create balance item
|
|
158
162
|
const balanceItem = new BalanceItem();
|
|
159
163
|
balanceItem.orderId = order.id;
|
|
160
164
|
balanceItem.type = BalanceItemType.Order;
|
|
161
|
-
balanceItem.unitPrice = totalPrice
|
|
162
|
-
balanceItem.description = webshop.meta.name
|
|
163
|
-
balanceItem.pricePaid = 0
|
|
165
|
+
balanceItem.unitPrice = totalPrice;
|
|
166
|
+
balanceItem.description = webshop.meta.name;
|
|
167
|
+
balanceItem.pricePaid = 0;
|
|
164
168
|
balanceItem.organizationId = organization.id;
|
|
165
169
|
balanceItem.status = BalanceItemStatus.Pending;
|
|
166
170
|
balanceItem.relations = new Map([
|
|
167
171
|
[
|
|
168
|
-
BalanceItemRelationType.Webshop,
|
|
172
|
+
BalanceItemRelationType.Webshop,
|
|
169
173
|
BalanceItemRelation.create({
|
|
170
174
|
id: webshop.id,
|
|
171
175
|
name: webshop.meta.name,
|
|
172
|
-
})
|
|
173
|
-
]
|
|
174
|
-
])
|
|
176
|
+
}),
|
|
177
|
+
],
|
|
178
|
+
]);
|
|
175
179
|
await balanceItem.save();
|
|
176
180
|
|
|
177
181
|
// Create one balance item payment to pay it in one payment
|
|
178
|
-
const balanceItemPayment = new BalanceItemPayment()
|
|
182
|
+
const balanceItemPayment = new BalanceItemPayment();
|
|
179
183
|
balanceItemPayment.balanceItemId = balanceItem.id;
|
|
180
184
|
balanceItemPayment.paymentId = payment.id;
|
|
181
185
|
balanceItemPayment.organizationId = organization.id;
|
|
@@ -183,50 +187,53 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
183
187
|
await balanceItemPayment.save();
|
|
184
188
|
|
|
185
189
|
if (payment.method == PaymentMethod.Transfer) {
|
|
186
|
-
await order.markValid(payment, [])
|
|
187
|
-
await payment.save()
|
|
188
|
-
await order.save()
|
|
189
|
-
}
|
|
190
|
+
await order.markValid(payment, []);
|
|
191
|
+
await payment.save();
|
|
192
|
+
await order.save();
|
|
193
|
+
}
|
|
194
|
+
else if (payment.method == PaymentMethod.PointOfSale) {
|
|
190
195
|
// Not really paid, but needed to create the tickets if needed
|
|
191
|
-
await order.markPaid(payment, organization, webshop)
|
|
192
|
-
await payment.save()
|
|
193
|
-
await order.save()
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
+
await order.markPaid(payment, organization, webshop);
|
|
197
|
+
await payment.save();
|
|
198
|
+
await order.save();
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
throw new Error('Unsupported payment method');
|
|
196
202
|
}
|
|
197
203
|
|
|
198
|
-
balanceItem.description = order.generateBalanceDescription(webshop)
|
|
199
|
-
await balanceItem.save()
|
|
204
|
+
balanceItem.description = order.generateBalanceDescription(webshop);
|
|
205
|
+
await balanceItem.save();
|
|
200
206
|
}
|
|
201
|
-
}
|
|
202
|
-
|
|
207
|
+
}
|
|
208
|
+
catch (e) {
|
|
209
|
+
await order.deleteOrderBecauseOfCreationError();
|
|
203
210
|
throw e;
|
|
204
211
|
}
|
|
205
|
-
|
|
206
|
-
orders.push(order)
|
|
212
|
+
|
|
213
|
+
orders.push(order);
|
|
207
214
|
}
|
|
208
215
|
|
|
209
216
|
for (const patch of body.getPatches()) {
|
|
210
|
-
const model = orders.find(p => p.id == patch.id)
|
|
217
|
+
const model = orders.find(p => p.id == patch.id);
|
|
211
218
|
if (!model) {
|
|
212
219
|
throw new SimpleError({
|
|
213
|
-
code:
|
|
214
|
-
message:
|
|
215
|
-
})
|
|
220
|
+
code: 'not_found',
|
|
221
|
+
message: 'Order with id ' + patch.id + ' does not exist',
|
|
222
|
+
});
|
|
216
223
|
}
|
|
217
224
|
const previousToPay = model.totalToPay;
|
|
218
|
-
const previousStatus = model.status
|
|
225
|
+
const previousStatus = model.status;
|
|
219
226
|
|
|
220
|
-
model.status = patch.status ?? model.status
|
|
227
|
+
model.status = patch.status ?? model.status;
|
|
221
228
|
|
|
222
229
|
// For now, we don't invalidate tickets, because they will get invalidated at scan time (the order status is checked)
|
|
223
|
-
// This allows you to revalidate a ticket without needing to generate a new one (e.g. when accidentally canceling an order)
|
|
230
|
+
// This allows you to revalidate a ticket without needing to generate a new one (e.g. when accidentally canceling an order)
|
|
224
231
|
// -> the user doesn't need to download the ticket again
|
|
225
232
|
// + added benefit: we can inform the user that the ticket was canceled, instead of throwing an 'invalid ticket' error
|
|
226
233
|
|
|
227
|
-
const previousData = model.data.clone()
|
|
234
|
+
const previousData = model.data.clone();
|
|
228
235
|
if (patch.data) {
|
|
229
|
-
model.data.patchOrPut(patch.data)
|
|
236
|
+
model.data.patchOrPut(patch.data);
|
|
230
237
|
|
|
231
238
|
if (model.status !== OrderStatus.Deleted) {
|
|
232
239
|
// Make sure all data is up to date and validated (= possible corrections happen here too)
|
|
@@ -235,59 +242,61 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
235
242
|
}
|
|
236
243
|
|
|
237
244
|
if (model.status === OrderStatus.Deleted) {
|
|
238
|
-
model.data.removePersonalData()
|
|
245
|
+
model.data.removePersonalData();
|
|
239
246
|
}
|
|
240
247
|
|
|
241
248
|
if (model.status === OrderStatus.Deleted || model.status === OrderStatus.Canceled) {
|
|
242
|
-
model.markUpdated()
|
|
249
|
+
model.markUpdated();
|
|
243
250
|
// Cancel payment if still pending
|
|
244
|
-
await BalanceItem.deleteForDeletedOrders([model.id])
|
|
245
|
-
}
|
|
251
|
+
await BalanceItem.deleteForDeletedOrders([model.id]);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
246
254
|
if (previousStatus === OrderStatus.Canceled || previousStatus === OrderStatus.Deleted) {
|
|
247
|
-
model.markUpdated()
|
|
255
|
+
model.markUpdated();
|
|
248
256
|
// Undo deletion
|
|
249
|
-
await BalanceItem.undoForDeletedOrders([model.id])
|
|
257
|
+
await BalanceItem.undoForDeletedOrders([model.id]);
|
|
250
258
|
}
|
|
251
259
|
}
|
|
252
260
|
|
|
253
261
|
// Update balance item prices for this order if price has changed
|
|
254
262
|
if (previousToPay !== model.totalToPay) {
|
|
255
|
-
const items = await BalanceItem.where({ orderId: model.id })
|
|
263
|
+
const items = await BalanceItem.where({ orderId: model.id });
|
|
256
264
|
if (items.length >= 1) {
|
|
257
|
-
model.markUpdated()
|
|
258
|
-
items[0].unitPrice = model.totalToPay
|
|
259
|
-
items[0].description = model.generateBalanceDescription(webshop)
|
|
265
|
+
model.markUpdated();
|
|
266
|
+
items[0].unitPrice = model.totalToPay;
|
|
267
|
+
items[0].description = model.generateBalanceDescription(webshop);
|
|
260
268
|
items[0].updateStatus();
|
|
261
|
-
await items[0].save()
|
|
269
|
+
await items[0].save();
|
|
262
270
|
|
|
263
271
|
// Zero out the other items
|
|
264
|
-
const otherItems = items.slice(1)
|
|
265
|
-
await BalanceItem.deleteItems(otherItems)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
model.
|
|
272
|
+
const otherItems = items.slice(1);
|
|
273
|
+
await BalanceItem.deleteItems(otherItems);
|
|
274
|
+
}
|
|
275
|
+
else if (items.length === 0
|
|
276
|
+
&& model.totalToPay > 0) {
|
|
277
|
+
model.markUpdated();
|
|
269
278
|
const balanceItem = new BalanceItem();
|
|
270
279
|
balanceItem.orderId = model.id;
|
|
271
|
-
balanceItem.unitPrice = model.totalToPay
|
|
272
|
-
balanceItem.description = model.generateBalanceDescription(webshop)
|
|
273
|
-
balanceItem.pricePaid = 0
|
|
280
|
+
balanceItem.unitPrice = model.totalToPay;
|
|
281
|
+
balanceItem.description = model.generateBalanceDescription(webshop);
|
|
282
|
+
balanceItem.pricePaid = 0;
|
|
274
283
|
balanceItem.organizationId = organization.id;
|
|
275
284
|
balanceItem.status = BalanceItemStatus.Pending;
|
|
276
285
|
await balanceItem.save();
|
|
277
286
|
}
|
|
278
287
|
}
|
|
279
288
|
|
|
280
|
-
await model.save()
|
|
281
|
-
await model.setRelation(Order.webshop, webshop).updateStock(previousData)
|
|
282
|
-
await model.setRelation(Order.webshop, webshop).updateTickets()
|
|
289
|
+
await model.save();
|
|
290
|
+
await model.setRelation(Order.webshop, webshop).updateStock(previousData);
|
|
291
|
+
await model.setRelation(Order.webshop, webshop).updateTickets();
|
|
283
292
|
}
|
|
284
293
|
|
|
285
|
-
const mapped = orders.map(order => order.setRelation(Order.webshop, webshop))
|
|
286
|
-
return mapped
|
|
287
|
-
})
|
|
294
|
+
const mapped = orders.map(order => order.setRelation(Order.webshop, webshop));
|
|
295
|
+
return mapped;
|
|
296
|
+
});
|
|
288
297
|
|
|
289
298
|
return new Response(
|
|
290
|
-
await Order.getPrivateStructures(orders)
|
|
299
|
+
await Order.getPrivateStructures(orders),
|
|
291
300
|
);
|
|
292
301
|
}
|
|
293
302
|
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { ArrayDecoder, AutoEncoderPatchType, Decoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
3
|
-
import { SimpleError, SimpleErrors } from
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
|
+
import { SimpleError, SimpleErrors } from '@simonbackx/simple-errors';
|
|
4
4
|
import { Ticket, Token, Webshop } from '@stamhoofd/models';
|
|
5
|
-
import { PermissionLevel, TicketPrivate } from
|
|
5
|
+
import { PermissionLevel, TicketPrivate } from '@stamhoofd/structures';
|
|
6
6
|
|
|
7
7
|
import { Context } from '../../../../helpers/Context';
|
|
8
8
|
|
|
9
9
|
type Params = { id: string };
|
|
10
10
|
type Query = undefined;
|
|
11
|
-
type Body = AutoEncoderPatchType<TicketPrivate>[]
|
|
12
|
-
type ResponseBody = TicketPrivate[]
|
|
11
|
+
type Body = AutoEncoderPatchType<TicketPrivate>[];
|
|
12
|
+
type ResponseBody = TicketPrivate[];
|
|
13
13
|
|
|
14
14
|
export class PatchWebshopTicketsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
15
|
-
bodyDecoder = new ArrayDecoder(TicketPrivate.patchType() as Decoder<AutoEncoderPatchType<TicketPrivate>>)
|
|
15
|
+
bodyDecoder = new ArrayDecoder(TicketPrivate.patchType() as Decoder<AutoEncoderPatchType<TicketPrivate>>);
|
|
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, '/webshop/@id/tickets/private', { id: String });
|
|
23
23
|
|
|
24
24
|
if (params) {
|
|
25
25
|
return [true, params as Params];
|
|
@@ -29,52 +29,52 @@ export class PatchWebshopTicketsEndpoint extends Endpoint<Params, Query, Body, R
|
|
|
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
|
// Fast throw first (more in depth checking for patches later)
|
|
35
35
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
36
|
-
throw Context.auth.error()
|
|
36
|
+
throw Context.auth.error();
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
if (request.body.length == 0) {
|
|
40
40
|
return new Response([]);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const webshop = await Webshop.getByID(request.params.id)
|
|
43
|
+
const webshop = await Webshop.getByID(request.params.id);
|
|
44
44
|
if (!webshop || !await Context.auth.canAccessWebshopTickets(webshop, PermissionLevel.Write)) {
|
|
45
|
-
throw Context.auth.notFoundOrNoAccess(
|
|
45
|
+
throw Context.auth.notFoundOrNoAccess('Je hebt geen toegang om tickets te wijzigen van deze webshop');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const tickets: Ticket[] = []
|
|
49
|
-
const errors = new SimpleErrors()
|
|
48
|
+
const tickets: Ticket[] = [];
|
|
49
|
+
const errors = new SimpleErrors();
|
|
50
50
|
|
|
51
51
|
for (const patch of request.body) {
|
|
52
|
-
const model = await Ticket.getByID(patch.id)
|
|
52
|
+
const model = await Ticket.getByID(patch.id);
|
|
53
53
|
if (!model || model.webshopId !== webshop.id) {
|
|
54
54
|
errors.addError(new SimpleError({
|
|
55
|
-
code:
|
|
55
|
+
code: 'ticket_not_found',
|
|
56
56
|
field: patch.id,
|
|
57
|
-
message:
|
|
58
|
-
}))
|
|
59
|
-
continue
|
|
57
|
+
message: 'Ticket with id ' + patch.id + ' does not exist',
|
|
58
|
+
}));
|
|
59
|
+
continue;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
if (patch.scannedAt !== undefined) {
|
|
63
|
-
model.scannedAt = patch.scannedAt
|
|
63
|
+
model.scannedAt = patch.scannedAt;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
if (patch.scannedBy !== undefined) {
|
|
67
|
-
model.scannedBy = patch.scannedBy
|
|
67
|
+
model.scannedBy = patch.scannedBy;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
await model.save()
|
|
70
|
+
await model.save();
|
|
71
71
|
|
|
72
|
-
tickets.push(model)
|
|
72
|
+
tickets.push(model);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
errors.throwIfNotEmpty();
|
|
76
76
|
return new Response(
|
|
77
|
-
tickets.map(ticket => TicketPrivate.create(ticket))
|
|
77
|
+
tickets.map(ticket => TicketPrivate.create(ticket)),
|
|
78
78
|
);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
3
3
|
import { Token, Webshop } from '@stamhoofd/models';
|
|
4
4
|
import { QueueHandler } from '@stamhoofd/queues';
|
|
5
|
-
import { PermissionLevel, PrivateWebshop, WebshopPrivateMetaData } from
|
|
5
|
+
import { PermissionLevel, PrivateWebshop, WebshopPrivateMetaData } from '@stamhoofd/structures';
|
|
6
6
|
|
|
7
|
-
import { Context } from
|
|
7
|
+
import { Context } from '../../../../helpers/Context';
|
|
8
8
|
|
|
9
9
|
type Params = { id: string };
|
|
10
10
|
type Query = undefined;
|
|
@@ -16,13 +16,12 @@ type ResponseBody = PrivateWebshop;
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
export class VerifyWebshopDomainEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
19
|
-
|
|
20
19
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
21
|
-
if (request.method
|
|
20
|
+
if (request.method !== 'POST') {
|
|
22
21
|
return [false];
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
const params = Endpoint.parseParameters(request.url,
|
|
24
|
+
const params = Endpoint.parseParameters(request.url, '/webshop/@id/verify-domain', { id: String });
|
|
26
25
|
|
|
27
26
|
if (params) {
|
|
28
27
|
return [true, params as Params];
|
|
@@ -32,28 +31,29 @@ export class VerifyWebshopDomainEndpoint extends Endpoint<Params, Query, Body, R
|
|
|
32
31
|
|
|
33
32
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
34
33
|
const organization = await Context.setOrganizationScope();
|
|
35
|
-
await Context.authenticate()
|
|
34
|
+
await Context.authenticate();
|
|
36
35
|
|
|
37
36
|
// Fast throw first (more in depth checking for patches later)
|
|
38
37
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
39
|
-
throw Context.auth.error()
|
|
38
|
+
throw Context.auth.error();
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
return await QueueHandler.schedule(
|
|
43
|
-
const webshop = await Webshop.getByID(request.params.id)
|
|
41
|
+
return await QueueHandler.schedule('webshop-stock/' + request.params.id, async () => {
|
|
42
|
+
const webshop = await Webshop.getByID(request.params.id);
|
|
44
43
|
if (!webshop || !await Context.auth.canAccessWebshop(webshop, PermissionLevel.Full)) {
|
|
45
|
-
throw Context.auth.notFoundOrNoAccess()
|
|
44
|
+
throw Context.auth.notFoundOrNoAccess();
|
|
46
45
|
}
|
|
47
|
-
|
|
46
|
+
|
|
48
47
|
if (webshop.domain !== null) {
|
|
49
|
-
webshop.privateMeta.dnsRecords = WebshopPrivateMetaData.buildDNSRecords(webshop.domain)
|
|
50
|
-
await webshop.updateDNSRecords()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
webshop.
|
|
48
|
+
webshop.privateMeta.dnsRecords = WebshopPrivateMetaData.buildDNSRecords(webshop.domain);
|
|
49
|
+
await webshop.updateDNSRecords();
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
webshop.privateMeta.dnsRecords = [];
|
|
53
|
+
webshop.meta.domainActive = false;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
await webshop.save()
|
|
56
|
+
await webshop.save();
|
|
57
57
|
return new Response(PrivateWebshop.create(webshop));
|
|
58
58
|
});
|
|
59
59
|
}
|