@nymphjs/tilmeld 1.0.0-beta.121 → 1.0.0-beta.122
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 +12 -0
- package/README.md +6 -3
- package/dist/Group.d.ts +5 -6
- package/dist/Group.js +83 -50
- package/dist/Group.js.map +1 -1
- package/dist/Group.testArtifacts.js +3 -3
- package/dist/Group.testArtifacts.js.map +1 -1
- package/dist/User.d.ts +5 -6
- package/dist/User.js +86 -84
- 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 +93 -68
- package/src/User.testArtifacts.ts +7 -7
- package/src/User.ts +97 -95
- 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
|
@@ -95,7 +95,7 @@ export function UserTest(
|
|
|
95
95
|
expect(e).toBeInstanceOf(EntityUniqueConstraintError);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
await newUserA.$deleteSkipAC();
|
|
99
99
|
|
|
100
100
|
tilmeld.config.generatePrimary = true;
|
|
101
101
|
});
|
|
@@ -139,7 +139,7 @@ export function UserTest(
|
|
|
139
139
|
expect(e).toBeInstanceOf(EntityUniqueConstraintError);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
await newUserA.$deleteSkipAC();
|
|
143
143
|
|
|
144
144
|
tilmeld.config.generatePrimary = true;
|
|
145
145
|
});
|
|
@@ -155,7 +155,7 @@ export function UserTest(
|
|
|
155
155
|
domainAdmin.$password('password');
|
|
156
156
|
domainAdmin.$grant('tilmeld/domain/example.com/admin');
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
await domainAdmin.$saveSkipAC();
|
|
159
159
|
|
|
160
160
|
// Log in the domain admin.
|
|
161
161
|
await tilmeld.fillSession(domainAdmin);
|
|
@@ -169,13 +169,13 @@ export function UserTest(
|
|
|
169
169
|
domainUser.name = 'New User';
|
|
170
170
|
domainUser.$password('password');
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
await domainUser.$save();
|
|
173
173
|
|
|
174
174
|
tilmeld.clearSession();
|
|
175
175
|
|
|
176
176
|
for (const user of [domainAdmin, domainUser]) {
|
|
177
177
|
if (user.guid != null) {
|
|
178
|
-
|
|
178
|
+
await user.$deleteSkipAC();
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
});
|
|
@@ -191,7 +191,7 @@ export function UserTest(
|
|
|
191
191
|
domainAdmin.$password('password');
|
|
192
192
|
domainAdmin.$grant('tilmeld/domain/example.com/admin');
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
await domainAdmin.$saveSkipAC();
|
|
195
195
|
|
|
196
196
|
// Log in the domain admin.
|
|
197
197
|
await tilmeld.fillSession(domainAdmin);
|
|
@@ -218,7 +218,7 @@ export function UserTest(
|
|
|
218
218
|
|
|
219
219
|
for (const user of [domainAdmin, domainUser]) {
|
|
220
220
|
if (user.guid != null) {
|
|
221
|
-
|
|
221
|
+
await user.$deleteSkipAC();
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
});
|
package/src/User.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
-
import
|
|
3
|
-
Nymph,
|
|
4
|
-
EntityData,
|
|
5
|
-
EntityJson,
|
|
6
|
-
EntityPatch,
|
|
7
|
-
Selector,
|
|
8
|
-
SerializedEntityData,
|
|
2
|
+
import {
|
|
3
|
+
type Nymph,
|
|
4
|
+
type EntityData,
|
|
5
|
+
type EntityJson,
|
|
6
|
+
type EntityPatch,
|
|
7
|
+
type Selector,
|
|
8
|
+
type SerializedEntityData,
|
|
9
|
+
MethodFailedError,
|
|
10
|
+
HttpError,
|
|
9
11
|
} from '@nymphjs/nymph';
|
|
10
12
|
import { humanSecret, nanoid } from '@nymphjs/guid';
|
|
11
13
|
import type { EmailOptions } from 'email-templates';
|
|
@@ -465,7 +467,9 @@ export default class User extends AbleObject<UserData> {
|
|
|
465
467
|
// Create a unique secret.
|
|
466
468
|
getUser.recoverSecret = humanSecret();
|
|
467
469
|
getUser.recoverSecretDate = Date.now();
|
|
468
|
-
|
|
470
|
+
try {
|
|
471
|
+
await getUser.$saveSkipAC();
|
|
472
|
+
} catch (e: any) {
|
|
469
473
|
return { result: false, message: "Couldn't save recovery secret." };
|
|
470
474
|
}
|
|
471
475
|
|
|
@@ -554,13 +558,14 @@ export default class User extends AbleObject<UserData> {
|
|
|
554
558
|
user.$password(data.password);
|
|
555
559
|
delete user.recoverSecret;
|
|
556
560
|
delete user.recoverSecretDate;
|
|
557
|
-
|
|
561
|
+
try {
|
|
562
|
+
await user.$saveSkipAC();
|
|
558
563
|
return {
|
|
559
564
|
result: true,
|
|
560
565
|
message:
|
|
561
566
|
'Your password has been reset. You can now log in using your new password.',
|
|
562
567
|
};
|
|
563
|
-
}
|
|
568
|
+
} catch (e: any) {
|
|
564
569
|
return { result: false, message: 'Error saving new password.' };
|
|
565
570
|
}
|
|
566
571
|
}
|
|
@@ -675,20 +680,6 @@ export default class User extends AbleObject<UserData> {
|
|
|
675
680
|
this.$updateDataProtection();
|
|
676
681
|
}
|
|
677
682
|
|
|
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
683
|
async $getUniques(): Promise<string[]> {
|
|
693
684
|
const tilmeld = enforceTilmeld(this);
|
|
694
685
|
const uniques = [`u:${this.$data.username}`];
|
|
@@ -1581,13 +1572,14 @@ export default class User extends AbleObject<UserData> {
|
|
|
1581
1572
|
if (data.revokeCurrentTokens) {
|
|
1582
1573
|
this.$data.revokeTokenDate = Date.now();
|
|
1583
1574
|
}
|
|
1584
|
-
|
|
1575
|
+
try {
|
|
1576
|
+
await this.$save();
|
|
1585
1577
|
if (data.revokeCurrentTokens) {
|
|
1586
1578
|
const tilmeld = enforceTilmeld(this);
|
|
1587
1579
|
await tilmeld.login(this, true);
|
|
1588
1580
|
}
|
|
1589
1581
|
return { result: true, message: 'Your password has been changed.' };
|
|
1590
|
-
}
|
|
1582
|
+
} catch (e: any) {
|
|
1591
1583
|
return { result: false, message: "Couldn't save new password." };
|
|
1592
1584
|
}
|
|
1593
1585
|
}
|
|
@@ -1639,14 +1631,15 @@ export default class User extends AbleObject<UserData> {
|
|
|
1639
1631
|
|
|
1640
1632
|
this.$data.revokeTokenDate = Date.now();
|
|
1641
1633
|
|
|
1642
|
-
|
|
1634
|
+
try {
|
|
1635
|
+
await this.$save();
|
|
1643
1636
|
const tilmeld = enforceTilmeld(this);
|
|
1644
1637
|
await tilmeld.login(this, true);
|
|
1645
1638
|
return {
|
|
1646
1639
|
result: true,
|
|
1647
1640
|
message: 'You have logged out of all other sessions.',
|
|
1648
1641
|
};
|
|
1649
|
-
}
|
|
1642
|
+
} catch (e: any) {
|
|
1650
1643
|
return { result: false, message: "Couldn't save revocation date." };
|
|
1651
1644
|
}
|
|
1652
1645
|
}
|
|
@@ -1766,9 +1759,10 @@ export default class User extends AbleObject<UserData> {
|
|
|
1766
1759
|
|
|
1767
1760
|
this.$data.totpSecret = data.secret;
|
|
1768
1761
|
|
|
1769
|
-
|
|
1762
|
+
try {
|
|
1763
|
+
await this.$save();
|
|
1770
1764
|
return { result: true, message: 'Your two factor secret is now set.' };
|
|
1771
|
-
}
|
|
1765
|
+
} catch (e: any) {
|
|
1772
1766
|
return { result: false, message: "Couldn't save two factor secret." };
|
|
1773
1767
|
}
|
|
1774
1768
|
}
|
|
@@ -1824,12 +1818,13 @@ export default class User extends AbleObject<UserData> {
|
|
|
1824
1818
|
|
|
1825
1819
|
delete this.$data.totpSecret;
|
|
1826
1820
|
|
|
1827
|
-
|
|
1821
|
+
try {
|
|
1822
|
+
await this.$save();
|
|
1828
1823
|
return {
|
|
1829
1824
|
result: true,
|
|
1830
1825
|
message: 'Two factor secret has been removed.',
|
|
1831
1826
|
};
|
|
1832
|
-
}
|
|
1827
|
+
} catch (e: any) {
|
|
1833
1828
|
return { result: false, message: "Couldn't remove two factor secret." };
|
|
1834
1829
|
}
|
|
1835
1830
|
}
|
|
@@ -2198,7 +2193,8 @@ export default class User extends AbleObject<UserData> {
|
|
|
2198
2193
|
'tilmeld',
|
|
2199
2194
|
`Registering new user "${this.$data.username}".`,
|
|
2200
2195
|
);
|
|
2201
|
-
|
|
2196
|
+
try {
|
|
2197
|
+
await this.$saveSkipAC();
|
|
2202
2198
|
this.$nymph.config.debugLog(
|
|
2203
2199
|
'tilmeld',
|
|
2204
2200
|
`New user registered "${this.$data.username}".`,
|
|
@@ -2266,7 +2262,10 @@ export default class User extends AbleObject<UserData> {
|
|
|
2266
2262
|
});
|
|
2267
2263
|
}
|
|
2268
2264
|
}
|
|
2269
|
-
}
|
|
2265
|
+
} catch (e: any) {
|
|
2266
|
+
if (e instanceof HttpError) {
|
|
2267
|
+
throw e;
|
|
2268
|
+
}
|
|
2270
2269
|
this.$nymph.config.debugError(
|
|
2271
2270
|
'tilmeld',
|
|
2272
2271
|
`Error registering new user "${this.$data.username}".`,
|
|
@@ -2307,7 +2306,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2307
2306
|
public async $save() {
|
|
2308
2307
|
let tilmeld = enforceTilmeld(this);
|
|
2309
2308
|
if (this.$data.username == null || !this.$data.username.trim().length) {
|
|
2310
|
-
|
|
2309
|
+
throw new BadUsernameError('Username must not be empty.');
|
|
2311
2310
|
}
|
|
2312
2311
|
|
|
2313
2312
|
if (
|
|
@@ -2673,9 +2672,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2673
2672
|
changed = true;
|
|
2674
2673
|
}
|
|
2675
2674
|
if (changed || group.guid == null) {
|
|
2676
|
-
|
|
2677
|
-
throw Error('Error updating primary group for user.');
|
|
2678
|
-
}
|
|
2675
|
+
await group.$saveSkipAC();
|
|
2679
2676
|
}
|
|
2680
2677
|
this.$data.group = group;
|
|
2681
2678
|
}
|
|
@@ -2719,7 +2716,6 @@ export default class User extends AbleObject<UserData> {
|
|
|
2719
2716
|
throw e;
|
|
2720
2717
|
}
|
|
2721
2718
|
|
|
2722
|
-
let ret = false;
|
|
2723
2719
|
let preGuid = this.guid;
|
|
2724
2720
|
let preCdate = this.cdate;
|
|
2725
2721
|
let preMdate = this.mdate;
|
|
@@ -2732,7 +2728,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2732
2728
|
}
|
|
2733
2729
|
}
|
|
2734
2730
|
|
|
2735
|
-
|
|
2731
|
+
await super.$save();
|
|
2736
2732
|
} catch (e: any) {
|
|
2737
2733
|
await tnymph.rollback(transaction);
|
|
2738
2734
|
this.guid = preGuid;
|
|
@@ -2742,45 +2738,41 @@ export default class User extends AbleObject<UserData> {
|
|
|
2742
2738
|
throw e;
|
|
2743
2739
|
}
|
|
2744
2740
|
|
|
2745
|
-
if (
|
|
2746
|
-
|
|
2747
|
-
|
|
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.");
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
|
|
2758
|
-
this.$descendantGroups = undefined;
|
|
2759
|
-
this.$gatekeeperCache = undefined;
|
|
2760
|
-
|
|
2761
|
-
try {
|
|
2762
|
-
for (let callback of (this.constructor as typeof User)
|
|
2763
|
-
.afterSaveCallbacks) {
|
|
2764
|
-
if (callback) {
|
|
2765
|
-
await callback(this);
|
|
2766
|
-
}
|
|
2767
|
-
}
|
|
2768
|
-
} catch (e: any) {
|
|
2741
|
+
if (sendVerification) {
|
|
2742
|
+
// The email has changed, so send a new verification email.
|
|
2743
|
+
if (!(await this.$sendEmailVerification())) {
|
|
2769
2744
|
await tnymph.rollback(transaction);
|
|
2770
2745
|
this.guid = preGuid;
|
|
2771
2746
|
this.cdate = preCdate;
|
|
2772
2747
|
this.mdate = preMdate;
|
|
2773
2748
|
this.$setNymph(nymph);
|
|
2774
|
-
throw
|
|
2749
|
+
throw new Error("Couldn't send verification email.");
|
|
2775
2750
|
}
|
|
2751
|
+
}
|
|
2776
2752
|
|
|
2777
|
-
|
|
2778
|
-
|
|
2753
|
+
this.$descendantGroups = undefined;
|
|
2754
|
+
this.$gatekeeperCache = undefined;
|
|
2755
|
+
|
|
2756
|
+
try {
|
|
2757
|
+
for (let callback of (this.constructor as typeof User)
|
|
2758
|
+
.afterSaveCallbacks) {
|
|
2759
|
+
if (callback) {
|
|
2760
|
+
await callback(this);
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
} catch (e: any) {
|
|
2779
2764
|
await tnymph.rollback(transaction);
|
|
2765
|
+
this.guid = preGuid;
|
|
2766
|
+
this.cdate = preCdate;
|
|
2767
|
+
this.mdate = preMdate;
|
|
2768
|
+
this.$setNymph(nymph);
|
|
2769
|
+
throw e;
|
|
2780
2770
|
}
|
|
2771
|
+
|
|
2772
|
+
const committed = await tnymph.commit(transaction);
|
|
2781
2773
|
this.$setNymph(nymph);
|
|
2782
2774
|
|
|
2783
|
-
if (
|
|
2775
|
+
if (committed) {
|
|
2784
2776
|
this.$originalEmail = this.$data.email;
|
|
2785
2777
|
this.$originalUsername = this.$data.username;
|
|
2786
2778
|
|
|
@@ -2790,9 +2782,9 @@ export default class User extends AbleObject<UserData> {
|
|
|
2790
2782
|
// Update the user in the session cache.
|
|
2791
2783
|
await tilmeld.fillSession(this);
|
|
2792
2784
|
}
|
|
2785
|
+
} else {
|
|
2786
|
+
throw new MethodFailedError('Transaction could not be committed.');
|
|
2793
2787
|
}
|
|
2794
|
-
|
|
2795
|
-
return ret;
|
|
2796
2788
|
}
|
|
2797
2789
|
|
|
2798
2790
|
/**
|
|
@@ -2800,7 +2792,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2800
2792
|
*/
|
|
2801
2793
|
public async $saveSkipAC() {
|
|
2802
2794
|
this.$skipAcWhenSaving = true;
|
|
2803
|
-
|
|
2795
|
+
await this.$save();
|
|
2804
2796
|
}
|
|
2805
2797
|
|
|
2806
2798
|
public $tilmeldSaveSkipAC() {
|
|
@@ -2838,8 +2830,6 @@ export default class User extends AbleObject<UserData> {
|
|
|
2838
2830
|
const tnymph = await nymph.startTransaction(transaction);
|
|
2839
2831
|
this.$setNymph(tnymph);
|
|
2840
2832
|
|
|
2841
|
-
let success = false;
|
|
2842
|
-
|
|
2843
2833
|
try {
|
|
2844
2834
|
if (!(await this.$refresh())) {
|
|
2845
2835
|
throw new BadDataError('User could not be refreshed.');
|
|
@@ -2871,15 +2861,15 @@ export default class User extends AbleObject<UserData> {
|
|
|
2871
2861
|
const $skipAcWhenDeleting = this.$skipAcWhenDeleting;
|
|
2872
2862
|
|
|
2873
2863
|
// Delete the user.
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2864
|
+
await super.$delete();
|
|
2865
|
+
// Delete the generated group.
|
|
2866
|
+
if ($skipAcWhenDeleting) {
|
|
2867
|
+
await this.$data.group.$deleteSkipAC();
|
|
2868
|
+
} else {
|
|
2869
|
+
await this.$data.group.$delete();
|
|
2880
2870
|
}
|
|
2881
2871
|
} else {
|
|
2882
|
-
|
|
2872
|
+
await super.$delete();
|
|
2883
2873
|
}
|
|
2884
2874
|
} catch (e: any) {
|
|
2885
2875
|
await tnymph.rollback(transaction);
|
|
@@ -2887,25 +2877,37 @@ export default class User extends AbleObject<UserData> {
|
|
|
2887
2877
|
throw e;
|
|
2888
2878
|
}
|
|
2889
2879
|
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
await callback(this);
|
|
2896
|
-
}
|
|
2880
|
+
try {
|
|
2881
|
+
for (let callback of (this.constructor as typeof User)
|
|
2882
|
+
.afterDeleteCallbacks) {
|
|
2883
|
+
if (callback) {
|
|
2884
|
+
await callback(this);
|
|
2897
2885
|
}
|
|
2898
|
-
}
|
|
2886
|
+
}
|
|
2887
|
+
} catch (e: any) {
|
|
2888
|
+
try {
|
|
2899
2889
|
await tnymph.rollback(transaction);
|
|
2900
|
-
|
|
2901
|
-
|
|
2890
|
+
} catch (e: any) {
|
|
2891
|
+
nymph.config.debugError(
|
|
2892
|
+
'tilmeld',
|
|
2893
|
+
`Rollback of transaction ${transaction} failed, reason: ${e.message}`,
|
|
2894
|
+
);
|
|
2902
2895
|
}
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2896
|
+
this.$setNymph(nymph);
|
|
2897
|
+
throw e;
|
|
2898
|
+
}
|
|
2899
|
+
|
|
2900
|
+
let committed = false;
|
|
2901
|
+
try {
|
|
2902
|
+
committed = await tnymph.commit(transaction);
|
|
2903
|
+
} catch (e: any) {
|
|
2904
|
+
committed = false;
|
|
2906
2905
|
}
|
|
2907
2906
|
this.$setNymph(nymph);
|
|
2908
|
-
|
|
2907
|
+
|
|
2908
|
+
if (!committed) {
|
|
2909
|
+
throw new MethodFailedError('Transaction could not be committed.');
|
|
2910
|
+
}
|
|
2909
2911
|
}
|
|
2910
2912
|
|
|
2911
2913
|
/*
|
|
@@ -2913,7 +2915,7 @@ export default class User extends AbleObject<UserData> {
|
|
|
2913
2915
|
*/
|
|
2914
2916
|
async $deleteSkipAC() {
|
|
2915
2917
|
this.$skipAcWhenDeleting = true;
|
|
2916
|
-
|
|
2918
|
+
await this.$delete();
|
|
2917
2919
|
}
|
|
2918
2920
|
|
|
2919
2921
|
$tilmeldDeleteSkipAC() {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Entity, HttpError } from '@nymphjs/nymph';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A decorator that checks for an ability before running the method.
|
|
5
|
+
*
|
|
6
|
+
* If the logged in user does not have the given ability, the decorator will
|
|
7
|
+
* cause the method to throw a 403 Forbidden HttpError.
|
|
8
|
+
*
|
|
9
|
+
* @param ability The ability to check for.
|
|
10
|
+
*/
|
|
11
|
+
export function requireAbility(ability: string) {
|
|
12
|
+
return function (
|
|
13
|
+
target: (...args: any[]) => any,
|
|
14
|
+
_context: ClassMethodDecoratorContext,
|
|
15
|
+
) {
|
|
16
|
+
return function (this: Entity, ...args: unknown[]) {
|
|
17
|
+
if (
|
|
18
|
+
this.$nymph.tilmeld == null ||
|
|
19
|
+
!this.$nymph.tilmeld.gatekeeper(ability)
|
|
20
|
+
) {
|
|
21
|
+
throw new HttpError('Forbidden', 403);
|
|
22
|
+
}
|
|
23
|
+
return target.apply(this, args);
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Entity, HttpError } from '@nymphjs/nymph';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A decorator that checks for authentication before running the method.
|
|
5
|
+
*
|
|
6
|
+
* If the user is not logged in, the decorator will cause the method to throw a
|
|
7
|
+
* 403 Forbidden HttpError.
|
|
8
|
+
*/
|
|
9
|
+
export function requireAuthentication(
|
|
10
|
+
target: (...args: any[]) => any,
|
|
11
|
+
_context: ClassMethodDecoratorContext,
|
|
12
|
+
) {
|
|
13
|
+
return function (this: Entity, ...args: unknown[]) {
|
|
14
|
+
if (this.$nymph.tilmeld == null || !this.$nymph.tilmeld.gatekeeper()) {
|
|
15
|
+
throw new HttpError('Forbidden', 403);
|
|
16
|
+
}
|
|
17
|
+
return target.apply(this, args);
|
|
18
|
+
};
|
|
19
|
+
}
|