@nymphjs/tilmeld 1.0.0-beta.13 → 1.0.0-beta.131

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.
Files changed (105) hide show
  1. package/CHANGELOG.md +604 -0
  2. package/README.md +21 -5
  3. package/dist/AbleObject.d.ts +15 -0
  4. package/dist/AbleObject.js +18 -6
  5. package/dist/AbleObject.js.map +1 -1
  6. package/dist/Group.d.ts +183 -19
  7. package/dist/Group.js +814 -440
  8. package/dist/Group.js.map +1 -1
  9. package/dist/Group.testArtifacts.d.ts +3 -0
  10. package/dist/Group.testArtifacts.js +120 -0
  11. package/dist/Group.testArtifacts.js.map +1 -0
  12. package/dist/Tilmeld.d.ts +241 -12
  13. package/dist/Tilmeld.js +725 -286
  14. package/dist/Tilmeld.js.map +1 -1
  15. package/dist/Tilmeld.types.d.ts +5 -5
  16. package/dist/Tilmeld.types.js +1 -2
  17. package/dist/User.d.ts +396 -26
  18. package/dist/User.js +1955 -1058
  19. package/dist/User.js.map +1 -1
  20. package/dist/User.testArtifacts.d.ts +3 -0
  21. package/dist/User.testArtifacts.js +175 -0
  22. package/dist/User.testArtifacts.js.map +1 -0
  23. package/dist/conf/defaults.d.ts +1 -1
  24. package/dist/conf/defaults.js +196 -141
  25. package/dist/conf/defaults.js.map +1 -1
  26. package/dist/conf/index.d.ts +355 -2
  27. package/dist/conf/index.js +2 -8
  28. package/dist/conf/index.js.map +1 -1
  29. package/dist/decorators/index.d.ts +2 -0
  30. package/dist/decorators/index.js +3 -0
  31. package/dist/decorators/index.js.map +1 -0
  32. package/dist/decorators/requireAbility.d.ts +10 -0
  33. package/dist/decorators/requireAbility.js +21 -0
  34. package/dist/decorators/requireAbility.js.map +1 -0
  35. package/dist/decorators/requireAuthentication.d.ts +8 -0
  36. package/dist/decorators/requireAuthentication.js +16 -0
  37. package/dist/decorators/requireAuthentication.js.map +1 -0
  38. package/dist/enforceTilmeld.d.ts +3 -0
  39. package/dist/enforceTilmeld.js +18 -0
  40. package/dist/enforceTilmeld.js.map +1 -0
  41. package/dist/errors/AccessControlError.d.ts +2 -1
  42. package/dist/errors/AccessControlError.js +3 -6
  43. package/dist/errors/AccessControlError.js.map +1 -1
  44. package/dist/errors/BadDataError.d.ts +2 -1
  45. package/dist/errors/BadDataError.js +3 -6
  46. package/dist/errors/BadDataError.js.map +1 -1
  47. package/dist/errors/BadEmailError.d.ts +2 -1
  48. package/dist/errors/BadEmailError.js +3 -6
  49. package/dist/errors/BadEmailError.js.map +1 -1
  50. package/dist/errors/BadUsernameError.d.ts +2 -1
  51. package/dist/errors/BadUsernameError.js +3 -6
  52. package/dist/errors/BadUsernameError.js.map +1 -1
  53. package/dist/errors/CouldNotChangeDefaultPrimaryGroupError.js +1 -5
  54. package/dist/errors/CouldNotChangeDefaultPrimaryGroupError.js.map +1 -1
  55. package/dist/errors/EmailChangeRateLimitExceededError.js +1 -5
  56. package/dist/errors/EmailChangeRateLimitExceededError.js.map +1 -1
  57. package/dist/errors/index.d.ts +6 -6
  58. package/dist/errors/index.js +6 -22
  59. package/dist/errors/index.js.map +1 -1
  60. package/dist/index.d.ts +12 -10
  61. package/dist/index.js +17 -35
  62. package/dist/index.js.map +1 -1
  63. package/dist/testArtifacts.d.ts +23 -0
  64. package/dist/testArtifacts.js +1317 -0
  65. package/dist/testArtifacts.js.map +1 -0
  66. package/dist/tilmeldJoiProps.d.ts +3 -3
  67. package/dist/tilmeldJoiProps.js +13 -18
  68. package/dist/tilmeldJoiProps.js.map +1 -1
  69. package/jest.config.js +31 -5
  70. package/package.json +49 -36
  71. package/src/AbleObject.ts +2 -2
  72. package/src/Group.testArtifacts.ts +159 -0
  73. package/src/Group.ts +647 -241
  74. package/src/Tilmeld.ts +550 -315
  75. package/src/Tilmeld.types.ts +5 -5
  76. package/src/User.testArtifacts.ts +226 -0
  77. package/src/User.ts +1657 -637
  78. package/src/conf/defaults.ts +172 -109
  79. package/src/conf/index.ts +370 -2
  80. package/src/decorators/index.ts +2 -0
  81. package/src/decorators/requireAbility.ts +26 -0
  82. package/src/decorators/requireAuthentication.ts +19 -0
  83. package/src/enforceTilmeld.ts +20 -0
  84. package/src/errors/AccessControlError.ts +4 -2
  85. package/src/errors/BadDataError.ts +4 -2
  86. package/src/errors/BadEmailError.ts +4 -2
  87. package/src/errors/BadUsernameError.ts +4 -2
  88. package/src/errors/index.ts +6 -6
  89. package/src/index.ts +13 -10
  90. package/src/testArtifacts.ts +2098 -0
  91. package/src/tilmeldJoiProps.ts +8 -23
  92. package/tsconfig.json +6 -3
  93. package/typedoc.json +4 -0
  94. package/dist/Group.test.d.ts +0 -1
  95. package/dist/Group.test.js +0 -48
  96. package/dist/Group.test.js.map +0 -1
  97. package/dist/User.test.d.ts +0 -1
  98. package/dist/User.test.js +0 -51
  99. package/dist/User.test.js.map +0 -1
  100. package/dist/conf/d.d.ts +0 -55
  101. package/dist/conf/d.js +0 -3
  102. package/dist/conf/d.js.map +0 -1
  103. package/src/Group.test.ts +0 -58
  104. package/src/User.test.ts +0 -61
  105. package/src/conf/d.ts +0 -303
