@stamhoofd/backend 2.21.2 → 2.23.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stamhoofd/backend",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.23.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
"@simonbackx/simple-encoding": "2.15.0",
|
|
37
37
|
"@simonbackx/simple-endpoints": "1.14.0",
|
|
38
38
|
"@simonbackx/simple-logging": "^1.0.1",
|
|
39
|
-
"@stamhoofd/backend-i18n": "2.
|
|
40
|
-
"@stamhoofd/backend-middleware": "2.
|
|
41
|
-
"@stamhoofd/email": "2.
|
|
42
|
-
"@stamhoofd/models": "2.
|
|
43
|
-
"@stamhoofd/queues": "2.
|
|
44
|
-
"@stamhoofd/sql": "2.
|
|
45
|
-
"@stamhoofd/structures": "2.
|
|
46
|
-
"@stamhoofd/utility": "2.
|
|
39
|
+
"@stamhoofd/backend-i18n": "2.23.0",
|
|
40
|
+
"@stamhoofd/backend-middleware": "2.23.0",
|
|
41
|
+
"@stamhoofd/email": "2.23.0",
|
|
42
|
+
"@stamhoofd/models": "2.23.0",
|
|
43
|
+
"@stamhoofd/queues": "2.23.0",
|
|
44
|
+
"@stamhoofd/sql": "2.23.0",
|
|
45
|
+
"@stamhoofd/structures": "2.23.0",
|
|
46
|
+
"@stamhoofd/utility": "2.23.0",
|
|
47
47
|
"archiver": "^7.0.1",
|
|
48
48
|
"aws-sdk": "^2.885.0",
|
|
49
49
|
"axios": "1.6.8",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"postmark": "4.0.2",
|
|
61
61
|
"stripe": "^16.6.0"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "efcdf16aa2160bcb1fd295d0e5c72751caa3356b"
|
|
64
64
|
}
|
|
@@ -7,7 +7,7 @@ type Query = undefined;
|
|
|
7
7
|
type Body = undefined;
|
|
8
8
|
type ResponseBody = undefined;
|
|
9
9
|
|
|
10
|
-
export class
|
|
10
|
+
export class DeleteTokenEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
11
11
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
12
12
|
if (request.method != "DELETE") {
|
|
13
13
|
return [false];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
|
+
|
|
3
|
+
import { getDefaultEmailFrom, sendEmailTemplate } from '@stamhoofd/models';
|
|
4
|
+
import { EmailTemplateType, Recipient } from '@stamhoofd/structures';
|
|
5
|
+
import { Context } from '../../helpers/Context';
|
|
6
|
+
|
|
7
|
+
type Params = Record<string, never>;
|
|
8
|
+
type Query = undefined;
|
|
9
|
+
type Body = undefined;
|
|
10
|
+
type ResponseBody = undefined;
|
|
11
|
+
|
|
12
|
+
export class DeleteUserEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
13
|
+
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
14
|
+
if (request.method != "DELETE") {
|
|
15
|
+
return [false];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const params = Endpoint.parseParameters(request.url, "/user", {});
|
|
19
|
+
|
|
20
|
+
if (params) {
|
|
21
|
+
return [true, params as Params];
|
|
22
|
+
}
|
|
23
|
+
return [false];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async handle(_: DecodedRequest<Params, Query, Body>) {
|
|
27
|
+
const organization = await Context.setOptionalOrganizationScope()
|
|
28
|
+
const {user, token} = await Context.authenticate({allowWithoutAccount: true})
|
|
29
|
+
|
|
30
|
+
// Send an e-mail to inform everyone about this action
|
|
31
|
+
|
|
32
|
+
// Delete the account
|
|
33
|
+
|
|
34
|
+
const bcc = (await getDefaultEmailFrom(null, {
|
|
35
|
+
template: {}
|
|
36
|
+
}))
|
|
37
|
+
await sendEmailTemplate(organization, {
|
|
38
|
+
recipients: [
|
|
39
|
+
Recipient.create({
|
|
40
|
+
email: user.email
|
|
41
|
+
})
|
|
42
|
+
],
|
|
43
|
+
singleBcc: bcc.replyTo || bcc.from,
|
|
44
|
+
template: {
|
|
45
|
+
type: EmailTemplateType.DeleteAccountConfirmation,
|
|
46
|
+
},
|
|
47
|
+
type: 'transactional'
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// Soft delete until processed manually
|
|
51
|
+
user.verified = false;
|
|
52
|
+
user.password = null;
|
|
53
|
+
await user.save()
|
|
54
|
+
await token.delete()
|
|
55
|
+
|
|
56
|
+
return new Response(undefined)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -54,6 +54,7 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const errors = new SimpleErrors()
|
|
57
|
+
let shouldUpdateSetupSteps = false;
|
|
57
58
|
|
|
58
59
|
if (await Context.auth.hasFullAccess(organization.id)) {
|
|
59
60
|
organization.name = request.body.name ?? organization.name
|
|
@@ -100,9 +101,13 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
100
101
|
|
|
101
102
|
if (request.body.privateMeta && request.body.privateMeta.isPatch()) {
|
|
102
103
|
organization.privateMeta.emails = request.body.privateMeta.emails.applyTo(organization.privateMeta.emails)
|
|
104
|
+
if(request.body.privateMeta.emails) {
|
|
105
|
+
shouldUpdateSetupSteps = true;
|
|
106
|
+
}
|
|
107
|
+
|
|
103
108
|
organization.privateMeta.premises = patchObject(organization.privateMeta.premises, request.body.privateMeta.premises);
|
|
104
109
|
if(request.body.privateMeta.premises) {
|
|
105
|
-
|
|
110
|
+
shouldUpdateSetupSteps = true;
|
|
106
111
|
}
|
|
107
112
|
organization.privateMeta.roles = request.body.privateMeta.roles.applyTo(organization.privateMeta.roles)
|
|
108
113
|
organization.privateMeta.responsibilities = request.body.privateMeta.responsibilities.applyTo(organization.privateMeta.responsibilities)
|
|
@@ -215,6 +220,7 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
215
220
|
if (request.body.meta) {
|
|
216
221
|
if (request.body.meta.companies) {
|
|
217
222
|
await this.validateCompanies(organization, request.body.meta.companies)
|
|
223
|
+
shouldUpdateSetupSteps = true
|
|
218
224
|
}
|
|
219
225
|
|
|
220
226
|
const savedPackages = organization.meta.packages
|
|
@@ -373,6 +379,11 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
373
379
|
}
|
|
374
380
|
|
|
375
381
|
errors.throwIfNotEmpty()
|
|
382
|
+
|
|
383
|
+
if(shouldUpdateSetupSteps) {
|
|
384
|
+
await SetupStepUpdater.updateForOrganization(organization);
|
|
385
|
+
}
|
|
386
|
+
|
|
376
387
|
return new Response(await AuthenticatedStructures.organization(organization));
|
|
377
388
|
}
|
|
378
389
|
|
|
@@ -21,10 +21,12 @@ export class SetupStepUpdater {
|
|
|
21
21
|
SetupStepType,
|
|
22
22
|
SetupStepOperation
|
|
23
23
|
> = {
|
|
24
|
-
[SetupStepType.
|
|
24
|
+
[SetupStepType.Responsibilities]: this.updateStepResponsibilities,
|
|
25
25
|
[SetupStepType.Companies]: this.updateStepCompanies,
|
|
26
26
|
[SetupStepType.Groups]: this.updateStepGroups,
|
|
27
27
|
[SetupStepType.Premises]: this.updateStepPremises,
|
|
28
|
+
[SetupStepType.Emails]: this.updateStepEmails,
|
|
29
|
+
[SetupStepType.Payment]: this.updateStepPayment
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
static async updateSetupStepsForAllOrganizationsInCurrentPeriod({
|
|
@@ -218,13 +220,20 @@ export class SetupStepUpdater {
|
|
|
218
220
|
_organization: Organization,
|
|
219
221
|
_platform: PlatformStruct
|
|
220
222
|
) {
|
|
223
|
+
const totalSteps = 1;
|
|
224
|
+
let finishedSteps = 0;
|
|
225
|
+
|
|
226
|
+
if(_organization.meta.companies.length) {
|
|
227
|
+
finishedSteps = 1;
|
|
228
|
+
}
|
|
229
|
+
|
|
221
230
|
setupSteps.update(SetupStepType.Companies, {
|
|
222
|
-
totalSteps
|
|
223
|
-
finishedSteps
|
|
231
|
+
totalSteps,
|
|
232
|
+
finishedSteps,
|
|
224
233
|
});
|
|
225
234
|
}
|
|
226
235
|
|
|
227
|
-
private static async
|
|
236
|
+
private static async updateStepResponsibilities(
|
|
228
237
|
setupSteps: SetupSteps,
|
|
229
238
|
organization: Organization,
|
|
230
239
|
platform: PlatformStruct
|
|
@@ -304,9 +313,40 @@ export class SetupStepUpdater {
|
|
|
304
313
|
finishedSteps++;
|
|
305
314
|
}
|
|
306
315
|
|
|
307
|
-
setupSteps.update(SetupStepType.
|
|
316
|
+
setupSteps.update(SetupStepType.Responsibilities, {
|
|
308
317
|
totalSteps,
|
|
309
318
|
finishedSteps,
|
|
310
319
|
});
|
|
311
320
|
}
|
|
321
|
+
|
|
322
|
+
private static updateStepEmails(setupSteps: SetupSteps,
|
|
323
|
+
organization: Organization,
|
|
324
|
+
_platform: PlatformStruct) {
|
|
325
|
+
|
|
326
|
+
const totalSteps = 1;
|
|
327
|
+
let finishedSteps = 0;
|
|
328
|
+
|
|
329
|
+
const emails = organization.privateMeta.emails;
|
|
330
|
+
|
|
331
|
+
// organization should have 1 default email
|
|
332
|
+
if(emails.some(e => e.default)) {
|
|
333
|
+
finishedSteps = 1;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
setupSteps.update(SetupStepType.Emails, {
|
|
337
|
+
totalSteps,
|
|
338
|
+
finishedSteps,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
setupSteps.markReviewed(SetupStepType.Emails, {userId: 'backend', userName: 'backend'});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
private static updateStepPayment(setupSteps: SetupSteps,
|
|
345
|
+
_organization: Organization,
|
|
346
|
+
_platform: PlatformStruct) {
|
|
347
|
+
setupSteps.update(SetupStepType.Payment, {
|
|
348
|
+
totalSteps: 0,
|
|
349
|
+
finishedSteps: 0,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
312
352
|
}
|