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

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.
@@ -111,13 +111,26 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
111
111
  // Figure out which days are allowed
112
112
  const days = [];
113
113
  const numDaysInMonth = (new Date(year, month, 0)).getDate();
114
- const firstDay = (
115
- month === today.month
116
- ? today.day // Current month: start at current date
117
- : 1 // Future month: start at beginning of month
118
- );
119
- for (let day = firstDay; day <= numDaysInMonth; day++) {
120
- days.push(day);
114
+ if (chooseFromPast) {
115
+ // Past selection
116
+ const numDaysToAdd = (
117
+ (month === today.month)
118
+ ? today.day // Current month, only add up to today
119
+ : numDaysInMonth // Past month, add all days
120
+ );
121
+ for (let day = 1; day <= numDaysToAdd; day++) {
122
+ days.push(day);
123
+ }
124
+ } else {
125
+ // Future selection: add all remaining days of the month
126
+ const firstDay = (
127
+ month === today.month
128
+ ? today.day // Current month: start at current date
129
+ : 1 // Future month: start at beginning of month
130
+ );
131
+ for (let day = firstDay; day <= numDaysInMonth; day++) {
132
+ days.push(day);
133
+ }
121
134
  }
122
135
 
123
136
  choices.push({
@@ -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;
@@ -539,7 +539,7 @@ const genRouteHandler = (
539
539
  type: LogType.Action,
540
540
  target: (
541
541
  (opts as any).target
542
- ?? LogBuiltInMetadata.Target.NoSpecificTarget
542
+ ?? LogBuiltInMetadata.Target.NoTarget
543
543
  ),
544
544
  action: (
545
545
  (opts as any).action
@@ -2,6 +2,7 @@
2
2
  import LOG_ROUTE_PATH from '../constants/LOG_ROUTE_PATH';
3
3
  import LogBuiltInMetadata from '../types/LogBuiltInMetadata';
4
4
  import LogFunction from '../types/LogFunction';
5
+ import LogLevel from '../types/LogLevel';
5
6
 
6
7
  // Import shared functions
7
8
  import visitServerEndpoint from './visitServerEndpoint';
@@ -27,6 +28,10 @@ const logClientEvent: LogFunction = async (opts) => {
27
28
  opts.subcontext
28
29
  ?? LogBuiltInMetadata.Context.Uncategorized
29
30
  ),
31
+ level: (
32
+ opts.level
33
+ ?? LogLevel.Info
34
+ ),
30
35
  tags: JSON.stringify(opts.tags ?? []),
31
36
  metadata: JSON.stringify(opts.metadata ?? {}),
32
37
  errorMessage: (
@@ -48,7 +53,7 @@ const logClientEvent: LogFunction = async (opts) => {
48
53
  (opts as any).action
49
54
  ? (
50
55
  (opts as any).target
51
- ?? LogBuiltInMetadata.Target.NoSpecificTarget
56
+ ?? LogBuiltInMetadata.Target.NoTarget
52
57
  )
53
58
  : undefined
54
59
  ),
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,106 @@ 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 });
211
+
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
+ };
219
+
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
+ );
221
235
 
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;
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.get(
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 {
253
+ year,
254
+ month,
255
+ userId,
256
+ isAdmin,
257
+ } = params;
239
258
 
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
- }
259
+ // Validate user
260
+ const canReview = await canReviewLogs(userId, isAdmin);
261
+ if (!canReview) {
262
+ throw new ErrorWithCode(
263
+ 'You cannot access this resource because you do not have the appropriate permissions.',
264
+ ReactKitErrorCode.NotAllowedToReviewLogs,
265
+ );
266
+ }
249
267
 
250
- // Query for logs
251
- const logs: Log[] = await _logCollection.find({ userId });
268
+ // Query for logs
269
+ const logs: Log[] = await _logCollection.find({
270
+ year,
271
+ month,
272
+ });
252
273
 
253
- // Return logs
254
- return logs;
255
- },
256
- }),
257
- );
258
- }
274
+ // Return logs
275
+ return logs;
276
+ },
277
+ }),
278
+ );
259
279
  };
260
280
 
261
281
  export default initServer;
@@ -5,14 +5,14 @@
5
5
  const LogBuiltInMetadata = {
6
6
  // Contexts
7
7
  Context: {
8
- Uncategorized: 'n/a',
9
- ServerRenderedErrorPage: '_server-rendered-error-page',
10
- ServerEndpointError: '_server-endpoint-error',
11
- ClientFatalError: '_client-fatal-error',
8
+ Uncategorized: 'Uncategorized',
9
+ ServerRenderedErrorPage: 'ServerRenderedErrorPage',
10
+ ServerEndpointError: 'ServerEndpointError',
11
+ ClientFatalError: 'ClientFatalError',
12
12
  },
13
13
  // Targets
14
14
  Target: {
15
- NoSpecificTarget: 'n/a',
15
+ NoTarget: 'NoTarget',
16
16
  },
17
17
  };
18
18