@nymphjs/tilmeld 1.0.0-beta.61 → 1.0.0-beta.63
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 +20 -0
- package/dist/Group.d.ts +13 -4
- package/dist/Group.js +94 -45
- package/dist/Group.js.map +1 -1
- package/dist/Group.test.js +74 -0
- package/dist/Group.test.js.map +1 -1
- package/dist/Tilmeld.js +47 -43
- package/dist/Tilmeld.js.map +1 -1
- package/dist/User.d.ts +13 -4
- package/dist/User.js +250 -177
- package/dist/User.js.map +1 -1
- package/dist/User.test.js +60 -0
- package/dist/User.test.js.map +1 -1
- package/package.json +8 -8
- package/src/Group.test.ts +99 -1
- package/src/Group.ts +86 -21
- package/src/User.test.ts +77 -1
- package/src/User.ts +201 -132
- package/tsconfig.json +2 -2
package/dist/User.js
CHANGED
|
@@ -24,6 +24,94 @@ const errors_1 = require("./errors");
|
|
|
24
24
|
* @see http://nymph.io/
|
|
25
25
|
*/
|
|
26
26
|
class User extends AbleObject_1.default {
|
|
27
|
+
/**
|
|
28
|
+
* The instance of Tilmeld to use for queries.
|
|
29
|
+
*/
|
|
30
|
+
static ETYPE = 'tilmeld_user';
|
|
31
|
+
static class = 'User';
|
|
32
|
+
static checkUsernameCallbacks = [];
|
|
33
|
+
static beforeRegisterCallbacks = [];
|
|
34
|
+
static afterRegisterCallbacks = [];
|
|
35
|
+
static beforeLoginCallbacks = [];
|
|
36
|
+
static afterLoginCallbacks = [];
|
|
37
|
+
static beforeLogoutCallbacks = [];
|
|
38
|
+
static afterLogoutCallbacks = [];
|
|
39
|
+
static DEFAULT_CLIENT_ENABLED_METHODS = [
|
|
40
|
+
'$checkUsername',
|
|
41
|
+
'$checkEmail',
|
|
42
|
+
'$checkPhone',
|
|
43
|
+
'$getAvatar',
|
|
44
|
+
'$register',
|
|
45
|
+
];
|
|
46
|
+
static DEFAULT_PRIVATE_DATA = [
|
|
47
|
+
// The things that are commented are there to show what is _not_ private.
|
|
48
|
+
'abilities',
|
|
49
|
+
// 'username',
|
|
50
|
+
// 'nameFirst',
|
|
51
|
+
// 'nameMiddle',
|
|
52
|
+
// 'nameLast',
|
|
53
|
+
// 'name',
|
|
54
|
+
'email',
|
|
55
|
+
// 'avatar',
|
|
56
|
+
'phone',
|
|
57
|
+
'group',
|
|
58
|
+
'groups',
|
|
59
|
+
'inheritAbilities',
|
|
60
|
+
'enabled',
|
|
61
|
+
'secret',
|
|
62
|
+
'emailChangeDate',
|
|
63
|
+
'newEmailSecret',
|
|
64
|
+
'newEmailAddress',
|
|
65
|
+
'cancelEmailSecret',
|
|
66
|
+
'cancelEmailAddress',
|
|
67
|
+
'recoverSecret',
|
|
68
|
+
'recoverSecretDate',
|
|
69
|
+
'salt',
|
|
70
|
+
'password',
|
|
71
|
+
'passwordTemp',
|
|
72
|
+
'revokeTokenDate',
|
|
73
|
+
'totpSecret',
|
|
74
|
+
];
|
|
75
|
+
static DEFAULT_ALLOWLIST_DATA = [];
|
|
76
|
+
$clientEnabledMethods = [...User.DEFAULT_CLIENT_ENABLED_METHODS];
|
|
77
|
+
static clientEnabledStaticMethods = [
|
|
78
|
+
'current',
|
|
79
|
+
'loginUser',
|
|
80
|
+
'sendRecovery',
|
|
81
|
+
'recover',
|
|
82
|
+
'getClientConfig',
|
|
83
|
+
];
|
|
84
|
+
$privateData = [...User.DEFAULT_PRIVATE_DATA];
|
|
85
|
+
static searchRestrictedData = [...User.DEFAULT_PRIVATE_DATA];
|
|
86
|
+
$allowlistData = [...User.DEFAULT_ALLOWLIST_DATA];
|
|
87
|
+
$allowlistTags = [];
|
|
88
|
+
/**
|
|
89
|
+
* Gatekeeper ability cache.
|
|
90
|
+
*
|
|
91
|
+
* Gatekeeper will cache the user's abilities that it calculates, so it can
|
|
92
|
+
* check faster if that user has been checked before.
|
|
93
|
+
*/
|
|
94
|
+
$gatekeeperCache;
|
|
95
|
+
/**
|
|
96
|
+
* This should only be used by the backend.
|
|
97
|
+
*/
|
|
98
|
+
$skipAcWhenSaving = false;
|
|
99
|
+
/**
|
|
100
|
+
* This should only be used by the backend.
|
|
101
|
+
*/
|
|
102
|
+
$skipAcWhenDeleting = false;
|
|
103
|
+
/**
|
|
104
|
+
* The user's group descendants.
|
|
105
|
+
*/
|
|
106
|
+
$descendantGroups;
|
|
107
|
+
/**
|
|
108
|
+
* Used to save the current email address to send verification if it changes
|
|
109
|
+
* from the frontend.
|
|
110
|
+
*
|
|
111
|
+
* If you are changing a user's email address and want to bypass email
|
|
112
|
+
* verification, don't set this.
|
|
113
|
+
*/
|
|
114
|
+
$originalEmail;
|
|
27
115
|
static async factoryUsername(username) {
|
|
28
116
|
const entity = new this();
|
|
29
117
|
if (username != null) {
|
|
@@ -39,23 +127,6 @@ class User extends AbleObject_1.default {
|
|
|
39
127
|
}
|
|
40
128
|
return entity;
|
|
41
129
|
}
|
|
42
|
-
constructor() {
|
|
43
|
-
super();
|
|
44
|
-
this.$clientEnabledMethods = [...User.DEFAULT_CLIENT_ENABLED_METHODS];
|
|
45
|
-
this.$privateData = [...User.DEFAULT_PRIVATE_DATA];
|
|
46
|
-
this.$allowlistData = [...User.DEFAULT_ALLOWLIST_DATA];
|
|
47
|
-
this.$allowlistTags = [];
|
|
48
|
-
/**
|
|
49
|
-
* This is explicitly used only during the registration proccess.
|
|
50
|
-
*/
|
|
51
|
-
this.$skipAcWhenSaving = false;
|
|
52
|
-
// Defaults.
|
|
53
|
-
this.$data.enabled = true;
|
|
54
|
-
this.$data.abilities = [];
|
|
55
|
-
this.$data.groups = [];
|
|
56
|
-
this.$data.inheritAbilities = true;
|
|
57
|
-
this.$updateDataProtection();
|
|
58
|
-
}
|
|
59
130
|
static current(returnObjectIfNotExist) {
|
|
60
131
|
const tilmeld = (0, enforceTilmeld_1.enforceTilmeld)(this);
|
|
61
132
|
if (tilmeld.currentUser == null) {
|
|
@@ -216,6 +287,40 @@ class User extends AbleObject_1.default {
|
|
|
216
287
|
}
|
|
217
288
|
return result;
|
|
218
289
|
}
|
|
290
|
+
constructor() {
|
|
291
|
+
super();
|
|
292
|
+
// Defaults.
|
|
293
|
+
this.$data.enabled = true;
|
|
294
|
+
this.$data.abilities = [];
|
|
295
|
+
this.$data.groups = [];
|
|
296
|
+
this.$data.inheritAbilities = true;
|
|
297
|
+
this.$updateDataProtection();
|
|
298
|
+
}
|
|
299
|
+
$setNymph(nymph) {
|
|
300
|
+
this.$nymph = nymph;
|
|
301
|
+
if (!this.$asleep()) {
|
|
302
|
+
if (this.$data.group && this.$data.group.$nymph !== nymph) {
|
|
303
|
+
this.$data.group.$setNymph(nymph);
|
|
304
|
+
}
|
|
305
|
+
for (const group of this.$data.groups ?? []) {
|
|
306
|
+
if (group && group.$nymph !== nymph) {
|
|
307
|
+
group.$setNymph(nymph);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async $getUniques() {
|
|
313
|
+
const tilmeld = (0, enforceTilmeld_1.enforceTilmeld)(this);
|
|
314
|
+
const uniques = [`u:${this.$data.username}`];
|
|
315
|
+
if (!tilmeld.config.emailUsernames &&
|
|
316
|
+
tilmeld.config.userFields.includes('email')) {
|
|
317
|
+
uniques.push(`e:${this.$data.email}`);
|
|
318
|
+
if (this.$data.newEmailAddress != null) {
|
|
319
|
+
uniques.push(`e:${this.$data.newEmailAddress}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return uniques;
|
|
323
|
+
}
|
|
219
324
|
async $login(data) {
|
|
220
325
|
const tilmeld = (0, enforceTilmeld_1.enforceTilmeld)(this);
|
|
221
326
|
if (this.guid == null) {
|
|
@@ -1227,7 +1332,7 @@ class User extends AbleObject_1.default {
|
|
|
1227
1332
|
const transaction = 'tilmeld-register-' + (0, guid_1.nanoid)();
|
|
1228
1333
|
const nymph = this.$nymph;
|
|
1229
1334
|
const tnymph = await this.$nymph.startTransaction(transaction);
|
|
1230
|
-
this.$
|
|
1335
|
+
this.$setNymph(tnymph);
|
|
1231
1336
|
tilmeld = (0, enforceTilmeld_1.enforceTilmeld)(this);
|
|
1232
1337
|
let message = '';
|
|
1233
1338
|
let loggedin = false;
|
|
@@ -1242,71 +1347,13 @@ class User extends AbleObject_1.default {
|
|
|
1242
1347
|
}
|
|
1243
1348
|
catch (e) {
|
|
1244
1349
|
await tnymph.rollback(transaction);
|
|
1245
|
-
this.$nymph
|
|
1350
|
+
this.$setNymph(nymph);
|
|
1246
1351
|
return {
|
|
1247
1352
|
result: false,
|
|
1248
1353
|
loggedin: false,
|
|
1249
1354
|
message: e.message,
|
|
1250
1355
|
};
|
|
1251
1356
|
}
|
|
1252
|
-
// Add primary group.
|
|
1253
|
-
let generatedPrimaryGroup = null;
|
|
1254
|
-
if (tilmeld.config.generatePrimary) {
|
|
1255
|
-
// Generate a new primary group for the user.
|
|
1256
|
-
generatedPrimaryGroup = await tilmeld.Group.factory();
|
|
1257
|
-
generatedPrimaryGroup.groupname = this.$data.username;
|
|
1258
|
-
generatedPrimaryGroup.avatar = this.$data.avatar;
|
|
1259
|
-
if (tilmeld.config.userFields.includes('name')) {
|
|
1260
|
-
generatedPrimaryGroup.name = this.$data.name;
|
|
1261
|
-
}
|
|
1262
|
-
if (tilmeld.config.userFields.includes('email')) {
|
|
1263
|
-
generatedPrimaryGroup.email = this.$data.email;
|
|
1264
|
-
}
|
|
1265
|
-
const parent = await tnymph.getEntity({ class: tilmeld.Group }, {
|
|
1266
|
-
type: '&',
|
|
1267
|
-
equal: ['defaultPrimary', true],
|
|
1268
|
-
});
|
|
1269
|
-
if (parent != null) {
|
|
1270
|
-
generatedPrimaryGroup.parent = parent;
|
|
1271
|
-
}
|
|
1272
|
-
if (!(await generatedPrimaryGroup.$saveSkipAC())) {
|
|
1273
|
-
await tnymph.rollback(transaction);
|
|
1274
|
-
this.$nymph = nymph;
|
|
1275
|
-
return {
|
|
1276
|
-
result: false,
|
|
1277
|
-
loggedin: false,
|
|
1278
|
-
message: 'Error creating primary group for user.',
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
this.$data.group = generatedPrimaryGroup;
|
|
1282
|
-
}
|
|
1283
|
-
else {
|
|
1284
|
-
// Add the default primary.
|
|
1285
|
-
const group = await tnymph.getEntity({ class: tilmeld.Group }, {
|
|
1286
|
-
type: '&',
|
|
1287
|
-
equal: ['defaultPrimary', true],
|
|
1288
|
-
});
|
|
1289
|
-
if (group != null) {
|
|
1290
|
-
this.$data.group = group;
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
// Add secondary groups.
|
|
1294
|
-
if (tilmeld.config.userFields.includes('email') &&
|
|
1295
|
-
tilmeld.config.verifyEmail &&
|
|
1296
|
-
tilmeld.config.unverifiedAccess) {
|
|
1297
|
-
// Add the default secondaries for unverified users.
|
|
1298
|
-
this.$data.groups = await tnymph.getEntities({ class: tilmeld.Group }, {
|
|
1299
|
-
type: '&',
|
|
1300
|
-
equal: ['unverifiedSecondary', true],
|
|
1301
|
-
});
|
|
1302
|
-
}
|
|
1303
|
-
else {
|
|
1304
|
-
// Add the default secondaries.
|
|
1305
|
-
this.$data.groups = await tnymph.getEntities({ class: tilmeld.Group }, {
|
|
1306
|
-
type: '&',
|
|
1307
|
-
equal: ['defaultSecondary', true],
|
|
1308
|
-
});
|
|
1309
|
-
}
|
|
1310
1357
|
if (tilmeld.config.userFields.includes('email') &&
|
|
1311
1358
|
tilmeld.config.verifyEmail) {
|
|
1312
1359
|
// The user will be enabled after verifying their e-mail address.
|
|
@@ -1317,7 +1364,7 @@ class User extends AbleObject_1.default {
|
|
|
1317
1364
|
else {
|
|
1318
1365
|
this.$data.enabled = true;
|
|
1319
1366
|
}
|
|
1320
|
-
// If
|
|
1367
|
+
// If createAdmin is true and there are no other users, grant
|
|
1321
1368
|
// "system/admin".
|
|
1322
1369
|
let madeAdmin = false;
|
|
1323
1370
|
if (tilmeld.config.createAdmin) {
|
|
@@ -1354,19 +1401,6 @@ class User extends AbleObject_1.default {
|
|
|
1354
1401
|
},
|
|
1355
1402
|
}, this);
|
|
1356
1403
|
}
|
|
1357
|
-
// Save the primary group.
|
|
1358
|
-
if (generatedPrimaryGroup != null) {
|
|
1359
|
-
generatedPrimaryGroup.user = this;
|
|
1360
|
-
if (!(await generatedPrimaryGroup.$saveSkipAC())) {
|
|
1361
|
-
await tnymph.rollback(transaction);
|
|
1362
|
-
this.$nymph = nymph;
|
|
1363
|
-
return {
|
|
1364
|
-
result: false,
|
|
1365
|
-
loggedin: false,
|
|
1366
|
-
message: 'Your primary group could not be assigned. Please try again later.',
|
|
1367
|
-
};
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
1404
|
// Finish up.
|
|
1371
1405
|
if (tilmeld.config.verifyEmail &&
|
|
1372
1406
|
!tilmeld.config.unverifiedAccess &&
|
|
@@ -1409,7 +1443,7 @@ class User extends AbleObject_1.default {
|
|
|
1409
1443
|
else {
|
|
1410
1444
|
this.$nymph.config.debugError('tilmeld', `Error registering new user "${this.$data.username}".`);
|
|
1411
1445
|
await tnymph.rollback(transaction);
|
|
1412
|
-
this.$nymph
|
|
1446
|
+
this.$setNymph(nymph);
|
|
1413
1447
|
return {
|
|
1414
1448
|
result: false,
|
|
1415
1449
|
loggedin: false,
|
|
@@ -1420,12 +1454,12 @@ class User extends AbleObject_1.default {
|
|
|
1420
1454
|
catch (e) {
|
|
1421
1455
|
this.$nymph.config.debugError('tilmeld', `Error registering new user "${this.$data.username}": ${e}`);
|
|
1422
1456
|
await tnymph.rollback(transaction);
|
|
1423
|
-
this.$nymph
|
|
1457
|
+
this.$setNymph(nymph);
|
|
1424
1458
|
throw e;
|
|
1425
1459
|
}
|
|
1426
1460
|
try {
|
|
1427
1461
|
await tnymph.commit(transaction);
|
|
1428
|
-
this.$nymph
|
|
1462
|
+
this.$setNymph(nymph);
|
|
1429
1463
|
await this.$nymph.tilmeld?.fillSession(this);
|
|
1430
1464
|
}
|
|
1431
1465
|
catch (e) {
|
|
@@ -1442,7 +1476,8 @@ class User extends AbleObject_1.default {
|
|
|
1442
1476
|
if (this.$data.username == null || !this.$data.username.trim().length) {
|
|
1443
1477
|
return false;
|
|
1444
1478
|
}
|
|
1445
|
-
if (
|
|
1479
|
+
if (!this.$skipAcWhenSaving &&
|
|
1480
|
+
tilmeld.gatekeeper('tilmeld/admin') &&
|
|
1446
1481
|
!tilmeld.gatekeeper('system/admin') &&
|
|
1447
1482
|
this.$data.abilities?.includes('system/admin')) {
|
|
1448
1483
|
throw new errors_1.BadDataError("You don't have the authority to modify system admins.");
|
|
@@ -1615,53 +1650,133 @@ class User extends AbleObject_1.default {
|
|
|
1615
1650
|
if (this.$data.password == null) {
|
|
1616
1651
|
throw new errors_1.BadDataError('A password is required.');
|
|
1617
1652
|
}
|
|
1618
|
-
try {
|
|
1619
|
-
tilmeld.config.validatorUser(tilmeld, this);
|
|
1620
|
-
}
|
|
1621
|
-
catch (e) {
|
|
1622
|
-
throw new errors_1.BadDataError(e?.message);
|
|
1623
|
-
}
|
|
1624
1653
|
// Start transaction.
|
|
1625
1654
|
const transaction = 'tilmeld-save-' + (0, guid_1.nanoid)();
|
|
1626
1655
|
const nymph = this.$nymph;
|
|
1627
1656
|
const tnymph = await this.$nymph.startTransaction(transaction);
|
|
1628
|
-
this.$
|
|
1657
|
+
this.$setNymph(tnymph);
|
|
1629
1658
|
tilmeld = (0, enforceTilmeld_1.enforceTilmeld)(this);
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1659
|
+
// If the primary group is generated now, the user assigned to it won't have
|
|
1660
|
+
// a guid yet, so it needs to be assigned after the user is saved.
|
|
1661
|
+
let saveGeneratedPrimaryGroupAgain = false;
|
|
1662
|
+
try {
|
|
1663
|
+
let group = this.$data.group;
|
|
1664
|
+
await group?.$wake();
|
|
1665
|
+
if (group == null && this.guid == null) {
|
|
1666
|
+
if (tilmeld.config.generatePrimary) {
|
|
1667
|
+
// Generate a new primary group for the user.
|
|
1668
|
+
group = await tilmeld.Group.factory();
|
|
1669
|
+
// This user doesn't have a guid yet, so that's why we set
|
|
1670
|
+
// saveGeneratedPrimaryGroupAgain.
|
|
1671
|
+
group.user = this;
|
|
1672
|
+
saveGeneratedPrimaryGroupAgain = true;
|
|
1673
|
+
const parent = await tnymph.getEntity({ class: tilmeld.Group }, {
|
|
1674
|
+
type: '&',
|
|
1675
|
+
equal: ['defaultPrimary', true],
|
|
1676
|
+
});
|
|
1677
|
+
if (parent != null) {
|
|
1678
|
+
group.parent = parent;
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
else {
|
|
1682
|
+
// Add the default primary.
|
|
1683
|
+
const group = await tnymph.getEntity({ class: tilmeld.Group }, {
|
|
1684
|
+
type: '&',
|
|
1685
|
+
equal: ['defaultPrimary', true],
|
|
1686
|
+
});
|
|
1687
|
+
if (group != null) {
|
|
1688
|
+
this.$data.group = group;
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
if (group != null && group.user != null && this.$is(group.user)) {
|
|
1634
1693
|
// Update the user's generated primary group.
|
|
1635
|
-
|
|
1636
|
-
group.
|
|
1637
|
-
|
|
1694
|
+
let changed = false;
|
|
1695
|
+
if (group.groupname !== this.$data.username) {
|
|
1696
|
+
group.groupname = this.$data.username;
|
|
1697
|
+
changed = true;
|
|
1698
|
+
}
|
|
1699
|
+
if (group.avatar !== this.$data.avatar) {
|
|
1700
|
+
group.avatar = this.$data.avatar;
|
|
1701
|
+
changed = true;
|
|
1702
|
+
}
|
|
1703
|
+
if (tilmeld.config.userFields.includes('email') &&
|
|
1704
|
+
group.email !== this.$data.email) {
|
|
1638
1705
|
group.email = this.$data.email;
|
|
1706
|
+
changed = true;
|
|
1639
1707
|
}
|
|
1640
|
-
if (tilmeld.config.userFields.includes('name')
|
|
1708
|
+
if (tilmeld.config.userFields.includes('name') &&
|
|
1709
|
+
group.name !== this.$data.name) {
|
|
1641
1710
|
group.name = this.$data.name;
|
|
1711
|
+
changed = true;
|
|
1642
1712
|
}
|
|
1643
|
-
if (tilmeld.config.userFields.includes('phone')
|
|
1713
|
+
if (tilmeld.config.userFields.includes('phone') &&
|
|
1714
|
+
group.phone !== this.$data.phone) {
|
|
1644
1715
|
group.phone = this.$data.phone;
|
|
1716
|
+
changed = true;
|
|
1717
|
+
}
|
|
1718
|
+
if (changed) {
|
|
1719
|
+
if (!(await group.$saveSkipAC())) {
|
|
1720
|
+
throw Error('Error updating primary group for user.');
|
|
1721
|
+
}
|
|
1645
1722
|
}
|
|
1646
|
-
await group.$saveSkipAC();
|
|
1647
1723
|
this.$data.group = group;
|
|
1648
1724
|
}
|
|
1725
|
+
if (this.$data.groups == null || this.$data.groups.length === 0) {
|
|
1726
|
+
// Add secondary groups.
|
|
1727
|
+
if (tilmeld.config.userFields.includes('email') &&
|
|
1728
|
+
tilmeld.config.verifyEmail &&
|
|
1729
|
+
tilmeld.config.unverifiedAccess &&
|
|
1730
|
+
this.$data.secret != null) {
|
|
1731
|
+
// Add the default secondaries for unverified users.
|
|
1732
|
+
this.$data.groups = await tnymph.getEntities({ class: tilmeld.Group }, {
|
|
1733
|
+
type: '&',
|
|
1734
|
+
equal: ['unverifiedSecondary', true],
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1737
|
+
else {
|
|
1738
|
+
// Add the default secondaries.
|
|
1739
|
+
this.$data.groups = await tnymph.getEntities({ class: tilmeld.Group }, {
|
|
1740
|
+
type: '&',
|
|
1741
|
+
equal: ['defaultSecondary', true],
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
try {
|
|
1746
|
+
tilmeld.config.validatorUser(tilmeld, this);
|
|
1747
|
+
}
|
|
1649
1748
|
catch (e) {
|
|
1650
|
-
|
|
1651
|
-
this.$nymph = nymph;
|
|
1652
|
-
throw e;
|
|
1749
|
+
throw new errors_1.BadDataError(e?.message);
|
|
1653
1750
|
}
|
|
1654
1751
|
}
|
|
1752
|
+
catch (e) {
|
|
1753
|
+
await tnymph.rollback(transaction);
|
|
1754
|
+
this.$setNymph(nymph);
|
|
1755
|
+
throw e;
|
|
1756
|
+
}
|
|
1655
1757
|
let ret;
|
|
1656
1758
|
let preGuid = this.guid;
|
|
1657
1759
|
let preCdate = this.cdate;
|
|
1658
1760
|
let preMdate = this.mdate;
|
|
1659
1761
|
try {
|
|
1660
1762
|
ret = await super.$save();
|
|
1763
|
+
if (ret && saveGeneratedPrimaryGroupAgain) {
|
|
1764
|
+
const group = this.$data.group;
|
|
1765
|
+
if (group == null) {
|
|
1766
|
+
throw Error('Generated primary group not found.');
|
|
1767
|
+
}
|
|
1768
|
+
await group.$wake();
|
|
1769
|
+
// Now this user has a GUID, so saving it on the group will succeed.
|
|
1770
|
+
group.user = this;
|
|
1771
|
+
if (!(await group.$saveSkipAC())) {
|
|
1772
|
+
throw Error("Generated primary group couldn't be saved.");
|
|
1773
|
+
}
|
|
1774
|
+
this.$data.group = group;
|
|
1775
|
+
}
|
|
1661
1776
|
}
|
|
1662
1777
|
catch (e) {
|
|
1663
1778
|
await tnymph.rollback(transaction);
|
|
1664
|
-
this.$nymph
|
|
1779
|
+
this.$setNymph(nymph);
|
|
1665
1780
|
throw e;
|
|
1666
1781
|
}
|
|
1667
1782
|
if (ret) {
|
|
@@ -1672,7 +1787,7 @@ class User extends AbleObject_1.default {
|
|
|
1672
1787
|
this.guid = preGuid;
|
|
1673
1788
|
this.cdate = preCdate;
|
|
1674
1789
|
this.mdate = preMdate;
|
|
1675
|
-
this.$nymph
|
|
1790
|
+
this.$setNymph(nymph);
|
|
1676
1791
|
throw new Error("Couldn't send verification email.");
|
|
1677
1792
|
}
|
|
1678
1793
|
}
|
|
@@ -1688,7 +1803,7 @@ class User extends AbleObject_1.default {
|
|
|
1688
1803
|
else {
|
|
1689
1804
|
await tnymph.rollback(transaction);
|
|
1690
1805
|
}
|
|
1691
|
-
this.$nymph
|
|
1806
|
+
this.$setNymph(nymph);
|
|
1692
1807
|
return ret;
|
|
1693
1808
|
}
|
|
1694
1809
|
/**
|
|
@@ -1707,10 +1822,11 @@ class User extends AbleObject_1.default {
|
|
|
1707
1822
|
}
|
|
1708
1823
|
async $delete() {
|
|
1709
1824
|
const tilmeld = (0, enforceTilmeld_1.enforceTilmeld)(this);
|
|
1710
|
-
if (!tilmeld.gatekeeper('tilmeld/admin')) {
|
|
1825
|
+
if (!this.$skipAcWhenDeleting && !tilmeld.gatekeeper('tilmeld/admin')) {
|
|
1711
1826
|
throw new errors_1.BadDataError("You don't have the authority to delete users.");
|
|
1712
1827
|
}
|
|
1713
|
-
if (!
|
|
1828
|
+
if (!this.$skipAcWhenDeleting &&
|
|
1829
|
+
!tilmeld.gatekeeper('system/admin') &&
|
|
1714
1830
|
this.$data.abilities?.includes('system/admin')) {
|
|
1715
1831
|
throw new errors_1.BadDataError("You don't have the authority to delete system admins.");
|
|
1716
1832
|
}
|
|
@@ -1719,6 +1835,20 @@ class User extends AbleObject_1.default {
|
|
|
1719
1835
|
}
|
|
1720
1836
|
return await super.$delete();
|
|
1721
1837
|
}
|
|
1838
|
+
/*
|
|
1839
|
+
* This should *never* be accessible on the client.
|
|
1840
|
+
*/
|
|
1841
|
+
async $deleteSkipAC() {
|
|
1842
|
+
this.$skipAcWhenDeleting = true;
|
|
1843
|
+
return await this.$delete();
|
|
1844
|
+
}
|
|
1845
|
+
$tilmeldDeleteSkipAC() {
|
|
1846
|
+
if (this.$skipAcWhenDeleting) {
|
|
1847
|
+
this.$skipAcWhenDeleting = false;
|
|
1848
|
+
return true;
|
|
1849
|
+
}
|
|
1850
|
+
return false;
|
|
1851
|
+
}
|
|
1722
1852
|
static on(event, callback) {
|
|
1723
1853
|
const prop = (event + 'Callbacks');
|
|
1724
1854
|
if (!(prop in this)) {
|
|
@@ -1742,62 +1872,5 @@ class User extends AbleObject_1.default {
|
|
|
1742
1872
|
return true;
|
|
1743
1873
|
}
|
|
1744
1874
|
}
|
|
1745
|
-
/**
|
|
1746
|
-
* The instance of Tilmeld to use for queries.
|
|
1747
|
-
*/
|
|
1748
|
-
User.ETYPE = 'tilmeld_user';
|
|
1749
|
-
User.class = 'User';
|
|
1750
|
-
User.checkUsernameCallbacks = [];
|
|
1751
|
-
User.beforeRegisterCallbacks = [];
|
|
1752
|
-
User.afterRegisterCallbacks = [];
|
|
1753
|
-
User.beforeLoginCallbacks = [];
|
|
1754
|
-
User.afterLoginCallbacks = [];
|
|
1755
|
-
User.beforeLogoutCallbacks = [];
|
|
1756
|
-
User.afterLogoutCallbacks = [];
|
|
1757
|
-
User.DEFAULT_CLIENT_ENABLED_METHODS = [
|
|
1758
|
-
'$checkUsername',
|
|
1759
|
-
'$checkEmail',
|
|
1760
|
-
'$checkPhone',
|
|
1761
|
-
'$getAvatar',
|
|
1762
|
-
'$register',
|
|
1763
|
-
];
|
|
1764
|
-
User.DEFAULT_PRIVATE_DATA = [
|
|
1765
|
-
// The things that are commented are there to show what is _not_ private.
|
|
1766
|
-
'abilities',
|
|
1767
|
-
// 'username',
|
|
1768
|
-
// 'nameFirst',
|
|
1769
|
-
// 'nameMiddle',
|
|
1770
|
-
// 'nameLast',
|
|
1771
|
-
// 'name',
|
|
1772
|
-
'email',
|
|
1773
|
-
// 'avatar',
|
|
1774
|
-
'phone',
|
|
1775
|
-
'group',
|
|
1776
|
-
'groups',
|
|
1777
|
-
'inheritAbilities',
|
|
1778
|
-
'enabled',
|
|
1779
|
-
'secret',
|
|
1780
|
-
'emailChangeDate',
|
|
1781
|
-
'newEmailSecret',
|
|
1782
|
-
'newEmailAddress',
|
|
1783
|
-
'cancelEmailSecret',
|
|
1784
|
-
'cancelEmailAddress',
|
|
1785
|
-
'recoverSecret',
|
|
1786
|
-
'recoverSecretDate',
|
|
1787
|
-
'salt',
|
|
1788
|
-
'password',
|
|
1789
|
-
'passwordTemp',
|
|
1790
|
-
'revokeTokenDate',
|
|
1791
|
-
'totpSecret',
|
|
1792
|
-
];
|
|
1793
|
-
User.DEFAULT_ALLOWLIST_DATA = [];
|
|
1794
|
-
User.clientEnabledStaticMethods = [
|
|
1795
|
-
'current',
|
|
1796
|
-
'loginUser',
|
|
1797
|
-
'sendRecovery',
|
|
1798
|
-
'recover',
|
|
1799
|
-
'getClientConfig',
|
|
1800
|
-
];
|
|
1801
|
-
User.searchRestrictedData = [...User.DEFAULT_PRIVATE_DATA];
|
|
1802
1875
|
exports.default = User;
|
|
1803
1876
|
//# sourceMappingURL=User.js.map
|