@nymphjs/tilmeld 1.0.0-beta.45 → 1.0.0-beta.47

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.ts CHANGED
@@ -40,7 +40,7 @@ export type EventType =
40
40
  */
41
41
  export type TilmeldCheckUsernameCallback = (
42
42
  user: User & UserData,
43
- data: { username: string }
43
+ data: { username: string },
44
44
  ) => Promise<{ result: boolean; message?: string }>;
45
45
  /**
46
46
  * Theses are run before the user data checks, so the only checks before are
@@ -48,11 +48,11 @@ export type TilmeldCheckUsernameCallback = (
48
48
  */
49
49
  export type TilmeldBeforeRegisterCallback = (
50
50
  user: User & UserData,
51
- data: { password: string; additionalData?: { [k: string]: any } }
51
+ data: { password: string; additionalData?: { [k: string]: any } },
52
52
  ) => Promise<void>;
53
53
  export type TilmeldAfterRegisterCallback = (
54
54
  user: User & UserData,
55
- result: { loggedin: boolean; message: string }
55
+ result: { loggedin: boolean; message: string },
56
56
  ) => Promise<void>;
57
57
  /**
58
58
  * These are run after the authentication checks, but before the login action.
@@ -63,20 +63,20 @@ export type TilmeldBeforeLoginCallback = (
63
63
  username: string;
64
64
  password: string;
65
65
  additionalData?: { [k: string]: any };
66
- }
66
+ },
67
67
  ) => Promise<void>;
68
68
  /**
69
69
  * This is run before the transaction is committed, and you can perform
70
70
  * additional functions on the transaction, which is available in `user.$nymph`.
71
71
  */
72
72
  export type TilmeldAfterLoginCallback = (
73
- user: User & UserData
73
+ user: User & UserData,
74
74
  ) => Promise<void>;
75
75
  export type TilmeldBeforeLogoutCallback = (
76
- user: User & UserData
76
+ user: User & UserData,
77
77
  ) => Promise<void>;
78
78
  export type TilmeldAfterLogoutCallback = (
79
- user: User & UserData
79
+ user: User & UserData,
80
80
  ) => Promise<void>;
81
81
 
82
82
  export type UserData = {
@@ -303,7 +303,7 @@ export default class User extends AbleObject<UserData> {
303
303
  {
304
304
  type: '&',
305
305
  ilike: ['username', username.replace(/([\\%_])/g, (s) => `\\${s}`)],
306
- }
306
+ },
307
307
  );
