@nymphjs/tilmeld 1.0.0-beta.6 → 1.0.0-beta.61

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 (57) hide show
  1. package/CHANGELOG.md +284 -0
  2. package/README.md +14 -1
  3. package/dist/AbleObject.d.ts +15 -0
  4. package/dist/AbleObject.js +16 -1
  5. package/dist/AbleObject.js.map +1 -1
  6. package/dist/Group.d.ts +119 -8
  7. package/dist/Group.js +230 -97
  8. package/dist/Group.js.map +1 -1
  9. package/dist/Group.test.js +3 -2
  10. package/dist/Group.test.js.map +1 -1
  11. package/dist/Tilmeld.d.ts +237 -9
  12. package/dist/Tilmeld.js +559 -195
  13. package/dist/Tilmeld.js.map +1 -1
  14. package/dist/User.d.ts +333 -14
  15. package/dist/User.js +797 -204
  16. package/dist/User.js.map +1 -1
  17. package/dist/User.test.js +3 -2
  18. package/dist/User.test.js.map +1 -1
  19. package/dist/conf/d.d.ts +250 -3
  20. package/dist/conf/defaults.js +146 -98
  21. package/dist/conf/defaults.js.map +1 -1
  22. package/dist/enforceTilmeld.d.ts +3 -0
  23. package/dist/enforceTilmeld.js +22 -0
  24. package/dist/enforceTilmeld.js.map +1 -0
  25. package/dist/errors/AccessControlError.d.ts +2 -1
  26. package/dist/errors/AccessControlError.js +3 -2
  27. package/dist/errors/AccessControlError.js.map +1 -1
  28. package/dist/errors/BadDataError.d.ts +2 -1
  29. package/dist/errors/BadDataError.js +3 -2
  30. package/dist/errors/BadDataError.js.map +1 -1
  31. package/dist/errors/BadEmailError.d.ts +2 -1
  32. package/dist/errors/BadEmailError.js +3 -2
  33. package/dist/errors/BadEmailError.js.map +1 -1
  34. package/dist/errors/BadUsernameError.d.ts +2 -1
  35. package/dist/errors/BadUsernameError.js +3 -2
  36. package/dist/errors/BadUsernameError.js.map +1 -1
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.js +1 -0
  39. package/dist/index.js.map +1 -1
  40. package/package.json +30 -26
  41. package/src/AbleObject.ts +2 -2
  42. package/src/Group.test.ts +3 -3
  43. package/src/Group.ts +194 -143
  44. package/src/Tilmeld.ts +384 -249
  45. package/src/User.test.ts +3 -3
  46. package/src/User.ts +876 -266
  47. package/src/conf/d.ts +26 -13
  48. package/src/conf/defaults.ts +151 -104
  49. package/src/enforceTilmeld.ts +20 -0
  50. package/src/errors/AccessControlError.ts +4 -2
  51. package/src/errors/BadDataError.ts +4 -2
  52. package/src/errors/BadEmailError.ts +4 -2
  53. package/src/errors/BadUsernameError.ts +4 -2
  54. package/src/index.ts +2 -0
  55. package/src/tilmeldJoiProps.ts +9 -9
  56. package/tsconfig.json +1 -1
  57. package/typedoc.json +4 -0
@@ -34,14 +34,15 @@ describe('Group', () => {
34
34
  it('new group passes validation', async () => {
35
35
  const validGroup = await makeNewGroup();
36
36
  expect(() => {
37
- defaults_1.default.validatorGroup(validGroup);
37
+ defaults_1.default.validatorGroup({ config: defaults_1.default }, validGroup);
38
38
  }).not.toThrow();
39
39
  });
40
40
  it("doesn't allow unknown keys", async () => {
41
41
  const invalidGroup = await makeNewGroup();
42
+ // @ts-ignore: testing unknown keys
42
43
  invalidGroup.unknown = 'I should cause an error.';
43
44
  expect(() => {
44
- defaults_1.default.validatorGroup(invalidGroup);
45
+ defaults_1.default.validatorGroup({ config: defaults_1.default }, invalidGroup);
45
46
  }).toThrow('Invalid Group: "unknown" is not allowed');
46
47
  });
47
48
  });
