@nymphjs/tilmeld 1.0.0-beta.17 → 1.0.0-beta.18
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 +13 -0
- package/README.md +13 -0
- package/dist/Group.js +48 -22
- package/dist/Group.js.map +1 -1
- package/dist/Tilmeld.d.ts +3 -0
- package/dist/Tilmeld.js +99 -29
- package/dist/Tilmeld.js.map +1 -1
- package/dist/User.d.ts +8 -0
- package/dist/User.js +128 -42
- package/dist/User.js.map +1 -1
- package/dist/conf/d.d.ts +2 -1
- package/dist/conf/defaults.js +3 -2
- package/dist/conf/defaults.js.map +1 -1
- package/dist/enforceTilmeld.d.ts +3 -0
- package/dist/enforceTilmeld.js +22 -0
- package/dist/enforceTilmeld.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/package.json +7 -7
- package/src/Group.ts +70 -23
- package/src/Tilmeld.ts +139 -42
- package/src/User.ts +191 -42
- package/src/conf/d.ts +10 -1
- package/src/conf/defaults.ts +3 -2
- package/src/enforceTilmeld.ts +20 -0
- package/src/index.ts +2 -0
package/src/User.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { difference } from 'lodash';
|
|
|
14
14
|
import { humanSecret, nanoid } from '@nymphjs/guid';
|
|
15
15
|
|
|
16
16
|
import type Tilmeld from './Tilmeld';
|
|
17
|
+
import { enforceTilmeld } from './enforceTilmeld';
|
|
17
18
|
import AbleObject from './AbleObject';
|
|
18
19
|
import Group, { GroupData } from './Group';
|
|
19
20
|
import {
|
|
@@ -211,23 +212,31 @@ export default class User extends AbleObject<UserData> {
|
|
|
211
212
|
'$register',
|
|
212
213
|
];
|
|
213
214
|
private static DEFAULT_PRIVATE_DATA = [
|
|
215
|
+
// The things that are commented are there to show what is _not_ private.
|
|
216
|
+
'abilities',
|
|
217
|
+
// 'username',
|
|
218
|
+
// 'nameFirst',
|
|
219
|
+
// 'nameMiddle',
|
|
220
|
+
// 'nameLast',
|
|
221
|
+
// 'name',
|
|
214
222
|
'email',
|
|
215
|
-
'
|
|
223
|
+
// 'avatar',
|
|
216
224
|
'phone',
|
|
217
225
|
'group',
|
|
218
226
|
'groups',
|
|
219
|
-
'abilities',
|
|
220
227
|
'inheritAbilities',
|
|
221
|
-
'
|
|
222
|
-
'recoverSecretDate',
|
|
223
|
-
'password',
|
|
224
|
-
'salt',
|
|
228
|
+
'enabled',
|
|
225
229
|
'secret',
|
|
226
|
-
'
|
|
230
|
+
'emailChangeDate',
|
|
227
231
|
'newEmailSecret',
|
|
228
|
-
'
|
|
232
|
+
'newEmailAddress',
|
|
229
233
|
'cancelEmailSecret',
|
|
230
|
-
'
|
|
234
|
+
'cancelEmailAddress',
|
|
235
|
+
'recoverSecret',
|
|
236
|
+
'recoverSecretDate',
|
|
237
|
+
'salt',
|
|
238
|
+
'password',
|
|
239
|
+
'passwordTemp',
|
|
231
240
|
];
|
|
232
241
|
private static DEFAULT_ALLOWLIST_DATA: string[] = [];
|
|
233
242
|
|
|
@@ -512,7 +521,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
512
521
|
password: string;
|
|
513
522
|
additionalData?: { [k: string]: any };
|
|
514
523
|
}) {
|
|
515
|
-
const tilmeld = this
|
|
524
|
+
const tilmeld = enforceTilmeld(this);
|
|
516
525
|
if (this.guid == null) {
|
|
517
526
|
return { result: false, message: 'Incorrect login/password.' };
|
|
518
527
|
}
|
|
@@ -556,12 +565,84 @@ export default class User extends AbleObject<UserData> {
|
|
|
556
565
|
return { result: true, message: 'You are logged in.' };
|
|
557
566
|
}
|
|
558
567
|
|
|
568
|
+
public async $switchUser(data?: { additionalData?: { [k: string]: any } }) {
|
|
569
|
+
const tilmeld = enforceTilmeld(this);
|
|
570
|
+
if (this.guid == null) {
|
|
571
|
+
return { result: false, message: 'Incorrect login/password.' };
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
let user = tilmeld.User.current();
|
|
575
|
+
|
|
576
|
+
if (!user || user.guid == null) {
|
|
577
|
+
return { result: false, message: "You're not logged in." };
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const isCurrentUser = user != null && user.$is(this);
|
|
581
|
+
|
|
582
|
+
if (isCurrentUser) {
|
|
583
|
+
return { result: false, message: "You can't switch to yourself." };
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const toAbilities = this.$data.abilities || [];
|
|
587
|
+
const fromAbilities = user.abilities || [];
|
|
588
|
+
|
|
589
|
+
if (
|
|
590
|
+
fromAbilities.indexOf('tilmeld/switch') === -1 &&
|
|
591
|
+
fromAbilities.indexOf('system/admin') === -1
|
|
592
|
+
) {
|
|
593
|
+
return {
|
|
594
|
+
result: false,
|
|
595
|
+
message: "You don't have permission to switch users.",
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (
|
|
600
|
+
toAbilities.indexOf('system/admin') !== -1 ||
|
|
601
|
+
toAbilities.indexOf('tilmeld/admin') !== -1
|
|
602
|
+
) {
|
|
603
|
+
return { result: false, message: "You can't switch to an admin." };
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
try {
|
|
607
|
+
for (let callback of (this.constructor as typeof User)
|
|
608
|
+
.beforeLoginCallbacks) {
|
|
609
|
+
if (callback) {
|
|
610
|
+
await callback(this, {
|
|
611
|
+
username: this.$data.username || '',
|
|
612
|
+
password: '',
|
|
613
|
+
...(data || {}),
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
} catch (e: any) {
|
|
618
|
+
return {
|
|
619
|
+
result: false,
|
|
620
|
+
message: e.message,
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// Authentication was successful, attempt to login.
|
|
625
|
+
if (!tilmeld.loginSwitch(this, true)) {
|
|
626
|
+
return { result: false, message: 'Incorrect login/password.' };
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
for (let callback of (this.constructor as typeof User)
|
|
630
|
+
.afterLoginCallbacks) {
|
|
631
|
+
if (callback) {
|
|
632
|
+
await callback(this);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Login was successful.
|
|
637
|
+
return { result: true, message: 'You are logged in.' };
|
|
638
|
+
}
|
|
639
|
+
|
|
559
640
|
/**
|
|
560
641
|
* Log a user out of the system.
|
|
561
642
|
* @returns An object with a boolean 'result' entry and a 'message' entry.
|
|
562
643
|
*/
|
|
563
644
|
public async $logout() {
|
|
564
|
-
const tilmeld = this
|
|
645
|
+
const tilmeld = enforceTilmeld(this);
|
|
565
646
|
|
|
566
647
|
try {
|
|
567
648
|
for (let callback of (this.constructor as typeof User)
|
|
@@ -640,18 +721,39 @@ export default class User extends AbleObject<UserData> {
|
|
|
640
721
|
}
|
|
641
722
|
|
|
642
723
|
public $jsonAcceptData(input: EntityJson, allowConflict = false) {
|
|
643
|
-
const tilmeld = this
|
|
724
|
+
const tilmeld = enforceTilmeld(this);
|
|
644
725
|
this.$referenceWake();
|
|
645
726
|
|
|
646
727
|
if (
|
|
647
728
|
'abilities' in input.data &&
|
|
648
|
-
input.data.abilities
|
|
649
|
-
|
|
650
|
-
tilmeld.gatekeeper('tilmeld/admin') &&
|
|
729
|
+
input.data.abilities?.includes('system/admin') !==
|
|
730
|
+
this.$data.abilities?.includes('system/admin') &&
|
|
651
731
|
!tilmeld.gatekeeper('system/admin')
|
|
652
732
|
) {
|
|
653
733
|
throw new BadDataError(
|
|
654
|
-
"You don't have the authority to
|
|
734
|
+
"You don't have the authority to grant or revoke system/admin."
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
if (
|
|
739
|
+
'abilities' in input.data &&
|
|
740
|
+
input.data.abilities?.includes('tilmeld/admin') !==
|
|
741
|
+
this.$data.abilities?.includes('tilmeld/admin') &&
|
|
742
|
+
!tilmeld.gatekeeper('system/admin')
|
|
743
|
+
) {
|
|
744
|
+
throw new BadDataError(
|
|
745
|
+
"You don't have the authority to grant or revoke tilmeld/admin."
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (
|
|
750
|
+
'abilities' in input.data &&
|
|
751
|
+
input.data.abilities?.includes('tilmeld/switch') !==
|
|
752
|
+
this.$data.abilities?.includes('tilmeld/switch') &&
|
|
753
|
+
!tilmeld.gatekeeper('system/admin')
|
|
754
|
+
) {
|
|
755
|
+
throw new BadDataError(
|
|
756
|
+
"You don't have the authority to grant or revoke tilmeld/switch."
|
|
655
757
|
);
|
|
656
758
|
}
|
|
657
759
|
|
|
@@ -660,18 +762,39 @@ export default class User extends AbleObject<UserData> {
|
|
|
660
762
|
}
|
|
661
763
|
|
|
662
764
|
public $jsonAcceptPatch(patch: EntityPatch, allowConflict = false) {
|
|
663
|
-
const tilmeld = this
|
|
765
|
+
const tilmeld = enforceTilmeld(this);
|
|
664
766
|
this.$referenceWake();
|
|
665
767
|
|
|
666
768
|
if (
|
|
667
769
|
'abilities' in patch.set &&
|
|
668
|
-
patch.set.abilities
|
|
669
|
-
|
|
670
|
-
tilmeld.gatekeeper('tilmeld/admin') &&
|
|
770
|
+
patch.set.abilities?.includes('system/admin') !==
|
|
771
|
+
this.$data.abilities?.includes('system/admin') &&
|
|
671
772
|
!tilmeld.gatekeeper('system/admin')
|
|
672
773
|
) {
|
|
673
774
|
throw new BadDataError(
|
|
674
|
-
"You don't have the authority to
|
|
775
|
+
"You don't have the authority to grant or revoke system/admin."
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
if (
|
|
780
|
+
'abilities' in patch.set &&
|
|
781
|
+
patch.set.abilities?.includes('tilmeld/admin') !==
|
|
782
|
+
this.$data.abilities?.includes('tilmeld/admin') &&
|
|
783
|
+
!tilmeld.gatekeeper('system/admin')
|
|
784
|
+
) {
|
|
785
|
+
throw new BadDataError(
|
|
786
|
+
"You don't have the authority to grant or revoke tilmeld/admin."
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
if (
|
|
791
|
+
'abilities' in patch.set &&
|
|
792
|
+
patch.set.abilities?.includes('tilmeld/switch') !==
|
|
793
|
+
this.$data.abilities?.includes('tilmeld/switch') &&
|
|
794
|
+
!tilmeld.gatekeeper('system/admin')
|
|
795
|
+
) {
|
|
796
|
+
throw new BadDataError(
|
|
797
|
+
"You don't have the authority to grant or revoke tilmeld/switch."
|
|
675
798
|
);
|
|
676
799
|
}
|
|
677
800
|
|
|
@@ -690,7 +813,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
690
813
|
* @param givenUser User to update protection for. If undefined, will use the currently logged in user.
|
|
691
814
|
*/
|
|
692
815
|
public $updateDataProtection(givenUser?: User & UserData) {
|
|
693
|
-
const tilmeld = this
|
|
816
|
+
const tilmeld = enforceTilmeld(this);
|
|
694
817
|
let user = givenUser ?? tilmeld.User.current();
|
|
695
818
|
|
|
696
819
|
this.$clientEnabledMethods = [...User.DEFAULT_CLIENT_ENABLED_METHODS];
|
|
@@ -745,17 +868,43 @@ export default class User extends AbleObject<UserData> {
|
|
|
745
868
|
this.$allowlistData.push('phone');
|
|
746
869
|
}
|
|
747
870
|
this.$privateData = [
|
|
871
|
+
// The things that are commented are there to show what is _not_ private.
|
|
872
|
+
// 'abilities',
|
|
873
|
+
// 'username',
|
|
874
|
+
// 'nameFirst',
|
|
875
|
+
// 'nameMiddle',
|
|
876
|
+
// 'nameLast',
|
|
877
|
+
// 'name',
|
|
878
|
+
// 'email',
|
|
879
|
+
// 'avatar',
|
|
880
|
+
// 'phone',
|
|
881
|
+
// 'group',
|
|
882
|
+
// 'groups',
|
|
883
|
+
// 'inheritAbilities',
|
|
884
|
+
'enabled',
|
|
748
885
|
'secret',
|
|
886
|
+
'emailChangeDate',
|
|
749
887
|
'newEmailSecret',
|
|
750
|
-
'
|
|
888
|
+
// 'newEmailAddress',
|
|
751
889
|
'cancelEmailSecret',
|
|
752
|
-
'
|
|
890
|
+
'cancelEmailAddress',
|
|
753
891
|
'recoverSecret',
|
|
754
892
|
'recoverSecretDate',
|
|
755
|
-
'password',
|
|
756
893
|
'salt',
|
|
894
|
+
'password',
|
|
895
|
+
// 'passwordTemp',
|
|
757
896
|
];
|
|
758
897
|
}
|
|
898
|
+
|
|
899
|
+
if (
|
|
900
|
+
user != null &&
|
|
901
|
+
!isCurrentUser &&
|
|
902
|
+
(abilities.indexOf('tilmeld/switch') !== -1 ||
|
|
903
|
+
abilities.indexOf('system/admin') !== -1)
|
|
904
|
+
) {
|
|
905
|
+
// Users with this ability can switch to other users.
|
|
906
|
+
this.$clientEnabledMethods.push('$switchUser');
|
|
907
|
+
}
|
|
759
908
|
}
|
|
760
909
|
|
|
761
910
|
/**
|
|
@@ -773,7 +922,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
773
922
|
* @returns True or false.
|
|
774
923
|
*/
|
|
775
924
|
public $gatekeeper(ability?: string): boolean {
|
|
776
|
-
const tilmeld = this
|
|
925
|
+
const tilmeld = enforceTilmeld(this);
|
|
777
926
|
if (ability == null) {
|
|
778
927
|
return tilmeld.User.current()?.$is(this) ?? false;
|
|
779
928
|
}
|
|
@@ -800,7 +949,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
800
949
|
}
|
|
801
950
|
return (
|
|
802
951
|
(ability in this.$gatekeeperCache && !!this.$gatekeeperCache[ability]) ||
|
|
803
|
-
!!this.$
|
|
952
|
+
!!this.$data.abilities?.includes('system/admin')
|
|
804
953
|
);
|
|
805
954
|
}
|
|
806
955
|
|
|
@@ -817,7 +966,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
817
966
|
* @returns True on success, false on failure.
|
|
818
967
|
*/
|
|
819
968
|
public async $sendEmailVerification() {
|
|
820
|
-
const tilmeld = this
|
|
969
|
+
const tilmeld = enforceTilmeld(this);
|
|
821
970
|
if (this.guid == null) {
|
|
822
971
|
return false;
|
|
823
972
|
}
|
|
@@ -930,7 +1079,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
930
1079
|
* @returns True if the passwords match, otherwise false.
|
|
931
1080
|
*/
|
|
932
1081
|
public $checkPassword(password: string) {
|
|
933
|
-
const tilmeld = this
|
|
1082
|
+
const tilmeld = enforceTilmeld(this);
|
|
934
1083
|
switch (tilmeld.config.pwMethod) {
|
|
935
1084
|
case 'plain':
|
|
936
1085
|
return this.$data.password === password;
|
|
@@ -1041,7 +1190,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1041
1190
|
* @returns The resulting password or hash which is stored in the entity.
|
|
1042
1191
|
*/
|
|
1043
1192
|
public $password(password: string) {
|
|
1044
|
-
const tilmeld = this
|
|
1193
|
+
const tilmeld = enforceTilmeld(this);
|
|
1045
1194
|
switch (tilmeld.config.pwMethod) {
|
|
1046
1195
|
case 'plain':
|
|
1047
1196
|
delete this.$data.salt;
|
|
@@ -1068,7 +1217,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1068
1217
|
* @returns An object with a boolean 'result' entry and a 'message' entry.
|
|
1069
1218
|
*/
|
|
1070
1219
|
public async $checkUsername(): Promise<{ result: boolean; message: string }> {
|
|
1071
|
-
const tilmeld = this
|
|
1220
|
+
const tilmeld = enforceTilmeld(this);
|
|
1072
1221
|
if (!tilmeld.config.emailUsernames) {
|
|
1073
1222
|
if (this.$data.username == null || !this.$data.username.length) {
|
|
1074
1223
|
return { result: false, message: 'Please specify a username.' };
|
|
@@ -1167,7 +1316,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1167
1316
|
* @returns An object with a boolean 'result' entry and a 'message' entry.
|
|
1168
1317
|
*/
|
|
1169
1318
|
public async $checkEmail(): Promise<{ result: boolean; message: string }> {
|
|
1170
|
-
const tilmeld = this
|
|
1319
|
+
const tilmeld = enforceTilmeld(this);
|
|
1171
1320
|
if (this.$data.email == null || !this.$data.email.length) {
|
|
1172
1321
|
if (tilmeld.config.verifyEmail) {
|
|
1173
1322
|
return { result: false, message: 'Please specify an email.' };
|
|
@@ -1212,7 +1361,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1212
1361
|
* @returns An object with a boolean 'result' entry and a 'message' entry.
|
|
1213
1362
|
*/
|
|
1214
1363
|
public async $checkPhone(): Promise<{ result: boolean; message: string }> {
|
|
1215
|
-
const tilmeld = this
|
|
1364
|
+
const tilmeld = enforceTilmeld(this);
|
|
1216
1365
|
if (this.$data.phone == null || !this.$data.phone.length) {
|
|
1217
1366
|
return { result: false, message: 'Please specify a phone number.' };
|
|
1218
1367
|
}
|
|
@@ -1251,7 +1400,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1251
1400
|
password: string;
|
|
1252
1401
|
additionalData?: { [k: string]: any };
|
|
1253
1402
|
}): Promise<{ result: boolean; loggedin: boolean; message: string }> {
|
|
1254
|
-
let tilmeld = this
|
|
1403
|
+
let tilmeld = enforceTilmeld(this);
|
|
1255
1404
|
if (!tilmeld.config.allowRegistration) {
|
|
1256
1405
|
return {
|
|
1257
1406
|
result: false,
|
|
@@ -1313,7 +1462,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1313
1462
|
const nymph = this.$nymph;
|
|
1314
1463
|
const tnymph = await this.$nymph.startTransaction(transaction);
|
|
1315
1464
|
this.$nymph = tnymph;
|
|
1316
|
-
tilmeld = this
|
|
1465
|
+
tilmeld = enforceTilmeld(this);
|
|
1317
1466
|
|
|
1318
1467
|
try {
|
|
1319
1468
|
// Add primary group.
|
|
@@ -1518,7 +1667,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1518
1667
|
}
|
|
1519
1668
|
|
|
1520
1669
|
public async $save() {
|
|
1521
|
-
let tilmeld = this
|
|
1670
|
+
let tilmeld = enforceTilmeld(this);
|
|
1522
1671
|
if (this.$data.username == null || !this.$data.username.trim().length) {
|
|
1523
1672
|
return false;
|
|
1524
1673
|
}
|
|
@@ -1526,7 +1675,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1526
1675
|
if (
|
|
1527
1676
|
tilmeld.gatekeeper('tilmeld/admin') &&
|
|
1528
1677
|
!tilmeld.gatekeeper('system/admin') &&
|
|
1529
|
-
this.$
|
|
1678
|
+
this.$data.abilities?.includes('system/admin')
|
|
1530
1679
|
) {
|
|
1531
1680
|
throw new BadDataError(
|
|
1532
1681
|
"You don't have the authority to modify system admins."
|
|
@@ -1716,7 +1865,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
1716
1865
|
const nymph = this.$nymph;
|
|
1717
1866
|
const tnymph = await this.$nymph.startTransaction(transaction);
|
|
1718
1867
|
this.$nymph = tnymph;
|
|
1719
|
-
tilmeld = this
|
|
1868
|
+
tilmeld = enforceTilmeld(this);
|
|
1720
1869
|
|
|
1721
1870
|
if (
|
|
1722
1871
|
this.$data.group != null &&
|
|
@@ -1767,9 +1916,9 @@ export default class User extends AbleObject<UserData> {
|
|
|
1767
1916
|
this.$gatekeeperCache = undefined;
|
|
1768
1917
|
await tnymph.commit(transaction);
|
|
1769
1918
|
|
|
1770
|
-
if ((nymph
|
|
1919
|
+
if (enforceTilmeld(nymph).User.current(true).$is(this)) {
|
|
1771
1920
|
// Update the user in the session cache.
|
|
1772
|
-
(nymph
|
|
1921
|
+
enforceTilmeld(nymph).fillSession(this);
|
|
1773
1922
|
}
|
|
1774
1923
|
} else {
|
|
1775
1924
|
await tnymph.rollback(transaction);
|
|
@@ -1795,13 +1944,13 @@ export default class User extends AbleObject<UserData> {
|
|
|
1795
1944
|
}
|
|
1796
1945
|
|
|
1797
1946
|
public async $delete() {
|
|
1798
|
-
const tilmeld = this
|
|
1947
|
+
const tilmeld = enforceTilmeld(this);
|
|
1799
1948
|
if (!tilmeld.gatekeeper('tilmeld/admin')) {
|
|
1800
1949
|
throw new BadDataError("You don't have the authority to delete users.");
|
|
1801
1950
|
}
|
|
1802
1951
|
if (
|
|
1803
1952
|
!tilmeld.gatekeeper('system/admin') &&
|
|
1804
|
-
this.$
|
|
1953
|
+
this.$data.abilities?.includes('system/admin')
|
|
1805
1954
|
) {
|
|
1806
1955
|
throw new BadDataError(
|
|
1807
1956
|
"You don't have the authority to delete system admins."
|
package/src/conf/d.ts
CHANGED
|
@@ -217,6 +217,11 @@ export interface Config {
|
|
|
217
217
|
* How long from current time, in seconds, the JWT token expires.
|
|
218
218
|
*/
|
|
219
219
|
jwtExpire: number;
|
|
220
|
+
/**
|
|
221
|
+
* How long from current time, in seconds, the JWT token for a user switch
|
|
222
|
+
* expires.
|
|
223
|
+
*/
|
|
224
|
+
jwtSwitchExpire: number;
|
|
220
225
|
/**
|
|
221
226
|
* How long, in seconds, before the JWT token expires to give the user a new
|
|
222
227
|
* one.
|
|
@@ -225,7 +230,11 @@ export interface Config {
|
|
|
225
230
|
/**
|
|
226
231
|
* Function to build the JWT for user sessions.
|
|
227
232
|
*/
|
|
228
|
-
jwtBuilder: (
|
|
233
|
+
jwtBuilder: (
|
|
234
|
+
config: Config,
|
|
235
|
+
user: User & UserData,
|
|
236
|
+
switchToken?: boolean
|
|
237
|
+
) => string;
|
|
229
238
|
/**
|
|
230
239
|
* Function to verify that a JWT was signed with the secret key, vaildate its
|
|
231
240
|
* data, validate the XSRF token, and extract the GUID.
|
package/src/conf/defaults.ts
CHANGED
|
@@ -52,8 +52,9 @@ export default {
|
|
|
52
52
|
maxUsernameLength: 128,
|
|
53
53
|
jwtSecret: '',
|
|
54
54
|
jwtExpire: 60 * 60 * 24 * 7 * 8, // 8 weeks(ish)
|
|
55
|
+
jwtSwitchExpire: 60 * 60 * 6, // 6 hours
|
|
55
56
|
jwtRenew: 60 * 60 * 24 * 7 * 2, // 2 weeks(ish)
|
|
56
|
-
jwtBuilder: (config, user) => {
|
|
57
|
+
jwtBuilder: (config, user, switchToken) => {
|
|
57
58
|
const secret = config.jwtSecret;
|
|
58
59
|
if (secret === '') {
|
|
59
60
|
throw new Error('JWT secret is not configured.');
|
|
@@ -67,7 +68,7 @@ export default {
|
|
|
67
68
|
xsrfToken: 'TILMELDXSRF-' + nanoid(),
|
|
68
69
|
},
|
|
69
70
|
secret,
|
|
70
|
-
{ expiresIn: config.jwtExpire }
|
|
71
|
+
{ expiresIn: switchToken ? config.jwtSwitchExpire : config.jwtExpire }
|
|
71
72
|
);
|
|
72
73
|
},
|
|
73
74
|
jwtExtract: (config, token, xsrfToken?) => {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Entity, EntityConstructor, Nymph } from '@nymphjs/nymph';
|
|
2
|
+
|
|
3
|
+
import Tilmeld from './Tilmeld';
|
|
4
|
+
|
|
5
|
+
export function enforceTilmeld(object: Nymph | Entity | EntityConstructor) {
|
|
6
|
+
let tilmeld: Tilmeld | undefined;
|
|
7
|
+
if (object instanceof Entity) {
|
|
8
|
+
tilmeld = object.$nymph.tilmeld as Tilmeld | undefined;
|
|
9
|
+
} else if (object instanceof Nymph) {
|
|
10
|
+
tilmeld = object.tilmeld as Tilmeld | undefined;
|
|
11
|
+
} else {
|
|
12
|
+
tilmeld = object.nymph.tilmeld as Tilmeld | undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (tilmeld == null) {
|
|
16
|
+
throw new Error('Tilmeld was not configured on this Nymph instance!');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return tilmeld;
|
|
20
|
+
}
|