@nymphjs/tilmeld 1.0.0-alpha.3 → 1.0.0-alpha.33

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/src/User.test.ts CHANGED
@@ -40,6 +40,14 @@ describe('User', () => {
40
40
  return newUser;
41
41
  }
42
42
 
43
+ it('new user passes validation', async () => {
44
+ const validUser = await makeNewUser();
45
+
46
+ expect(() => {
47
+ defaults.validatorUser(validUser);
48
+ }).not.toThrow();
49
+ });
50
+
43
51
  it("doesn't allow unknown keys", async () => {
44
52
  const invalidUser = await makeNewUser();
45
53
 
package/src/User.ts CHANGED
@@ -24,6 +24,44 @@ import {
24
24
  EmailChangeRateLimitExceededError,
25
25
  } from './errors';
26
26
 
27
+ export type EventType =
28
+ | 'beforeRegister'
29
+ | 'afterRegister'
30
+ | 'beforeLogin'
31
+ | 'afterLogin'
32
+ | 'beforeLogout'
33
+ | 'afterLogout';
34
+ /**
35
+ * Theses are run before the user data checks, so the only checks before are
36
+ * whether registration is allowed and whether the user is already registered.
37
+ */
38
+ export type TilmeldBeforeRegisterCallback = (
39
+ user: User & UserData,
40
+ data: { password: string; additionalData?: { [k: string]: any } }
41
+ ) => Promise<void> | void;
42
+ export type TilmeldAfterRegisterCallback = (
43
+ user: User & UserData,
44
+ result: { loggedin: boolean; message: string }
45
+ ) => Promise<void> | void;
46
+ /**
47
+ * These are run after the authentication checks, but before the login action.
48
+ */
49
+ export type TilmeldBeforeLoginCallback = (
50
+ user: User & UserData,
51
+ data: {
52
+ username: string;
53
+ password: string;
54
+ additionalData?: { [k: string]: any };
55
+ }
56
+ ) => void;
57
+ /**
58
+ * This is run before the transaction is committed, and you can perform
59
+ * additional functions on the transaction, which is available in `user.$nymph`.
60
+ */
61
+ export type TilmeldAfterLoginCallback = (user: User & UserData) => void;
62
+ export type TilmeldBeforeLogoutCallback = (user: User & UserData) => void;
63
+ export type TilmeldAfterLogoutCallback = (user: User & UserData) => void;
64
+
27
65
  export type UserData = {
28
66
  /**
29
67
  * The abilities granted to the user.
@@ -126,13 +164,28 @@ export type UserData = {
126
164
  passwordTemp?: string;
127
165
  };
128
166
 
167
+ /**
168
+ * A user data model.
169
+ *
170
+ * Written by Hunter Perrin for SciActive.
171
+ *
172
+ * @author Hunter Perrin <hperrin@gmail.com>
173
+ * @copyright SciActive Inc
174
+ * @see http://nymph.io/
175
+ */
129
176
  export default class User extends AbleObject<UserData> {
130
177
  /**
131
178
  * The instance of Tilmeld to use for queries.
132
179
  */
133
- public static tilmeld: Tilmeld;
180
+ static tilmeld: Tilmeld;
134
181
  static ETYPE = 'tilmeld_user';
135
182
  static class = 'User';
183
+ private static beforeRegisterCallbacks: TilmeldBeforeRegisterCallback[] = [];
184
+ private static afterRegisterCallbacks: TilmeldAfterRegisterCallback[] = [];
185
+ private static beforeLoginCallbacks: TilmeldBeforeLoginCallback[] = [];
186
+ private static afterLoginCallbacks: TilmeldAfterLoginCallback[] = [];
187
+ private static beforeLogoutCallbacks: TilmeldBeforeLogoutCallback[] = [];
188
+ private static afterLogoutCallbacks: TilmeldAfterLogoutCallback[] = [];
136
189
 
137
190
  private static DEFAULT_CLIENT_ENABLED_METHODS = [
138
191
  '$checkUsername',
@@ -162,7 +215,7 @@ export default class User extends AbleObject<UserData> {
162
215
  ];
163
216
  private static DEFAULT_ALLOWLIST_DATA: string[] = [];
164
217
 
165
- protected $clientEnabledMethods = User.DEFAULT_CLIENT_ENABLED_METHODS;
218
+ protected $clientEnabledMethods = [...User.DEFAULT_CLIENT_ENABLED_METHODS];
166
219
  public static clientEnabledStaticMethods = [
167
220
  'current',
168
221
  'loginUser',
@@ -170,9 +223,9 @@ export default class User extends AbleObject<UserData> {
170
223
  'recover',
171
224
  'getClientConfig',
172
225
  ];
173
- protected $privateData = User.DEFAULT_PRIVATE_DATA;
174
- public static searchRestrictedData = User.DEFAULT_PRIVATE_DATA;
175
- protected $allowlistData? = User.DEFAULT_ALLOWLIST_DATA;
226
+ protected $privateData = [...User.DEFAULT_PRIVATE_DATA];
227
+ public static searchRestrictedData = [...User.DEFAULT_PRIVATE_DATA];
228
+ protected $allowlistData? = [...User.DEFAULT_ALLOWLIST_DATA];
176
229
  protected $allowlistTags?: string[] = [];
177
230
 
178
231
  /**
@@ -420,7 +473,11 @@ export default class User extends AbleObject<UserData> {
420
473
  };
421
474
  }
422
475
 
423
- public static async loginUser(data: { username: string; password: string }) {
476
+ public static async loginUser(data: {
477
+ username: string;
478
+ password: string;
479
+ additionalData?: { [k: string]: any };
480
+ }) {
424
481
  if (!('username' in data) || !data.username.length) {
425
482
  return { result: false, message: 'Incorrect login/password.' };
426
483
  }
@@ -434,7 +491,11 @@ export default class User extends AbleObject<UserData> {
434
491
  return result;
435
492
  }
436
493
 
437
- public $login(data: { username: string; password: string }) {
494
+ public $login(data: {
495
+ username: string;
496
+ password: string;
497
+ additionalData?: { [k: string]: any };
498
+ }) {
438
499
  const tilmeld = this.$nymph.tilmeld as Tilmeld;
439
500
  if (this.guid == null) {
440
501
  return { result: false, message: 'Incorrect login/password.' };
@@ -449,11 +510,32 @@ export default class User extends AbleObject<UserData> {
449
510
  return { result: false, message: 'Incorrect login/password.' };
450
511
  }
451
512
 
513
+ try {
514
+ for (let callback of (this.constructor as typeof User)
515
+ .beforeLoginCallbacks) {
516
+ if (callback) {
517
+ callback(this, data);
518
+ }
519
+ }
520
+ } catch (e: any) {
521
+ return {
522
+ result: false,
523
+ message: e.message,
524
+ };
525
+ }
526
+
452
527
  // Authentication was successful, attempt to login.
453
528
  if (!tilmeld.login(this, true)) {
454
529
  return { result: false, message: 'Incorrect login/password.' };
455
530
  }
456
531
 
532
+ for (let callback of (this.constructor as typeof User)
533
+ .afterLoginCallbacks) {
534
+ if (callback) {
535
+ callback(this);
536
+ }
537
+ }
538
+
457
539
  // Login was successful.
458
540
  return { result: true, message: 'You are logged in.' };
459
541
  }
@@ -464,7 +546,30 @@ export default class User extends AbleObject<UserData> {
464
546
  */
465
547
  public $logout() {
466
548
  const tilmeld = this.$nymph.tilmeld as Tilmeld;
549
+
550
+ try {
551
+ for (let callback of (this.constructor as typeof User)
552
+ .beforeLogoutCallbacks) {
553
+ if (callback) {
554
+ callback(this);
555
+ }
556
+ }
557
+ } catch (e: any) {
558
+ return {
559
+ result: false,
560
+ message: e.message,
561
+ };
562
+ }
563
+
467
564
  tilmeld.logout();
565
+
566
+ for (let callback of (this.constructor as typeof User)
567
+ .afterLogoutCallbacks) {
568
+ if (callback) {
569
+ callback(this);
570
+ }
571
+ }
572
+
468
573
  return { result: true, message: 'You have been logged out.' };
469
574
  }
470
575
 
@@ -570,9 +675,9 @@ export default class User extends AbleObject<UserData> {
570
675
  const tilmeld = this.$nymph.tilmeld as Tilmeld;
571
676
  let user = givenUser ?? tilmeld.User.current();
572
677
 
573
- this.$clientEnabledMethods = User.DEFAULT_CLIENT_ENABLED_METHODS;
574
- this.$privateData = User.DEFAULT_PRIVATE_DATA;
575
- this.$allowlistData = User.DEFAULT_ALLOWLIST_DATA;
678
+ this.$clientEnabledMethods = [...User.DEFAULT_CLIENT_ENABLED_METHODS];
679
+ this.$privateData = [...User.DEFAULT_PRIVATE_DATA];
680
+ this.$allowlistData = [...User.DEFAULT_ALLOWLIST_DATA];
576
681
 
577
682
  if (tilmeld.config.emailUsernames) {
578
683
  this.$privateData.push('username');
@@ -1114,6 +1219,7 @@ export default class User extends AbleObject<UserData> {
1114
1219
 
1115
1220
  public async $register(data: {
1116
1221
  password: string;
1222
+ additionalData?: { [k: string]: any };
1117
1223
  }): Promise<{ result: boolean; loggedin: boolean; message: string }> {
1118
1224
  const tilmeld = this.$nymph.tilmeld as Tilmeld;
1119
1225
  if (!tilmeld.config.allowRegistration) {
@@ -1130,6 +1236,22 @@ export default class User extends AbleObject<UserData> {
1130
1236
  message: 'This is already a registered user.',
1131
1237
  };
1132
1238
  }
1239
+
1240
+ try {
1241
+ for (let callback of (this.constructor as typeof User)
1242
+ .beforeRegisterCallbacks) {
1243
+ if (callback) {
1244
+ await callback(this, data);
1245
+ }
1246
+ }
1247
+ } catch (e: any) {
1248
+ return {
1249
+ result: false,
1250
+ loggedin: false,
1251
+ message: e.message,
1252
+ };
1253
+ }
1254
+
1133
1255
  if (!('password' in data) || !data.password.length) {
1134
1256
  return {
1135
1257
  result: false,
@@ -1158,7 +1280,9 @@ export default class User extends AbleObject<UserData> {
1158
1280
 
1159
1281
  // Start transaction.
1160
1282
  const transaction = 'tilmeld-register-' + nanoid();
1283
+ const nymph = this.$nymph;
1161
1284
  const tnymph = await this.$nymph.startTransaction(transaction);
1285
+ this.$nymph = tnymph;
1162
1286
 
1163
1287
  try {
1164
1288
  // Add primary group.
@@ -1182,6 +1306,7 @@ export default class User extends AbleObject<UserData> {
1182
1306
  }
1183
1307
  if (!(await generatedPrimaryGroup.$saveSkipAC())) {
1184
1308
  await tnymph.rollback(transaction);
1309
+ this.$nymph = nymph;
1185
1310
  return {
1186
1311
  result: false,
1187
1312
  loggedin: false,
@@ -1282,6 +1407,7 @@ export default class User extends AbleObject<UserData> {
1282
1407
  generatedPrimaryGroup.user = this;
1283
1408
  if (!(await generatedPrimaryGroup.$saveSkipAC())) {
1284
1409
  await tnymph.rollback(transaction);
1410
+ this.$nymph = nymph;
1285
1411
  return {
1286
1412
  result: false,
1287
1413
  loggedin: false,
@@ -1316,7 +1442,20 @@ export default class User extends AbleObject<UserData> {
1316
1442
  message += "You're now registered and logged in!";
1317
1443
  loggedin = true;
1318
1444
  }
1445
+
1446
+ for (let callback of (this.constructor as typeof User)
1447
+ .afterRegisterCallbacks) {
1448
+ if (callback) {
1449
+ await callback(this, {
1450
+ loggedin,
1451
+ message,
1452
+ });
1453
+ }
1454
+ }
1455
+
1319
1456
  await tnymph.commit(transaction);
1457
+ this.$nymph = nymph;
1458
+
1320
1459
  return {
1321
1460
  result: true,
1322
1461
  loggedin,
@@ -1324,6 +1463,7 @@ export default class User extends AbleObject<UserData> {
1324
1463
  };
1325
1464
  } else {
1326
1465
  await tnymph.rollback(transaction);
1466
+ this.$nymph = nymph;
1327
1467
  return {
1328
1468
  result: false,
1329
1469
  loggedin: false,
@@ -1332,6 +1472,7 @@ export default class User extends AbleObject<UserData> {
1332
1472
  }
1333
1473
  } catch (e: any) {
1334
1474
  await tnymph.rollback(transaction);
1475
+ this.$nymph = nymph;
1335
1476
  throw e;
1336
1477
  }
1337
1478
  }
@@ -1532,7 +1673,9 @@ export default class User extends AbleObject<UserData> {
1532
1673
 
1533
1674
  // Start transaction.
1534
1675
  const transaction = 'tilmeld-save-' + nanoid();
1676
+ const nymph = this.$nymph;
1535
1677
  const tnymph = await this.$nymph.startTransaction(transaction);
1678
+ this.$nymph = tnymph;
1536
1679
 
1537
1680
  if (
1538
1681
  this.$data.group != null &&
@@ -1549,6 +1692,7 @@ export default class User extends AbleObject<UserData> {
1549
1692
  await this.$data.group.$saveSkipAC();
1550
1693
  } catch (e: any) {
1551
1694
  await tnymph.rollback(transaction);
1695
+ this.$nymph = nymph;
1552
1696
  throw e;
1553
1697
  }
1554
1698
  }
@@ -1562,6 +1706,7 @@ export default class User extends AbleObject<UserData> {
1562
1706
  ret = await super.$save();
1563
1707
  } catch (e: any) {
1564
1708
  await tnymph.rollback(transaction);
1709
+ this.$nymph = nymph;
1565
1710
  throw e;
1566
1711
  }
1567
1712
  if (ret) {
@@ -1572,6 +1717,7 @@ export default class User extends AbleObject<UserData> {
1572
1717
  this.guid = preGuid;
1573
1718
  this.cdate = preCdate;
1574
1719
  this.mdate = preMdate;
1720
+ this.$nymph = nymph;
1575
1721
  throw new Error("Couldn't send verification email.");
1576
1722
  }
1577
1723
  }
@@ -1587,6 +1733,7 @@ export default class User extends AbleObject<UserData> {
1587
1733
  } else {
1588
1734
  await tnymph.rollback(transaction);
1589
1735
  }
1736
+ this.$nymph = nymph;
1590
1737
  return ret;
1591
1738
  }
1592
1739
 
@@ -1624,4 +1771,82 @@ export default class User extends AbleObject<UserData> {
1624
1771
  }
1625
1772
  return await super.$delete();
1626
1773
  }
1774
+
1775
+ public static on<T extends EventType>(
1776
+ event: T,
1777
+ callback: T extends 'beforeRegister'
1778
+ ? TilmeldBeforeRegisterCallback
1779
+ : T extends 'afterRegister'
1780
+ ? TilmeldAfterRegisterCallback
1781
+ : T extends 'beforeLogin'
1782
+ ? TilmeldBeforeLoginCallback
1783
+ : T extends 'afterLogin'
1784
+ ? TilmeldAfterLoginCallback
1785
+ : T extends 'beforeLogout'
1786
+ ? TilmeldBeforeLogoutCallback
1787
+ : T extends 'afterLogout'
1788
+ ? TilmeldAfterLogoutCallback
1789
+ : never
1790
+ ) {
1791
+ const prop = (event + 'Callbacks') as T extends 'beforeRegister'
1792
+ ? 'beforeRegisterCallbacks'
1793
+ : T extends 'afterRegister'
1794
+ ? 'afterRegisterCallbacks'
1795
+ : T extends 'beforeLogin'
1796
+ ? 'beforeLoginCallbacks'
1797
+ : T extends 'afterLogin'
1798
+ ? 'afterLoginCallbacks'
1799
+ : T extends 'beforeLogout'
1800
+ ? 'beforeLogoutCallbacks'
1801
+ : T extends 'afterLogout'
1802
+ ? 'afterLogoutCallbacks'
1803
+ : never;
1804
+ if (!(prop in this)) {
1805
+ throw new Error('Invalid event type.');
1806
+ }
1807
+ // @ts-ignore: The callback should always be the right type here.
1808
+ this[prop].push(callback);
1809
+ return () => this.off(event, callback);
1810
+ }
1811
+
1812
+ public static off<T extends EventType>(
1813
+ event: T,
1814
+ callback: T extends 'beforeRegister'
1815
+ ? TilmeldBeforeRegisterCallback
1816
+ : T extends 'afterRegister'
1817
+ ? TilmeldAfterRegisterCallback
1818
+ : T extends 'beforeLogin'
1819
+ ? TilmeldBeforeLoginCallback
1820
+ : T extends 'afterLogin'
1821
+ ? TilmeldAfterLoginCallback
1822
+ : T extends 'beforeLogout'
1823
+ ? TilmeldBeforeLogoutCallback
1824
+ : T extends 'afterLogout'
1825
+ ? TilmeldAfterLogoutCallback
1826
+ : never
1827
+ ) {
1828
+ const prop = (event + 'Callbacks') as T extends 'beforeRegister'
1829
+ ? 'beforeRegisterCallbacks'
1830
+ : T extends 'afterRegister'
1831
+ ? 'afterRegisterCallbacks'
1832
+ : T extends 'beforeLogin'
1833
+ ? 'beforeLoginCallbacks'
1834
+ : T extends 'afterLogin'
1835
+ ? 'afterLoginCallbacks'
1836
+ : T extends 'beforeLogout'
1837
+ ? 'beforeLogoutCallbacks'
1838
+ : T extends 'afterLogout'
1839
+ ? 'afterLogoutCallbacks'
1840
+ : never;
1841
+ if (!(prop in this)) {
1842
+ return false;
1843
+ }
1844
+ // @ts-ignore: The callback should always be the right type here.
1845
+ const i = this[prop].indexOf(callback);
1846
+ if (i > -1) {
1847
+ // @ts-ignore: The callback should always be the right type here.
1848
+ this[prop].splice(i, 1);
1849
+ }
1850
+ return true;
1851
+ }
1627
1852
  }
package/src/conf/d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { EmailOptions } from 'email-templates';
2
+
2
3
  import type Tilmeld from '../Tilmeld';
3
4
  import Group, { GroupData } from '../Group';
4
5
  import User, { UserData } from '../User';
@@ -64,6 +65,35 @@ export interface Config {
64
65
  * a concern. Same risks as user search if generatePrimary is true.)
65
66
  */
66
67
  enableGroupSearch: boolean;
68
+ /**
69
+ * A list of UIDs that can be read from the client by anyone. (getUID)
70
+ *
71
+ * Note: If you'd like to limit the access to logged in users, give them an
72
+ * ability like "uid/get/nameofuid".
73
+ */
74
+ clientReadableUIDs: string[];
75
+ /**
76
+ * A list of UIDs that can be created from the client by anyone. (newUID)
77
+ *
78
+ * Inclusion in this list implies inclusion in clientReadableUIDs.
79
+ *
80
+ * Note: If you'd like to limit the access to logged in users, give them an
81
+ * ability like "uid/new/nameofuid".
82
+ */
83
+ clientEnabledUIDs: string[];
84
+ /**
85
+ * A list of UIDs that can be set from the client by anyone. (setUID,
86
+ * renameUID)
87
+ *
88
+ * Inclusion in this list implies inclusion in clientReadableUIDs and
89
+ * clientEnabledUIDs.
90
+ *
91
+ * Note: There is no way to run renameUID from the client.
92
+ *
93
+ * Note: If you'd like to limit the access to logged in users, give them an
94
+ * ability like "uid/set/nameofuid".
95
+ */
96
+ clientSetabledUIDs: string[];
67
97
  /**
68
98
  * These will be the available fields for users. (Some fields, like username,
69
99
  * can't be excluded.)
@@ -1,3 +1,4 @@
1
+ import { nymphJoiProps } from '@nymphjs/nymph';
1
2
  import path from 'path';
2
3
  import jwt from 'jsonwebtoken';
3
4
  import { nanoid } from 'nanoid';
@@ -20,6 +21,9 @@ export default {
20
21
  allowUsernameChange: true,
21
22
  enableUserSearch: false,
22
23
  enableGroupSearch: false,
24
+ clientReadableUIDs: [],
25
+ clientEnabledUIDs: [],
26
+ clientSetabledUIDs: [],
23
27
  userFields: ['name', 'email', 'phone'],
24
28
  regFields: ['name', 'email'],
25
29
  verifyEmail: true,
@@ -154,29 +158,8 @@ export default {
154
158
  Joi.attempt(
155
159
  group.$getValidatable(),
156
160
  Joi.object().keys({
157
- guid: Joi.alternatives()
158
- .try(
159
- Joi.any().only().allow(null),
160
- Joi.string().trim(false).length(24).hex()
161
- )
162
- .required(),
163
- cdate: Joi.alternatives()
164
- .try(Joi.any().only().allow(null), Joi.number())
165
- .required(),
166
- mdate: Joi.alternatives()
167
- .try(Joi.any().only().allow(null), Joi.number())
168
- .required(),
169
- tags: Joi.array()
170
- .items(
171
- Joi.string()
172
- .pattern(/[\x01-\x1F\x7F]/, {
173
- name: 'control characters',
174
- invert: true,
175
- })
176
- .min(1)
177
- )
178
- .required(),
179
- groupname: Joi.string().trim(false).min(1).required(),
161
+ ...nymphJoiProps,
162
+ groupname: Joi.string().trim(false).required(),
180
163
  enabled: Joi.boolean().required(),
181
164
  email: Joi.string()
182
165
  .trim(false)
@@ -188,7 +171,6 @@ export default {
188
171
  name: 'control characters',
189
172
  invert: true,
190
173
  })
191
- .min(1)
192
174
  .max(512)
193
175
  .required(),
194
176
  avatar: Joi.string()
@@ -198,7 +180,6 @@ export default {
198
180
  name: 'control characters',
199
181
  invert: true,
200
182
  })
201
- .min(1)
202
183
  .max(1024),
203
184
  phone: Joi.string()
204
185
  .trim(false)
@@ -211,7 +192,6 @@ export default {
211
192
  name: 'control characters',
212
193
  invert: true,
213
194
  })
214
- .min(1)
215
195
  .max(256)
216
196
  ),
217
197
  defaultPrimary: Joi.boolean(),
@@ -225,29 +205,8 @@ export default {
225
205
  Joi.attempt(
226
206
  user.$getValidatable(),
227
207
  Joi.object().keys({
228
- guid: Joi.alternatives()
229
- .try(
230
- Joi.any().only().allow(null),
231
- Joi.string().trim(false).length(24).hex()
232
- )
233
- .required(),
234
- cdate: Joi.alternatives()
235
- .try(Joi.any().only().allow(null), Joi.number())
236
- .required(),
237
- mdate: Joi.alternatives()
238
- .try(Joi.any().only().allow(null), Joi.number())
239
- .required(),
240
- tags: Joi.array()
241
- .items(
242
- Joi.string()
243
- .pattern(/[\x01-\x1F\x7F]/, {
244
- name: 'control characters',
245
- invert: true,
246
- })
247
- .min(1)
248
- )
249
- .required(),
250
- username: Joi.string().trim(false).min(1).required(),
208
+ ...nymphJoiProps,
209
+ username: Joi.string().trim(false).required(),
251
210
  enabled: Joi.boolean().required(),
252
211
  email: Joi.string()
253
212
  .trim(false)
@@ -259,7 +218,6 @@ export default {
259
218
  name: 'control characters',
260
219
  invert: true,
261
220
  })
262
- .min(1)
263
221
  .max(512)
264
222
  .required(),
265
223
  nameMiddle: Joi.string()
@@ -268,7 +226,6 @@ export default {
268
226
  name: 'control characters',
269
227
  invert: true,
270
228
  })
271
- .min(1)
272
229
  .max(512),
273
230
  nameLast: Joi.string()
274
231
  .trim(false)
@@ -276,7 +233,6 @@ export default {
276
233
  name: 'control characters',
277
234
  invert: true,
278
235
  })
279
- .min(1)
280
236
  .max(512),
281
237
  name: Joi.string()
282
238
  .trim(false)
@@ -284,7 +240,6 @@ export default {
284
240
  name: 'control characters',
285
241
  invert: true,
286
242
  })
287
- .min(1)
288
243
  .max(512)
289
244
  .required(),
290
245
  avatar: Joi.string()
@@ -294,7 +249,6 @@ export default {
294
249
  name: 'control characters',
295
250
  invert: true,
296
251
  })
297
- .min(1)
298
252
  .max(1024),
299
253
  phone: Joi.string()
300
254
  .trim(false)
@@ -307,7 +261,6 @@ export default {
307
261
  name: 'control characters',
308
262
  invert: true,
309
263
  })
310
- .min(1)
311
264
  .max(256)
312
265
  ),
313
266
  inheritAbilities: Joi.boolean(),
@@ -347,8 +300,8 @@ export default {
347
300
  })
348
301
  .length(10),
349
302
  recoverSecretDate: Joi.number(),
350
- salt: Joi.string().trim(false).min(1),
351
- password: Joi.string().trim(false).min(1).required(),
303
+ salt: Joi.string().trim(false),
304
+ password: Joi.string().trim(false).required(),
352
305
  }),
353
306
  'Invalid User: '
354
307
  );
package/src/index.ts CHANGED
@@ -14,6 +14,9 @@ export { Tilmeld };
14
14
 
15
15
  export * from './Tilmeld.types';
16
16
 
17
+ import tilmeldJoiProps from './tilmeldJoiProps';
18
+ export { tilmeldJoiProps };
19
+
17
20
  export * from './User';
18
21
  import User from './User';
19
22
  export { User };
@@ -0,0 +1,46 @@
1
+ import { TilmeldAccessLevels } from '@nymphjs/nymph';
2
+ import Joi from 'joi';
3
+
4
+ import User from './User';
5
+ import Group from './Group';
6
+
7
+ export default {
8
+ user: Joi.object().instance(User),
9
+ group: Joi.object().instance(Group),
10
+ acUser: Joi.number().valid(
11
+ TilmeldAccessLevels.NO_ACCESS,
12
+ TilmeldAccessLevels.READ_ACCESS,
13
+ TilmeldAccessLevels.WRITE_ACCESS,
14
+ TilmeldAccessLevels.FULL_ACCESS
15
+ ),
16
+ acGroup: Joi.number().valid(
17
+ TilmeldAccessLevels.NO_ACCESS,
18
+ TilmeldAccessLevels.READ_ACCESS,
19
+ TilmeldAccessLevels.WRITE_ACCESS,
20
+ TilmeldAccessLevels.FULL_ACCESS
21
+ ),
22
+ acOther: Joi.number().valid(
23
+ TilmeldAccessLevels.NO_ACCESS,
24
+ TilmeldAccessLevels.READ_ACCESS,
25
+ TilmeldAccessLevels.WRITE_ACCESS,
26
+ TilmeldAccessLevels.FULL_ACCESS
27
+ ),
28
+ acRead: Joi.array().items(
29
+ Joi.alternatives().try(
30
+ Joi.object().instance(User),
31
+ Joi.object().instance(Group)
32
+ )
33
+ ),
34
+ acWrite: Joi.array().items(
35
+ Joi.alternatives().try(
36
+ Joi.object().instance(User),
37
+ Joi.object().instance(Group)
38
+ )
39
+ ),
40
+ acFull: Joi.array().items(
41
+ Joi.alternatives().try(
42
+ Joi.object().instance(User),
43
+ Joi.object().instance(Group)
44
+ )
45
+ ),
46
+ };