@@ -1 +1 @@
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
+ {"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,EAAE,MAAM,EAAE,kBAAQ,EAAa,EAAE,UAAU,CAAC,CAAC;QACvE,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;QAE1C,mCAAmC;QACnC,YAAY,CAAC,OAAO,GAAG,0BAA0B,CAAC;QAElD,MAAM,CAAC,GAAG,EAAE;YACV,kBAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,kBAAQ,EAAa,EAAE,YAAY,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/Tilmeld.d.ts CHANGED
@@ -1,32 +1,260 @@
1
- import { Nymph, EntityInterface, FormattedSelector, Options, TilmeldInterface, TilmeldAccessLevels } from '@nymphjs/nymph';
1
+ /// <reference types="cookie-parser" />
2
+ import { Nymph, EntityInterface, FormattedSelector, Options, TilmeldInterface, TilmeldAccessLevels, ACProperties } from '@nymphjs/nymph';
2
3
  import { Request, Response } from 'express';
3
4
  import { Config } from './conf';
4
5
  import Group from './Group';
5
6
  import User, { UserData } from './User';
6
- import { AccessControlData } from './Tilmeld.types';
7
+ /**
8
+ * A user and group system for Nymph.js.
9
+ *
10
+ * Written by Hunter Perrin for SciActive.
11
+ *
12
+ * @author Hunter Perrin <hperrin@gmail.com>
13
+ * @copyright SciActive Inc
14
+ * @see http://nymph.io/
15
+ */
7
16
  export default class Tilmeld implements TilmeldInterface {
17
+ /**
18
+ * The Nymph instance.
19
+ */
8
20
  nymph: Nymph;
21
+ /**
22
+ * The Tilmeld config.
23
+ */
9
24
  config: Config;
25
+ /**
26
+ * The currently logged in user.
27
+ */
10
28
  currentUser: (User & UserData) | null;
29
+ /**
30
+ * The user class for this instance of Tilmeld.
31
+ */
11
32
  User: typeof User;
33
+ /**
34
+ * The group class for this instance of Tilmeld.
35
+ */
12
36
  Group: typeof Group;
37
+ /**
38
+ * If you will be performing authentication functions (logging in/out), you
39
+ * should set these so Tilmeld can read and write cookies and headers.
40
+ *
41
+ * If you want the user to be authenticated with the cookie and/or header they
42
+ * provide, you should set at least the request. It's better to set both, so
43
+ * the JWT can be updated if needed.
44
+ *
45
+ * After you set these, call `authenticate()` to read user authentication data
46
+ * from them and fill the user's session.
47
+ *
48
+ * If you want to support cookie based authentication (which still requires an
49
+ * XSRF token for security), you should enable the cookie parser middleware.
50
+ */
13
51
  request: Request | null;
14
52
  response: Response | null;
15
- private skipAuthenticate;
53
+ /**
54
+ * Used to avoid infinite loop.
55
+ */
56
+ private alreadyLoggedOutSwitch;
57
+ /**
58
+ * Gatekeeper ability cache.
59
+ *
60
+ * Gatekeeper will cache the user's abilities that it calculates, so it can
61
+ * check faster if that user has been checked before.
62
+ */
63
+ private gatekeeperCache;
64
+ /**
65
+ * Create a new instance of Tilmeld.
66
+ *
67
+ * @param config The Tilmeld configuration.
68
+ */
16
69
  constructor(config: Partial<Config> & {
17
70
  jwtSecret: string;
18
71
  });
72
+ /**
73
+ * This is used internally by Nymph. Don't call it yourself.
74
+ *
75
+ * @returns A clone of this instance.
76
+ */
19
77
  clone(): Tilmeld;
78
+ /**
79
+ * Initialize Tilmeld.
80
+ *
81
+ * This is meant to be called internally by Nymph. Don't call this directly.
82
+ *
83
+ * @param nymph The Nymph instance.
84
+ */
20
85
  init(nymph: Nymph): void;
86
+ /**
87
+ * Check to see if the current user has an ability.
88
+ *
89
+ * If `ability` is undefined, it will check to see if a user is currently
90
+ * logged in.
91
+ *
92
+ * @param ability The ability.
93
+ * @returns Whether the user has the given ability.
94
+ */
21
95
  gatekeeper(ability?: string): boolean;
22
96
  private initAccessControl;
97
+ /**
98
+ * Add selectors to a list of options and selectors which will limit results
99
+ * to only entities the current user has access to.
100
+ *
101
+ * @param optionsAndSelectors The options and selectors of the query.
102
+ */
23
103
  addAccessControlSelectors(options: Options, selectors: FormattedSelector[]): void;
24
- checkPermissions(entity: EntityInterface & AccessControlData, type?: TilmeldAccessLevels, user?: (User & UserData) | false): boolean;
25
- checkClientUIDPermissions(name: string, type?: TilmeldAccessLevels, user?: (User & UserData) | false): boolean;
26
- fillSession(user: User & UserData): void;
104
+ /**
105
+ * Check an entity's permissions for a user.
106
+ *
107
+ * This will check the AC (Access Control) properties of the entity. These
108
+ * include the following properties:
109
+ *
110
+ * - acUser
111
+ * - acGroup
112
+ * - acOther
113
+ * - acRead
114
+ * - acWrite
115
+ * - acFull
116
+ *
117
+ * "acUser" refers to the entity's owner, "acGroup" refers to all users in the
118
+ * entity's group and all ancestor groups, and "acOther" refers to any user
119
+ * who doesn't fit these descriptions.
120
+ *
121
+ * Each of these properties should be either NO_ACCESS, READ_ACCESS,
122
+ * WRITE_ACCESS, or FULL_ACCESS.
123
+ *
124
+ * - NO_ACCESS - the user has no access to the entity.
125
+ * - READ_ACCESS, the user has read access to the entity.
126
+ * - WRITE_ACCESS, the user has read and write access to the entity, but can't
127
+ * delete it, change its access controls, or change its ownership.
128
+ * - FULL_ACCESS, the user has read, write, and delete access to the entity,
129
+ * as well as being able to manage its access controls and ownership.
130
+ *
131
+ * These properties default to:
132
+ *
133
+ * - acUser = TilmeldAccessLevels.FULL_ACCESS
134
+ * - acGroup = TilmeldAccessLevels.READ_ACCESS
135
+ * - acOther = TilmeldAccessLevels.NO_ACCESS
136
+ *
137
+ * "acRead", "acWrite", and "acFull" are arrays of users and/or groups that
138
+ * also have those permissions.
139
+ *
140
+ * Only users with FULL_ACCESS have the ability to change any of the ac*,
141
+ * user, and group properties.
142
+ *
143
+ * The following conditions will result in different checks, which determine
144
+ * whether the check passes:
145
+ *
146
+ * - It is a user or group. (True for READ_ACCESS or Tilmeld admins.)
147
+ * - No user is logged in. (Check other AC.)
148
+ * - The entity is the user. (Always true.)
149
+ * - It is the user's primary group. (True for READ_ACCESS.)
150
+ * - The user or its groups are listed in "acRead". (True for READ_ACCESS.)
151
+ * - The user or its groups are listed in "acWrite". (True for READ_ACCESS and
152
+ * WRITE_ACCESS.)
153
+ * - The user or its groups are listed in "acFull". (Always true.)
154
+ * - Its "user" is the user. (It is owned by the user.) (Check user AC.)
155
+ * - Its "group" is the user's primary group. (Check group AC.)
156
+ * - Its "group" is one of the user's secondary groups. (Check group AC.)
157
+ * - Its "group" is a descendant of one of the user's groups. (Check group
158
+ * AC.)
159
+ * - None of the above. (Check other AC.)
160
+ *
161
+ * @param entity The entity to check.
162
+ * @param type The lowest level of permission to consider a pass.
163
+ * @param user The user to check permissions for. If null, uses the current user. If false, checks for public access.
164
+ * @param acProperties The acProperties to use instead of getting them from the entity.
165
+ * @returns Whether the current user has at least `type` permission for the entity.
166
+ */
167
+ checkPermissions(entity: EntityInterface, type?: TilmeldAccessLevels, user?: (User & UserData) | false, acProperties?: ACProperties): boolean;
168
+ /**
169
+ * Check a UID's permissions for a user.
170
+ *
171
+ * ## THIS ONLY CHECKS AUTOMATICALLY FOR CLIENT REQUESTS.
172
+ *
173
+ * UID functions on the Node.js side are not checked automatically. This
174
+ * function is only run automatically for UID functions run from the client.
175
+ * You should call this function manually if you're running a UID function on
176
+ * the Node.js side and you want it gated.
177
+ *
178
+ * This will check the Tilmeld config and the user's abilities.
179
+ *
180
+ * - READ_ACCESS, the UID is listed in clientReadableUIDs or the user has the
181
+ * "uid/get/nameofuid" ability.
182
+ * - WRITE_ACCESS, the UID is listed in clientEnabledUIDs or the user has the
183
+ * "uid/new/nameofuid" ability.
184
+ * - FULL_ACCESS, the UID is listed in clientSetabledUIDs or the user has the
185
+ * "uid/set/nameofuid" ability.
186
+ *
187
+ * @param name The UID to check.
188
+ * @param type The lowest level of permission to consider a pass.
189
+ * @param user The user to check permissions for. If null, uses the current user. If false, checks for public access.
190
+ * @returns Whether the current user has at least `type` permission for the UID.
191
+ */
192
+ checkClientUIDPermissions(name: string, type?: TilmeldAccessLevels, user?: (User & UserData) | false): Promise<boolean>;
193
+ /**
194
+ * Fill session user data.
195
+ *
196
+ * @param user The user.
197
+ */
198
+ fillSession(user: User & UserData): Promise<void>;
199
+ /**
200
+ * Clear session user data.
201
+ */
27
202
  clearSession(): void;
203
+ /**
204
+ * Validate and extract the user from a token.
205
+ *
206
+ * @param token The authentication token.
207
+ * @returns The user on success, null on failure.
208
+ */
28
209
  extractToken(token: string): Promise<(User & UserData) | null>;
29
- authenticate(skipXsrfToken?: boolean): boolean;
30
- login(user: User & UserData, sendAuthHeader: boolean): boolean;
31
- logout(): void;
210
+ /**
211
+ * Check for TILMELDAUTH and TILMELDSWITCH tokens, and, if set, authenticate
212
+ * from it/them.
213
+ *
214
+ * You can also call this function after setting `response.locals.user` to the
215
+ * user you want to authenticate. You *should* check for `user.enabled` before
216
+ * setting this variable, unless you explicitly want to log in as a disabled
217
+ * user. (The user must be an instance of the User class for this Tilmeld
218
+ * instance.)
219
+ *
220
+ * This function will set `response.locals.user` to the logged in user on
221
+ * successful authentication.
222
+ *
223
+ * @param skipXsrfToken Skip the XSRF token check.
224
+ * @param skipRenew Skip the token renewal step, even if the token is close to expiration.
225
+ * @returns True if a user was authenticated, false on any failure.
226
+ */
227
+ authenticate(skipXsrfToken?: boolean, skipRenew?: boolean): Promise<boolean>;
228
+ /**
229
+ * Logs the given user into the system.
230
+ *
231
+ * @param user The user.
232
+ * @param sendAuthHeader Send the auth token as a custom header.
233
+ * @param sendCookie Send the auth token as a cookie.
234
+ * @returns True on success, false on failure.
235
+ */
236
+ login(user: User & UserData, sendAuthHeader: boolean, sendCookie?: boolean): Promise<boolean>;
237
+ /**
238
+ * Adds a switch auth token for the given user.
239
+ *
240
+ * This effectively logs the current user in to the system as the given user.
241
+ *
242
+ * @param user The user.
243
+ * @param sendAuthHeader Send the auth token as a custom header.
244
+ * @param sendCookie Send the auth token as a cookie.
245
+ * @returns True on success, false on failure.
246
+ */
247
+ loginSwitch(user: User & UserData, sendAuthHeader: boolean, sendCookie?: boolean): Promise<boolean>;
248
+ /**
249
+ * Logs the current user out of the system.
250
+ *
251
+ * @param clearCookie Clear the auth cookie. (Also send a header.)
252
+ */
253
+ logout(clearCookie?: boolean): Promise<void>;
254
+ /**
255
+ * Clears the switch user out of the system.
256
+ *
257
+ * @param clearCookie Clear the auth cookie. (Also send a header.)
258
+ */
259
+ logoutSwitch(clearCookie?: boolean): Promise<void>;
32
260
  }