@@ -1,8 +1,8 @@
1
1
  import { TilmeldAccessLevels } from '@nymphjs/nymph';
2
2
  import Joi from 'joi';
3
3
 
4
- import User from './User';
5
- import Group from './Group';
4
+ import User from './User.js';
5
+ import Group from './Group.js';
6
6
 
7
7
  export default {
8
8
  user: Joi.object().instance(User),
@@ -11,36 +11,21 @@ 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
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
- )
26
+ TilmeldAccessLevels.FULL_ACCESS,
45
27
  ),
28
+ acRead: Joi.array().items(Joi.string().pattern(/^[0-9a-f]{24}$/i, 'GUID')),
29
+ acWrite: Joi.array().items(Joi.string().pattern(/^[0-9a-f]{24}$/i, 'GUID')),
30
+ acFull: Joi.array().items(Joi.string().pattern(/^[0-9a-f]{24}$/i, 'GUID')),
46
31
  };
package/tsconfig.json CHANGED
@@ -2,10 +2,13 @@
2
2
  "extends": "@tsconfig/recommended/tsconfig.json",
3
3
 
4
4
  "compilerOptions": {
5
- "lib": ["ES2021"],
6
- "target": "ES2021",
5
+ "types": ["node", "jest"],
6
+ "module": "nodenext",
7
+ "moduleResolution": "nodenext",
8
+ "lib": ["es2024"],
9
+ "target": "es2024",
7
10
  "noImplicitAny": true,
8
- "removeComments": true,
11
+ "removeComments": false,
9
12
  "sourceMap": true,
10
13
  "outDir": "dist",
11
14
  "resolveJsonModule": true,
package/typedoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["../../typedoc.base.json"],
3
+ "entryPoints": ["src/index.ts"]
4
+ }
@@ -1 +0,0 @@
1
- export {};
@@ -1,48 +0,0 @@
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 driver_sqlite3_1 = require("@nymphjs/driver-sqlite3");
7
- const nymph_1 = require("@nymphjs/nymph");
8
- const Tilmeld_1 = __importDefault(require("./Tilmeld"));
9
- const defaults_1 = __importDefault(require("./conf/defaults"));
10
- const tilmeld = new Tilmeld_1.default({
11
- appName: 'My App',
12
- appUrl: 'http://localhost:8080',
13
- cookieDomain: 'localhost',
14
- cookiePath: '/',
15
- setupPath: '/user',
16
- emailUsernames: false,
17
- verifyRedirect: 'http://localhost:8080',
18
- verifyChangeRedirect: 'http://localhost:8080',
19
- cancelChangeRedirect: 'http://localhost:8080',
20
- jwtSecret: 'shhhhh',
21
- });
22
- const _nymph = new nymph_1.Nymph({}, new driver_sqlite3_1.SQLite3Driver({
23
- filename: ':memory:',
24
- }), tilmeld);
25
- const Group = tilmeld.Group;
26
- describe('Group', () => {
27
- async function makeNewGroup() {
28
- const newGroup = await Group.factory();
29
- newGroup.groupname = 'new-group';
30
- newGroup.email = 'newgroup@localhost';
31
- newGroup.name = 'New Group';
32
- return newGroup;
33
- }
34
- it('new group passes validation', async () => {
35
- const validGroup = await makeNewGroup();
36
- expect(() => {
37
- defaults_1.default.validatorGroup(validGroup);
38
- }).not.toThrow();
39
- });
40
- it("doesn't allow unknown keys", async () => {
41
- const invalidGroup = await makeNewGroup();
42
- invalidGroup.unknown = 'I should cause an error.';
43
- expect(() => {
44
- defaults_1.default.validatorGroup(invalidGroup);
45
- }).toThrow('Invalid Group: "unknown" is not allowed');
46
- });
47
- });
48
- //# sourceMappingURL=Group.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Group.test.js","sourceRoot":"","sources":["../src/Group.test.ts"],"names":[],"mappings":";;;;;AAAA,4DAAwD;AACxD,0CAAuC;AAEvC,wDAAgC;AAChC,+DAAuC;AAEvC,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC;IAC1B,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,uBAAuB;IAC/B,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,GAAG;IACf,SAAS,EAAE,OAAO;IAClB,cAAc,EAAE,KAAK;IACrB,cAAc,EAAE,uBAAuB;IACvC,oBAAoB,EAAE,uBAAuB;IAC7C,oBAAoB,EAAE,uBAAuB;IAC7C,SAAS,EAAE,QAAQ;CACpB,CAAC,CAAC;AACH,MAAM,MAAM,GAAG,IAAI,aAAK,CACtB,EAAE,EACF,IAAI,8BAAa,CAAC;IAChB,QAAQ,EAAE,UAAU;CACrB,CAAC,EACF,OAAO,CACR,CAAC;AAEF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AAE5B,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,KAAK,UAAU,YAAY;QACzB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QAEvC,QAAQ,CAAC,SAAS,GAAG,WAAW,CAAC;QACjC,QAAQ,CAAC,KAAK,GAAG,oBAAoB,CAAC;QACtC,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAC;QAE5B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,UAAU,GAAG,MAAM,YAAY,EAAE,CAAC;QAExC,MAAM,CAAC,GAAG,EAAE;YACV,kBAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,YAAY,GAAG,MAAM,YAAY,EAAE,CAAC;QAG1C,YAAY,CAAC,OAAO,GAAG,0BAA0B,CAAC;QAElD,MAAM,CAAC,GAAG,EAAE;YACV,kBAAQ,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- export {};
package/dist/User.test.js DELETED
@@ -1,51 +0,0 @@
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 driver_sqlite3_1 = require("@nymphjs/driver-sqlite3");
7
- const nymph_1 = require("@nymphjs/nymph");
8
- const Tilmeld_1 = __importDefault(require("./Tilmeld"));
9
- const defaults_1 = __importDefault(require("./conf/defaults"));
10
- const tilmeld = new Tilmeld_1.default({
11
- appName: 'My App',
12
- appUrl: 'http://localhost:8080',
13
- cookieDomain: 'localhost',
14
- cookiePath: '/',
15
- setupPath: '/user',
16
- emailUsernames: false,
17
- verifyRedirect: 'http://localhost:8080',
18
- verifyChangeRedirect: 'http://localhost:8080',
19
- cancelChangeRedirect: 'http://localhost:8080',
20
- jwtSecret: 'shhhhh',
21
- });
22
- const _nymph = new nymph_1.Nymph({}, new driver_sqlite3_1.SQLite3Driver({
23
- filename: ':memory:',
24
- }), tilmeld);
25
- const User = tilmeld.User;
26
- describe('User', () => {
27
- async function makeNewUser() {
28
- const newUser = await User.factory();
29
- newUser.username = 'new-user';
30
- newUser.email = 'newuser@localhost';
31
- newUser.nameFirst = 'New';
32
- newUser.nameLast = 'User';
33
- newUser.name = 'New User';
34
- newUser.$password('password');
35
- return newUser;
36
- }
37
- it('new user passes validation', async () => {
38
- const validUser = await makeNewUser();
39
- expect(() => {
40
- defaults_1.default.validatorUser(validUser);
41
- }).not.toThrow();
42
- });
43
- it("doesn't allow unknown keys", async () => {
44
- const invalidUser = await makeNewUser();
45
- invalidUser.unknown = 'I should cause an error.';
46
- expect(() => {
47
- defaults_1.default.validatorUser(invalidUser);
48
- }).toThrow('Invalid User: "unknown" is not allowed');
49
- });
50
- });
51
- //# sourceMappingURL=User.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"User.test.js","sourceRoot":"","sources":["../src/User.test.ts"],"names":[],"mappings":";;;;;AAAA,4DAAwD;AACxD,0CAAuC;AAEvC,wDAAgC;AAChC,+DAAuC;AAEvC,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC;IAC1B,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,uBAAuB;IAC/B,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,GAAG;IACf,SAAS,EAAE,OAAO;IAClB,cAAc,EAAE,KAAK;IACrB,cAAc,EAAE,uBAAuB;IACvC,oBAAoB,EAAE,uBAAuB;IAC7C,oBAAoB,EAAE,uBAAuB;IAC7C,SAAS,EAAE,QAAQ;CACpB,CAAC,CAAC;AACH,MAAM,MAAM,GAAG,IAAI,aAAK,CACtB,EAAE,EACF,IAAI,8BAAa,CAAC;IAChB,QAAQ,EAAE,UAAU;CACrB,CAAC,EACF,OAAO,CACR,CAAC;AAEF,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;AAE1B,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,KAAK,UAAU,WAAW;QACxB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QAErC,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC;QAC9B,OAAO,CAAC,KAAK,GAAG,mBAAmB,CAAC;QACpC,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC;QAC1B,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC;QAC1B,OAAO,CAAC,IAAI,GAAG,UAAU,CAAC;QAC1B,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAE9B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,SAAS,GAAG,MAAM,WAAW,EAAE,CAAC;QAEtC,MAAM,CAAC,GAAG,EAAE;YACV,kBAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,WAAW,GAAG,MAAM,WAAW,EAAE,CAAC;QAGxC,WAAW,CAAC,OAAO,GAAG,0BAA0B,CAAC;QAEjD,MAAM,CAAC,GAAG,EAAE;YACV,kBAAQ,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/conf/d.d.ts DELETED
@@ -1,55 +0,0 @@
1
- import { EmailOptions, EmailConfig } from 'email-templates';
2
- import type Tilmeld from '../Tilmeld';
3
- import Group, { GroupData } from '../Group';
4
- import User, { UserData } from '../User';
5
- export interface Config {
6
- appName: string;
7
- appUrl: string;
8
- cookieDomain: string;
9
- cookiePath: string;
10
- setupPath: string;
11
- createAdmin: boolean;
12
- emailUsernames: boolean;
13
- allowRegistration: boolean;
14
- allowUsernameChange: boolean;
15
- enableUserSearch: boolean;
16
- enableGroupSearch: boolean;
17
- clientReadableUIDs: string[];
18
- clientEnabledUIDs: string[];
19
- clientSetabledUIDs: string[];
20
- userFields: string[];
21
- regFields: string[];
22
- verifyEmail: boolean;
23
- verifyRedirect: string;
24
- verifyChangeRedirect: string;
25
- cancelChangeRedirect: string;
26
- unverifiedAccess: boolean;
27
- emailRateLimit: string;
28
- pwRecovery: boolean;
29
- pwRecoveryTimeLimit: string;
30
- pwMethod: 'plain' | 'digest' | 'salt';
31
- generatePrimary: boolean;
32
- highestPrimary: string | boolean;
33
- highestSecondary: string | boolean;
34
- validChars: string;
35
- validCharsNotice: string;
36
- validRegex: RegExp;
37
- validRegexNotice: string;
38
- validEmailRegex: RegExp;
39
- validEmailRegexNotice: string;
40
- maxUsernameLength: number;
41
- jwtSecret: string;
42
- jwtExpire: number;
43
- jwtRenew: number;
44
- jwtBuilder: (config: Config, user: User) => string;
45
- jwtExtract: (config: Config, token: string, xsrfToken?: string) => {
46
- guid: string;
47
- expire: Date;
48
- } | null;
49
- emailTemplateDir: string;
50
- configEmail: (tilmeld: Tilmeld, options: EmailOptions, user: User & UserData) => Promise<EmailConfig>;
51
- sendEmail: (tilmeld: Tilmeld, options: EmailOptions, user: User & UserData) => Promise<boolean>;
52
- userRegisteredRecipient: string | null;
53
- validatorGroup: (group: Group & GroupData) => void;
54
- validatorUser: (user: User & UserData) => void;
55
- }
package/dist/conf/d.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=d.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"d.js","sourceRoot":"","sources":["../../src/conf/d.ts"],"names":[],"mappings":""}
package/src/Group.test.ts DELETED
@@ -1,58 +0,0 @@
1
- import { SQLite3Driver } from '@nymphjs/driver-sqlite3';
2
- import { Nymph } from '@nymphjs/nymph';
3
-
4
- import Tilmeld from './Tilmeld';
5
- import defaults from './conf/defaults';
6
-
7
- const tilmeld = new Tilmeld({
8
- appName: 'My App',
9
- appUrl: 'http://localhost:8080',
10
- cookieDomain: 'localhost',
11
- cookiePath: '/',
12
- setupPath: '/user',
13
- emailUsernames: false,
14
- verifyRedirect: 'http://localhost:8080',
15
- verifyChangeRedirect: 'http://localhost:8080',
16
- cancelChangeRedirect: 'http://localhost:8080',
17
- jwtSecret: 'shhhhh',
18
- });
19
- const _nymph = new Nymph(
20
- {},
21
- new SQLite3Driver({
22
- filename: ':memory:',
23
- }),
24
- tilmeld
25
- );
26
-
27
- const Group = tilmeld.Group;
28
-
29
- describe('Group', () => {
30
- async function makeNewGroup() {
31
- const newGroup = await Group.factory();
32
-
33
- newGroup.groupname = 'new-group';
34
- newGroup.email = 'newgroup@localhost';
35
- newGroup.name = 'New Group';
36
-
37
- return newGroup;
38
- }
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
-
48
- it("doesn't allow unknown keys", async () => {
49
- const invalidGroup = await makeNewGroup();
50
-
51
- // @ts-ignore: testing unknown keys
52
- invalidGroup.unknown = 'I should cause an error.';
53
-
54
- expect(() => {
55
- defaults.validatorGroup(invalidGroup);
56
- }).toThrow('Invalid Group: "unknown" is not allowed');
57
- });
58
- });
package/src/User.test.ts DELETED
@@ -1,61 +0,0 @@
1
- import { SQLite3Driver } from '@nymphjs/driver-sqlite3';
2
- import { Nymph } from '@nymphjs/nymph';
3
-
4
- import Tilmeld from './Tilmeld';
5
- import defaults from './conf/defaults';
6
-
7
- const tilmeld = new Tilmeld({
8
- appName: 'My App',
9
- appUrl: 'http://localhost:8080',
10
- cookieDomain: 'localhost',
11
- cookiePath: '/',
12
- setupPath: '/user',
13
- emailUsernames: false,
14
- verifyRedirect: 'http://localhost:8080',
15
- verifyChangeRedirect: 'http://localhost:8080',
16
- cancelChangeRedirect: 'http://localhost:8080',
17
- jwtSecret: 'shhhhh',
18
- });
19
- const _nymph = new Nymph(
20
- {},
21
- new SQLite3Driver({
22
- filename: ':memory:',
23
- }),
24
- tilmeld
25
- );
26
-
27
- const User = tilmeld.User;
28
-
29
- describe('User', () => {
30
- async function makeNewUser() {
31
- const newUser = await User.factory();
32
-
33
- newUser.username = 'new-user';
34
- newUser.email = 'newuser@localhost';
35
- newUser.nameFirst = 'New';
36
- newUser.nameLast = 'User';
37
- newUser.name = 'New User';
38
- newUser.$password('password');
39
-
40
- return newUser;
41
- }
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
-
51
- it("doesn't allow unknown keys", async () => {
52
- const invalidUser = await makeNewUser();
53
-
54
- // @ts-ignore: testing unknown keys
55
- invalidUser.unknown = 'I should cause an error.';
56
-
57
- expect(() => {
58
- defaults.validatorUser(invalidUser);
59
- }).toThrow('Invalid User: "unknown" is not allowed');
60
- });
61
- });
package/src/conf/d.ts DELETED
@@ -1,303 +0,0 @@
1
- import { EmailOptions, EmailConfig } from 'email-templates';
2
-
3
- import type Tilmeld from '../Tilmeld';
4
- import Group, { GroupData } from '../Group';
5
- import User, { UserData } from '../User';
6
-
7
- /**
8
- * Tilmeld Config
9
- */
10
- export interface Config {
11
- /**
12
- * The name of the app. Used in emails sent to users.
13
- */
14
- appName: string;
15
- /**
16
- * The URL of the app. Used to define cookie domain, path, and security. Must
17
- * be accessible to the Tilmeld client JS. (Note, cookies are not specific to
18
- * individual ports, so tokens will be sent to any port running on this host.)
19
- */
20
- appUrl: string;
21
- /**
22
- * The domain of the auth cookie.
23
- */
24
- cookieDomain: string;
25
- /**
26
- * The path of the auth cookie.
27
- */
28
- cookiePath: string;
29
- /**
30
- * The path (with leading slash and no trailing slash) where the setup utility
31
- * is accessible. This is also used for email address verification.
32
- *
33
- * ***************************************************************************
34
- * This portion of the app will **not** check for the XSRF token, so make sure
35
- * your REST endpoint is **not** under this URL.
36
- * ***************************************************************************
37
- */
38
- setupPath: string;
39
- /**
40
- * Allow the creation of an admin user. When a user is created, if there are
41
- * no other users in the system, they will be granted all abilities.
42
- */
43
- createAdmin: boolean;
44
- /**
45
- * Instead of a "username", a user logs in and is referred to by their email
46
- * address. Enabling this after many users have been created can be messy.
47
- * Make sure they all have email addresses first.
48
- */
49
- emailUsernames: boolean;
50
- /**
51
- * Allow users to register.
52
- */
53
- allowRegistration: boolean;
54
- /**
55
- * Allow users to change their username.
56
- */
57
- allowUsernameChange: boolean;
58
- /**
59
- * Whether frontend can search users. (Probably not a good idea if privacy is
60
- * a concern.)
61
- */
62
- enableUserSearch: boolean;
63
- /**
64
- * Whether frontend can search groups. (Probably not a good idea if privacy is
65
- * a concern. Same risks as user search if generatePrimary is true.)
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[];
97
- /**
98
- * These will be the available fields for users. (Some fields, like username,
99
- * can't be excluded.)
100
- */
101
- userFields: string[];
102
- /**
103
- * These fields will be available for the user to fill in when they register.
104
- */
105
- regFields: string[];
106
- /**
107
- * Verify users' email addresses upon registration/email change before
108
- * allowing them to log in/change it.
109
- */
110
- verifyEmail: boolean;
111
- /**
112
- * After the user verifies their address, redirect them to this URL.
113
- */
114
- verifyRedirect: string;
115
- /**
116
- * After the user verifies an address change, redirect them to this URL.
117
- */
118
- verifyChangeRedirect: string;
119
- /**
120
- * After the user cancels an address change, redirect them to this URL.
121
- */
122
- cancelChangeRedirect: string;
123
- /**
124
- * Unverified users will be able to log in, but will only have the "unverified
125
- * users" secondary group(s) until they verify their email. If set to false,
126
- * their account will instead be disabled until they verify.
127
- */
128
- unverifiedAccess: boolean;
129
- /**
130
- * Don't let users change their email address more often than this. You can
131
- * enter one value and one unit of time, such as "2 weeks". Leave blank to
132
- * disable rate limiting.
133
- *
134
- * This also controls how long a user has to cancel an email address change
135
- * from a link emailed to the old address.
136
- */
137
- emailRateLimit: string;
138
- /**
139
- * Allow users to recover their username and/or password through their
140
- * registered email.
141
- */
142
- pwRecovery: boolean;
143
- /**
144
- * How long a recovery request is valid.
145
- */
146
- pwRecoveryTimeLimit: string;
147
- /**
148
- * Method used to store passwords. Salt is more secure if the database is
149
- * compromised. Plain: store the password in plaintext. Digest: store the
150
- * password's digest (hash). Salt: store the password's digest using a
151
- * complex, unique salt.
152
- *
153
- * Digests are SHA-256, so a salt probably isn't necessary, but who knows.
154
- *
155
- * Options are: "plain", "digest", "salt"
156
- */
157
- pwMethod: 'plain' | 'digest' | 'salt';
158
- /**
159
- * Whether to create a new primary group for every user who registers. This
160
- * can be useful for providing access to entities the user creates.
161
- *
162
- * In the case this is set, the default primary group, rather than being
163
- * assigned to the user, is assigned as the parent of the generated group.
164
- */
165
- generatePrimary: boolean;
166
- /**
167
- * The GUID of the group above the highest groups allowed to be assigned as
168
- * primary groups. True means all groups, and false means no groups.
169
- */
170
- highestPrimary: string | boolean;
171
- /**
172
- * The GUID of the group above the highest groups allowed to be assigned as
173
- * secondary groups. True means all groups, and false means no groups.
174
- */
175
- highestSecondary: string | boolean;
176
- /**
177
- * Only these characters can be used when creating usernames and groupnames.
178
- * (Doesn't apply to emails as usernames.)
179
- */
180
- validChars: string;
181
- /**
182
- * When a user enters an invalid name, this message will be displayed.
183
- */
184
- validCharsNotice: string;
185
- /**
186
- * Usernames and groupnames must match this regular expression. (Doesn't apply
187
- * to emails as usernames.) By default, this ensures that the name begins and
188
- * ends with an alphanumeric. (To allow anything, use .* inside the slashes.)
189
- */
190
- validRegex: RegExp;
191
- /**
192
- * When a user enters a name that doesn't match the regex, this message will
193
- * be displayed.
194
- */
195
- validRegexNotice: string;
196
- /**
197
- * Email addresses must match this regular expression. By default, this uses
198
- * the regex from the W3C HTML email element validation:
199
- *
200
- * https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)
201
- */
202
- validEmailRegex: RegExp;
203
- /**
204
- * When a user enters an email that doesn't match the regex, this message will
205
- * be displayed.
206
- */
207
- validEmailRegexNotice: string;
208
- /**
209
- * The maximum length for usernames. Infinity for unlimited.
210
- */
211
- maxUsernameLength: number;
212
- /**
213
- * The secret used to sign the JWT.
214
- */
215
- jwtSecret: string;
216
- /**
217
- * How long from current time, in seconds, the JWT token expires.
218
- */
219
- jwtExpire: number;
220
- /**
221
- * How long, in seconds, before the JWT token expires to give the user a new
222
- * one.
223
- */
224
- jwtRenew: number;
225
- /**
226
- * Function to build the JWT for user sessions.
227
- */
228
- jwtBuilder: (config: Config, user: User) => string;
229
- /**
230
- * Function to verify that a JWT was signed with the secret key, vaildate its
231
- * data, validate the XSRF token, and extract the GUID.
232
- *
233
- * If no XSRF token is supplied, ignore it.
234
- *
235
- * Return false if the JWT is not valid, or an array of GUID and expire
236
- * timestamp otherwise.
237
- */
238
- jwtExtract: (
239
- config: Config,
240
- token: string,
241
- xsrfToken?: string
242
- ) => { guid: string; expire: Date } | null;
243
- /**
244
- * The absolute path to the email template directory. Used by the default
245
- * email sender.
246
- */
247
- emailTemplateDir: string;
248
- /**
249
- * Configure an email object to prepare for sending.
250
- *
251
- * You can use this, for example, for DKIM signing.
252
- *
253
- * See: https://github.com/forwardemail/email-templates/blob/v8.0.9/README.md#Options
254
- */
255
- configEmail: (
256
- tilmeld: Tilmeld,
257
- options: EmailOptions,
258
- user: User & UserData
259
- ) => Promise<EmailConfig>;
260
- /**
261
- * Send an email to a user. Uses `email-templates` by default.
262
- *
263
- * Check out the `emails` directory to see the templates used.
264
- *
265
- * In addition to the specific `locals` for each template, there are
266
- * additional locals added by the default email sender:
267
- *
268
- * - System Information
269
- * - siteName
270
- * - siteLink
271
- * - Recipient Information
272
- * - toUsername
273
- * - toName
274
- * - toFirstName
275
- * - toLastName
276
- * - toEmail
277
- * - toPhone
278
- * - Current User Information (Only available if a user is logged in.)
279
- * - username
280
- * - name
281
- * - firstName
282
- * - lastName
283
- * - email
284
- */
285
- sendEmail: (
286
- tilmeld: Tilmeld,
287
- options: EmailOptions,
288
- user: User & UserData
289
- ) => Promise<boolean>;
290
- /**
291
- * The address you'd like to receive a notification of registered users, if
292
- * any.
293
- */
294
- userRegisteredRecipient: string | null;
295
- /**
296
- * The validator used to check groups before saving.
297
- */
298
- validatorGroup: (group: Group & GroupData) => void;
299
- /**
300
- * The validator used to check users before saving.
301
- */
302
- validatorUser: (user: User & UserData) => void;
303
- }