@nymphjs/tilmeld 1.0.0-alpha.1 → 1.0.0-alpha.5

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/src/User.ts CHANGED
@@ -1,4 +1,4 @@
1
- import Nymph, {
1
+ import {
2
2
  EntityData,
3
3
  EntityJson,
4
4
  EntityPatch,
@@ -14,9 +14,9 @@ import sha256 from 'crypto-js/sha256';
14
14
  import md5 from 'crypto-js/md5';
15
15
  import { difference } from 'lodash';
16
16
 
17
+ import type Tilmeld from './Tilmeld';
17
18
  import AbleObject from './AbleObject';
18
19
  import Group, { GroupData } from './Group';
19
- import Tilmeld from './Tilmeld';
20
20
  import {
21
21
  BadDataError,
22
22
  BadEmailError,
@@ -126,7 +126,20 @@ export type UserData = {
126
126
  passwordTemp?: string;
127
127
  };
128
128
 
129
+ /**
130
+ * A user data model.
131
+ *
132
+ * Written by Hunter Perrin for SciActive.
133
+ *
134
+ * @author Hunter Perrin <hperrin@gmail.com>
135
+ * @copyright SciActive Inc
136
+ * @see http://nymph.io/
137
+ */
129
138
  export default class User extends AbleObject<UserData> {
139
+ /**
140
+ * The instance of Tilmeld to use for queries.
141
+ */
142
+ static tilmeld: Tilmeld;
130
143
  static ETYPE = 'tilmeld_user';
131
144
  static class = 'User';
132
145
 
@@ -202,7 +215,7 @@ export default class User extends AbleObject<UserData> {
202
215
  static async factoryUsername(username?: string): Promise<User & UserData> {
203
216
  const entity = new this();
204
217
  if (username != null) {
205
- const entity = await Nymph.getEntity(
218
+ const entity = await this.nymph.getEntity(
206
219
  {
207
220
  class: this,
208
221
  },
@@ -242,10 +255,10 @@ export default class User extends AbleObject<UserData> {
242
255
  public static current(
243
256
  returnObjectIfNotExist?: boolean
244
257
  ): (User & UserData) | null {
245
- if (Tilmeld.currentUser == null) {
258
+ if (this.tilmeld.currentUser == null) {
246
259
  return returnObjectIfNotExist ? this.factorySync() : null;
247
260
  }
248
- return Tilmeld.currentUser;
261
+ return this.tilmeld.currentUser;
249
262
  }
250
263
 
251
264
  /**
@@ -258,7 +271,7 @@ export default class User extends AbleObject<UserData> {
258
271
  recoveryType: 'username' | 'password';
259
272
  account: string;
260
273
  }): Promise<{ result: boolean; message: string }> {
261
- if (!Tilmeld.config.pwRecovery) {
274
+ if (!this.tilmeld.config.pwRecovery) {
262
275
  return {
263
276
  result: false,
264
277
  message: 'Account recovery is not allowed.',
@@ -268,11 +281,14 @@ export default class User extends AbleObject<UserData> {
268
281
  let user: User & UserData;
269
282
  const options: EmailOptions = {};
270
283
 
271
- if (!Tilmeld.config.emailUsernames && data.recoveryType === 'username') {
284
+ if (
285
+ !this.tilmeld.config.emailUsernames &&
286
+ data.recoveryType === 'username'
287
+ ) {
272
288
  // Create a username recovery email.
273
289
 
274
- const getUser = await Nymph.getEntity(
275
- { class: User, skipAc: true },
290
+ const getUser = await this.nymph.getEntity(
291
+ { class: this.tilmeld.User, skipAc: true },
276
292
  {
277
293
  type: '&',
278
294
  ilike: ['email', data.account.replace(/([\\%_])/g, (s) => `\\${s}`)],
@@ -299,7 +315,7 @@ export default class User extends AbleObject<UserData> {
299
315
  } else if (data.recoveryType === 'password') {
300
316
  // Create a password recovery email.
301
317
 
302
- const getUser = await User.factoryUsername(data.account);
318
+ const getUser = await this.tilmeld.User.factoryUsername(data.account);
303
319
 
304
320
  if (getUser.guid == null) {
305
321
  return {
@@ -326,14 +342,14 @@ export default class User extends AbleObject<UserData> {
326
342
  };
327
343
  options.locals = {
328
344
  recoverCode: getUser.recoverSecret,
329
- timeLimit: Tilmeld.config.pwRecoveryTimeLimit,
345
+ timeLimit: this.tilmeld.config.pwRecoveryTimeLimit,
330
346
  };
331
347
  } else {
332
348
  return { result: false, message: 'Invalid recovery type.' };
333
349
  }
334
350
 
335
351
  // Send the email.
336
- if (await Tilmeld.config.sendEmail(options, user)) {
352
+ if (await this.tilmeld.config.sendEmail(this.tilmeld, options, user)) {
337
353
  return {
338
354
  result: true,
339
355
  message:
@@ -356,21 +372,21 @@ export default class User extends AbleObject<UserData> {
356
372
  secret: string;
357
373
  password: string;
358
374
  }): Promise<{ result: boolean; message: string }> {
359
- if (!Tilmeld.config.pwRecovery) {
375
+ if (!this.tilmeld.config.pwRecovery) {
360
376
  return {
361
377
  result: false,
362
378
  message: 'Account recovery is not allowed.',
363
379
  };
364
380
  }
365
381
 
366
- const user = await User.factoryUsername(data.username);
382
+ const user = await this.tilmeld.User.factoryUsername(data.username);
367
383
 
368
384
  if (
369
385
  user.guid == null ||
370
386
  user.recoverSecret == null ||
371
387
  data.secret !== user.recoverSecret ||
372
388
  strtotime(
373
- '+' + Tilmeld.config.pwRecoveryTimeLimit,
389
+ '+' + this.tilmeld.config.pwRecoveryTimeLimit,
374
390
  Math.floor((user.recoverSecretDate ?? 0) / 1000)
375
391
  ) *
376
392
  1000 <
@@ -402,14 +418,14 @@ export default class User extends AbleObject<UserData> {
402
418
 
403
419
  public static getClientConfig() {
404
420
  return {
405
- regFields: Tilmeld.config.regFields,
406
- userFields: Tilmeld.config.userFields,
407
- emailUsernames: Tilmeld.config.emailUsernames,
408
- allowRegistration: Tilmeld.config.allowRegistration,
409
- allowUsernameChange: Tilmeld.config.allowUsernameChange,
410
- pwRecovery: Tilmeld.config.pwRecovery,
411
- verifyEmail: Tilmeld.config.verifyEmail,
412
- unverifiedAccess: Tilmeld.config.unverifiedAccess,
421
+ regFields: this.tilmeld.config.regFields,
422
+ userFields: this.tilmeld.config.userFields,
423
+ emailUsernames: this.tilmeld.config.emailUsernames,
424
+ allowRegistration: this.tilmeld.config.allowRegistration,
425
+ allowUsernameChange: this.tilmeld.config.allowUsernameChange,
426
+ pwRecovery: this.tilmeld.config.pwRecovery,
427
+ verifyEmail: this.tilmeld.config.verifyEmail,
428
+ unverifiedAccess: this.tilmeld.config.unverifiedAccess,
413
429
  };
414
430
  }
415
431
 
@@ -417,7 +433,7 @@ export default class User extends AbleObject<UserData> {
417
433
  if (!('username' in data) || !data.username.length) {
418
434
  return { result: false, message: 'Incorrect login/password.' };
419
435
  }
420
- const user = await User.factoryUsername(data.username);
436
+ const user = await this.tilmeld.User.factoryUsername(data.username);
421
437
  const result: { result: boolean; message: string; user?: User & UserData } =
422
438
  user.$login(data);
423
439
  if (result.result) {
@@ -428,6 +444,7 @@ export default class User extends AbleObject<UserData> {
428
444
  }
429
445
 
430
446
  public $login(data: { username: string; password: string }) {
447
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
431
448
  if (this.guid == null) {
432
449
  return { result: false, message: 'Incorrect login/password.' };
433
450
  }
@@ -442,7 +459,7 @@ export default class User extends AbleObject<UserData> {
442
459
  }
443
460
 
444
461
  // Authentication was successful, attempt to login.
445
- if (!Tilmeld.login(this, true)) {
462
+ if (!tilmeld.login(this, true)) {
446
463
  return { result: false, message: 'Incorrect login/password.' };
447
464
  }
448
465
 
@@ -455,7 +472,8 @@ export default class User extends AbleObject<UserData> {
455
472
  * @returns An object with a boolean 'result' entry and a 'message' entry.
456
473
  */
457
474
  public $logout() {
458
- Tilmeld.logout();
475
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
476
+ tilmeld.logout();
459
477
  return { result: true, message: 'You have been logged out.' };
460
478
  }
461
479
 
@@ -510,13 +528,14 @@ export default class User extends AbleObject<UserData> {
510
528
  }
511
529
 
512
530
  public $jsonAcceptData(input: EntityJson, allowConflict = false) {
531
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
513
532
  this.$referenceWake();
514
533
 
515
534
  if (
516
- input.data.abilities.indexOf('system/admin') !== -1 &&
535
+ input.data.abilities?.indexOf('system/admin') !== -1 &&
517
536
  this.$data.abilities?.indexOf('system/admin') === -1 &&
518
- Tilmeld.gatekeeper('tilmeld/admin') &&
519
- !Tilmeld.gatekeeper('system/admin')
537
+ tilmeld.gatekeeper('tilmeld/admin') &&
538
+ !tilmeld.gatekeeper('system/admin')
520
539
  ) {
521
540
  throw new BadDataError(
522
541
  "You don't have the authority to make this user a system admin."
@@ -528,13 +547,14 @@ export default class User extends AbleObject<UserData> {
528
547
  }
529
548
 
530
549
  public $jsonAcceptPatch(patch: EntityPatch, allowConflict = false) {
550
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
531
551
  this.$referenceWake();
532
552
 
533
553
  if (
534
- patch.set.abilities.indexOf('system/admin') !== -1 &&
554
+ patch.set.abilities?.indexOf('system/admin') !== -1 &&
535
555
  this.$data.abilities?.indexOf('system/admin') === -1 &&
536
- Tilmeld.gatekeeper('tilmeld/admin') &&
537
- !Tilmeld.gatekeeper('system/admin')
556
+ tilmeld.gatekeeper('tilmeld/admin') &&
557
+ !tilmeld.gatekeeper('system/admin')
538
558
  ) {
539
559
  throw new BadDataError(
540
560
  "You don't have the authority to make this user a system admin."
@@ -556,13 +576,14 @@ export default class User extends AbleObject<UserData> {
556
576
  * @param givenUser User to update protection for. If undefined, will use the currently logged in user.
557
577
  */
558
578
  public $updateDataProtection(givenUser?: User & UserData) {
559
- let user = givenUser ?? User.current();
579
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
580
+ let user = givenUser ?? tilmeld.User.current();
560
581
 
561
582
  this.$clientEnabledMethods = User.DEFAULT_CLIENT_ENABLED_METHODS;
562
583
  this.$privateData = User.DEFAULT_PRIVATE_DATA;
563
584
  this.$allowlistData = User.DEFAULT_ALLOWLIST_DATA;
564
585
 
565
- if (Tilmeld.config.emailUsernames) {
586
+ if (tilmeld.config.emailUsernames) {
566
587
  this.$privateData.push('username');
567
588
  }
568
589
 
@@ -593,20 +614,20 @@ export default class User extends AbleObject<UserData> {
593
614
  this.$allowlistData = undefined;
594
615
  } else if (isCurrentUser || isNewUser) {
595
616
  // Users can see their own data, and edit some of it.
596
- if (Tilmeld.config.allowUsernameChange || isNewUser) {
617
+ if (tilmeld.config.allowUsernameChange || isNewUser) {
597
618
  this.$allowlistData.push('username');
598
619
  }
599
620
  this.$allowlistData.push('avatar');
600
- if (Tilmeld.config.userFields.indexOf('name') !== -1) {
621
+ if (tilmeld.config.userFields.indexOf('name') !== -1) {
601
622
  this.$allowlistData.push('nameFirst');
602
623
  this.$allowlistData.push('nameMiddle');
603
624
  this.$allowlistData.push('nameLast');
604
625
  this.$allowlistData.push('name');
605
626
  }
606
- if (Tilmeld.config.userFields.indexOf('email') !== -1) {
627
+ if (tilmeld.config.userFields.indexOf('email') !== -1) {
607
628
  this.$allowlistData.push('email');
608
629
  }
609
- if (Tilmeld.config.userFields.indexOf('phone') !== -1) {
630
+ if (tilmeld.config.userFields.indexOf('phone') !== -1) {
610
631
  this.$allowlistData.push('phone');
611
632
  }
612
633
  this.$privateData = [
@@ -638,8 +659,9 @@ export default class User extends AbleObject<UserData> {
638
659
  * @returns True or false.
639
660
  */
640
661
  public $gatekeeper(ability?: string): boolean {
662
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
641
663
  if (ability == null) {
642
- return User.current()?.$is(this) ?? false;
664
+ return tilmeld.User.current()?.$is(this) ?? false;
643
665
  }
644
666
  // Check the cache to see if we've already checked this user.
645
667
  if (this.$gatekeeperCache == null) {
@@ -681,13 +703,14 @@ export default class User extends AbleObject<UserData> {
681
703
  * @returns True on success, false on failure.
682
704
  */
683
705
  public async $sendEmailVerification() {
706
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
684
707
  if (this.guid == null) {
685
708
  return false;
686
709
  }
687
710
  let success = true;
688
711
 
689
- const verifyUrl = `${Tilmeld.config.appUrl.replace(/\/$/, () => '')}${
690
- Tilmeld.config.setupPath
712
+ const verifyUrl = `${tilmeld.config.appUrl.replace(/\/$/, () => '')}${
713
+ tilmeld.config.setupPath
691
714
  }/verify`;
692
715
 
693
716
  if (this.$data.secret != null) {
@@ -696,7 +719,8 @@ export default class User extends AbleObject<UserData> {
696
719
  )}&secret=${encodeURIComponent(this.$data.secret)}`;
697
720
  success =
698
721
  success &&
699
- (await Tilmeld.config.sendEmail(
722
+ (await tilmeld.config.sendEmail(
723
+ tilmeld,
700
724
  {
701
725
  template: 'VerifyEmail',
702
726
  message: {
@@ -719,7 +743,8 @@ export default class User extends AbleObject<UserData> {
719
743
  )}&secret=${encodeURIComponent(this.$data.newEmailSecret)}`;
720
744
  success =
721
745
  success &&
722
- (await Tilmeld.config.sendEmail(
746
+ (await tilmeld.config.sendEmail(
747
+ tilmeld,
723
748
  {
724
749
  template: 'VerifyEmailChange',
725
750
  message: {
@@ -744,7 +769,8 @@ export default class User extends AbleObject<UserData> {
744
769
  )}&secret=${encodeURIComponent(this.$data.cancelEmailSecret)}`;
745
770
  success =
746
771
  success &&
747
- (await Tilmeld.config.sendEmail(
772
+ (await tilmeld.config.sendEmail(
773
+ tilmeld,
748
774
  {
749
775
  template: 'CancelEmailChange',
750
776
  message: {
@@ -790,7 +816,8 @@ export default class User extends AbleObject<UserData> {
790
816
  * @returns True if the passwords match, otherwise false.
791
817
  */
792
818
  public $checkPassword(password: string) {
793
- switch (Tilmeld.config.pwMethod) {
819
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
820
+ switch (tilmeld.config.pwMethod) {
794
821
  case 'plain':
795
822
  return this.$data.password === password;
796
823
  case 'digest':
@@ -900,7 +927,8 @@ export default class User extends AbleObject<UserData> {
900
927
  * @returns The resulting password or hash which is stored in the entity.
901
928
  */
902
929
  public $password(password: string) {
903
- switch (Tilmeld.config.pwMethod) {
930
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
931
+ switch (tilmeld.config.pwMethod) {
904
932
  case 'plain':
905
933
  delete this.$data.salt;
906
934
  this.$data.password = password;
@@ -926,19 +954,20 @@ export default class User extends AbleObject<UserData> {
926
954
  * @returns An object with a boolean 'result' entry and a 'message' entry.
927
955
  */
928
956
  public async $checkUsername(): Promise<{ result: boolean; message: string }> {
929
- if (!Tilmeld.config.emailUsernames) {
957
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
958
+ if (!tilmeld.config.emailUsernames) {
930
959
  if (this.$data.username == null || !this.$data.username.length) {
931
960
  return { result: false, message: 'Please specify a username.' };
932
961
  }
933
962
  if (
934
- Tilmeld.config.maxUsernameLength > 0 &&
935
- this.$data.username.length > Tilmeld.config.maxUsernameLength
963
+ tilmeld.config.maxUsernameLength > 0 &&
964
+ this.$data.username.length > tilmeld.config.maxUsernameLength
936
965
  ) {
937
966
  return {
938
967
  result: false,
939
968
  message:
940
969
  'Usernames must not exceed ' +
941
- Tilmeld.config.maxUsernameLength +
970
+ tilmeld.config.maxUsernameLength +
942
971
  ' characters.',
943
972
  };
944
973
  }
@@ -946,18 +975,18 @@ export default class User extends AbleObject<UserData> {
946
975
  if (
947
976
  difference(
948
977
  this.$data.username.split(''),
949
- Tilmeld.config.validChars.split('')
978
+ tilmeld.config.validChars.split('')
950
979
  ).length
951
980
  ) {
952
981
  return {
953
982
  result: false,
954
- message: Tilmeld.config.validCharsNotice,
983
+ message: tilmeld.config.validCharsNotice,
955
984
  };
956
985
  }
957
- if (!Tilmeld.config.validRegex.test(this.$data.username)) {
986
+ if (!tilmeld.config.validRegex.test(this.$data.username)) {
958
987
  return {
959
988
  result: false,
960
- message: Tilmeld.config.validRegexNotice,
989
+ message: tilmeld.config.validRegexNotice,
961
990
  };
962
991
  }
963
992
 
@@ -971,8 +1000,8 @@ export default class User extends AbleObject<UserData> {
971
1000
  if (this.guid != null) {
972
1001
  selector['!guid'] = this.guid;
973
1002
  }
974
- const test = await Nymph.getEntity(
975
- { class: User, skipAc: true },
1003
+ const test = await this.$nymph.getEntity(
1004
+ { class: tilmeld.User, skipAc: true },
976
1005
  selector
977
1006
  );
978
1007
  if (test != null) {
@@ -990,14 +1019,14 @@ export default class User extends AbleObject<UserData> {
990
1019
  return { result: false, message: 'Please specify an email.' };
991
1020
  }
992
1021
  if (
993
- Tilmeld.config.maxUsernameLength > 0 &&
994
- this.$data.username.length > Tilmeld.config.maxUsernameLength
1022
+ tilmeld.config.maxUsernameLength > 0 &&
1023
+ this.$data.username.length > tilmeld.config.maxUsernameLength
995
1024
  ) {
996
1025
  return {
997
1026
  result: false,
998
1027
  message:
999
1028
  'Emails must not exceed ' +
1000
- Tilmeld.config.maxUsernameLength +
1029
+ tilmeld.config.maxUsernameLength +
1001
1030
  ' characters.',
1002
1031
  };
1003
1032
  }
@@ -1012,17 +1041,18 @@ export default class User extends AbleObject<UserData> {
1012
1041
  * @returns An object with a boolean 'result' entry and a 'message' entry.
1013
1042
  */
1014
1043
  public async $checkEmail(): Promise<{ result: boolean; message: string }> {
1044
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
1015
1045
  if (this.$data.email == null || !this.$data.email.length) {
1016
- if (Tilmeld.config.verifyEmail) {
1046
+ if (tilmeld.config.verifyEmail) {
1017
1047
  return { result: false, message: 'Please specify an email.' };
1018
1048
  } else {
1019
1049
  return { result: true, message: '' };
1020
1050
  }
1021
1051
  }
1022
- if (!Tilmeld.config.validEmailRegex.test(this.$data.email)) {
1052
+ if (!tilmeld.config.validEmailRegex.test(this.$data.email)) {
1023
1053
  return {
1024
1054
  result: false,
1025
- message: Tilmeld.config.validEmailRegexNotice,
1055
+ message: tilmeld.config.validEmailRegexNotice,
1026
1056
  };
1027
1057
  }
1028
1058
  const selector: Selector = {
@@ -1032,7 +1062,10 @@ export default class User extends AbleObject<UserData> {
1032
1062
  if (this.guid != null) {
1033
1063
  selector['!guid'] = this.guid;
1034
1064
  }
1035
- const test = await Nymph.getEntity({ class: User, skipAc: true }, selector);
1065
+ const test = await this.$nymph.getEntity(
1066
+ { class: tilmeld.User, skipAc: true },
1067
+ selector
1068
+ );
1036
1069
  if (test != null) {
1037
1070
  return {
1038
1071
  result: false,
@@ -1053,6 +1086,7 @@ export default class User extends AbleObject<UserData> {
1053
1086
  * @returns An object with a boolean 'result' entry and a 'message' entry.
1054
1087
  */
1055
1088
  public async $checkPhone(): Promise<{ result: boolean; message: string }> {
1089
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
1056
1090
  if (this.$data.phone == null || !this.$data.phone.length) {
1057
1091
  return { result: false, message: 'Please specify a phone number.' };
1058
1092
  }
@@ -1072,7 +1106,10 @@ export default class User extends AbleObject<UserData> {
1072
1106
  if (this.guid != null) {
1073
1107
  selector['!guid'] = this.guid;
1074
1108
  }
1075
- const test = await Nymph.getEntity({ class: User, skipAc: true }, selector);
1109
+ const test = await this.$nymph.getEntity(
1110
+ { class: tilmeld.User, skipAc: true },
1111
+ selector
1112
+ );
1076
1113
  if (test != null) {
1077
1114
  return { result: false, message: 'Phone number is in use.' };
1078
1115
  }
@@ -1087,7 +1124,8 @@ export default class User extends AbleObject<UserData> {
1087
1124
  public async $register(data: {
1088
1125
  password: string;
1089
1126
  }): Promise<{ result: boolean; loggedin: boolean; message: string }> {
1090
- if (!Tilmeld.config.allowRegistration) {
1127
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
1128
+ if (!tilmeld.config.allowRegistration) {
1091
1129
  return {
1092
1130
  result: false,
1093
1131
  loggedin: false,
@@ -1114,7 +1152,7 @@ export default class User extends AbleObject<UserData> {
1114
1152
  }
1115
1153
 
1116
1154
  this.$password(data.password);
1117
- if (Tilmeld.config.regFields.indexOf('name') !== -1) {
1155
+ if (tilmeld.config.regFields.indexOf('name') !== -1) {
1118
1156
  this.$data.name =
1119
1157
  this.$data.nameFirst +
1120
1158
  (this.$data.nameMiddle == null ? '' : ' ' + this.$data.nameMiddle) +
@@ -1123,26 +1161,26 @@ export default class User extends AbleObject<UserData> {
1123
1161
  this.$data.name = this.$data.username;
1124
1162
  }
1125
1163
  }
1126
- if (Tilmeld.config.emailUsernames) {
1164
+ if (tilmeld.config.emailUsernames) {
1127
1165
  this.$data.email = this.$data.username;
1128
1166
  }
1129
1167
 
1130
1168
  // Start transaction.
1131
1169
  const transaction = 'tilmeld-register-' + nanoid();
1132
- await Nymph.startTransaction(transaction);
1170
+ const tnymph = await this.$nymph.startTransaction(transaction);
1133
1171
 
1134
1172
  try {
1135
1173
  // Add primary group.
1136
1174
  let generatedPrimaryGroup: (Group & GroupData) | null = null;
1137
- if (Tilmeld.config.generatePrimary) {
1175
+ if (tilmeld.config.generatePrimary) {
1138
1176
  // Generate a new primary group for the user.
1139
- generatedPrimaryGroup = await Group.factory();
1177
+ generatedPrimaryGroup = await tilmeld.Group.factory();
1140
1178
  generatedPrimaryGroup.groupname = this.$data.username;
1141
1179
  generatedPrimaryGroup.avatar = this.$data.avatar;
1142
1180
  generatedPrimaryGroup.name = this.$data.name;
1143
1181
  generatedPrimaryGroup.email = this.$data.email;
1144
- const parent = await Nymph.getEntity(
1145
- { class: Group },
1182
+ const parent = await tnymph.getEntity(
1183
+ { class: tilmeld.Group },
1146
1184
  {
1147
1185
  type: '&',
1148
1186
  equal: ['defaultPrimary', true],
@@ -1152,7 +1190,7 @@ export default class User extends AbleObject<UserData> {
1152
1190
  generatedPrimaryGroup.parent = parent;
1153
1191
  }
1154
1192
  if (!(await generatedPrimaryGroup.$saveSkipAC())) {
1155
- await Nymph.rollback(transaction);
1193
+ await tnymph.rollback(transaction);
1156
1194
  return {
1157
1195
  result: false,
1158
1196
  loggedin: false,
@@ -1162,8 +1200,8 @@ export default class User extends AbleObject<UserData> {
1162
1200
  this.$data.group = generatedPrimaryGroup;
1163
1201
  } else {
1164
1202
  // Add the default primary.
1165
- const group = await Nymph.getEntity(
1166
- { class: Group },
1203
+ const group = await tnymph.getEntity(
1204
+ { class: tilmeld.Group },
1167
1205
  {
1168
1206
  type: '&',
1169
1207
  equal: ['defaultPrimary', true],
@@ -1175,10 +1213,10 @@ export default class User extends AbleObject<UserData> {
1175
1213
  }
1176
1214
 
1177
1215
  // Add secondary groups.
1178
- if (Tilmeld.config.verifyEmail && Tilmeld.config.unverifiedAccess) {
1216
+ if (tilmeld.config.verifyEmail && tilmeld.config.unverifiedAccess) {
1179
1217
  // Add the default secondaries for unverified users.
1180
- this.$data.groups = await Nymph.getEntities(
1181
- { class: Group },
1218
+ this.$data.groups = await tnymph.getEntities(
1219
+ { class: tilmeld.Group },
1182
1220
  {
1183
1221
  type: '&',
1184
1222
  equal: ['unverifiedSecondary', true],
@@ -1186,8 +1224,8 @@ export default class User extends AbleObject<UserData> {
1186
1224
  );
1187
1225
  } else {
1188
1226
  // Add the default secondaries.
1189
- this.$data.groups = await Nymph.getEntities(
1190
- { class: Group },
1227
+ this.$data.groups = await tnymph.getEntities(
1228
+ { class: tilmeld.Group },
1191
1229
  {
1192
1230
  type: '&',
1193
1231
  equal: ['defaultSecondary', true],
@@ -1195,9 +1233,9 @@ export default class User extends AbleObject<UserData> {
1195
1233
  );
1196
1234
  }
1197
1235
 
1198
- if (Tilmeld.config.verifyEmail) {
1236
+ if (tilmeld.config.verifyEmail) {
1199
1237
  // The user will be enabled after verifying their e-mail address.
1200
- if (!Tilmeld.config.unverifiedAccess) {
1238
+ if (!tilmeld.config.unverifiedAccess) {
1201
1239
  this.$data.enabled = false;
1202
1240
  }
1203
1241
  } else {
@@ -1207,9 +1245,9 @@ export default class User extends AbleObject<UserData> {
1207
1245
  // If create_admin is true and there are no other users, grant
1208
1246
  // "system/admin".
1209
1247
  let madeAdmin = false;
1210
- if (Tilmeld.config.createAdmin) {
1211
- const otherUsers = await Nymph.getEntities({
1212
- class: User,
1248
+ if (tilmeld.config.createAdmin) {
1249
+ const otherUsers = await tnymph.getEntities({
1250
+ class: tilmeld.User,
1213
1251
  skipAc: true,
1214
1252
  limit: 1,
1215
1253
  return: 'guid',
@@ -1224,12 +1262,13 @@ export default class User extends AbleObject<UserData> {
1224
1262
 
1225
1263
  if (await this.$saveSkipAC()) {
1226
1264
  // Send the new user registered email.
1227
- if (Tilmeld.config.userRegisteredRecipient != null) {
1228
- await Tilmeld.config.sendEmail(
1265
+ if (tilmeld.config.userRegisteredRecipient != null) {
1266
+ await tilmeld.config.sendEmail(
1267
+ tilmeld,
1229
1268
  {
1230
1269
  template: 'UserRegistered',
1231
1270
  message: {
1232
- to: Tilmeld.config.userRegisteredRecipient,
1271
+ to: tilmeld.config.userRegisteredRecipient,
1233
1272
  },
1234
1273
  locals: {
1235
1274
  userUsername: this.$data.username,
@@ -1251,7 +1290,7 @@ export default class User extends AbleObject<UserData> {
1251
1290
  if (generatedPrimaryGroup != null) {
1252
1291
  generatedPrimaryGroup.user = this;
1253
1292
  if (!(await generatedPrimaryGroup.$saveSkipAC())) {
1254
- await Nymph.rollback(transaction);
1293
+ await tnymph.rollback(transaction);
1255
1294
  return {
1256
1295
  result: false,
1257
1296
  loggedin: false,
@@ -1263,37 +1302,37 @@ export default class User extends AbleObject<UserData> {
1263
1302
 
1264
1303
  // Finish up.
1265
1304
  if (
1266
- Tilmeld.config.verifyEmail &&
1267
- !Tilmeld.config.unverifiedAccess &&
1305
+ tilmeld.config.verifyEmail &&
1306
+ !tilmeld.config.unverifiedAccess &&
1268
1307
  !madeAdmin
1269
1308
  ) {
1270
1309
  message +=
1271
1310
  `Almost there. An email has been sent to ${this.$data.email} ` +
1272
1311
  'with a verification link for you to finish registration.';
1273
1312
  } else if (
1274
- Tilmeld.config.verifyEmail &&
1275
- Tilmeld.config.unverifiedAccess &&
1313
+ tilmeld.config.verifyEmail &&
1314
+ tilmeld.config.unverifiedAccess &&
1276
1315
  !madeAdmin
1277
1316
  ) {
1278
- Tilmeld.login(this, true);
1317
+ tilmeld.login(this, true);
1279
1318
  message +=
1280
1319
  "You're now logged in! An email has been sent to " +
1281
1320
  `${this.$data.email} with a verification link for you to finish ` +
1282
1321
  'registration.';
1283
1322
  loggedin = true;
1284
1323
  } else {
1285
- Tilmeld.login(this, true);
1324
+ tilmeld.login(this, true);
1286
1325
  message += "You're now registered and logged in!";
1287
1326
  loggedin = true;
1288
1327
  }
1289
- await Nymph.commit(transaction);
1328
+ await tnymph.commit(transaction);
1290
1329
  return {
1291
1330
  result: true,
1292
1331
  loggedin,
1293
1332
  message,
1294
1333
  };
1295
1334
  } else {
1296
- await Nymph.rollback(transaction);
1335
+ await tnymph.rollback(transaction);
1297
1336
  return {
1298
1337
  result: false,
1299
1338
  loggedin: false,
@@ -1301,19 +1340,20 @@ export default class User extends AbleObject<UserData> {
1301
1340
  };
1302
1341
  }
1303
1342
  } catch (e: any) {
1304
- await Nymph.rollback(transaction);
1343
+ await tnymph.rollback(transaction);
1305
1344
  throw e;
1306
1345
  }
1307
1346
  }
1308
1347
 
1309
1348
  public async $save() {
1349
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
1310
1350
  if (this.$data.username == null || !this.$data.username.trim().length) {
1311
1351
  return false;
1312
1352
  }
1313
1353
 
1314
1354
  if (
1315
- Tilmeld.gatekeeper('tilmeld/admin') &&
1316
- !Tilmeld.gatekeeper('system/admin') &&
1355
+ tilmeld.gatekeeper('tilmeld/admin') &&
1356
+ !tilmeld.gatekeeper('system/admin') &&
1317
1357
  this.$gatekeeper('system/admin')
1318
1358
  ) {
1319
1359
  throw new BadDataError(
@@ -1325,7 +1365,7 @@ export default class User extends AbleObject<UserData> {
1325
1365
 
1326
1366
  // Formatting.
1327
1367
  this.$data.username = this.$data.username.trim();
1328
- if (Tilmeld.config.emailUsernames) {
1368
+ if (tilmeld.config.emailUsernames) {
1329
1369
  this.$data.email = this.$data.username;
1330
1370
  }
1331
1371
  this.$data.nameFirst = (this.$data.nameFirst ?? '').trim();
@@ -1399,7 +1439,7 @@ export default class User extends AbleObject<UserData> {
1399
1439
  if (!unCheck.result) {
1400
1440
  throw new BadUsernameError(unCheck.message);
1401
1441
  }
1402
- if (!Tilmeld.config.emailUsernames) {
1442
+ if (!tilmeld.config.emailUsernames) {
1403
1443
  const emCheck = await this.$checkEmail();
1404
1444
  if (!emCheck.result) {
1405
1445
  throw new BadEmailError(emCheck.message);
@@ -1407,10 +1447,10 @@ export default class User extends AbleObject<UserData> {
1407
1447
  }
1408
1448
 
1409
1449
  // Email changes.
1410
- if (!Tilmeld.gatekeeper('tilmeld/admin')) {
1450
+ if (!tilmeld.gatekeeper('tilmeld/admin')) {
1411
1451
  // The user isn't an admin, so email address changes should contain some
1412
1452
  // security measures.
1413
- if (Tilmeld.config.verifyEmail) {
1453
+ if (tilmeld.config.verifyEmail) {
1414
1454
  // The user needs to verify this new email address.
1415
1455
  if (this.guid == null) {
1416
1456
  // If this is the first user, they'll be made an admin, so they don't
@@ -1425,16 +1465,16 @@ export default class User extends AbleObject<UserData> {
1425
1465
  ) {
1426
1466
  // The user already has an old email address.
1427
1467
  if (
1428
- Tilmeld.config.emailRateLimit !== '' &&
1468
+ tilmeld.config.emailRateLimit !== '' &&
1429
1469
  this.$data.emailChangeDate != null &&
1430
1470
  this.$data.emailChangeDate >=
1431
- strtotime('-' + Tilmeld.config.emailRateLimit) * 1000
1471
+ strtotime('-' + tilmeld.config.emailRateLimit) * 1000
1432
1472
  ) {
1433
1473
  throw new EmailChangeRateLimitExceededError(
1434
1474
  'You already changed your email address recently. Please wait until ' +
1435
1475
  new Date(
1436
1476
  strtotime(
1437
- '+' + Tilmeld.config.emailRateLimit,
1477
+ '+' + tilmeld.config.emailRateLimit,
1438
1478
  Math.floor(this.$data.emailChangeDate / 1000)
1439
1479
  ) * 1000
1440
1480
  ).toString() +
@@ -1443,12 +1483,12 @@ export default class User extends AbleObject<UserData> {
1443
1483
  } else {
1444
1484
  if (
1445
1485
  this.$data.newEmailSecret == null &&
1446
- Tilmeld.config.emailRateLimit !== '' &&
1486
+ tilmeld.config.emailRateLimit !== '' &&
1447
1487
  // Make sure the user has at least the rate limit time to cancel
1448
1488
  // an email change.
1449
1489
  (this.$data.emailChangeDate == null ||
1450
1490
  this.$data.emailChangeDate <
1451
- strtotime('-' + Tilmeld.config.emailRateLimit) * 1000)
1491
+ strtotime('-' + tilmeld.config.emailRateLimit) * 1000)
1452
1492
  ) {
1453
1493
  // Save the old email in case the cancel change link is clicked.
1454
1494
  this.$data.cancelEmailAddress = this.$originalEmail;
@@ -1459,7 +1499,7 @@ export default class User extends AbleObject<UserData> {
1459
1499
  // it).
1460
1500
  this.$data.newEmailAddress = this.$data.email;
1461
1501
  this.$data.email = this.$originalEmail;
1462
- if (Tilmeld.config.emailUsernames) {
1502
+ if (tilmeld.config.emailUsernames) {
1463
1503
  this.$data.username = this.$data.email;
1464
1504
  }
1465
1505
  this.$data.newEmailSecret = nanoid();
@@ -1474,7 +1514,7 @@ export default class User extends AbleObject<UserData> {
1474
1514
  // email change.
1475
1515
  (this.$data.emailChangeDate == null ||
1476
1516
  this.$data.emailChangeDate <
1477
- strtotime('-' + Tilmeld.config.emailRateLimit) * 1000)
1517
+ strtotime('-' + tilmeld.config.emailRateLimit) * 1000)
1478
1518
  ) {
1479
1519
  // The user doesn't need to verify their new email address, but should
1480
1520
  // be able to cancel the email change from their old address.
@@ -1494,14 +1534,14 @@ export default class User extends AbleObject<UserData> {
1494
1534
  }
1495
1535
 
1496
1536
  try {
1497
- Tilmeld.config.validatorUser(this);
1537
+ tilmeld.config.validatorUser(this);
1498
1538
  } catch (e: any) {
1499
1539
  throw new BadDataError(e?.message);
1500
1540
  }
1501
1541
 
1502
1542
  // Start transaction.
1503
1543
  const transaction = 'tilmeld-save-' + nanoid();
1504
- await Nymph.startTransaction(transaction);
1544
+ const tnymph = await this.$nymph.startTransaction(transaction);
1505
1545
 
1506
1546
  if (
1507
1547
  this.$data.group != null &&
@@ -1517,7 +1557,7 @@ export default class User extends AbleObject<UserData> {
1517
1557
  this.$data.group.phone = this.$data.phone;
1518
1558
  await this.$data.group.$saveSkipAC();
1519
1559
  } catch (e: any) {
1520
- await Nymph.rollback(transaction);
1560
+ await tnymph.rollback(transaction);
1521
1561
  throw e;
1522
1562
  }
1523
1563
  }
@@ -1530,14 +1570,14 @@ export default class User extends AbleObject<UserData> {
1530
1570
  try {
1531
1571
  ret = await super.$save();
1532
1572
  } catch (e: any) {
1533
- await Nymph.rollback(transaction);
1573
+ await tnymph.rollback(transaction);
1534
1574
  throw e;
1535
1575
  }
1536
1576
  if (ret) {
1537
1577
  if (sendVerification) {
1538
1578
  // The email has changed, so send a new verification email.
1539
1579
  if (!(await this.$sendEmailVerification())) {
1540
- await Nymph.rollback(transaction);
1580
+ await tnymph.rollback(transaction);
1541
1581
  this.guid = preGuid;
1542
1582
  this.cdate = preCdate;
1543
1583
  this.mdate = preMdate;
@@ -1545,16 +1585,16 @@ export default class User extends AbleObject<UserData> {
1545
1585
  }
1546
1586
  }
1547
1587
 
1548
- if (User.current(true).$is(this)) {
1588
+ if (tilmeld.User.current(true).$is(this)) {
1549
1589
  // Update the user in the session cache.
1550
- Tilmeld.fillSession(this);
1590
+ tilmeld.fillSession(this);
1551
1591
  }
1552
1592
 
1553
1593
  this.$descendantGroups = undefined;
1554
1594
  this.$gatekeeperCache = undefined;
1555
- await Nymph.commit(transaction);
1595
+ await tnymph.commit(transaction);
1556
1596
  } else {
1557
- await Nymph.rollback(transaction);
1597
+ await tnymph.rollback(transaction);
1558
1598
  }
1559
1599
  return ret;
1560
1600
  }
@@ -1576,22 +1616,21 @@ export default class User extends AbleObject<UserData> {
1576
1616
  }
1577
1617
 
1578
1618
  public async $delete() {
1579
- if (!Tilmeld.gatekeeper('tilmeld/admin')) {
1619
+ const tilmeld = this.$nymph.tilmeld as Tilmeld;
1620
+ if (!tilmeld.gatekeeper('tilmeld/admin')) {
1580
1621
  throw new BadDataError("You don't have the authority to delete users.");
1581
1622
  }
1582
1623
  if (
1583
- !Tilmeld.gatekeeper('system/admin') &&
1624
+ !tilmeld.gatekeeper('system/admin') &&
1584
1625
  this.$gatekeeper('system/admin')
1585
1626
  ) {
1586
1627
  throw new BadDataError(
1587
1628
  "You don't have the authority to delete system admins."
1588
1629
  );
1589
1630
  }
1590
- if (User.current(true).$is(this)) {
1631
+ if (tilmeld.User.current(true).$is(this)) {
1591
1632
  this.$logout();
1592
1633
  }
1593
1634
  return await super.$delete();
1594
1635
  }
1595
1636
  }
1596
-
1597
- Nymph.setEntityClass(User.class, User);