308
308
  if (entity != null) {
309
309
  return entity;
@@ -329,10 +329,10 @@ export default class User extends AbleObject<UserData> {
329
329
 
330
330
  public static current(returnObjectIfNotExist: true): User & UserData;
331
331
  public static current(
332
- returnObjectIfNotExist?: false
332
+ returnObjectIfNotExist?: false,
333
333
  ): (User & UserData) | null;
334
334
  public static current(
335
- returnObjectIfNotExist?: boolean
335
+ returnObjectIfNotExist?: boolean,
336
336
  ): (User & UserData) | null {
337
337
  const tilmeld = enforceTilmeld(this);
338
338
  if (tilmeld.currentUser == null) {
@@ -370,7 +370,7 @@ export default class User extends AbleObject<UserData> {
370
370
  {
371
371
  type: '&',
372
372
  ilike: ['email', data.account.replace(/([\\%_])/g, (s) => `\\${s}`)],
373
- }
373
+ },
374
374
  );
375
375
 
376
376
  if (getUser == null) {
@@ -466,7 +466,7 @@ export default class User extends AbleObject<UserData> {
466
466
  data.secret !== user.recoverSecret ||
467
467
  strtotime(
468
468
  '+' + tilmeld.config.pwRecoveryTimeLimit,
469
- Math.floor((user.recoverSecretDate ?? 0) / 1000)
469
+ Math.floor((user.recoverSecretDate ?? 0) / 1000),
470
470
  ) *
471
471
  1000 <
472
472
  Date.now()
@@ -745,7 +745,7 @@ export default class User extends AbleObject<UserData> {
745
745
  await Promise.all(this.$data.groups?.map((e) => e.$wake()) || []);
746
746
  for (let curGroup of this.$data.groups ?? []) {
747
747
  this.$descendantGroups = this.$descendantGroups?.concat(
748
- await curGroup.$getDescendants()
748
+ await curGroup.$getDescendants(),
749
749
  );
750
750
  }
751
751
  }
@@ -764,7 +764,7 @@ export default class User extends AbleObject<UserData> {
764
764
  !tilmeld.currentUser.abilities?.includes('system/admin'))
765
765
  ) {
766
766
  throw new BadDataError(
767
- "You don't have the authority to grant or revoke system/admin."
767
+ "You don't have the authority to grant or revoke system/admin.",
768
768
  );
769
769
  }
770
770
 
@@ -776,7 +776,7 @@ export default class User extends AbleObject<UserData> {
776
776
  !tilmeld.currentUser.abilities?.includes('system/admin'))
777
777
  ) {
778
778
  throw new BadDataError(
779
- "You don't have the authority to grant or revoke tilmeld/admin."
779
+ "You don't have the authority to grant or revoke tilmeld/admin.",
780
780
  );
781
781
  }
782
782
 
@@ -788,7 +788,7 @@ export default class User extends AbleObject<UserData> {
788
788
  !tilmeld.currentUser.abilities?.includes('system/admin'))
789
789
  ) {
790
790
  throw new BadDataError(
791
- "You don't have the authority to grant or revoke tilmeld/switch."
791
+ "You don't have the authority to grant or revoke tilmeld/switch.",
792
792
  );
793
793
  }
794
794
 
@@ -808,7 +808,7 @@ export default class User extends AbleObject<UserData> {
808
808
  !tilmeld.currentUser.abilities?.includes('system/admin'))
809
809
  ) {
810
810
  throw new BadDataError(
811
- "You don't have the authority to grant or revoke system/admin."
811
+ "You don't have the authority to grant or revoke system/admin.",
812
812
  );
813
813
  }
814
814
 
@@ -820,7 +820,7 @@ export default class User extends AbleObject<UserData> {
820
820
  !tilmeld.currentUser.abilities?.includes('system/admin'))
821
821
  ) {
822
822
  throw new BadDataError(
823
- "You don't have the authority to grant or revoke tilmeld/admin."
823
+ "You don't have the authority to grant or revoke tilmeld/admin.",
824
824
  );
825
825
  }
826
826
 
@@ -832,7 +832,7 @@ export default class User extends AbleObject<UserData> {
832
832
  !tilmeld.currentUser.abilities?.includes('system/admin'))
833
833
  ) {
834
834
  throw new BadDataError(
835
- "You don't have the authority to grant or revoke tilmeld/switch."
835
+ "You don't have the authority to grant or revoke tilmeld/switch.",
836
836
  );
837
837
  }
838
838
 
@@ -891,6 +891,8 @@ export default class User extends AbleObject<UserData> {
891
891
  ) {
892
892
  // Users who can edit other users can see most of their data.
893
893
  this.$privateData = ['password', 'salt', 'totpSecret'];
894
+ this.$clientEnabledMethods.push('$hasTOTPSecret');
895
+ this.$clientEnabledMethods.push('$removeTOTPSecret');
894
896
  this.$allowlistData = undefined;
895
897
  } else if (isCurrentUser || isNewUser) {
896
898
  // Users can see their own data, and edit some of it.
@@ -1013,7 +1015,7 @@ export default class User extends AbleObject<UserData> {
1013
1015
  }
1014
1016
  }
1015
1017
  return Object.fromEntries(
1016
- abilities.map((ability) => [ability, true as true])
1018
+ abilities.map((ability) => [ability, true as true]),
1017
1019
  );
1018
1020
  }
1019
1021
 
