dce-reactkit 3.2.2-beta.2 → 3.2.2-beta.4

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.
@@ -48,6 +48,7 @@ import logClientEvent from './helpers/logClientEvent';
48
48
  import initLogCollection from './server/initLogCollection';
49
49
  import getMonthName from './helpers/getMonthName';
50
50
  import genCSV from './helpers/genCSV';
51
+ import canReviewLogs from './helpers/canReviewLogs';
51
52
  import ModalButtonType from './types/ModalButtonType';
52
53
  import ModalSize from './types/ModalSize';
53
54
  import ModalType from './types/ModalType';
@@ -63,4 +64,4 @@ import LogBuiltInMetadata from './types/LogBuiltInMetadata';
63
64
  import LogMetadataType from './types/LogMetadataType';
64
65
  import IntelliTableColumn from './types/IntelliTableColumn';
65
66
  import PickableItem from './components/ItemPicker/types/PickableItem';
66
- export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, alert, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, visitServerEndpoint, logClientEvent, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, IntelliTableColumn, PickableItem, ParamType, };
67
+ export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, alert, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, canReviewLogs, visitServerEndpoint, logClientEvent, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, IntelliTableColumn, PickableItem, ParamType, };
@@ -25,7 +25,7 @@ export declare const internalGetLogCollection: () => any;
25
25
  * @param opts.getLaunchInfo CACCL LTI's get launch info function
26
26
  * @param [opts.logCollection] mongo collection from dce-mango to use for
27
27
  * storing logs. If none is included, logs are written to the console
28
- * @param [opts.logReviewAdmins=all admins] info on which admins can review
28
+ * @param [opts.logReviewAdmins=all] info on which admins can review
29
29
  * logs from the client. If not included, all Canvas admins are allowed to
30
30
  * review logs. If null, no Canvas admins are allowed to review logs.
31
31
  * If an array of Canvas userIds (numbers), only Canvas admins with those
