dce-expresskit 4.1.0 → 4.2.1

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 (34) hide show
  1. package/lib/helpers/dataSigner.js +7 -5
  2. package/lib/helpers/dataSigner.js.map +1 -1
  3. package/lib/helpers/genRouteHandler.d.ts +1 -1
  4. package/lib/helpers/genRouteHandler.js +61 -24
  5. package/lib/helpers/genRouteHandler.js.map +1 -1
  6. package/lib/helpers/initExpressKitCollections.d.ts +33 -0
  7. package/lib/helpers/initExpressKitCollections.js +180 -0
  8. package/lib/helpers/initExpressKitCollections.js.map +1 -0
  9. package/lib/helpers/initServer.d.ts +0 -33
  10. package/lib/helpers/initServer.js +31 -63
  11. package/lib/helpers/initServer.js.map +1 -1
  12. package/lib/index.d.ts +2 -3
  13. package/lib/index.js +3 -5
  14. package/lib/index.js.map +1 -1
  15. package/lib/types/ExpressKitErrorCode.d.ts +2 -1
  16. package/lib/types/ExpressKitErrorCode.js +1 -0
  17. package/lib/types/ExpressKitErrorCode.js.map +1 -1
  18. package/lib/types/LogReviewerAdmin.d.ts +10 -0
  19. package/lib/types/LogReviewerAdmin.js +3 -0
  20. package/lib/types/LogReviewerAdmin.js.map +1 -0
  21. package/lib/types/SelectAdmin.d.ts +10 -0
  22. package/lib/types/SelectAdmin.js +3 -0
  23. package/lib/types/SelectAdmin.js.map +1 -0
  24. package/package.json +2 -2
  25. package/src/helpers/dataSigner.ts +2 -2
  26. package/src/helpers/genRouteHandler.ts +46 -8
  27. package/src/helpers/initExpressKitCollections.ts +144 -0
  28. package/src/helpers/initServer.ts +38 -67
  29. package/src/index.ts +2 -4
  30. package/src/types/ExpressKitErrorCode.ts +1 -0
  31. package/src/types/LogReviewerAdmin.ts +14 -0
  32. package/src/types/SelectAdmin.ts +14 -0
  33. package/src/helpers/initCrossServerCredentialCollection.ts +0 -19
  34. package/src/helpers/initLogCollection.ts +0 -30
@@ -10,7 +10,6 @@ import {
10
10
  LogFunction,
11
11
  LOG_ROUTE_PATH,
12
12
  LOG_REVIEW_STATUS_ROUTE,
13
- Log,
14
13
  LOG_REVIEW_GET_LOGS_ROUTE,
15
14
  ErrorWithCode,
16
15
  } from 'dce-reactkit';
@@ -21,37 +20,12 @@ import getLogReviewerLogs from './getLogReviewerLogs';
21
20
 
22
21
  // Import shared types
23
22
  import ExpressKitErrorCode from '../types/ExpressKitErrorCode';
24
- import CrossServerCredential from '../types/CrossServerCredential';
25
23
 
26
- // Stored copy of dce-mango log collection
27
- let _logCollection: Collection<Log>;
28
-
29
- // Stored copy of dce-mango cross-server credential collection
30
- let _crossServerCredentialCollection: Collection<CrossServerCredential>;
31
-
32
- /*------------------------------------------------------------------------*/
33
- /* Helpers */
34
- /*------------------------------------------------------------------------*/
35
-
36
- /**
37
- * Get log collection
38
- * @author Gabe Abrams
39
- * @returns log collection if one was included during launch or null if we don't
40
- * have a log collection (yet)
41
- */
42
- export const internalGetLogCollection = () => {
43
- return _logCollection ?? null;
44
- };
45
-
46
- /**
47
- * Get cross-server credential collection
48
- * @author Gabe Abrams
49
- * @return cross-server credential collection if one was included during launch or null
50
- * if we don't have a cross-server credential collection (yet)
51
- */
52
- export const internalGetCrossServerCredentialCollection = () => {
53
- return _crossServerCredentialCollection ?? null;
54
- };
24
+ // Import shared helpers
25
+ import {
26
+ internalGetLogCollection,
27
+ internalGetLogReviewerAdminCollection,
28
+ } from './initExpressKitCollections';
55
29
 
56
30
  /*------------------------------------------------------------------------*/
57
31
  /* Main */