@@ -1042,7 +1044,7 @@ export default class User extends AbleObject<UserData> {
1042
1044
 
1043
1045
  if (this.$data.secret != null) {
1044
1046
  const link = `${verifyUrl}?action=verify&id=${encodeURIComponent(
1045
- this.guid
1047
+ this.guid,
1046
1048
  )}&secret=${encodeURIComponent(this.$data.secret)}`;
1047
1049
  success =
1048
1050
  success &&
@@ -1060,13 +1062,13 @@ export default class User extends AbleObject<UserData> {
1060
1062
  verifyLink: link,
1061
1063
  },
1062
1064
  },
1063
- this
1065
+ this,
1064
1066
  ));
1065
1067
  }
1066
1068
 
1067
1069
  if (this.$data.newEmailSecret != null) {
1068
1070
  const link = `${verifyUrl}?action=verifychange&id=${encodeURIComponent(
1069
- this.guid
1071
+ this.guid,
1070
1072
  )}&secret=${encodeURIComponent(this.$data.newEmailSecret)}`;
1071
1073
  success =
1072
1074
  success &&
@@ -1086,13 +1088,13 @@ export default class User extends AbleObject<UserData> {
1086
1088
  newEmail: this.$data.newEmailAddress,
1087
1089
  },
1088
1090
  },
1089
- this
1091
+ this,
1090
1092
  ));
1091
1093
  }
1092
1094
 
1093
1095
  if (this.$data.cancelEmailSecret != null) {
1094
1096
  const link = `${verifyUrl}?action=cancelchange&id=${encodeURIComponent(
1095
- this.guid
1097
+ this.guid,
1096
1098
  )}&secret=${encodeURIComponent(this.$data.cancelEmailSecret)}`;
1097
1099
  success =
1098
1100
  success &&
@@ -1112,7 +1114,7 @@ export default class User extends AbleObject<UserData> {
1112
1114
  newEmail: this.$data.newEmailAddress ?? this.$data.email,
1113
1115
  },
1114
1116
  },
1115
- this
1117
+ this,
1116
1118
  ));
1117
1119
  }
1118
1120
 
@@ -1284,7 +1286,7 @@ export default class User extends AbleObject<UserData> {
1284
1286
  default:
1285
1287
  this.$data.salt = nanoid();
1286
1288
  this.$data.password = sha256(password + this.$data.salt).toString(
1287
- Base64
1289
+ Base64,
1288
1290
  );
1289
1291
  break;
1290
1292
  }
