@nymphjs/tilmeld 1.0.0-beta.121 → 1.0.0-beta.123
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/CHANGELOG.md +22 -0
- package/README.md +6 -3
- package/dist/Group.d.ts +9 -9
- package/dist/Group.js +790 -793
- package/dist/Group.js.map +1 -1
- package/dist/Group.testArtifacts.js +3 -3
- package/dist/Group.testArtifacts.js.map +1 -1
- package/dist/Tilmeld.js +6 -15
- package/dist/Tilmeld.js.map +1 -1
- package/dist/User.d.ts +8 -9
- package/dist/User.js +1838 -1957
- package/dist/User.js.map +1 -1
- package/dist/User.testArtifacts.js +7 -7
- package/dist/User.testArtifacts.js.map +1 -1
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +3 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/requireAbility.d.ts +10 -0
- package/dist/decorators/requireAbility.js +21 -0
- package/dist/decorators/requireAbility.js.map +1 -0
- package/dist/decorators/requireAuthentication.d.ts +8 -0
- package/dist/decorators/requireAuthentication.js +16 -0
- package/dist/decorators/requireAuthentication.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/testArtifacts.d.ts +5 -1
- package/dist/testArtifacts.js +211 -67
- package/dist/testArtifacts.js.map +1 -1
- package/package.json +13 -7
- package/src/Group.testArtifacts.ts +3 -3
- package/src/Group.ts +108 -158
- package/src/Tilmeld.ts +6 -35
- package/src/User.testArtifacts.ts +7 -7
- package/src/User.ts +364 -515
- package/src/decorators/index.ts +2 -0
- package/src/decorators/requireAbility.ts +26 -0
- package/src/decorators/requireAuthentication.ts +19 -0
- package/src/index.ts +1 -0
- package/src/testArtifacts.ts +165 -46
package/src/User.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import {
|
|
3
|
+
type EntityData,
|
|
4
|
+
type EntityJson,
|
|
5
|
+
type EntityPatch,
|
|
6
|
+
type Selector,
|
|
7
|
+
type SerializedEntityData,
|
|
8
|
+
transaction,
|
|
9
|
+
transactional,
|
|
9
10
|
} from '@nymphjs/nymph';
|
|
10
11
|
import { humanSecret, nanoid } from '@nymphjs/guid';
|
|
11
12
|
import type { EmailOptions } from 'email-templates';
|
|
@@ -372,9 +373,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
372
373
|
const entity = new this();
|
|
373
374
|
if (username != null) {
|
|
374
375
|
const entity = await this.nymph.getEntity(
|
|
375
|
-
{
|
|
376
|
-
class: this,
|
|
377
|
-
},
|
|
376
|
+
{ class: this },
|
|
378
377
|
{
|
|
379
378
|
type: '&',
|
|
380
379
|
ilike: ['username', username.replace(/([\\%_])/g, (s) => `\\${s}`)],
|
|
@@ -413,10 +412,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
413
412
|
}): Promise<{ result: boolean; message: string }> {
|
|
414
413
|
const tilmeld = enforceTilmeld(this);
|
|
415
414
|
if (!tilmeld.config.pwRecovery) {
|
|
416
|
-
return {
|
|
417
|
-
result: false,
|
|
418
|
-
message: 'Account recovery is not allowed.',
|
|
419
|
-
};
|
|
415
|
+
return { result: false, message: 'Account recovery is not allowed.' };
|
|
420
416
|
}
|
|
421
417
|
|
|
422
418
|
let user: User & UserData;
|
|
@@ -444,10 +440,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
444
440
|
user = getUser;
|
|
445
441
|
options.template = 'RecoverUsername';
|
|
446
442
|
options.message = {
|
|
447
|
-
to: {
|
|
448
|
-
name: user.name ?? '',
|
|
449
|
-
address: user.email ?? '',
|
|
450
|
-
},
|
|
443
|
+
to: { name: user.name ?? '', address: user.email ?? '' },
|
|
451
444
|
};
|
|
452
445
|
options.locals = {};
|
|
453
446
|
} else if (data.recoveryType === 'password') {
|
|
@@ -465,7 +458,9 @@ export default class User extends AbleObject<UserData> {
|
|
|
465
458
|
// Create a unique secret.
|
|
466
459
|
getUser.recoverSecret = humanSecret();
|
|
467
460
|
getUser.recoverSecretDate = Date.now();
|
|
468
|
-
|
|
461
|
+
try {
|
|
462
|
+
await getUser.$saveSkipAC();
|
|
463
|
+
} catch (e: any) {
|
|
469
464
|
return { result: false, message: "Couldn't save recovery secret." };
|
|
470
465
|
}
|
|
471
466
|
|
|
@@ -473,10 +468,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
473
468
|
user = getUser;
|
|
474
469
|
options.template = 'RecoverPassword';
|
|
475
470
|
options.message = {
|
|
476
|
-
to: {
|
|
477
|
-
name: user.name ?? '',
|
|
478
|
-
address: user.email ?? '',
|
|
479
|
-
},
|
|
471
|
+
to: { name: user.name ?? '', address: user.email ?? '' },
|
|
480
472
|
};
|
|
481
473
|
options.locals = {
|
|
482
474
|
recoverCode: getUser.recoverSecret,
|
|
@@ -517,10 +509,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
517
509
|
}): Promise<{ result: boolean; message: string }> {
|
|
518
510
|
const tilmeld = enforceTilmeld(this);
|
|
519
511
|
if (!tilmeld.config.pwRecovery) {
|
|
520
|
-
return {
|
|
521
|
-
result: false,
|
|
522
|
-
message: 'Account recovery is not allowed.',
|
|
523
|
-
};
|
|
512
|
+
return { result: false, message: 'Account recovery is not allowed.' };
|
|
524
513
|
}
|
|
525
514
|
|
|
526
515
|
const user = await tilmeld.User.factoryUsername(data.username);
|
|
@@ -536,10 +525,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
536
525
|
1000 <
|
|
537
526
|
Date.now()
|
|
538
527
|
) {
|
|
539
|
-
return {
|
|
540
|
-
result: false,
|
|
541
|
-
message: 'The secret code does not match.',
|
|
542
|
-
};
|
|
528
|
+
return { result: false, message: 'The secret code does not match.' };
|
|
543
529
|
}
|
|
544
530
|
|
|
545
531
|
if (!('password' in data) || !data.password.length) {
|
|
@@ -554,13 +540,14 @@ export default class User extends AbleObject<UserData> {
|
|
|
554
540
|
user.$password(data.password);
|
|
555
541
|
delete user.recoverSecret;
|
|
556
542
|
delete user.recoverSecretDate;
|
|
557
|
-
|
|
543
|
+
try {
|
|
544
|
+
await user.$saveSkipAC();
|
|
558
545
|
return {
|
|
559
546
|
result: true,
|
|
560
547
|
message:
|
|
561
548
|
'Your password has been reset. You can now log in using your new password.',
|
|
562
549
|
};
|
|
563
|
-
}
|
|
550
|
+
} catch (e: any) {
|
|
564
551
|
return { result: false, message: 'Error saving new password.' };
|
|
565
552
|
}
|
|
566
553
|
}
|
|
@@ -636,26 +623,10 @@ export default class User extends AbleObject<UserData> {
|
|
|
636
623
|
return await this.nymph.getEntities(
|
|
637
624
|
{
|
|
638
625
|
class: this.nymph.getEntityClass(User),
|
|
639
|
-
...(options?.limit != null
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
: {}),
|
|
644
|
-
...(options?.offset != null
|
|
645
|
-
? {
|
|
646
|
-
offset: options.offset,
|
|
647
|
-
}
|
|
648
|
-
: {}),
|
|
649
|
-
...(options?.sort != null
|
|
650
|
-
? {
|
|
651
|
-
sort: options.sort,
|
|
652
|
-
}
|
|
653
|
-
: {}),
|
|
654
|
-
...(options?.reverse != null
|
|
655
|
-
? {
|
|
656
|
-
reverse: options.reverse,
|
|
657
|
-
}
|
|
658
|
-
: {}),
|
|
626
|
+
...(options?.limit != null ? { limit: options.limit } : {}),
|
|
627
|
+
...(options?.offset != null ? { offset: options.offset } : {}),
|
|
628
|
+
...(options?.sort != null ? { sort: options.sort } : {}),
|
|
629
|
+
...(options?.reverse != null ? { reverse: options.reverse } : {}),
|
|
659
630
|
},
|
|
660
631
|
{
|
|
661
632
|
type: '&',
|
|
@@ -675,20 +646,6 @@ export default class User extends AbleObject<UserData> {
|
|
|
675
646
|
this.$updateDataProtection();
|
|
676
647
|
}
|
|
677
648
|
|
|
678
|
-
$setNymph(nymph: Nymph) {
|
|
679
|
-
this.$nymph = nymph;
|
|
680
|
-
if (!this.$asleep()) {
|
|
681
|
-
if (this.$data.group && this.$data.group.$nymph !== nymph) {
|
|
682
|
-
this.$data.group.$setNymph(nymph);
|
|
683
|
-
}
|
|
684
|
-
for (const group of this.$data.groups ?? []) {
|
|
685
|
-
if (group && group.$nymph !== nymph) {
|
|
686
|
-
group.$setNymph(nymph);
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
|
|
692
649
|
async $getUniques(): Promise<string[]> {
|
|
693
650
|
const tilmeld = enforceTilmeld(this);
|
|
694
651
|
const uniques = [`u:${this.$data.username}`];
|
|
@@ -754,10 +711,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
754
711
|
}
|
|
755
712
|
}
|
|
756
713
|
} catch (e: any) {
|
|
757
|
-
return {
|
|
758
|
-
result: false,
|
|
759
|
-
message: e.message,
|
|
760
|
-
};
|
|
714
|
+
return { result: false, message: e.message };
|
|
761
715
|
}
|
|
762
716
|
|
|
763
717
|
this.$nymph.config.debugLog(
|
|
@@ -781,7 +735,9 @@ export default class User extends AbleObject<UserData> {
|
|
|
781
735
|
return { result: true, message: 'You are logged in.' };
|
|
782
736
|
}
|
|
783
737
|
|
|
784
|
-
public async $switchUser(data?: {
|
|
738
|
+
public async $switchUser(data?: {
|
|
739
|
+
additionalData?: { [k: string]: any };
|
|
740
|
+
}): Promise<{ result: boolean; message: string }> {
|
|
785
741
|
const tilmeld = enforceTilmeld(this);
|
|
786
742
|
if (this.guid == null) {
|
|
787
743
|
return { result: false, message: 'Incorrect login/password.' };
|
|
@@ -831,10 +787,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
831
787
|
}
|
|
832
788
|
}
|
|
833
789
|
} catch (e: any) {
|
|
834
|
-
return {
|
|
835
|
-
result: false,
|
|
836
|
-
message: e.message,
|
|
837
|
-
};
|
|
790
|
+
return { result: false, message: e.message };
|
|
838
791
|
}
|
|
839
792
|
|
|
840
793
|
this.$nymph.config.debugLog(
|
|
@@ -862,7 +815,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
862
815
|
* Log a user out of the system.
|
|
863
816
|
* @returns An object with a boolean 'result' entry and a 'message' entry.
|
|
864
817
|
*/
|
|
865
|
-
public async $logout() {
|
|
818
|
+
public async $logout(): Promise<{ result: boolean; message: string }> {
|
|
866
819
|
const tilmeld = enforceTilmeld(this);
|
|
867
820
|
|
|
868
821
|
try {
|
|
@@ -873,10 +826,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
873
826
|
}
|
|
874
827
|
}
|
|
875
828
|
} catch (e: any) {
|
|
876
|
-
return {
|
|
877
|
-
result: false,
|
|
878
|
-
message: e.message,
|
|
879
|
-
};
|
|
829
|
+
return { result: false, message: e.message };
|
|
880
830
|
}
|
|
881
831
|
|
|
882
832
|
this.$nymph.config.debugLog(
|
|
@@ -896,7 +846,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
896
846
|
return { result: true, message: 'You have been logged out.' };
|
|
897
847
|
}
|
|
898
848
|
|
|
899
|
-
public $getAvatar() {
|
|
849
|
+
public $getAvatar(): string {
|
|
900
850
|
if (this.$data.avatar != null && this.$data.avatar !== '') {
|
|
901
851
|
return this.$data.avatar;
|
|
902
852
|
}
|
|
@@ -1130,7 +1080,6 @@ export default class User extends AbleObject<UserData> {
|
|
|
1130
1080
|
this.$clientEnabledMethods.push('$changePassword');
|
|
1131
1081
|
this.$clientEnabledMethods.push('$revokeCurrentTokens');
|
|
1132
1082
|
this.$clientEnabledMethods.push('$logout');
|
|
1133
|
-
this.$clientEnabledMethods.push('$sendEmailVerification');
|
|
1134
1083
|
this.$clientEnabledMethods.push('$hasTOTPSecret');
|
|
1135
1084
|
this.$clientEnabledMethods.push('$getNewTOTPSecret');
|
|
1136
1085
|
this.$clientEnabledMethods.push('$saveTOTPSecret');
|
|
@@ -1344,7 +1293,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1344
1293
|
*
|
|
1345
1294
|
* @returns True on success, false on failure.
|
|
1346
1295
|
*/
|
|
1347
|
-
public async $sendEmailVerification() {
|
|
1296
|
+
public async $sendEmailVerification(): Promise<boolean> {
|
|
1348
1297
|
const tilmeld = enforceTilmeld(this);
|
|
1349
1298
|
if (this.guid == null) {
|
|
1350
1299
|
return false;
|
|
@@ -1371,9 +1320,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1371
1320
|
address: this.$data.email ?? '',
|
|
1372
1321
|
},
|
|
1373
1322
|
},
|
|
1374
|
-
locals: {
|
|
1375
|
-
verifyLink: link,
|
|
1376
|
-
},
|
|
1323
|
+
locals: { verifyLink: link },
|
|
1377
1324
|
},
|
|
1378
1325
|
this,
|
|
1379
1326
|
));
|
|
@@ -1581,13 +1528,14 @@ export default class User extends AbleObject<UserData> {
|
|
|
1581
1528
|
if (data.revokeCurrentTokens) {
|
|
1582
1529
|
this.$data.revokeTokenDate = Date.now();
|
|
1583
1530
|
}
|
|
1584
|
-
|
|
1531
|
+
try {
|
|
1532
|
+
await this.$save();
|
|
1585
1533
|
if (data.revokeCurrentTokens) {
|
|
1586
1534
|
const tilmeld = enforceTilmeld(this);
|
|
1587
1535
|
await tilmeld.login(this, true);
|
|
1588
1536
|
}
|
|
1589
1537
|
return { result: true, message: 'Your password has been changed.' };
|
|
1590
|
-
}
|
|
1538
|
+
} catch (e: any) {
|
|
1591
1539
|
return { result: false, message: "Couldn't save new password." };
|
|
1592
1540
|
}
|
|
1593
1541
|
}
|
|
@@ -1639,19 +1587,20 @@ export default class User extends AbleObject<UserData> {
|
|
|
1639
1587
|
|
|
1640
1588
|
this.$data.revokeTokenDate = Date.now();
|
|
1641
1589
|
|
|
1642
|
-
|
|
1590
|
+
try {
|
|
1591
|
+
await this.$save();
|
|
1643
1592
|
const tilmeld = enforceTilmeld(this);
|
|
1644
1593
|
await tilmeld.login(this, true);
|
|
1645
1594
|
return {
|
|
1646
1595
|
result: true,
|
|
1647
1596
|
message: 'You have logged out of all other sessions.',
|
|
1648
1597
|
};
|
|
1649
|
-
}
|
|
1598
|
+
} catch (e: any) {
|
|
1650
1599
|
return { result: false, message: "Couldn't save revocation date." };
|
|
1651
1600
|
}
|
|
1652
1601
|
}
|
|
1653
1602
|
|
|
1654
|
-
public
|
|
1603
|
+
public $hasTOTPSecret(): boolean {
|
|
1655
1604
|
return this.$data.totpSecret != null;
|
|
1656
1605
|
}
|
|
1657
1606
|
|
|
@@ -1685,7 +1634,11 @@ export default class User extends AbleObject<UserData> {
|
|
|
1685
1634
|
*
|
|
1686
1635
|
* @returns An object with 'uri', 'qrcode', and 'secret'.
|
|
1687
1636
|
*/
|
|
1688
|
-
public async $getNewTOTPSecret() {
|
|
1637
|
+
public async $getNewTOTPSecret(): Promise<{
|
|
1638
|
+
uri: string;
|
|
1639
|
+
qrcode: string;
|
|
1640
|
+
secret: string;
|
|
1641
|
+
}> {
|
|
1689
1642
|
const tilmeld = enforceTilmeld(this);
|
|
1690
1643
|
|
|
1691
1644
|
if (this.$data.totpSecret != null) {
|
|
@@ -1707,11 +1660,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1707
1660
|
|
|
1708
1661
|
const qrcode = await toDataURL(uri);
|
|
1709
1662
|
|
|
1710
|
-
return {
|
|
1711
|
-
uri,
|
|
1712
|
-
qrcode,
|
|
1713
|
-
secret: secret.base32,
|
|
1714
|
-
};
|
|
1663
|
+
return { uri, qrcode, secret: secret.base32 };
|
|
1715
1664
|
}
|
|
1716
1665
|
|
|
1717
1666
|
/**
|
|
@@ -1766,9 +1715,10 @@ export default class User extends AbleObject<UserData> {
|
|
|
1766
1715
|
|
|
1767
1716
|
this.$data.totpSecret = data.secret;
|
|
1768
1717
|
|
|
1769
|
-
|
|
1718
|
+
try {
|
|
1719
|
+
await this.$save();
|
|
1770
1720
|
return { result: true, message: 'Your two factor secret is now set.' };
|
|
1771
|
-
}
|
|
1721
|
+
} catch (e: any) {
|
|
1772
1722
|
return { result: false, message: "Couldn't save two factor secret." };
|
|
1773
1723
|
}
|
|
1774
1724
|
}
|
|
@@ -1824,12 +1774,10 @@ export default class User extends AbleObject<UserData> {
|
|
|
1824
1774
|
|
|
1825
1775
|
delete this.$data.totpSecret;
|
|
1826
1776
|
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
};
|
|
1832
|
-
} else {
|
|
1777
|
+
try {
|
|
1778
|
+
await this.$save();
|
|
1779
|
+
return { result: true, message: 'Two factor secret has been removed.' };
|
|
1780
|
+
} catch (e: any) {
|
|
1833
1781
|
return { result: false, message: "Couldn't remove two factor secret." };
|
|
1834
1782
|
}
|
|
1835
1783
|
}
|
|
@@ -1889,16 +1837,10 @@ export default class User extends AbleObject<UserData> {
|
|
|
1889
1837
|
difference(username.split(''), tilmeld.config.validChars.split(''))
|
|
1890
1838
|
.length
|
|
1891
1839
|
) {
|
|
1892
|
-
return {
|
|
1893
|
-
result: false,
|
|
1894
|
-
message: tilmeld.config.validCharsNotice,
|
|
1895
|
-
};
|
|
1840
|
+
return { result: false, message: tilmeld.config.validCharsNotice };
|
|
1896
1841
|
}
|
|
1897
1842
|
if (!tilmeld.config.validRegex.test(username)) {
|
|
1898
|
-
return {
|
|
1899
|
-
result: false,
|
|
1900
|
-
message: tilmeld.config.validRegexNotice,
|
|
1901
|
-
};
|
|
1843
|
+
return { result: false, message: tilmeld.config.validRegexNotice };
|
|
1902
1844
|
}
|
|
1903
1845
|
if (domain != null) {
|
|
1904
1846
|
if (!tilmeld.config.validDomainRegex.test(domain)) {
|
|
@@ -2004,10 +1946,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2004
1946
|
}
|
|
2005
1947
|
}
|
|
2006
1948
|
if (!tilmeld.config.validEmailRegex.test(this.$data.email)) {
|
|
2007
|
-
return {
|
|
2008
|
-
result: false,
|
|
2009
|
-
message: tilmeld.config.validEmailRegexNotice,
|
|
2010
|
-
};
|
|
1949
|
+
return { result: false, message: tilmeld.config.validEmailRegexNotice };
|
|
2011
1950
|
}
|
|
2012
1951
|
const selector: Selector = {
|
|
2013
1952
|
type: '&',
|
|
@@ -2127,187 +2066,163 @@ export default class User extends AbleObject<UserData> {
|
|
|
2127
2066
|
this.$data.email = this.$data.username;
|
|
2128
2067
|
}
|
|
2129
2068
|
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2069
|
+
try {
|
|
2070
|
+
const result = await transaction(
|
|
2071
|
+
this.$nymph,
|
|
2072
|
+
'tilmeld-register-' + nanoid(),
|
|
2073
|
+
async (nymph) => {
|
|
2074
|
+
this.$setNymph(nymph);
|
|
2075
|
+
const tilmeld = enforceTilmeld(this);
|
|
2136
2076
|
|
|
2137
|
-
|
|
2138
|
-
|
|
2077
|
+
let message = '';
|
|
2078
|
+
let loggedin = false;
|
|
2139
2079
|
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
await callback(this, data);
|
|
2080
|
+
for (let callback of (this.constructor as typeof User)
|
|
2081
|
+
.beforeRegisterCallbacks) {
|
|
2082
|
+
if (callback) {
|
|
2083
|
+
await callback(this, data);
|
|
2084
|
+
}
|
|
2146
2085
|
}
|
|
2147
|
-
}
|
|
2148
|
-
} catch (e: any) {
|
|
2149
|
-
await tnymph.rollback(transaction);
|
|
2150
|
-
this.$setNymph(nymph);
|
|
2151
|
-
return {
|
|
2152
|
-
result: false,
|
|
2153
|
-
loggedin: false,
|
|
2154
|
-
message: e.message,
|
|
2155
|
-
};
|
|
2156
|
-
}
|
|
2157
2086
|
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2087
|
+
if (
|
|
2088
|
+
tilmeld.config.userFields.includes('email') &&
|
|
2089
|
+
tilmeld.config.verifyEmail
|
|
2090
|
+
) {
|
|
2091
|
+
// The user will be enabled after verifying their e-mail address.
|
|
2092
|
+
if (!tilmeld.config.unverifiedAccess) {
|
|
2093
|
+
this.$data.enabled = false;
|
|
2094
|
+
}
|
|
2095
|
+
} else {
|
|
2096
|
+
this.$data.enabled = true;
|
|
2097
|
+
}
|
|
2169
2098
|
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
if (!otherUsers.length) {
|
|
2191
|
-
this.$grant('system/admin');
|
|
2192
|
-
this.$data.enabled = true;
|
|
2193
|
-
madeAdmin = true;
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2099
|
+
// If createAdmin is true and there are no other users, grant
|
|
2100
|
+
// "system/admin".
|
|
2101
|
+
let madeAdmin = false;
|
|
2102
|
+
if (tilmeld.config.createAdmin) {
|
|
2103
|
+
const otherUsers = await this.$nymph.getEntities({
|
|
2104
|
+
class: tilmeld.User,
|
|
2105
|
+
skipAc: true,
|
|
2106
|
+
limit: 1,
|
|
2107
|
+
return: 'guid',
|
|
2108
|
+
});
|
|
2109
|
+
// Make sure it's not just null, cause that means an error.
|
|
2110
|
+
if (otherUsers == null) {
|
|
2111
|
+
throw new Error('An error occurred.');
|
|
2112
|
+
}
|
|
2113
|
+
if (!otherUsers.length) {
|
|
2114
|
+
this.$grant('system/admin');
|
|
2115
|
+
this.$data.enabled = true;
|
|
2116
|
+
madeAdmin = true;
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2196
2119
|
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
);
|
|
2201
|
-
if (await this.$saveSkipAC()) {
|
|
2202
|
-
this.$nymph.config.debugLog(
|
|
2203
|
-
'tilmeld',
|
|
2204
|
-
`New user registered "${this.$data.username}".`,
|
|
2205
|
-
);
|
|
2206
|
-
// Send the new user registered email.
|
|
2207
|
-
if (tilmeld.config.userRegisteredRecipient != null) {
|
|
2208
|
-
await tilmeld.config.sendEmail(
|
|
2209
|
-
tilmeld,
|
|
2210
|
-
{
|
|
2211
|
-
template: 'UserRegistered',
|
|
2212
|
-
message: {
|
|
2213
|
-
to: tilmeld.config.userRegisteredRecipient,
|
|
2214
|
-
},
|
|
2215
|
-
locals: {
|
|
2216
|
-
userUsername: this.$data.username,
|
|
2217
|
-
userName: this.$data.name,
|
|
2218
|
-
userFirstName: this.$data.nameFirst,
|
|
2219
|
-
userLastName: this.$data.nameLast,
|
|
2220
|
-
userEmail: this.$data.email,
|
|
2221
|
-
userPhone: this.$data.phone,
|
|
2222
|
-
},
|
|
2223
|
-
},
|
|
2224
|
-
this,
|
|
2120
|
+
this.$nymph.config.debugLog(
|
|
2121
|
+
'tilmeld',
|
|
2122
|
+
`Registering new user "${this.$data.username}".`,
|
|
2225
2123
|
);
|
|
2226
|
-
}
|
|
2227
2124
|
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2125
|
+
await this.$saveSkipAC();
|
|
2126
|
+
|
|
2127
|
+
// Finish up.
|
|
2128
|
+
if (
|
|
2129
|
+
tilmeld.config.verifyEmail &&
|
|
2130
|
+
!tilmeld.config.unverifiedAccess &&
|
|
2131
|
+
!madeAdmin &&
|
|
2132
|
+
tilmeld.config.userFields.includes('email')
|
|
2133
|
+
) {
|
|
2134
|
+
message +=
|
|
2135
|
+
`Almost there. An email has been sent to ${this.$data.email} ` +
|
|
2136
|
+
'with a verification link for you to finish registration.';
|
|
2137
|
+
} else if (
|
|
2138
|
+
tilmeld.config.verifyEmail &&
|
|
2139
|
+
tilmeld.config.unverifiedAccess &&
|
|
2140
|
+
!madeAdmin &&
|
|
2141
|
+
tilmeld.config.userFields.includes('email')
|
|
2142
|
+
) {
|
|
2143
|
+
if (!(await tilmeld.login(this, true))) {
|
|
2144
|
+
throw new Error('An error occurred trying to log you in.');
|
|
2145
|
+
}
|
|
2146
|
+
message +=
|
|
2147
|
+
"You're now logged in! An email has been sent to " +
|
|
2148
|
+
`${this.$data.email} with a verification link for you to finish ` +
|
|
2149
|
+
'registration.';
|
|
2150
|
+
loggedin = true;
|
|
2151
|
+
} else {
|
|
2152
|
+
if (!(await tilmeld.login(this, true))) {
|
|
2153
|
+
throw new Error('An error occurred trying to log you in.');
|
|
2154
|
+
}
|
|
2155
|
+
message += "You're now registered and logged in!";
|
|
2156
|
+
loggedin = true;
|
|
2246
2157
|
}
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
if (!(await tilmeld.login(this, true))) {
|
|
2254
|
-
throw new Error('An error occurred trying to log you in.');
|
|
2158
|
+
|
|
2159
|
+
for (let callback of (this.constructor as typeof User)
|
|
2160
|
+
.afterRegisterCallbacks) {
|
|
2161
|
+
if (callback) {
|
|
2162
|
+
await callback(this, { loggedin, message });
|
|
2163
|
+
}
|
|
2255
2164
|
}
|
|
2256
|
-
message += "You're now registered and logged in!";
|
|
2257
|
-
loggedin = true;
|
|
2258
|
-
}
|
|
2259
2165
|
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2166
|
+
return { result: true, loggedin, message };
|
|
2167
|
+
},
|
|
2168
|
+
async (nymph) => {
|
|
2169
|
+
this.$setNymph(nymph);
|
|
2170
|
+
},
|
|
2171
|
+
);
|
|
2172
|
+
|
|
2173
|
+
// Send the new user registered email.
|
|
2174
|
+
if (tilmeld.config.userRegisteredRecipient != null) {
|
|
2175
|
+
try {
|
|
2176
|
+
if (
|
|
2177
|
+
!(await tilmeld.config.sendEmail(
|
|
2178
|
+
tilmeld,
|
|
2179
|
+
{
|
|
2180
|
+
template: 'UserRegistered',
|
|
2181
|
+
message: { to: tilmeld.config.userRegisteredRecipient },
|
|
2182
|
+
locals: {
|
|
2183
|
+
userUsername: this.$data.username,
|
|
2184
|
+
userName: this.$data.name,
|
|
2185
|
+
userFirstName: this.$data.nameFirst,
|
|
2186
|
+
userLastName: this.$data.nameLast,
|
|
2187
|
+
userEmail: this.$data.email,
|
|
2188
|
+
userPhone: this.$data.phone,
|
|
2189
|
+
},
|
|
2190
|
+
},
|
|
2191
|
+
this,
|
|
2192
|
+
))
|
|
2193
|
+
) {
|
|
2194
|
+
throw new Error('Failed to send.');
|
|
2267
2195
|
}
|
|
2196
|
+
} catch (e: any) {
|
|
2197
|
+
this.$nymph.config.debugError(
|
|
2198
|
+
'tilmeld',
|
|
2199
|
+
`Couldn't send new user registered email for "${this.$data.username}": ${e.message}`,
|
|
2200
|
+
);
|
|
2268
2201
|
}
|
|
2269
|
-
} else {
|
|
2270
|
-
this.$nymph.config.debugError(
|
|
2271
|
-
'tilmeld',
|
|
2272
|
-
`Error registering new user "${this.$data.username}".`,
|
|
2273
|
-
);
|
|
2274
|
-
await tnymph.rollback(transaction);
|
|
2275
|
-
this.$setNymph(nymph);
|
|
2276
|
-
return {
|
|
2277
|
-
result: false,
|
|
2278
|
-
loggedin: false,
|
|
2279
|
-
message: 'Error registering user.',
|
|
2280
|
-
};
|
|
2281
2202
|
}
|
|
2282
|
-
} catch (e: any) {
|
|
2283
|
-
this.$nymph.config.debugError(
|
|
2284
|
-
'tilmeld',
|
|
2285
|
-
`Error registering new user "${this.$data.username}": ${e}`,
|
|
2286
|
-
);
|
|
2287
|
-
await tnymph.rollback(transaction);
|
|
2288
|
-
this.$setNymph(nymph);
|
|
2289
|
-
throw e;
|
|
2290
|
-
}
|
|
2291
2203
|
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2204
|
+
if (result.loggedin) {
|
|
2205
|
+
try {
|
|
2206
|
+
await this.$nymph.tilmeld?.fillSession(this);
|
|
2207
|
+
} catch (e: any) {
|
|
2208
|
+
return {
|
|
2209
|
+
result: true,
|
|
2210
|
+
loggedin: false,
|
|
2211
|
+
message: `You are registered, but an error occurred logging you in: ${e.message}`,
|
|
2212
|
+
};
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
return result;
|
|
2296
2217
|
} catch (e: any) {
|
|
2297
|
-
|
|
2218
|
+
return { result: false, loggedin: false, message: e.message };
|
|
2298
2219
|
}
|
|
2299
|
-
|
|
2300
|
-
return {
|
|
2301
|
-
result: true,
|
|
2302
|
-
loggedin,
|
|
2303
|
-
message,
|
|
2304
|
-
};
|
|
2305
2220
|
}
|
|
2306
2221
|
|
|
2307
2222
|
public async $save() {
|
|
2308
2223
|
let tilmeld = enforceTilmeld(this);
|
|
2309
2224
|
if (this.$data.username == null || !this.$data.username.trim().length) {
|
|
2310
|
-
|
|
2225
|
+
throw new BadUsernameError('Username must not be empty.');
|
|
2311
2226
|
}
|
|
2312
2227
|
|
|
2313
2228
|
if (
|
|
@@ -2591,208 +2506,167 @@ export default class User extends AbleObject<UserData> {
|
|
|
2591
2506
|
throw new BadDataError('A password is required.');
|
|
2592
2507
|
}
|
|
2593
2508
|
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2509
|
+
let preGuid = this.guid;
|
|
2510
|
+
let preCdate = this.cdate;
|
|
2511
|
+
let preMdate = this.mdate;
|
|
2512
|
+
return await transaction(
|
|
2513
|
+
this.$nymph,
|
|
2514
|
+
'tilmeld-save-user-' + (this.guid || nanoid()),
|
|
2515
|
+
async (nymph) => {
|
|
2516
|
+
this.$setNymph(nymph);
|
|
2517
|
+
const tilmeld = enforceTilmeld(this);
|
|
2518
|
+
const Group = this.$nymph.getEntityClass(GroupClass);
|
|
2601
2519
|
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2520
|
+
let group = this.$data.group;
|
|
2521
|
+
if (group != null) {
|
|
2522
|
+
// Make sure to get fresh group data.
|
|
2523
|
+
if (group.$asleep()) {
|
|
2524
|
+
await group.$wake();
|
|
2525
|
+
} else {
|
|
2526
|
+
if (!(await group.$refresh())) {
|
|
2527
|
+
throw new Error("Couldn't retrieve primary group info.");
|
|
2528
|
+
}
|
|
2611
2529
|
}
|
|
2612
2530
|
}
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
}
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
group
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
type: '&',
|
|
2635
|
-
equal: ['defaultPrimary', true],
|
|
2636
|
-
},
|
|
2637
|
-
);
|
|
2638
|
-
if (group != null) {
|
|
2639
|
-
this.$data.group = group;
|
|
2531
|
+
if (group == null && this.guid == null) {
|
|
2532
|
+
if (tilmeld.config.generatePrimary) {
|
|
2533
|
+
// Generate a new primary group for the user.
|
|
2534
|
+
group = await Group.factory();
|
|
2535
|
+
group.user = this;
|
|
2536
|
+
const parent = await this.$nymph.getEntity(
|
|
2537
|
+
{ class: Group },
|
|
2538
|
+
{ type: '&', equal: ['defaultPrimary', true] },
|
|
2539
|
+
);
|
|
2540
|
+
if (parent != null) {
|
|
2541
|
+
group.parent = parent;
|
|
2542
|
+
}
|
|
2543
|
+
} else {
|
|
2544
|
+
// Add the default primary.
|
|
2545
|
+
const group = await this.$nymph.getEntity(
|
|
2546
|
+
{ class: Group },
|
|
2547
|
+
{ type: '&', equal: ['defaultPrimary', true] },
|
|
2548
|
+
);
|
|
2549
|
+
if (group != null) {
|
|
2550
|
+
this.$data.group = group;
|
|
2551
|
+
}
|
|
2640
2552
|
}
|
|
2641
2553
|
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
changed = true;
|
|
2660
|
-
}
|
|
2661
|
-
if (
|
|
2662
|
-
tilmeld.config.userFields.includes('name') &&
|
|
2663
|
-
group.name !== this.$data.name
|
|
2664
|
-
) {
|
|
2665
|
-
group.name = this.$data.name;
|
|
2666
|
-
changed = true;
|
|
2667
|
-
}
|
|
2668
|
-
if (
|
|
2669
|
-
tilmeld.config.userFields.includes('phone') &&
|
|
2670
|
-
group.phone !== this.$data.phone
|
|
2671
|
-
) {
|
|
2672
|
-
group.phone = this.$data.phone;
|
|
2673
|
-
changed = true;
|
|
2674
|
-
}
|
|
2675
|
-
if (changed || group.guid == null) {
|
|
2676
|
-
if (!(await group.$saveSkipAC())) {
|
|
2677
|
-
throw Error('Error updating primary group for user.');
|
|
2554
|
+
if (group != null && group.user != null && this.$is(group.user)) {
|
|
2555
|
+
// Update the user's generated primary group.
|
|
2556
|
+
let changed = false;
|
|
2557
|
+
if (group.groupname !== this.$data.username) {
|
|
2558
|
+
group.groupname = this.$data.username;
|
|
2559
|
+
changed = true;
|
|
2560
|
+
}
|
|
2561
|
+
if (group.avatar !== this.$data.avatar) {
|
|
2562
|
+
group.avatar = this.$data.avatar;
|
|
2563
|
+
changed = true;
|
|
2564
|
+
}
|
|
2565
|
+
if (
|
|
2566
|
+
tilmeld.config.userFields.includes('email') &&
|
|
2567
|
+
group.email !== this.$data.email
|
|
2568
|
+
) {
|
|
2569
|
+
group.email = this.$data.email;
|
|
2570
|
+
changed = true;
|
|
2678
2571
|
}
|
|
2572
|
+
if (
|
|
2573
|
+
tilmeld.config.userFields.includes('name') &&
|
|
2574
|
+
group.name !== this.$data.name
|
|
2575
|
+
) {
|
|
2576
|
+
group.name = this.$data.name;
|
|
2577
|
+
changed = true;
|
|
2578
|
+
}
|
|
2579
|
+
if (
|
|
2580
|
+
tilmeld.config.userFields.includes('phone') &&
|
|
2581
|
+
group.phone !== this.$data.phone
|
|
2582
|
+
) {
|
|
2583
|
+
group.phone = this.$data.phone;
|
|
2584
|
+
changed = true;
|
|
2585
|
+
}
|
|
2586
|
+
if (changed || group.guid == null) {
|
|
2587
|
+
await group.$saveSkipAC();
|
|
2588
|
+
}
|
|
2589
|
+
this.$data.group = group;
|
|
2679
2590
|
}
|
|
2680
|
-
this.$data.group = group;
|
|
2681
|
-
}
|
|
2682
2591
|
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
{
|
|
2704
|
-
type: '&',
|
|
2705
|
-
equal: ['defaultSecondary', true],
|
|
2706
|
-
},
|
|
2707
|
-
);
|
|
2592
|
+
if (this.$data.groups == null || this.$data.groups.length === 0) {
|
|
2593
|
+
// Add secondary groups.
|
|
2594
|
+
if (
|
|
2595
|
+
tilmeld.config.userFields.includes('email') &&
|
|
2596
|
+
tilmeld.config.verifyEmail &&
|
|
2597
|
+
tilmeld.config.unverifiedAccess &&
|
|
2598
|
+
this.$data.secret != null
|
|
2599
|
+
) {
|
|
2600
|
+
// Add the default secondaries for unverified users.
|
|
2601
|
+
this.$data.groups = await this.$nymph.getEntities(
|
|
2602
|
+
{ class: Group },
|
|
2603
|
+
{ type: '&', equal: ['unverifiedSecondary', true] },
|
|
2604
|
+
);
|
|
2605
|
+
} else {
|
|
2606
|
+
// Add the default secondaries.
|
|
2607
|
+
this.$data.groups = await this.$nymph.getEntities(
|
|
2608
|
+
{ class: Group },
|
|
2609
|
+
{ type: '&', equal: ['defaultSecondary', true] },
|
|
2610
|
+
);
|
|
2611
|
+
}
|
|
2708
2612
|
}
|
|
2709
|
-
}
|
|
2710
2613
|
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
} catch (e: any) {
|
|
2717
|
-
await tnymph.rollback(transaction);
|
|
2718
|
-
this.$setNymph(nymph);
|
|
2719
|
-
throw e;
|
|
2720
|
-
}
|
|
2721
|
-
|
|
2722
|
-
let ret = false;
|
|
2723
|
-
let preGuid = this.guid;
|
|
2724
|
-
let preCdate = this.cdate;
|
|
2725
|
-
let preMdate = this.mdate;
|
|
2614
|
+
try {
|
|
2615
|
+
tilmeld.config.validatorUser(tilmeld, this);
|
|
2616
|
+
} catch (e: any) {
|
|
2617
|
+
throw new BadDataError(e?.message);
|
|
2618
|
+
}
|
|
2726
2619
|
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2620
|
+
for (let callback of (this.constructor as typeof User)
|
|
2621
|
+
.beforeSaveCallbacks) {
|
|
2622
|
+
if (callback) {
|
|
2623
|
+
await callback(this);
|
|
2624
|
+
}
|
|
2732
2625
|
}
|
|
2733
|
-
}
|
|
2734
2626
|
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
throw e;
|
|
2743
|
-
}
|
|
2744
|
-
|
|
2745
|
-
if (ret) {
|
|
2746
|
-
if (sendVerification) {
|
|
2747
|
-
// The email has changed, so send a new verification email.
|
|
2748
|
-
if (!(await this.$sendEmailVerification())) {
|
|
2749
|
-
await tnymph.rollback(transaction);
|
|
2750
|
-
this.guid = preGuid;
|
|
2751
|
-
this.cdate = preCdate;
|
|
2752
|
-
this.mdate = preMdate;
|
|
2753
|
-
this.$setNymph(nymph);
|
|
2754
|
-
throw new Error("Couldn't send verification email.");
|
|
2627
|
+
await super.$save();
|
|
2628
|
+
|
|
2629
|
+
if (sendVerification) {
|
|
2630
|
+
// The email has changed, so send a new verification email.
|
|
2631
|
+
if (!(await this.$sendEmailVerification())) {
|
|
2632
|
+
throw new Error("Couldn't send verification email.");
|
|
2633
|
+
}
|
|
2755
2634
|
}
|
|
2756
|
-
}
|
|
2757
2635
|
|
|
2758
|
-
|
|
2759
|
-
|
|
2636
|
+
this.$descendantGroups = undefined;
|
|
2637
|
+
this.$gatekeeperCache = undefined;
|
|
2760
2638
|
|
|
2761
|
-
try {
|
|
2762
2639
|
for (let callback of (this.constructor as typeof User)
|
|
2763
2640
|
.afterSaveCallbacks) {
|
|
2764
2641
|
if (callback) {
|
|
2765
2642
|
await callback(this);
|
|
2766
2643
|
}
|
|
2767
2644
|
}
|
|
2768
|
-
}
|
|
2769
|
-
|
|
2770
|
-
this.guid = preGuid;
|
|
2771
|
-
this.cdate = preCdate;
|
|
2772
|
-
this.mdate = preMdate;
|
|
2645
|
+
},
|
|
2646
|
+
async (nymph, committed) => {
|
|
2773
2647
|
this.$setNymph(nymph);
|
|
2774
|
-
throw e;
|
|
2775
|
-
}
|
|
2776
|
-
|
|
2777
|
-
ret = await tnymph.commit(transaction);
|
|
2778
|
-
} else {
|
|
2779
|
-
await tnymph.rollback(transaction);
|
|
2780
|
-
}
|
|
2781
|
-
this.$setNymph(nymph);
|
|
2782
|
-
|
|
2783
|
-
if (ret) {
|
|
2784
|
-
this.$originalEmail = this.$data.email;
|
|
2785
|
-
this.$originalUsername = this.$data.username;
|
|
2786
2648
|
|
|
2787
|
-
|
|
2649
|
+
if (committed) {
|
|
2650
|
+
this.$originalEmail = this.$data.email;
|
|
2651
|
+
this.$originalUsername = this.$data.username;
|
|
2788
2652
|
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
await tilmeld.fillSession(this);
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
2653
|
+
try {
|
|
2654
|
+
const tilmeld = enforceTilmeld(nymph);
|
|
2794
2655
|
|
|
2795
|
-
|
|
2656
|
+
if (tilmeld.User.current(true).$is(this)) {
|
|
2657
|
+
// Update the user in the session cache.
|
|
2658
|
+
await tilmeld.fillSession(this);
|
|
2659
|
+
}
|
|
2660
|
+
} catch (e: any) {
|
|
2661
|
+
// Ignore.
|
|
2662
|
+
}
|
|
2663
|
+
} else {
|
|
2664
|
+
this.guid = preGuid;
|
|
2665
|
+
this.cdate = preCdate;
|
|
2666
|
+
this.mdate = preMdate;
|
|
2667
|
+
}
|
|
2668
|
+
},
|
|
2669
|
+
);
|
|
2796
2670
|
}
|
|
2797
2671
|
|
|
2798
2672
|
/**
|
|
@@ -2800,7 +2674,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2800
2674
|
*/
|
|
2801
2675
|
public async $saveSkipAC() {
|
|
2802
2676
|
this.$skipAcWhenSaving = true;
|
|
2803
|
-
|
|
2677
|
+
await this.$save();
|
|
2804
2678
|
}
|
|
2805
2679
|
|
|
2806
2680
|
public $tilmeldSaveSkipAC() {
|
|
@@ -2811,6 +2685,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2811
2685
|
return false;
|
|
2812
2686
|
}
|
|
2813
2687
|
|
|
2688
|
+
@transactional
|
|
2814
2689
|
public async $delete() {
|
|
2815
2690
|
const tilmeld = enforceTilmeld(this);
|
|
2816
2691
|
if (!this.$skipAcWhenDeleting && !tilmeld.gatekeeper('tilmeld/admin')) {
|
|
@@ -2833,79 +2708,53 @@ export default class User extends AbleObject<UserData> {
|
|
|
2833
2708
|
);
|
|
2834
2709
|
}
|
|
2835
2710
|
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
this.$setNymph(tnymph);
|
|
2840
|
-
|
|
2841
|
-
let success = false;
|
|
2842
|
-
|
|
2843
|
-
try {
|
|
2844
|
-
if (!(await this.$refresh())) {
|
|
2845
|
-
throw new BadDataError('User could not be refreshed.');
|
|
2846
|
-
}
|
|
2711
|
+
if (!(await this.$refresh())) {
|
|
2712
|
+
throw new BadDataError('User could not be refreshed.');
|
|
2713
|
+
}
|
|
2847
2714
|
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
}
|
|
2715
|
+
if (this.$data.group != null) {
|
|
2716
|
+
if (this.$data.group.$asleep()) {
|
|
2717
|
+
await this.$data.group.$wake();
|
|
2718
|
+
} else {
|
|
2719
|
+
if (!(await this.$data.group.$refresh())) {
|
|
2720
|
+
throw new BadDataError('Group could not be refreshed.');
|
|
2855
2721
|
}
|
|
2856
2722
|
}
|
|
2723
|
+
}
|
|
2857
2724
|
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
}
|
|
2725
|
+
for (let callback of (this.constructor as typeof User)
|
|
2726
|
+
.beforeDeleteCallbacks) {
|
|
2727
|
+
if (callback) {
|
|
2728
|
+
await callback(this);
|
|
2863
2729
|
}
|
|
2730
|
+
}
|
|
2864
2731
|
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2732
|
+
if (tilmeld.User.current(true).$is(this)) {
|
|
2733
|
+
await this.$logout();
|
|
2734
|
+
}
|
|
2868
2735
|
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
? await this.$data.group.$deleteSkipAC()
|
|
2879
|
-
: await this.$data.group.$delete();
|
|
2880
|
-
}
|
|
2736
|
+
if (this.$data.group != null && this.$is(this.$data.group.user)) {
|
|
2737
|
+
// Read the skip ac value here, because super.$delete changes it.
|
|
2738
|
+
const $skipAcWhenDeleting = this.$skipAcWhenDeleting;
|
|
2739
|
+
|
|
2740
|
+
// Delete the user.
|
|
2741
|
+
await super.$delete();
|
|
2742
|
+
// Delete the generated group.
|
|
2743
|
+
if ($skipAcWhenDeleting) {
|
|
2744
|
+
await this.$data.group.$deleteSkipAC();
|
|
2881
2745
|
} else {
|
|
2882
|
-
|
|
2746
|
+
await this.$data.group.$delete();
|
|
2883
2747
|
}
|
|
2884
|
-
}
|
|
2885
|
-
await
|
|
2886
|
-
this.$setNymph(nymph);
|
|
2887
|
-
throw e;
|
|
2748
|
+
} else {
|
|
2749
|
+
await super.$delete();
|
|
2888
2750
|
}
|
|
2889
2751
|
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
if (callback) {
|
|
2895
|
-
await callback(this);
|
|
2896
|
-
}
|
|
2897
|
-
}
|
|
2898
|
-
} catch (e: any) {
|
|
2899
|
-
await tnymph.rollback(transaction);
|
|
2900
|
-
this.$setNymph(nymph);
|
|
2901
|
-
throw e;
|
|
2752
|
+
for (let callback of (this.constructor as typeof User)
|
|
2753
|
+
.afterDeleteCallbacks) {
|
|
2754
|
+
if (callback) {
|
|
2755
|
+
await callback(this);
|
|
2902
2756
|
}
|
|
2903
|
-
success = await tnymph.commit(transaction);
|
|
2904
|
-
} else {
|
|
2905
|
-
await tnymph.rollback(transaction);
|
|
2906
2757
|
}
|
|
2907
|
-
this.$setNymph(nymph);
|
|
2908
|
-
return success;
|
|
2909
2758
|
}
|
|
2910
2759
|
|
|
2911
2760
|
/*
|
|
@@ -2913,7 +2762,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2913
2762
|
*/
|
|
2914
2763
|
async $deleteSkipAC() {
|
|
2915
2764
|
this.$skipAcWhenDeleting = true;
|
|
2916
|
-
|
|
2765
|
+
await this.$delete();
|
|
2917
2766
|
}
|
|
2918
2767
|
|
|
2919
2768
|
$tilmeldDeleteSkipAC() {
|