@@ -63,31 +37,12 @@ export const internalGetCrossServerCredentialCollection = () => {
63
37
  * @param opts object containing all arguments
64
38
  * @param opts.app express app from inside of the postprocessor function that
65
39
  * we will add routes to
66
- * @param opts.getLaunchInfo CACCL LTI's get launch info function
67
- * @param [opts.logCollection] mongo collection from dce-mango to use for
68
- * storing logs. If none is included, logs are written to the console
69
- * @param [opts.logReviewAdmins=all] info on which admins can review
70
- * logs from the client. If not included, all Canvas admins are allowed to
71
- * review logs. If null, no Canvas admins are allowed to review logs.
72
- * If an array of Canvas userIds (numbers), only Canvas admins with those
73
- * userIds are allowed to review logs. If a dce-mango collection, only
74
- * Canvas admins with entries in that collection ({ userId, ...}) are allowed
75
- * to review logs
76
- * @param [opts.crossServerCredentialCollection] mongo collection from dce-mango to use for
77
- * storing cross-server credentials. If none is included, cross-server credentials
78
- * are not supported
79
40
  */
80
41
  const initServer = (
81
42
  opts: {
82
43
  app: express.Application,
83
- logReviewAdmins?: (number[] | Collection<any>),
84
- logCollection?: Collection<Log>,
85
- crossServerCredentialCollection?: Collection<CrossServerCredential>,
86
44
  },
87
45
  ) => {
88
- _logCollection = opts.logCollection;
89
- _crossServerCredentialCollection = opts.crossServerCredentialCollection;
90
-
91
46
  /*----------------------------------------*/
92
47
  /* Logging */
93
48
  /*----------------------------------------*/
@@ -109,6 +64,10 @@ const initServer = (
109
64
  * @param {string} [target] Target of the action (each app determines the list
110
65
  * of targets) These are usually buttons, panels, elements, etc.
111
66
  * @param {LogAction} [action] the type of action performed on the target
67
+ * @param {object} [overriddenUserInfo] object containing info to override
68
+ * @param {number} [opts.userId] overriding Canvas id of the user performing the action
69
+ * @param {string} [opts.userFirstName] overriding first name of the user performing the action
70
+ * @param {string} [opts.userLastName] overriding last name of the user performing the action
112
71
  * @returns {Log}
113
72
  */
114
73
  opts.app.post(
@@ -125,6 +84,7 @@ const initServer = (
125
84
  errorStack: ParamType.StringOptional,
126
85
  target: ParamType.StringOptional,
127
86
  action: ParamType.StringOptional,
87
+ overriddenUserInfo: ParamType.JSONOptional,
128
88
  },
129
89
  handler: ({ params, logServerEvent }) => {
130
90
  // Create log info
@@ -142,6 +102,9 @@ const initServer = (
142
102
  code: params.errorCode,
143
103
  stack: params.errorStack,
144
104
  },
105
+ userId: (params.overriddenUserInfo ? params.overriddenUserInfo.userId : undefined),
106
+ userFirstName: (params.overriddenUserInfo ? params.overriddenUserInfo.userFirstName : undefined),
107
+ userLastName: (params.overriddenUserInfo ? params.overriddenUserInfo.userLastName : undefined),
145
108
  }
146
109
  // Action
147
110
  : {
@@ -152,6 +115,9 @@ const initServer = (
152
115
  metadata: params.metadata,
153
116
  target: params.target,
154
117
  action: params.action,
118
+ userId: (params.overriddenUserInfo ? params.overriddenUserInfo.userId : undefined),
119
+ userFirstName: (params.overriddenUserInfo ? params.overriddenUserInfo.userFirstName : undefined),
120
+ userLastName: (params.overriddenUserInfo ? params.overriddenUserInfo.userLastName : undefined),
155
121
  }
156
122
  );
157
123
 
@@ -190,22 +156,15 @@ const initServer = (
190
156
  return false;
191
157
  }
192
158
 
193
- // If all admins are allowed, we're done
194
- if (!opts.logReviewAdmins) {
195
- return true;
196
- }
159
+ /* ------- Look Up Credential ------- */
197
160
 
198
- // Do a dynamic check
199
- try {
200
- // Array of userIds
201
- if (Array.isArray(opts.logReviewAdmins)) {
202
- return opts.logReviewAdmins.some((allowedId) => {
203
- return (userId === allowedId);
204
- });
205
- }
161
+ // Get the log reviewer admin collection
162
+ const logReviewerAdminCollection = await internalGetLogReviewerAdminCollection();
206
163
 
207
- // Must be a collection
208
- const matches = await opts.logReviewAdmins.find({ userId });
164
+ // Check if the user is in the log reviewer admin collection
165
+ try {
166
+ // Must be in the collection
167
+ const matches = await logReviewerAdminCollection.find({ id: userId });
209
168
 
210
169
  // Make sure at least one entry matches
211
170
  return matches.length > 0;
@@ -224,8 +183,16 @@ const initServer = (
224
183
  LOG_REVIEW_STATUS_ROUTE,
225
184
  genRouteHandler({
226
185
  handler: async ({ params }) => {
227
- const { userId, isAdmin } = params;
186
+ // Destructure params
187
+ const {
188
+ userId,
189
+ isAdmin,
190
+ } = params;
191
+
192
+ // Check if user can review logs
228
193
  const canReview = await canReviewLogs(userId, isAdmin);
194
+
195
+ // Return result
229
196
  return canReview;
230
197
  },
231
198
  }),
@@ -233,7 +200,8 @@ const initServer = (
233
200
 
234
201
  /**
235
202
  * Get filtered logs based on provided filters
236
- * @author Gabe Abrams, Yuen Ler Chow
203
+ * @author Gabe Abrams
204
+ * @author Yuen Ler Chow
237
205
  * @param pageNumber the page number to get
238
206
  * @param filters the filters to apply to the logs
239
207
  * @returns {Log[]} list of logs that match the filters
@@ -265,12 +233,15 @@ const initServer = (
265
233
  );
266
234
  }
267
235
 
236
+ // Get log collection
237
+ const logCollection = await internalGetLogCollection();
238
+
268
239
  // Get logs
269
240
  const response = await getLogReviewerLogs({
270
241
  pageNumber,
271
242
  filters,
272
243
  countDocuments,
273
- logCollection: _logCollection,
244
+ logCollection,
274
245
  });
275
246
 
276
247
  // Return response
package/src/index.ts CHANGED
@@ -48,14 +48,13 @@ import {
48
48
  } from 'dce-reactkit';
49
49
 
50
50
  // Import helpers
51
- import initCrossServerCredentialCollection from './helpers/initCrossServerCredentialCollection';
52
- import initLogCollection from './helpers/initLogCollection';
53
51
  import initServer from './helpers/initServer';
54
52
  import genRouteHandler from './helpers/genRouteHandler';
55
53
  import handleError from './helpers/handleError';
56
54
  import handleSuccess from './helpers/handleSuccess';
57
55
  import addDBEditorEndpoints from './helpers/addDBEditorEndpoints';
58
56
  import visitEndpointOnAnotherServer from './helpers/visitEndpointOnAnotherServer';
57
+ import initExpressKitCollections from './helpers/initExpressKitCollections';
59
58
 
60
59
  // Import types
61
60
  import CrossServerCredential from './types/CrossServerCredential';
@@ -106,8 +105,7 @@ export {
106
105
  genRouteHandler,
107
106
  handleError,
108
107
  handleSuccess,
109
- initLogCollection,
110
- initCrossServerCredentialCollection,
108
+ initExpressKitCollections,
111
109
  addDBEditorEndpoints,
112
110
  visitEndpointOnAnotherServer,
113
111
  // Types
@@ -32,6 +32,7 @@ enum ExpressKitErrorCode {
32
32
  NoCryptoLib = 'DEK32',
33
33
  InvalidCrossServerCredentialsFormat = 'DEK33',
34
34
  UnknownCrossServerError = 'DEK34',
35
+ NotSelectAdmin = 'DEK35',
35
36
  }
36
37
 
37
38
  export default ExpressKitErrorCode;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Type describing a LogReviewerAdmin user
3
+ * @author Yuen Ler Chow
4
+ */
5
+ type LogReviewerAdmin = {
6
+ // User Canvas Id
7
+ id: number,
8
+ // User first name
9
+ userFirstName: string,
10
+ // User last name
11
+ userLastName: string,
12
+ };
13
+
14
+ export default LogReviewerAdmin;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Type describing a SelectAdmin user (subset of Admin)
3
+ * @author Gardenia Liu
4
+ */
5
+ type SelectAdmin = {
6
+ // User Canvas Id
7
+ id: number,
8
+ // User first name
9
+ userFirstName: string,
10
+ // User last name
11
+ userLastName: string,
12
+ };
13
+
14
+ export default SelectAdmin;
@@ -1,19 +0,0 @@
1
- // Import dce-mango
2
- import { Collection as MangoCollection } from 'dce-mango';
3
-
4
- /**
5
- * Initialize a cross-server credential collection given the dce-mango Collection class
6
- * @author Gabe Abrams
7
- * @param Collection the Collection class from dce-mango
8
- * @returns initialized logCollection
9
- */
10
- const initCrossServerCredentialCollection = (Collection: typeof MangoCollection) => {
11
- return new Collection(
12
- 'CrossServerCredential',
13
- {
14
- uniqueIndexKey: 'key',
15
- },
16
- );
17
- };
18
-
19
- export default initCrossServerCredentialCollection;
@@ -1,30 +0,0 @@
1
- // Import dce-mango
2
- import { Collection as MangoCollection } from 'dce-mango';
3
-
4
- /**
5
- * Initialize a log collection given the dce-mango Collection class
6
- * @author Gabe Abrams
7
- * @param Collection the Collection class from dce-mango
8
- * @returns initialized logCollection
9
- */
10
- const initLogCollection = (Collection: typeof MangoCollection) => {
11
- return new Collection(
12
- 'Log',
13
- {
14
- uniqueIndexKey: 'id',
15
- indexKeys: [
16
- 'courseId',
17
- 'context',
18
- 'subcontext',
19
- 'tags',
20
- 'year',
21
- 'month',
22
- 'day',
23
- 'hour',
24
- 'type',
25
- ],
26
- },
27
- );
28
- };
29
-
30
- export default initLogCollection;