@@ -1447,39 +1449,46 @@ export default class User extends AbleObject<UserData> {
1447
1449
  * @param data The input data from the client.
1448
1450
  * @returns An object with a boolean 'result' entry and a 'message' entry.
1449
1451
  */
1450
- public async $removeTOTPSecret(data: {
1452
+ public async $removeTOTPSecret(data?: {
1451
1453
  password: string;
1452
1454
  code: string;
1453
1455
  }): Promise<{ result: boolean; message: string }> {
1454
- if (!this.$checkPassword(data.password ?? '')) {
1455
- return { result: false, message: 'Incorrect password.' };
1456
- }
1457
-
1458
- if (this.$data.totpSecret == null) {
1459
- return { result: false, message: "You don't have a 2FA secret." };
1460
- }
1456
+ const tilmeld = enforceTilmeld(this);
1461
1457
 
1462
- if (
1463
- data.code == null ||
1464
- typeof data.code !== 'string' ||
1465
- data.code.length !== 6
1466
- ) {
1467
- return { result: false, message: '2FA code is invalid.' };
1468
- }
1458
+ if (data) {
1459
+ if (!this.$checkPassword(data.password ?? '')) {
1460
+ return { result: false, message: 'Incorrect password.' };
1461
+ }
1469
1462
 
1470
- const tilmeld = enforceTilmeld(this);
1463
+ if (
1464
+ data.code == null ||
1465
+ typeof data.code !== 'string' ||
1466
+ data.code.length !== 6
1467
+ ) {
1468
+ return { result: false, message: '2FA code is invalid.' };
1469
+ }
1471
1470
 
1472
- const totp = new TOTP({
1473
- issuer: tilmeld.config.appName,
1474
- label: this.$data.username,
1475
- algorithm: 'SHA1',
1476
- digits: 6,
1477
- period: 30,
1478
- secret: this.$data.totpSecret,
1479
- });
1471
+ if (this.$data.totpSecret == null) {
1472
+ return { result: false, message: "You don't have a 2FA secret." };
1473
+ }
1480
1474
 
1481
- if (totp.validate({ token: data.code, window: 2 }) == null) {
1482
- return { result: false, message: '2FA code is incorrect.' };
1475
+ const totp = new TOTP({
1476
+ issuer: tilmeld.config.appName,
1477
+ label: this.$data.username,
1478
+ algorithm: 'SHA1',
1479
+ digits: 6,
1480
+ period: 30,
1481
+ secret: this.$data.totpSecret,
1482
+ });
1483
+
1484
+ if (totp.validate({ token: data.code, window: 2 }) == null) {
1485
+ return { result: false, message: '2FA code is incorrect.' };
1486
+ }
1487
+ } else if (!tilmeld.gatekeeper('tilmeld/admin')) {
1488
+ return {
1489
+ result: false,
1490
+ message: 'You must provide your password and 2FA code.',
1491
+ };
1483
1492
  }
1484
1493
 
1485
1494
  delete this.$data.totpSecret;
@@ -1487,7 +1496,7 @@ export default class User extends AbleObject<UserData> {
1487
1496
  if (await this.$save()) {
1488
1497
  return {
1489
1498
  result: true,
1490
- message: 'Your two factor secret has been removed.',
1499
+ message: 'Two factor secret has been removed.',
1491
1500
  };
1492
1501
  } else {
1493
1502
  return { result: false, message: "Couldn't remove two factor secret." };
@@ -1505,10 +1514,16 @@ export default class User extends AbleObject<UserData> {
1505
1514
  if (this.$data.username == null || !this.$data.username.length) {
1506
1515
  return { result: false, message: 'Please specify a username.' };
1507
1516
  }
1508
- if (
1509
- tilmeld.config.maxUsernameLength > 0 &&
1510
- this.$data.username.length > tilmeld.config.maxUsernameLength
1511
- ) {
1517
+ if (this.$data.username.length < tilmeld.config.minUsernameLength) {
1518
+ return {
1519
+ result: false,
1520
+ message:
1521
+ 'Usernames must be at least ' +
1522
+ tilmeld.config.minUsernameLength +
1523
+ ' characters.',
1524
+ };
1525
+ }
1526
+ if (this.$data.username.length > tilmeld.config.maxUsernameLength) {
1512
1527
  return {
1513
1528
  result: false,
1514
1529
  message:
@@ -1521,7 +1536,7 @@ export default class User extends AbleObject<UserData> {
1521
1536
  if (
1522
1537
  difference(
1523
1538
  this.$data.username.split(''),
1524
- tilmeld.config.validChars.split('')
1539
+ tilmeld.config.validChars.split(''),
1525
1540
  ).length
1526
1541
  ) {
1527
1542
  return {
@@ -1548,7 +1563,7 @@ export default class User extends AbleObject<UserData> {
1548
1563
  }
1549
1564
  const test = await this.$nymph.getEntity(
1550
1565
  { class: tilmeld.User, skipAc: true },
1551
- selector
1566
+ selector,
1552
1567
  );
1553
1568
  if (test != null) {
1554
1569
  return { result: false, message: 'That username is taken.' };
@@ -1576,10 +1591,16 @@ export default class User extends AbleObject<UserData> {
1576
1591
  if (this.$data.username == null || !this.$data.username.length) {
1577
1592
  return { result: false, message: 'Please specify an email.' };
1578
1593
  }
1579
- if (
1580
- tilmeld.config.maxUsernameLength > 0 &&
1581
- this.$data.username.length > tilmeld.config.maxUsernameLength
1582
- ) {
1594
+ if (this.$data.username.length < tilmeld.config.minUsernameLength) {
1595
+ return {
1596
+ result: false,
1597
+ message:
1598
+ 'Emails must be at least ' +
1599
+ tilmeld.config.minUsernameLength +
1600
+ ' characters.',
1601
+ };
1602
+ }
1603
+ if (this.$data.username.length > tilmeld.config.maxUsernameLength) {
1583
1604
  return {
1584
1605
  result: false,
1585
1606
  message:
@@ -1622,7 +1643,7 @@ export default class User extends AbleObject<UserData> {
1622
1643
  }
1623
1644
  const test = await this.$nymph.getEntity(
1624
1645
  { class: tilmeld.User, skipAc: true },
1625
- selector
1646
+ selector,
1626
1647
  );
1627
1648
  if (test != null) {
1628
1649
  return {
@@ -1666,7 +1687,7 @@ export default class User extends AbleObject<UserData> {
1666
1687
  }
1667
1688
  const test = await this.$nymph.getEntity(
1668
1689
  { class: tilmeld.User, skipAc: true },
1669
- selector
1690
+ selector,
1670
1691
  );
1671
1692
  if (test != null) {
1672
1693
  return { result: false, message: 'Phone number is in use.' };
@@ -1762,7 +1783,7 @@ export default class User extends AbleObject<UserData> {
1762
1783
  {
1763
1784
  type: '&',
1764
1785
  equal: ['defaultPrimary', true],
1765
- }
1786
+ },
1766
1787
  );
1767
1788
  if (parent != null) {
1768
1789
  generatedPrimaryGroup.parent = parent;
@@ -1784,7 +1805,7 @@ export default class User extends AbleObject<UserData> {
1784
1805
  {
1785
1806
  type: '&',
1786
1807
  equal: ['defaultPrimary', true],
1787
- }
1808
+ },
1788
1809
  );
1789
1810
  if (group != null) {
1790
1811
  this.$data.group = group;
@@ -1799,7 +1820,7 @@ export default class User extends AbleObject<UserData> {
1799
1820
  {
1800
1821
  type: '&',
1801
1822
  equal: ['unverifiedSecondary', true],
1802
- }
1823
+ },
1803
1824
  );
1804
1825
  } else {
1805
1826
  // Add the default secondaries.
@@ -1808,7 +1829,7 @@ export default class User extends AbleObject<UserData> {
1808
1829
  {
1809
1830
  type: '&',
1810
1831
  equal: ['defaultSecondary', true],
1811
- }
1832
+ },
1812
1833
  );
1813
1834
  }
1814
1835
 
@@ -1858,7 +1879,7 @@ export default class User extends AbleObject<UserData> {
1858
1879
  userPhone: this.$data.phone,
1859
1880
  },
1860
1881
  },
1861
- this
1882
+ this,
1862
1883
  );
1863
1884
  }
1864
1885
 
@@ -1961,7 +1982,7 @@ export default class User extends AbleObject<UserData> {
1961
1982
  this.$data.abilities?.includes('system/admin')
1962
1983
  ) {
1963
1984
  throw new BadDataError(
1964
- "You don't have the authority to modify system admins."
1985
+ "You don't have the authority to modify system admins.",
1965
1986
  );
1966
1987
  }
1967
1988
 
@@ -2079,10 +2100,10 @@ export default class User extends AbleObject<UserData> {
2079
2100
  new Date(
2080
2101
  strtotime(
2081
2102
  '+' + tilmeld.config.emailRateLimit,
2082
- Math.floor(this.$data.emailChangeDate / 1000)
2083
- ) * 1000
2103
+ Math.floor(this.$data.emailChangeDate / 1000),
2104
+ ) * 1000,
2084
2105
  ).toString() +
2085
- ' to change your email address again.'
2106
+ ' to change your email address again.',
2086
2107
  );
2087
2108
  } else {
2088
2109
  if (
@@ -2237,7 +2258,7 @@ export default class User extends AbleObject<UserData> {
2237
2258
  this.$data.abilities?.includes('system/admin')
2238
2259
  ) {
2239
2260
  throw new BadDataError(
2240
- "You don't have the authority to delete system admins."
2261
+ "You don't have the authority to delete system admins.",
2241
2262
  );
2242
2263
  }
2243
2264
  if (tilmeld.User.current(true).$is(this)) {
@@ -2262,7 +2283,7 @@ export default class User extends AbleObject<UserData> {
2262
2283
  ? TilmeldBeforeLogoutCallback
2263
2284
  : T extends 'afterLogout'
2264
2285
  ? TilmeldAfterLogoutCallback
2265
- : never
2286
+ : never,
2266
2287
  ) {
2267
2288
  const prop = (event + 'Callbacks') as T extends 'checkUsername'
2268
2289
  ? 'checkUsernameCallbacks'
@@ -2303,7 +2324,7 @@ export default class User extends AbleObject<UserData> {
2303
2324
  ? TilmeldBeforeLogoutCallback
2304
2325
  : T extends 'afterLogout'
2305
2326
  ? TilmeldAfterLogoutCallback
2306
- : never
2327
+ : never,
2307
2328
  ) {
2308
2329
  const prop = (event + 'Callbacks') as T extends 'checkUsername'
2309
2330
  ? 'checkUsernameCallbacks'
package/src/conf/d.ts CHANGED
@@ -206,7 +206,11 @@ export interface Config {
206
206
  */
207
207
  validEmailRegexNotice: string;
208
208
  /**
209
- * The maximum length for usernames. Infinity for unlimited.
209
+ * The minimum length for usernames.
210
+ */
211
+ minUsernameLength: number;
212
+ /**
213
+ * The maximum length for usernames. `Infinity` for unlimited.
210
214
  */
211
215
  maxUsernameLength: number;
212
216
  /**
@@ -233,7 +237,7 @@ export interface Config {
233
237
  jwtBuilder: (
234
238
  config: Config,
235
239
  user: User & UserData,
236
- switchToken?: boolean
240
+ switchToken?: boolean,
237
241
  ) => string;
238
242
  /**
239
243
  * Function to verify that a JWT was signed with the secret key, validate its
@@ -247,7 +251,7 @@ export interface Config {
247
251
  jwtExtract: (
248
252
  config: Config,
249
253
  token: string,
250
- xsrfToken?: string
254
+ xsrfToken?: string,
251
255
  ) => { guid: string; issued: Date; expire: Date } | null;
252
256
  /**
253
257
  * The absolute path to the email template directory. Used by the default
@@ -264,7 +268,7 @@ export interface Config {
264
268
  configEmail: (
265
269
  tilmeld: Tilmeld,
266
270
  options: EmailOptions,
267
- user: User & UserData
271
+ user: User & UserData,
268
272
  ) => Promise<EmailConfig>;
269
273
  /**
270
274
  * Send an email to a user. Uses `email-templates` by default.
@@ -294,7 +298,7 @@ export interface Config {
294
298
  sendEmail: (
295
299
  tilmeld: Tilmeld,
296
300
  options: EmailOptions,
297
- user: User & UserData
301
+ user: User & UserData,
298
302
  ) => Promise<boolean>;
299
303
  /**
300
304
  * The address you'd like to receive a notification of registered users, if
@@ -49,6 +49,7 @@ export default {
49
49
  validEmailRegex:
50
50
  /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
51
51
  validEmailRegexNotice: 'Email must be a correctly formatted address.',
52
+ minUsernameLength: 1,
52
53
  maxUsernameLength: 128,
53
54
  jwtSecret: '',
54
55
  jwtExpire: 60 * 60 * 24 * 7 * 8, // 8 weeks(ish)
@@ -68,7 +69,7 @@ export default {
68
69
  xsrfToken: 'TILMELDXSRF-' + nanoid(),
69
70
  },
70
71
  secret,
71
- { expiresIn: switchToken ? config.jwtSwitchExpire : config.jwtExpire }
72
+ { expiresIn: switchToken ? config.jwtSwitchExpire : config.jwtExpire },
72
73
  );
73
74
  },
74
75
  jwtExtract: (config, token, xsrfToken?) => {
@@ -128,14 +129,14 @@ export default {
128
129
  },
129
130
  sendEmail: async (tilmeld, options, user) => {
130
131
  const email = new Email(
131
- await tilmeld.config.configEmail(tilmeld, options, user)
132
+ await tilmeld.config.configEmail(tilmeld, options, user),
132
133
  );
133
134
  try {
134
135
  const result = await email.send({
135
136
  ...options,
136
137
  template: path.join(
137
138
  tilmeld.config.emailTemplateDir,
138
- options.template ?? '.'
139
+ options.template ?? '.',
139
140
  ),
140
141
  locals: {
141
142
  // System
@@ -205,13 +206,13 @@ export default {
205
206
  name: 'control characters',
206
207
  invert: true,
207
208
  })
208
- .max(256)
209
+ .max(256),
209
210
  ),
210
211
  defaultPrimary: Joi.boolean(),
211
212
  defaultSecondary: Joi.boolean(),
212
213
  unverifiedSecondary: Joi.boolean(),
213
214
  }),
214
- 'Invalid Group: '
215
+ 'Invalid Group: ',
215
216
  );
216
217
  },
217
218
  validatorUser: (user) => {
@@ -274,7 +275,7 @@ export default {
274
275
  name: 'control characters',
275
276
  invert: true,
276
277
  })
277
- .max(256)
278
+ .max(256),
278
279
  ),
279
280
  inheritAbilities: Joi.boolean(),
280
281
  secret: Joi.string()
@@ -322,7 +323,7 @@ export default {
322
323
  .max(40)
323
324
  .pattern(/^[A-Z234567]+$/, 'base32 encoded unpadded'),
324
325
  }),
325
- 'Invalid User: '
326
+ 'Invalid User: ',
326
327
  );
327
328
  },
328
329
  } as Config;
@@ -11,36 +11,36 @@ export default {
11
11
  TilmeldAccessLevels.NO_ACCESS,
12
12
  TilmeldAccessLevels.READ_ACCESS,
13
13
  TilmeldAccessLevels.WRITE_ACCESS,
14
- TilmeldAccessLevels.FULL_ACCESS
14
+ TilmeldAccessLevels.FULL_ACCESS,
15
15
  ),
16
16
  acGroup: Joi.number().valid(
17
17
  TilmeldAccessLevels.NO_ACCESS,
18
18
  TilmeldAccessLevels.READ_ACCESS,
19
19
  TilmeldAccessLevels.WRITE_ACCESS,
20
- TilmeldAccessLevels.FULL_ACCESS
20
+ TilmeldAccessLevels.FULL_ACCESS,
21
21
  ),
22
22
  acOther: Joi.number().valid(
23
23
  TilmeldAccessLevels.NO_ACCESS,
24
24
  TilmeldAccessLevels.READ_ACCESS,
25
25
  TilmeldAccessLevels.WRITE_ACCESS,
26
- TilmeldAccessLevels.FULL_ACCESS
26
+ TilmeldAccessLevels.FULL_ACCESS,
27
27
  ),
28
28
  acRead: Joi.array().items(
29
29
  Joi.alternatives().try(
30
30
  Joi.object().instance(User),
31
- Joi.object().instance(Group)
32
- )
31
+ Joi.object().instance(Group),
32
+ ),
33
33
  ),
34
34
  acWrite: Joi.array().items(
35
35
  Joi.alternatives().try(
36
36
  Joi.object().instance(User),
37
- Joi.object().instance(Group)
38
- )
37
+ Joi.object().instance(Group),
38
+ ),
39
39
  ),
40
40
  acFull: Joi.array().items(
41
41
  Joi.alternatives().try(
42
42
  Joi.object().instance(User),
43
- Joi.object().instance(Group)
44
- )
43
+ Joi.object().instance(Group),
44
+ ),
45
45
  ),
46
46
  };