@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.21.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.21.2",
40
- "@stamhoofd/backend-middleware": "2.21.2",
41
- "@stamhoofd/email": "2.21.2",
42
- "@stamhoofd/models": "2.21.2",
43
- "@stamhoofd/queues": "2.21.2",
44
- "@stamhoofd/sql": "2.21.2",
45
- "@stamhoofd/structures": "2.21.2",
46
- "@stamhoofd/utility": "2.21.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": "0a6775791c85979a66905925d0ccc332cff1e3d7"
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 CreateTokenEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
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
- await SetupStepUpdater.updateForOrganization(organization);
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.Functions]: this.updateStepFunctions,
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: 0,
223
- finishedSteps: 0,
231
+ totalSteps,
232
+ finishedSteps,
224
233
  });
225
234
  }
226
235
 
227
- private static async updateStepFunctions(
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.Functions, {
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
  }