@nymphjs/tilmeld 1.0.0-alpha.1 → 1.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +15 -10
- package/dist/Group.d.ts +2 -0
- package/dist/Group.js +68 -59
- package/dist/Group.js.map +1 -1
- package/dist/Group.test.js +12 -7
- package/dist/Group.test.js.map +1 -1
- package/dist/Tilmeld.d.ts +26 -22
- package/dist/Tilmeld.js +172 -92
- package/dist/Tilmeld.js.map +1 -1
- package/dist/User.d.ts +2 -0
- package/dist/User.js +134 -122
- package/dist/User.js.map +1 -1
- package/dist/User.test.js +12 -7
- package/dist/User.test.js.map +1 -1
- package/dist/conf/d.d.ts +7 -3
- package/dist/conf/defaults.js +41 -109
- package/dist/conf/defaults.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/tilmeldJoiProps.d.ts +12 -0
- package/dist/tilmeldJoiProps.js +20 -0
- package/dist/tilmeldJoiProps.js.map +1 -0
- package/package.json +6 -6
- package/src/Group.test.ts +18 -7
- package/src/Group.ts +88 -64
- package/src/Tilmeld.ts +284 -116
- package/src/User.test.ts +18 -7
- package/src/User.ts +164 -125
- package/src/conf/d.ts +38 -2
- package/src/conf/defaults.ts +29 -68
- package/src/index.ts +3 -1
- package/src/tilmeldJoiProps.ts +46 -0
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
14
|
};
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.User = exports.Tilmeld = exports.Group = exports.AbleObject = void 0;
|
|
16
|
+
exports.User = exports.tilmeldJoiProps = exports.Tilmeld = exports.Group = exports.AbleObject = void 0;
|
|
17
17
|
__exportStar(require("./conf"), exports);
|
|
18
18
|
__exportStar(require("./errors"), exports);
|
|
19
19
|
const AbleObject_1 = __importDefault(require("./AbleObject"));
|
|
@@ -23,8 +23,9 @@ const Group_1 = __importDefault(require("./Group"));
|
|
|
23
23
|
exports.Group = Group_1.default;
|
|
24
24
|
const Tilmeld_1 = __importDefault(require("./Tilmeld"));
|
|
25
25
|
exports.Tilmeld = Tilmeld_1.default;
|
|
26
|
-
exports.default = Tilmeld_1.default;
|
|
27
26
|
__exportStar(require("./Tilmeld.types"), exports);
|
|
27
|
+
const tilmeldJoiProps_1 = __importDefault(require("./tilmeldJoiProps"));
|
|
28
|
+
exports.tilmeldJoiProps = tilmeldJoiProps_1.default;
|
|
28
29
|
__exportStar(require("./User"), exports);
|
|
29
30
|
const User_1 = __importDefault(require("./User"));
|
|
30
31
|
exports.User = User_1.default;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AAEvB,2CAAyB;AAEzB,8DAAsC;AAC7B,qBADF,oBAAU,CACE;AAEnB,0CAAwB;AACxB,oDAA4B;AACnB,gBADF,eAAK,CACE;AAEd,wDAAgC;AACvB,kBADF,iBAAO,CACE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AAEvB,2CAAyB;AAEzB,8DAAsC;AAC7B,qBADF,oBAAU,CACE;AAEnB,0CAAwB;AACxB,oDAA4B;AACnB,gBADF,eAAK,CACE;AAEd,wDAAgC;AACvB,kBADF,iBAAO,CACE;AAEhB,kDAAgC;AAEhC,wEAAgD;AACvC,0BADF,yBAAe,CACE;AAExB,yCAAuB;AACvB,kDAA0B;AACjB,eADF,cAAI,CACE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
user: Joi.ObjectSchema<any>;
|
|
4
|
+
group: Joi.ObjectSchema<any>;
|
|
5
|
+
acUser: Joi.NumberSchema;
|
|
6
|
+
acGroup: Joi.NumberSchema;
|
|
7
|
+
acOther: Joi.NumberSchema;
|
|
8
|
+
acRead: Joi.ArraySchema;
|
|
9
|
+
acWrite: Joi.ArraySchema;
|
|
10
|
+
acFull: Joi.ArraySchema;
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const nymph_1 = require("@nymphjs/nymph");
|
|
7
|
+
const joi_1 = __importDefault(require("joi"));
|
|
8
|
+
const User_1 = __importDefault(require("./User"));
|
|
9
|
+
const Group_1 = __importDefault(require("./Group"));
|
|
10
|
+
exports.default = {
|
|
11
|
+
user: joi_1.default.object().instance(User_1.default),
|
|
12
|
+
group: joi_1.default.object().instance(Group_1.default),
|
|
13
|
+
acUser: joi_1.default.number().valid(nymph_1.TilmeldAccessLevels.NO_ACCESS, nymph_1.TilmeldAccessLevels.READ_ACCESS, nymph_1.TilmeldAccessLevels.WRITE_ACCESS, nymph_1.TilmeldAccessLevels.FULL_ACCESS),
|
|
14
|
+
acGroup: joi_1.default.number().valid(nymph_1.TilmeldAccessLevels.NO_ACCESS, nymph_1.TilmeldAccessLevels.READ_ACCESS, nymph_1.TilmeldAccessLevels.WRITE_ACCESS, nymph_1.TilmeldAccessLevels.FULL_ACCESS),
|
|
15
|
+
acOther: joi_1.default.number().valid(nymph_1.TilmeldAccessLevels.NO_ACCESS, nymph_1.TilmeldAccessLevels.READ_ACCESS, nymph_1.TilmeldAccessLevels.WRITE_ACCESS, nymph_1.TilmeldAccessLevels.FULL_ACCESS),
|
|
16
|
+
acRead: joi_1.default.array().items(joi_1.default.alternatives().try(joi_1.default.object().instance(User_1.default), joi_1.default.object().instance(Group_1.default))),
|
|
17
|
+
acWrite: joi_1.default.array().items(joi_1.default.alternatives().try(joi_1.default.object().instance(User_1.default), joi_1.default.object().instance(Group_1.default))),
|
|
18
|
+
acFull: joi_1.default.array().items(joi_1.default.alternatives().try(joi_1.default.object().instance(User_1.default), joi_1.default.object().instance(Group_1.default))),
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=tilmeldJoiProps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tilmeldJoiProps.js","sourceRoot":"","sources":["../src/tilmeldJoiProps.ts"],"names":[],"mappings":";;;;;AAAA,0CAAqD;AACrD,8CAAsB;AAEtB,kDAA0B;AAC1B,oDAA4B;AAE5B,kBAAe;IACb,IAAI,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAI,CAAC;IACjC,KAAK,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAK,CAAC;IACnC,MAAM,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CACxB,2BAAmB,CAAC,SAAS,EAC7B,2BAAmB,CAAC,WAAW,EAC/B,2BAAmB,CAAC,YAAY,EAChC,2BAAmB,CAAC,WAAW,CAChC;IACD,OAAO,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CACzB,2BAAmB,CAAC,SAAS,EAC7B,2BAAmB,CAAC,WAAW,EAC/B,2BAAmB,CAAC,YAAY,EAChC,2BAAmB,CAAC,WAAW,CAChC;IACD,OAAO,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CACzB,2BAAmB,CAAC,SAAS,EAC7B,2BAAmB,CAAC,WAAW,EAC/B,2BAAmB,CAAC,YAAY,EAChC,2BAAmB,CAAC,WAAW,CAChC;IACD,MAAM,EAAE,aAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CACvB,aAAG,CAAC,YAAY,EAAE,CAAC,GAAG,CACpB,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,EAC3B,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAK,CAAC,CAC7B,CACF;IACD,OAAO,EAAE,aAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CACxB,aAAG,CAAC,YAAY,EAAE,CAAC,GAAG,CACpB,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,EAC3B,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAK,CAAC,CAC7B,CACF;IACD,MAAM,EAAE,aAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CACvB,aAAG,CAAC,YAAY,EAAE,CAAC,GAAG,CACpB,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,EAC3B,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAK,CAAC,CAC7B,CACF;CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nymphjs/tilmeld",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.5",
|
|
4
4
|
"description": "NymphJS - Tilmeld User and Group System",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"license": "Apache-2.0",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@nymphjs/nymph": "^1.0.0-alpha.
|
|
34
|
+
"@nymphjs/nymph": "^1.0.0-alpha.5",
|
|
35
35
|
"crypto-js": "^4.1.1",
|
|
36
36
|
"email-templates": "^8.0.8",
|
|
37
37
|
"express": "^4.17.1",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"pug": "^3.0.2"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@nymphjs/client": "^1.0.0-alpha.
|
|
48
|
-
"@nymphjs/client-node": "^1.0.0-alpha.
|
|
49
|
-
"@nymphjs/driver-sqlite3": "^1.0.0-alpha.
|
|
47
|
+
"@nymphjs/client": "^1.0.0-alpha.5",
|
|
48
|
+
"@nymphjs/client-node": "^1.0.0-alpha.5",
|
|
49
|
+
"@nymphjs/driver-sqlite3": "^1.0.0-alpha.5",
|
|
50
50
|
"@tsconfig/recommended": "^1.0.1",
|
|
51
51
|
"@types/crypto-js": "^4.0.2",
|
|
52
52
|
"@types/email-templates": "^8.0.4",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"ts-jest": "^27.0.5",
|
|
61
61
|
"typescript": "^4.3.5"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "fdbe87041444a03a08aac11a6eef2c5f49cfa7d6"
|
|
64
64
|
}
|
package/src/Group.test.ts
CHANGED
|
@@ -2,15 +2,9 @@ import { SQLite3Driver } from '@nymphjs/driver-sqlite3';
|
|
|
2
2
|
import { Nymph } from '@nymphjs/nymph';
|
|
3
3
|
|
|
4
4
|
import Tilmeld from './Tilmeld';
|
|
5
|
-
import Group from './Group';
|
|
6
5
|
import defaults from './conf/defaults';
|
|
7
6
|
|
|
8
|
-
const
|
|
9
|
-
filename: ':memory:',
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
Nymph.init({}, new SQLite3Driver(sqliteConfig), Tilmeld);
|
|
13
|
-
Tilmeld.init({
|
|
7
|
+
const tilmeld = new Tilmeld({
|
|
14
8
|
appName: 'My App',
|
|
15
9
|
appUrl: 'http://localhost:8080',
|
|
16
10
|
cookieDomain: 'localhost',
|
|
@@ -22,6 +16,15 @@ Tilmeld.init({
|
|
|
22
16
|
cancelChangeRedirect: 'http://localhost:8080',
|
|
23
17
|
jwtSecret: 'shhhhh',
|
|
24
18
|
});
|
|
19
|
+
const _nymph = new Nymph(
|
|
20
|
+
{},
|
|
21
|
+
new SQLite3Driver({
|
|
22
|
+
filename: ':memory:',
|
|
23
|
+
}),
|
|
24
|
+
tilmeld
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const Group = tilmeld.Group;
|
|
25
28
|
|
|
26
29
|
describe('Group', () => {
|
|
27
30
|
async function makeNewGroup() {
|
|
@@ -34,6 +37,14 @@ describe('Group', () => {
|
|
|
34
37
|
return newGroup;
|
|
35
38
|
}
|
|
36
39
|
|
|
40
|
+
it('new group passes validation', async () => {
|
|
41
|
+
const validGroup = await makeNewGroup();
|
|
42
|
+
|
|
43
|
+
expect(() => {
|
|
44
|
+
defaults.validatorGroup(validGroup);
|
|
45
|
+
}).not.toThrow();
|
|
46
|
+
});
|
|
47
|
+
|
|
37
48
|
it("doesn't allow unknown keys", async () => {
|
|
38
49
|
const invalidGroup = await makeNewGroup();
|
|
39
50
|
|
package/src/Group.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
2
|
EntityData,
|
|
3
3
|
EntityInterface,
|
|
4
4
|
EntityJson,
|
|
@@ -10,6 +10,7 @@ import Nymph, {
|
|
|
10
10
|
import md5 from 'crypto-js/md5';
|
|
11
11
|
import { difference } from 'lodash';
|
|
12
12
|
|
|
13
|
+
import type Tilmeld from './Tilmeld';
|
|
13
14
|
import AbleObject from './AbleObject';
|
|
14
15
|
import {
|
|
15
16
|
BadDataError,
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
BadUsernameError,
|
|
18
19
|
CouldNotChangeDefaultPrimaryGroupError,
|
|
19
20
|
} from './errors';
|
|
20
|
-
import Tilmeld from './Tilmeld';
|
|
21
21
|
import User, { UserData } from './User';
|
|
22
22
|
|
|
23
23
|
export type GroupData = {
|
|
@@ -72,7 +72,20 @@ export type GroupData = {
|
|
|
72
72
|
unverifiedSecondary?: boolean;
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* A user group data model.
|
|
77
|
+
*
|
|
78
|
+
* Written by Hunter Perrin for SciActive.
|
|
79
|
+
*
|
|
80
|
+
* @author Hunter Perrin <hperrin@gmail.com>
|
|
81
|
+
* @copyright SciActive Inc
|
|
82
|
+
* @see http://nymph.io/
|
|
83
|
+
*/
|
|
75
84
|
export default class Group extends AbleObject<GroupData> {
|
|
85
|
+
/**
|
|
86
|
+
* The instance of Tilmeld to use for queries.
|
|
87
|
+
*/
|
|
88
|
+
static tilmeld: Tilmeld;
|
|
76
89
|
static ETYPE = 'tilmeld_group';
|
|
77
90
|
static class = 'Group';
|
|
78
91
|
|
|
@@ -112,7 +125,7 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
112
125
|
): Promise<Group & GroupData> {
|
|
113
126
|
const entity = new this();
|
|
114
127
|
if (groupname != null) {
|
|
115
|
-
const entity = await
|
|
128
|
+
const entity = await this.nymph.getEntity(
|
|
116
129
|
{
|
|
117
130
|
class: this,
|
|
118
131
|
},
|
|
@@ -154,13 +167,13 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
154
167
|
options?: Options,
|
|
155
168
|
selectors?: Selector[]
|
|
156
169
|
) {
|
|
157
|
-
if (!
|
|
170
|
+
if (!this.tilmeld.gatekeeper('tilmeld/admin')) {
|
|
158
171
|
throw new Error("You don't have permission to do that.");
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
return await this.getAssignableGroups(
|
|
162
|
-
|
|
163
|
-
{ ...options, class: Group, return: 'entity' },
|
|
175
|
+
this.tilmeld.config.highestPrimary,
|
|
176
|
+
{ ...options, class: this.tilmeld.Group, return: 'entity' },
|
|
164
177
|
[...(selectors ?? [])]
|
|
165
178
|
);
|
|
166
179
|
}
|
|
@@ -176,13 +189,13 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
176
189
|
options?: Options,
|
|
177
190
|
selectors?: Selector[]
|
|
178
191
|
) {
|
|
179
|
-
if (!
|
|
192
|
+
if (!this.tilmeld.gatekeeper('tilmeld/admin')) {
|
|
180
193
|
throw new Error("You don't have permission to do that.");
|
|
181
194
|
}
|
|
182
195
|
|
|
183
196
|
return await this.getAssignableGroups(
|
|
184
|
-
|
|
185
|
-
{ ...options, class: Group, return: 'entity' },
|
|
197
|
+
this.tilmeld.config.highestSecondary,
|
|
198
|
+
{ ...options, class: this.tilmeld.Group, return: 'entity' },
|
|
186
199
|
[...(selectors ?? [])]
|
|
187
200
|
);
|
|
188
201
|
}
|
|
@@ -198,8 +211,8 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
198
211
|
return assignableGroups;
|
|
199
212
|
}
|
|
200
213
|
|
|
201
|
-
assignableGroups = await
|
|
202
|
-
{ ...options, class: Group },
|
|
214
|
+
assignableGroups = await this.nymph.getEntities(
|
|
215
|
+
{ ...options, class: this.tilmeld.Group },
|
|
203
216
|
...selectors
|
|
204
217
|
);
|
|
205
218
|
if (highestParent !== true) {
|
|
@@ -232,13 +245,14 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
232
245
|
}
|
|
233
246
|
|
|
234
247
|
public $jsonAcceptData(input: EntityJson, allowConflict = false) {
|
|
248
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
235
249
|
this.$referenceWake();
|
|
236
250
|
|
|
237
251
|
if (
|
|
238
|
-
input.data.abilities
|
|
252
|
+
input.data.abilities?.indexOf('system/admin') !== -1 &&
|
|
239
253
|
this.$data.abilities?.indexOf('system/admin') === -1 &&
|
|
240
|
-
|
|
241
|
-
!
|
|
254
|
+
tilmeld.gatekeeper('tilmeld/admin') &&
|
|
255
|
+
!tilmeld.gatekeeper('system/admin')
|
|
242
256
|
) {
|
|
243
257
|
throw new BadDataError(
|
|
244
258
|
"You don't have the authority to make this group a system admin."
|
|
@@ -249,13 +263,14 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
249
263
|
}
|
|
250
264
|
|
|
251
265
|
public $jsonAcceptPatch(patch: EntityPatch, allowConflict = false) {
|
|
266
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
252
267
|
this.$referenceWake();
|
|
253
268
|
|
|
254
269
|
if (
|
|
255
|
-
patch.set.abilities
|
|
270
|
+
patch.set.abilities?.indexOf('system/admin') !== -1 &&
|
|
256
271
|
this.$data.abilities?.indexOf('system/admin') === -1 &&
|
|
257
|
-
|
|
258
|
-
!
|
|
272
|
+
tilmeld.gatekeeper('tilmeld/admin') &&
|
|
273
|
+
!tilmeld.gatekeeper('system/admin')
|
|
259
274
|
) {
|
|
260
275
|
throw new BadDataError(
|
|
261
276
|
"You don't have the authority to make this group a system admin."
|
|
@@ -276,12 +291,13 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
276
291
|
* @param givenUser User to update protection for. If undefined, will use the currently logged in user.
|
|
277
292
|
*/
|
|
278
293
|
public $updateDataProtection(givenUser?: User & UserData) {
|
|
279
|
-
|
|
294
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
295
|
+
let user = givenUser ?? tilmeld.User.current();
|
|
280
296
|
|
|
281
297
|
this.$privateData = Group.DEFAULT_PRIVATE_DATA;
|
|
282
298
|
this.$allowlistData = Group.DEFAULT_ALLOWLIST_DATA;
|
|
283
299
|
|
|
284
|
-
if (
|
|
300
|
+
if (tilmeld.config.emailUsernames) {
|
|
285
301
|
this.$privateData.push('groupname');
|
|
286
302
|
}
|
|
287
303
|
|
|
@@ -310,9 +326,10 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
310
326
|
* @returns True or false.
|
|
311
327
|
*/
|
|
312
328
|
public $isDescendant(givenGroup: (Group & GroupData) | string): boolean {
|
|
329
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
313
330
|
let group: Group & GroupData;
|
|
314
331
|
if (typeof givenGroup === 'string') {
|
|
315
|
-
group = Group.factorySync(givenGroup);
|
|
332
|
+
group = tilmeld.Group.factorySync(givenGroup);
|
|
316
333
|
} else {
|
|
317
334
|
group = givenGroup;
|
|
318
335
|
}
|
|
@@ -338,8 +355,9 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
338
355
|
* @returns An array of groups.
|
|
339
356
|
*/
|
|
340
357
|
public async $getChildren() {
|
|
341
|
-
|
|
342
|
-
|
|
358
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
359
|
+
return await this.$nymph.getEntities(
|
|
360
|
+
{ class: tilmeld.Group },
|
|
343
361
|
{
|
|
344
362
|
type: '&',
|
|
345
363
|
equal: ['enabled', true],
|
|
@@ -357,9 +375,10 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
357
375
|
public async $getDescendants(
|
|
358
376
|
andSelf = false
|
|
359
377
|
): Promise<(Group & GroupData)[]> {
|
|
378
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
360
379
|
let groups: (Group & GroupData)[] = [];
|
|
361
|
-
const entities = await
|
|
362
|
-
{ class: Group },
|
|
380
|
+
const entities = await this.$nymph.getEntities(
|
|
381
|
+
{ class: tilmeld.Group },
|
|
363
382
|
{
|
|
364
383
|
type: '&',
|
|
365
384
|
equal: ['enabled', true],
|
|
@@ -382,12 +401,13 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
382
401
|
* @returns An array of groups.
|
|
383
402
|
*/
|
|
384
403
|
public $getDescendantsSync(andSelf = false): (Group & GroupData)[] {
|
|
404
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
385
405
|
let groups: (Group & GroupData)[] = [];
|
|
386
406
|
let entity: EntityInterface | null;
|
|
387
407
|
let offset = 0;
|
|
388
408
|
do {
|
|
389
|
-
entity =
|
|
390
|
-
{ class: Group, offset },
|
|
409
|
+
entity = this.$nymph.driver.getEntitySync(
|
|
410
|
+
{ class: tilmeld.Group, offset },
|
|
391
411
|
{
|
|
392
412
|
type: '&',
|
|
393
413
|
equal: ['enabled', true],
|
|
@@ -417,7 +437,8 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
417
437
|
* @returns The level of the group.
|
|
418
438
|
*/
|
|
419
439
|
public $getLevel() {
|
|
420
|
-
|
|
440
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
441
|
+
let group = tilmeld.Group.factorySync(this.guid ?? undefined);
|
|
421
442
|
let level = 0;
|
|
422
443
|
while (group.parent != null && group.parent.cdate != null && level < 1024) {
|
|
423
444
|
level++;
|
|
@@ -439,13 +460,14 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
439
460
|
limit?: number,
|
|
440
461
|
offset?: number
|
|
441
462
|
): Promise<(User & UserData)[]> {
|
|
463
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
442
464
|
let groups: (Group & GroupData)[] = [];
|
|
443
465
|
if (descendants) {
|
|
444
466
|
groups = await this.$getDescendants();
|
|
445
467
|
}
|
|
446
|
-
return await
|
|
468
|
+
return await this.$nymph.getEntities(
|
|
447
469
|
{
|
|
448
|
-
class: User,
|
|
470
|
+
class: tilmeld.User,
|
|
449
471
|
limit,
|
|
450
472
|
offset,
|
|
451
473
|
},
|
|
@@ -480,37 +502,38 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
480
502
|
result: boolean;
|
|
481
503
|
message: string;
|
|
482
504
|
}> {
|
|
483
|
-
|
|
505
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
506
|
+
if (!tilmeld.config.emailUsernames) {
|
|
484
507
|
if (this.$data.groupname == null || !this.$data.groupname.length) {
|
|
485
508
|
return { result: false, message: 'Please specify a groupname.' };
|
|
486
509
|
}
|
|
487
510
|
if (
|
|
488
|
-
|
|
489
|
-
this.$data.groupname.length >
|
|
511
|
+
tilmeld.config.maxUsernameLength > 0 &&
|
|
512
|
+
this.$data.groupname.length > tilmeld.config.maxUsernameLength
|
|
490
513
|
) {
|
|
491
514
|
return {
|
|
492
515
|
result: false,
|
|
493
516
|
message:
|
|
494
517
|
'Groupnames must not exceed ' +
|
|
495
|
-
|
|
518
|
+
tilmeld.config.maxUsernameLength +
|
|
496
519
|
' characters.',
|
|
497
520
|
};
|
|
498
521
|
}
|
|
499
522
|
if (
|
|
500
523
|
difference(
|
|
501
524
|
this.$data.groupname.split(''),
|
|
502
|
-
|
|
525
|
+
tilmeld.config.validChars.split('')
|
|
503
526
|
).length
|
|
504
527
|
) {
|
|
505
528
|
return {
|
|
506
529
|
result: false,
|
|
507
|
-
message:
|
|
530
|
+
message: tilmeld.config.validCharsNotice,
|
|
508
531
|
};
|
|
509
532
|
}
|
|
510
|
-
if (!
|
|
533
|
+
if (!tilmeld.config.validRegex.test(this.$data.groupname)) {
|
|
511
534
|
return {
|
|
512
535
|
result: false,
|
|
513
|
-
message:
|
|
536
|
+
message: tilmeld.config.validRegexNotice,
|
|
514
537
|
};
|
|
515
538
|
}
|
|
516
539
|
|
|
@@ -524,8 +547,8 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
524
547
|
if (this.guid != null) {
|
|
525
548
|
selector['!guid'] = this.guid;
|
|
526
549
|
}
|
|
527
|
-
const test = await
|
|
528
|
-
{ class: Group, skipAc: true },
|
|
550
|
+
const test = await this.$nymph.getEntity(
|
|
551
|
+
{ class: tilmeld.Group, skipAc: true },
|
|
529
552
|
selector
|
|
530
553
|
);
|
|
531
554
|
if (test != null) {
|
|
@@ -543,14 +566,14 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
543
566
|
return { result: false, message: 'Please specify an email.' };
|
|
544
567
|
}
|
|
545
568
|
if (
|
|
546
|
-
|
|
547
|
-
this.$data.groupname.length >
|
|
569
|
+
tilmeld.config.maxUsernameLength > 0 &&
|
|
570
|
+
this.$data.groupname.length > tilmeld.config.maxUsernameLength
|
|
548
571
|
) {
|
|
549
572
|
return {
|
|
550
573
|
result: false,
|
|
551
574
|
message:
|
|
552
575
|
'Emails must not exceed ' +
|
|
553
|
-
|
|
576
|
+
tilmeld.config.maxUsernameLength +
|
|
554
577
|
' characters.',
|
|
555
578
|
};
|
|
556
579
|
}
|
|
@@ -565,16 +588,17 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
565
588
|
* @returns An object with a boolean 'result' entry and a 'message' entry.
|
|
566
589
|
*/
|
|
567
590
|
public async $checkEmail(): Promise<{ result: boolean; message: string }> {
|
|
591
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
568
592
|
if (this.$data.email === '') {
|
|
569
593
|
return { result: true, message: '' };
|
|
570
594
|
}
|
|
571
595
|
if (this.$data.email == null) {
|
|
572
596
|
return { result: false, message: 'Please specify a valid email.' };
|
|
573
597
|
}
|
|
574
|
-
if (!
|
|
598
|
+
if (!tilmeld.config.validEmailRegex.test(this.$data.email)) {
|
|
575
599
|
return {
|
|
576
600
|
result: false,
|
|
577
|
-
message:
|
|
601
|
+
message: tilmeld.config.validEmailRegexNotice,
|
|
578
602
|
};
|
|
579
603
|
}
|
|
580
604
|
const selector: Selector = {
|
|
@@ -584,8 +608,8 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
584
608
|
if (this.guid != null) {
|
|
585
609
|
selector['!guid'] = this.guid;
|
|
586
610
|
}
|
|
587
|
-
const test = await
|
|
588
|
-
{ class: Group, skipAc: true },
|
|
611
|
+
const test = await this.$nymph.getEntity(
|
|
612
|
+
{ class: tilmeld.Group, skipAc: true },
|
|
589
613
|
selector
|
|
590
614
|
);
|
|
591
615
|
if (test != null) {
|
|
@@ -603,13 +627,14 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
603
627
|
}
|
|
604
628
|
|
|
605
629
|
public async $save() {
|
|
630
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
606
631
|
if (this.$data.groupname == null || !this.$data.groupname.trim().length) {
|
|
607
632
|
return false;
|
|
608
633
|
}
|
|
609
634
|
|
|
610
635
|
// Formatting.
|
|
611
636
|
this.$data.groupname = this.$data.groupname.trim();
|
|
612
|
-
if (
|
|
637
|
+
if (tilmeld.config.emailUsernames) {
|
|
613
638
|
this.$data.email = this.$data.groupname;
|
|
614
639
|
}
|
|
615
640
|
this.$data.email = (this.$data.email ?? '').trim();
|
|
@@ -659,7 +684,7 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
659
684
|
if (!unCheck.result) {
|
|
660
685
|
throw new BadUsernameError(unCheck.message);
|
|
661
686
|
}
|
|
662
|
-
if (!
|
|
687
|
+
if (!tilmeld.config.emailUsernames) {
|
|
663
688
|
const emCheck = await this.$checkEmail();
|
|
664
689
|
if (!emCheck.result) {
|
|
665
690
|
throw new BadEmailError(emCheck.message);
|
|
@@ -679,15 +704,15 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
679
704
|
}
|
|
680
705
|
|
|
681
706
|
try {
|
|
682
|
-
|
|
707
|
+
tilmeld.config.validatorGroup(this);
|
|
683
708
|
} catch (e: any) {
|
|
684
709
|
throw new BadDataError(e?.message);
|
|
685
710
|
}
|
|
686
711
|
|
|
687
712
|
// Only one default primary group is allowed.
|
|
688
713
|
if (this.$data.defaultPrimary) {
|
|
689
|
-
const currentPrimary = await
|
|
690
|
-
{ class: Group },
|
|
714
|
+
const currentPrimary = await this.$nymph.getEntity(
|
|
715
|
+
{ class: tilmeld.Group },
|
|
691
716
|
{ type: '&', truthy: 'defaultPrimary' }
|
|
692
717
|
);
|
|
693
718
|
if (currentPrimary != null && !this.$is(currentPrimary)) {
|
|
@@ -721,28 +746,29 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
721
746
|
}
|
|
722
747
|
|
|
723
748
|
public async $delete() {
|
|
724
|
-
|
|
749
|
+
const tilmeld = this.$nymph.tilmeld as Tilmeld;
|
|
750
|
+
if (!tilmeld.gatekeeper('tilmeld/admin')) {
|
|
725
751
|
throw new BadDataError("You don't have the authority to delete groups.");
|
|
726
752
|
}
|
|
727
753
|
|
|
728
754
|
const transaction = 'tilmeld-delete-' + this.guid;
|
|
729
|
-
await
|
|
755
|
+
const tnymph = await this.$nymph.startTransaction(transaction);
|
|
730
756
|
|
|
731
757
|
// Delete descendants.
|
|
732
758
|
const descendants = await this.$getDescendants();
|
|
733
759
|
if (descendants.length) {
|
|
734
760
|
for (let curGroup of descendants) {
|
|
735
761
|
if (!(await curGroup.$delete())) {
|
|
736
|
-
await
|
|
762
|
+
await tnymph.rollback(transaction);
|
|
737
763
|
return false;
|
|
738
764
|
}
|
|
739
765
|
}
|
|
740
766
|
}
|
|
741
767
|
|
|
742
768
|
// Remove users from this primary group.
|
|
743
|
-
const primaryUsers = await
|
|
769
|
+
const primaryUsers = await tnymph.getEntities(
|
|
744
770
|
{
|
|
745
|
-
class: User,
|
|
771
|
+
class: tilmeld.User,
|
|
746
772
|
skipAc: true,
|
|
747
773
|
},
|
|
748
774
|
{
|
|
@@ -753,15 +779,15 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
753
779
|
for (let user of primaryUsers) {
|
|
754
780
|
delete user.group;
|
|
755
781
|
if (!(await user.$save())) {
|
|
756
|
-
await
|
|
782
|
+
await tnymph.rollback(transaction);
|
|
757
783
|
return false;
|
|
758
784
|
}
|
|
759
785
|
}
|
|
760
786
|
|
|
761
787
|
// Remove users from this secondary group.
|
|
762
|
-
const secondaryUsers = await
|
|
788
|
+
const secondaryUsers = await tnymph.getEntities(
|
|
763
789
|
{
|
|
764
|
-
class: User,
|
|
790
|
+
class: tilmeld.User,
|
|
765
791
|
skipAc: true,
|
|
766
792
|
},
|
|
767
793
|
{
|
|
@@ -772,7 +798,7 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
772
798
|
for (let user of secondaryUsers) {
|
|
773
799
|
user.$delGroup(this);
|
|
774
800
|
if (!(await user.$save())) {
|
|
775
|
-
await
|
|
801
|
+
await tnymph.rollback(transaction);
|
|
776
802
|
return false;
|
|
777
803
|
}
|
|
778
804
|
}
|
|
@@ -780,12 +806,10 @@ export default class Group extends AbleObject<GroupData> {
|
|
|
780
806
|
// Delete the group.
|
|
781
807
|
const success = await super.$delete();
|
|
782
808
|
if (success) {
|
|
783
|
-
await
|
|
809
|
+
await tnymph.commit(transaction);
|
|
784
810
|
} else {
|
|
785
|
-
await
|
|
811
|
+
await tnymph.rollback(transaction);
|
|
786
812
|
}
|
|
787
813
|
return success;
|
|
788
814
|
}
|
|
789
815
|
}
|
|
790
|
-
|
|
791
|
-
Nymph.setEntityClass(Group.class, Group);
|