package/dist/index.d.ts CHANGED
@@ -822,7 +822,7 @@ declare type GetLaunchInfoFunction = (req: any) => {
822
822
  * @param opts.getLaunchInfo CACCL LTI's get launch info function
823
823
  * @param [opts.logCollection] mongo collection from dce-mango to use for
824
824
  * storing logs. If none is included, logs are written to the console
825
- * @param [opts.logReviewAdmins=all admins] info on which admins can review
825
+ * @param [opts.logReviewAdmins=all] info on which admins can review
826
826
  * logs from the client. If not included, all Canvas admins are allowed to
827
827
  * review logs. If null, no Canvas admins are allowed to review logs.
828
828
  * If an array of Canvas userIds (numbers), only Canvas admins with those
@@ -975,6 +975,13 @@ declare const genCSV: (data: {
975
975
  param: string;
976
976
  }[]) => string;
977
977
 
978
+ /**
979
+ * Check if the current user can review logs
980
+ * @author Gabe Abrams
981
+ * @returns true if current user can review logs
982
+ */
983
+ declare const canReviewLogs: () => Promise<boolean>;
984
+
978
985
  /**
979
986
  * List of error codes built into the react kit
980
987
  * @author Gabe Abrams
@@ -1023,4 +1030,4 @@ declare const LogBuiltInMetadata: {
1023
1030
  };
1024
1031
  };
1025
1032
 
1026
- export { AppWrapper, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DayOfWeek, Drawer, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genCSV, genRouteHandler, getHumanReadableDate, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, initLogCollection, initServer, logClientEvent, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, roundToNumDecimals, showFatalError, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, visitServerEndpoint, waitMs };
1033
+ export { AppWrapper, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DayOfWeek, Drawer, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, Variant, abbreviate, alert, avg, canReviewLogs, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genCSV, genRouteHandler, getHumanReadableDate, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, initLogCollection, initServer, logClientEvent, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, roundToNumDecimals, showFatalError, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, visitServerEndpoint, waitMs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.2.2-beta.2",
3
+ "version": "3.2.2-beta.4",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -5,6 +5,6 @@ import ROUTE_PATH_PREFIX from './ROUTE_PATH_PREFIX';
5
5
  * access to log review
6
6
  * @author Gabe Abrams
7
7
  */
8
- const LOG_REVIEW_STATUS_ROUTE = `/admin${ROUTE_PATH_PREFIX}/logs/access`;
8
+ const LOG_REVIEW_STATUS_ROUTE = `${ROUTE_PATH_PREFIX}/logs/access_allowed`;
9
9
 
10
10
  export default LOG_REVIEW_STATUS_ROUTE;
package/src/index.ts CHANGED
@@ -55,6 +55,7 @@ import logClientEvent from './helpers/logClientEvent';
55
55
  import initLogCollection from './server/initLogCollection';
56
56
  import getMonthName from './helpers/getMonthName';
57
57
  import genCSV from './helpers/genCSV';
58
+ import canReviewLogs from './helpers/canReviewLogs';
58
59
 
59
60
  // Import types
60
61
  import ModalButtonType from './types/ModalButtonType';
@@ -128,6 +129,7 @@ export {
128
129
  parallelLimit,
129
130
  getMonthName,
130
131
  genCSV,
132
+ canReviewLogs,
131
133
  // Client helpers
132
134
  visitServerEndpoint,
133
135
  logClientEvent,
@@ -71,7 +71,7 @@ export const internalGetLogCollection = () => {
71
71
  * @param opts.getLaunchInfo CACCL LTI's get launch info function
72
72
  * @param [opts.logCollection] mongo collection from dce-mango to use for
73
73
  * storing logs. If none is included, logs are written to the console
74
- * @param [opts.logReviewAdmins=all admins] info on which admins can review
74
+ * @param [opts.logReviewAdmins=all] info on which admins can review
75
75
  * logs from the client. If not included, all Canvas admins are allowed to
76
76
  * review logs. If null, no Canvas admins are allowed to review logs.
77
77
  * If an array of Canvas userIds (numbers), only Canvas admins with those
@@ -176,86 +176,99 @@ const initServer = (
176
176
  /* Log Reviewer */
177
177
  /*----------------------------------------*/
178
178
 
179
- if (opts.logReviewAdmins !== null) {
180
- /**
181
- * Check if a given user is allowed to review logs
182
- * @author Gabe Abrams
183
- * @param userId the id of the user
184
- * @returns true if the user can review logs
185
- */
186
- const canReviewLogs = async (userId: number): Promise<boolean> => {
187
- try {
188
- // Array of userIds
189
- if (Array.isArray(opts.logReviewAdmins)) {
190
- return opts.logReviewAdmins.some((allowedId) => {
191
- return (userId === allowedId);
192
- });
193
- }
179
+ /**
180
+ * Check if a given user is allowed to review logs
181
+ * @author Gabe Abrams
182
+ * @param userId the id of the user
183
+ * @param isAdmin if true, the user is an admin
184
+ * @returns true if the user can review logs
185
+ */
186
+ const canReviewLogs = async (
187
+ userId: number,
188
+ isAdmin: boolean,
189
+ ): Promise<boolean> => {
190
+ // Immediately deny access if user is not an admin
191
+ if (!isAdmin) {
192
+ return false;
193
+ }
194
194
 
195
- // Must be a collection
196
- const matches = await opts.logReviewAdmins.find({ userId });
195
+ // If all admins are allowed, we're done
196
+ if (!opts.logReviewAdmins) {
197
+ return true;
198
+ }
197
199
 
198
- // Make sure at least one entry matches
199
- return matches.length > 0;
200
- } catch (err) {
201
- // If an error occurred, simply return false
202
- return false;
200
+ // Do a dynamic check
201
+ try {
202
+ // Array of userIds
203
+ if (Array.isArray(opts.logReviewAdmins)) {
204
+ return opts.logReviewAdmins.some((allowedId) => {
205
+ return (userId === allowedId);
206
+ });
203
207
  }
204
- };
205
208
 
206
- /**
207
- * Check if the current user has access to logs
208
- * @author Gabe Abrams
209
- * @returns {boolean} true if user has access
210
- */
211
- opts.app.get(
212
- LOG_REVIEW_STATUS_ROUTE,
213
- genRouteHandler({
214
- handler: async ({ params }) => {
215
- const { userId } = params;
216
- const canReview = await canReviewLogs(userId);
217
- return canReview;
218
- },
219
- }),
220
- );
209
+ // Must be a collection
210
+ const matches = await opts.logReviewAdmins.find({ userId });
221
211
 
222
- /**
223
- * Get all logs for a certain month
224
- * @author Gabe Abrams
225
- * @param {number} year the year to query (e.g. 2022)
226
- * @param {number} month the month to query (e.g. 1 = January)
227
- * @returns {Log[]} list of logs from the given month
228
- */
229
- opts.app.post(
230
- `${LOG_REVIEW_ROUTE_PATH_PREFIX}/years/:year/months/:month`,
231
- genRouteHandler({
232
- paramTypes: {
233
- year: ParamType.Int,
234
- month: ParamType.Int,
235
- },
236
- handler: async ({ params }) => {
237
- // Get user info
238
- const { userId } = params;
212
+ // Make sure at least one entry matches
213
+ return matches.length > 0;
214
+ } catch (err) {
215
+ // If an error occurred, simply return false
216
+ return false;
217
+ }
218
+ };
239
219
 
240
- // Validate user
241
- // isAdmin is already checked because path starts with '/admin'
242
- const canReview = await canReviewLogs(userId);
243
- if (!canReview) {
244
- throw new ErrorWithCode(
245
- 'You cannot access this resource because you do not have the appropriate permissions.',
246
- ReactKitErrorCode.NotAllowedToReviewLogs,
247
- );
248
- }
220
+ /**
221
+ * Check if the current user has access to logs
222
+ * @author Gabe Abrams
223
+ * @returns {boolean} true if user has access
224
+ */
225
+ opts.app.get(
226
+ LOG_REVIEW_STATUS_ROUTE,
227
+ genRouteHandler({
228
+ handler: async ({ params }) => {
229
+ const { userId, isAdmin } = params;
230
+ const canReview = await canReviewLogs(userId, isAdmin);
231
+ return canReview;
232
+ },
233
+ }),
234
+ );
249
235
 
250
- // Query for logs
251
- const logs: Log[] = await _logCollection.find({ userId });
236
+ /**
237
+ * Get all logs for a certain month
238
+ * @author Gabe Abrams
239
+ * @param {number} year the year to query (e.g. 2022)
240
+ * @param {number} month the month to query (e.g. 1 = January)
241
+ * @returns {Log[]} list of logs from the given month
242
+ */
243
+ opts.app.post(
244
+ `${LOG_REVIEW_ROUTE_PATH_PREFIX}/years/:year/months/:month`,
245
+ genRouteHandler({
246
+ paramTypes: {
247
+ year: ParamType.Int,
248
+ month: ParamType.Int,
249
+ },
250
+ handler: async ({ params }) => {
251
+ // Get user info
252
+ const { userId, isAdmin } = params;
252
253
 
253
- // Return logs
254
- return logs;
255
- },
256
- }),
257
- );
258
- }
254
+ // Validate user
255
+ // isAdmin is already checked because path starts with '/admin'
256
+ const canReview = await canReviewLogs(userId, isAdmin);
257
+ if (!canReview) {
258
+ throw new ErrorWithCode(
259
+ 'You cannot access this resource because you do not have the appropriate permissions.',
260
+ ReactKitErrorCode.NotAllowedToReviewLogs,
261
+ );
262
+ }
263
+
264
+ // Query for logs
265
+ const logs: Log[] = await _logCollection.find({ userId });
266
+
267
+ // Return logs
268
+ return logs;
269
+ },
270
+ }),
271
+ );
259
272
  };
260
273
 
261
274
  export default initServer;