dce-expresskit 4.0.0-beta.8 → 4.0.0-log-reviewer-beta.10

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.
@@ -1,107 +1,84 @@
1
1
  // Import crypto lib
2
2
  import crypto from 'crypto';
3
3
 
4
- // Prompt
5
- import readline from 'readline';
6
-
7
- // Create a readline interface
8
- const readlineInterface = readline.createInterface({
9
- input: process.stdin,
10
- output: process.stdout
11
- });
12
-
13
- /**
14
- * Prompt user for input
15
- * @author Gabe Abrams
16
- * @param question the question to ask the user
17
- * @returns the text from the user
18
- */
19
- const prompt = (question: string): Promise<string> => {
20
- return new Promise((resolve, reject) => {
21
- readlineInterface.question(question, (answer: string) => {
22
- if (!answer || answer.trim().length === 0) {
23
- console.log('\nValue cannot be empty. Exiting...');
24
- process.exit(0);
25
- }
26
-
27
- resolve(answer);
28
- });
29
- });
30
- };
31
-
32
- // All chars for randomizer
33
4
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
34
5
 
35
- (async () => {
36
- console.log('––––– Generate Encoded Secret –––––');
37
- console.log('\nFirst, we need info on the *receiving* server');
38
- console.log('This is the server that hosts the cross-server endpoint, the one that receives requests from the sending server.\n');
39
-
40
- // Get salt
41
- console.log('Encoding salt on the *receiving* server')
42
- const salt = await prompt('Salt: ');
43
-
44
- // Get host
45
- console.log('Hostname of the *receiving* server');
46
- const host = await prompt('Host: ');
47
-
48
- console.log('\n\nSecond, we need info on the *sending* server');
49
- console.log('This is the server that sends requests to the receiving server.\n');
50
-
51
- // Get key
52
- console.log('Short unique key for the *sending* server (only letters and dashes, no whitespace)')
53
- const key = (await prompt('Key: ')).trim();
54
-
55
- // Get description
56
- console.log('Human-readable description of the *sending* server')
57
- const description = await prompt('Description: ');
58
-
6
+ // Get args
7
+ const DCEKIT_CRED_ENCODING_SALT = process.env.npm_config_salt;
8
+ if (!DCEKIT_CRED_ENCODING_SALT) {
9
+ console.log('Encoding salt is required: --salt=...');
10
+ process.exit(1);
11
+ }
12
+
13
+ // Get the key
14
+ let key = process.env.npm_config_key;
15
+ if (!key) {
16
+ console.log('Key is required: --key=...');
17
+ process.exit(1);
18
+ }
19
+
20
+ // Get the description
21
+ let description = process.env.npm_config_description;
22
+ if (!description) {
23
+ console.log('Description is required: --description=...');
24
+ process.exit(1);
25
+ }
26
+
27
+ // Get secret
28
+ let secret = process.env.npm_config_secret;
29
+ if (!secret) {
59
30
  // Generate a random secret
60
- let secret = '';
31
+ secret = '';
61
32
  for (let i = 0; i < 32; i++) {
62
33
  secret += chars.charAt(Math.floor(Math.random() * chars.length));
63
34
  }
64
- secret = Buffer.from(secret).toString('base64');
65
-
66
- // Encryption process based on:
67
- // https://medium.com/@tony.infisical/guide-to-nodes-crypto-module-for-encryption-decryption-65c077176980
68
-
69
- // Create a random initialization vector
70
- const iv = crypto.randomBytes(12).toString('base64');
71
-
72
- // Create a cipher
73
- console.log('salt', salt, Buffer.from(salt, 'base64'));
74
- const cipher = crypto.createCipheriv(
75
- 'aes-256-gcm',
76
- Buffer.from(salt, 'base64'),
77
- Buffer.from(iv, 'base64'),
78
- );
79
-
80
- // Encrypt the string
81
- let ciphertext = cipher.update(secret, 'utf8', 'base64');
82
-
83
- // Finalize the encryption
84
- ciphertext += cipher.final('base64');
85
-
86
- // Get the authentication tag
87
- const tag = cipher.getAuthTag();
88
-
89
- // JSONify the encrypted data
90
- const encryptionPack = encodeURIComponent(JSON.stringify({
91
- ciphertext,
92
- iv,
93
- tag,
94
- }));
95
-
96
- // Show the encrypted data
97
- console.log('\n\n');
98
- console.log('––––– Done! What\'s Next: –––––');
99
- console.log('');
100
- console.log('On the *sending* server, !!APPEND!! the following to the DCEKIT_CROSS_SERVER_CREDENTIALS env var:');
101
- console.log(`|${host}:${key}:${secret}|`);
102
- console.log('');
103
- console.log('On the *receiving* server, add an entry to its "CrossServerCredential" collection:');
104
- console.log(`{ "description": "${description}", "key": "${key}", "encodedeSecret": "${encryptionPack}", "scopes": [] }`);
105
- console.log('');
106
- console.log('For all scopes that the server should have access to, add them to the "scopes" array.');
107
- })();
35
+ console.log('Generated a random secret. If you have one in mind, use --secret=...');
36
+ }
37
+
38
+ // Get the host name
39
+ const host = process.env.npm_config_host;
40
+ if (!host) {
41
+ console.log('Host of the receiving server is required: --host=...');
42
+ process.exit(1);
43
+ }
44
+
45
+ // Encryption process based on:
46
+ // https://medium.com/@tony.infisical/guide-to-nodes-crypto-module-for-encryption-decryption-65c077176980
47
+
48
+ // Create a random initialization vector
49
+ const iv = crypto.randomBytes(12).toString('base64');
50
+
51
+ // Create a cipher
52
+ const cipher = crypto.createCipheriv(
53
+ 'aes-256-gcm',
54
+ Buffer.from(secret, 'base64'),
55
+ Buffer.from(iv, 'base64'),
56
+ );
57
+
58
+ // Encrypt the string
59
+ let ciphertext = cipher.update(secret, 'utf8', 'base64');
60
+
61
+ // Finalize the encryption
62
+ ciphertext += cipher.final('base64');
63
+
64
+ // Get the authentication tag
65
+ const tag = cipher.getAuthTag();
66
+
67
+ // JSONify the encrypted data
68
+ const encryptionPack = encodeURIComponent(JSON.stringify({
69
+ ciphertext,
70
+ iv,
71
+ tag,
72
+ }));
73
+
74
+ // Show the encrypted data
75
+ console.log('\n\n');
76
+ console.log('––––– Done! What\'s Next: –––––');
77
+ console.log('');
78
+ console.log('On the server *sending* the requests, append the following to the DCEKIT_CROSS_SERVER_CREDENTIALS env var:');
79
+ console.log(`|${host}:${key}:${secret}|`);
80
+ console.log('');
81
+ console.log('On the server *receiving* the requests, add an entry to the "CrossServerCredential" collection:');
82
+ console.log(`{ "description": "${description}", "key": "${key}", "encodedeSecret": "${encryptionPack}", "scopes": [] }`);
83
+ console.log('');
84
+ console.log('For all scopes that the server should have access to, add them to the "scopes" array.');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Log reviewer page size
3
+ * @author Yuen Ler Chow
4
+ */
5
+ declare const LOG_REVIEW_PAGE_SIZE = 100;
6
+ export default LOG_REVIEW_PAGE_SIZE;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Log reviewer page size
5
+ * @author Yuen Ler Chow
6
+ */
7
+ var LOG_REVIEW_PAGE_SIZE = 100;
8
+ exports.default = LOG_REVIEW_PAGE_SIZE;
9
+ //# sourceMappingURL=LOG_REVIEW_PAGE_SIZE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_REVIEW_PAGE_SIZE.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_PAGE_SIZE.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,IAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,kBAAe,oBAAoB,CAAC"}
@@ -165,7 +165,7 @@ exports.signRequest = signRequest;
165
165
  * @returns parsed and validated params
166
166
  */
167
167
  var validateSignedRequest = function (opts) { return __awaiter(void 0, void 0, void 0, function () {
168
- var signature, timestamp, key, method, path, params, crossServerCredentialCollection, crossServerCredential, allowedScopes, secret, expectedSignature, elapsedMs;
168
+ var signature, timestamp, key, method, path, params, scope, crossServerCredentialCollection, crossServerCredentialMatches, crossServerCredential, allowedScopes, secret, paramsToSign, expectedSignature, elapsedMs;
169
169
  return __generator(this, function (_a) {
170
170
  switch (_a.label) {
171
171
  case 0:
@@ -189,31 +189,39 @@ var validateSignedRequest = function (opts) { return __awaiter(void 0, void 0, v
189
189
  throw new dce_reactkit_1.ErrorWithCode('Could not validate a cross-server request there was no oauth consumer key.', ExpressKitErrorCode_1.default.CrossServerMissingSignedRequestInfo);
190
190
  }
191
191
  key = opts.params.oauth_consumer_key;
192
- method = opts.method, path = opts.path, params = opts.params;
192
+ method = opts.method, path = opts.path, params = opts.params, scope = opts.scope;
193
193
  crossServerCredentialCollection = (0, initServer_1.internalGetCrossServerCredentialCollection)();
194
194
  if (!crossServerCredentialCollection) {
195
195
  throw new dce_reactkit_1.ErrorWithCode('Could not validate a cross-server request because the cross-server credential collection was not ready in time.', ExpressKitErrorCode_1.default.SignedRequestInvalidCollection);
196
196
  }
197
197
  return [4 /*yield*/, crossServerCredentialCollection.find({ key: key })];
198
198
  case 1:
199
- crossServerCredential = _a.sent();
200
- console.log('Credential:', key, crossServerCredential);
201
- if (!crossServerCredential) {
199
+ crossServerCredentialMatches = _a.sent();
200
+ if (!crossServerCredentialMatches || crossServerCredentialMatches.length === 0) {
202
201
  throw new dce_reactkit_1.ErrorWithCode('Could not validate a cross-server request because the credential was not found.', ExpressKitErrorCode_1.default.SignedRequestInvalidCredential);
203
202
  }
203
+ crossServerCredential = crossServerCredentialMatches[0];
204
204
  allowedScopes = crossServerCredential.scopes;
205
- console.log('Scopes', allowedScopes);
206
- if (!allowedScopes || !Array.isArray(allowedScopes) || !allowedScopes.includes(opts.scope)) {
205
+ if (!allowedScopes || !Array.isArray(allowedScopes)) {
206
+ throw new dce_reactkit_1.ErrorWithCode('Could not validate a cross-server request because the credential does not have access to any scopes.', ExpressKitErrorCode_1.default.SignedRequestInvalidScope);
207
+ }
208
+ if (!allowedScopes.includes(scope)) {
207
209
  throw new dce_reactkit_1.ErrorWithCode('Could not validate a cross-server request because the required scope was not approved for the credential.', ExpressKitErrorCode_1.default.SignedRequestInvalidScope);
208
210
  }
209
211
  return [4 /*yield*/, decrypt(crossServerCredential.encodedeSecret)];
210
212
  case 2:
211
213
  secret = _a.sent();
212
- console.log('Decoded secret:', secret);
214
+ paramsToSign = __assign({}, params);
215
+ Object.keys(paramsToSign).forEach(function (key) {
216
+ // Delete oauth params
217
+ if (key.startsWith('oauth_')) {
218
+ delete paramsToSign[key];
219
+ }
220
+ });
213
221
  return [4 /*yield*/, genSignature({
214
222
  method: method,
215
223
  path: path,
216
- params: params,
224
+ params: paramsToSign,
217
225
  secret: secret,
218
226
  })];
219
227
  case 3:
@@ -223,7 +231,7 @@ var validateSignedRequest = function (opts) { return __awaiter(void 0, void 0, v
223
231
  throw new dce_reactkit_1.ErrorWithCode('Could not validate a cross-server request because the signature did not match.', ExpressKitErrorCode_1.default.SignedRequestInvalidSignature);
224
232
  }
225
233
  elapsedMs = Math.abs(Date.now() - timestamp);
226
- if (elapsedMs < dce_reactkit_1.MINUTE_IN_MS) {
234
+ if (elapsedMs > dce_reactkit_1.MINUTE_IN_MS) {
227
235
  throw new dce_reactkit_1.ErrorWithCode('Could not validate a cross-server request because the request was too old.', ExpressKitErrorCode_1.default.SignedRequestInvalidTimestamp);
228
236
  }
229
237
  return [2 /*return*/];
@@ -1 +1 @@
1
- {"version":3,"file":"dataSigner.js","sourceRoot":"","sources":["../../src/helpers/dataSigner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dataSigner.js","sourceRoot":"","sources":["../../src/helpers/dataSigner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Log, LogReviewerFilterState } from 'dce-reactkit';
2
+ import { Collection } from 'dce-mango';
3
+ /**
4
+ * Get logs for the log reviewer interface
5
+ * @author Yuen Ler Chow
6
+ * @param opts object containing all arguments
7
+ * @param opts.pageNumber the page number to retrieve (1-indexed)
8
+ * @param opts.filters filter criteria for logs
9
+ * @param opts.countDocuments if true, count number of documents matching
10
+ * filters and return num pages (not always required because if changing pages,
11
+ * we don't need to recount documents)
12
+ * @param opts.logCollection MongoDB collection containing logs
13
+ * @returns object with logs for the requested page and optionally total number of pages
14
+ */
15
+ declare const getLogReviewerLogs: (opts: {
16
+ pageNumber: number;
17
+ filters: LogReviewerFilterState;
18
+ countDocuments: boolean;
19
+ logCollection: Collection<Log>;
20
+ }) => Promise<import("dce-mango/lib/types/PaginatedResponse").default<Log> | {
21
+ numPages: number;
22
+ items: Log[];
23
+ currentPageNumber: number;
24
+ perPage: number;
25
+ hasAnotherPage: boolean;
26
+ }>;
27
+ export default getLogReviewerLogs;
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ // Import dce-reactkit
54
+ var dce_reactkit_1 = require("dce-reactkit");
55
+ // Import shared types
56
+ var LOG_REVIEW_PAGE_SIZE_1 = __importDefault(require("../constants/LOG_REVIEW_PAGE_SIZE"));
57
+ /**
58
+ * Get logs for the log reviewer interface
59
+ * @author Yuen Ler Chow
60
+ * @param opts object containing all arguments
61
+ * @param opts.pageNumber the page number to retrieve (1-indexed)
62
+ * @param opts.filters filter criteria for logs
63
+ * @param opts.countDocuments if true, count number of documents matching
64
+ * filters and return num pages (not always required because if changing pages,
65
+ * we don't need to recount documents)
66
+ * @param opts.logCollection MongoDB collection containing logs
67
+ * @returns object with logs for the requested page and optionally total number of pages
68
+ */
69
+ var getLogReviewerLogs = function (opts) { return __awaiter(void 0, void 0, void 0, function () {
70
+ var pageNumber, filters, countDocuments, logCollection, _a, dateFilterState, contextFilterState, tagFilterState, actionErrorFilterState, advancedFilterState, query, startDate, endDate, startTimestamp, endTimestamp, contextConditions, selectedTags, selectedTargets, selectedActions, roles, response, numPages, _b, _c;
71
+ return __generator(this, function (_d) {
72
+ switch (_d.label) {
73
+ case 0:
74
+ pageNumber = opts.pageNumber, filters = opts.filters, countDocuments = opts.countDocuments, logCollection = opts.logCollection;
75
+ _a = filters, dateFilterState = _a.dateFilterState, contextFilterState = _a.contextFilterState, tagFilterState = _a.tagFilterState, actionErrorFilterState = _a.actionErrorFilterState, advancedFilterState = _a.advancedFilterState;
76
+ query = {};
77
+ startDate = dateFilterState.startDate, endDate = dateFilterState.endDate;
78
+ startTimestamp = new Date("".concat(startDate.month, "/").concat(startDate.day, "/").concat(startDate.year)).getTime();
79
+ endTimestamp = ((new Date("".concat(endDate.month, "/").concat(endDate.day, "/").concat(endDate.year))).getTime()
80
+ + dce_reactkit_1.DAY_IN_MS);
81
+ // Add a date range condition to the query
82
+ query.timestamp = {
83
+ $gte: startTimestamp,
84
+ $lt: endTimestamp,
85
+ };
86
+ contextConditions = [];
87
+ Object.keys(contextFilterState).forEach(function (context) {
88
+ var value = contextFilterState[context];
89
+ if (typeof value === 'boolean') {
90
+ if (value) {
91
+ // The entire context is selected
92
+ contextConditions.push({ context: context });
93
+ }
94
+ }
95
+ else {
96
+ // The context has subcontexts
97
+ var subcontexts = Object.keys(value).filter(function (subcontext) {
98
+ return value[subcontext];
99
+ });
100
+ if (subcontexts.length > 0) {
101
+ contextConditions.push({
102
+ context: context,
103
+ subcontext: { $in: subcontexts },
104
+ });
105
+ }
106
+ }
107
+ });
108
+ if (contextConditions.length > 0) {
109
+ query.$or = contextConditions;
110
+ }
111
+ selectedTags = Object.keys(tagFilterState).filter(function (tag) { return tagFilterState[tag]; });
112
+ if (selectedTags.length > 0) {
113
+ query.tags = { $in: selectedTags };
114
+ }
115
+ /* --------- Action/Error Filter ---------- */
116
+ if (actionErrorFilterState.type) {
117
+ query.type = actionErrorFilterState.type;
118
+ }
119
+ if (actionErrorFilterState.type === dce_reactkit_1.LogType.Error) {
120
+ if (actionErrorFilterState.errorMessage) {
121
+ // Add error message to the query.
122
+ // $i is used for case-insensitive search, and $regex is used for partial matching
123
+ query.errorMessage = {
124
+ $regex: actionErrorFilterState.errorMessage,
125
+ $options: 'i',
126
+ };
127
+ }
128
+ if (actionErrorFilterState.errorCode) {
129
+ query.errorCode = {
130
+ $regex: actionErrorFilterState.errorCode,
131
+ $options: 'i',
132
+ };
133
+ }
134
+ }
135
+ if (actionErrorFilterState.type === dce_reactkit_1.LogType.Action) {
136
+ selectedTargets = (Object.keys(actionErrorFilterState.target)
137
+ .filter(function (target) {
138
+ return actionErrorFilterState.target[target];
139
+ }));
140
+ selectedActions = (Object.keys(actionErrorFilterState.action)
141
+ .filter(function (action) {
142
+ return actionErrorFilterState.action[action];
143
+ }));
144
+ if (selectedTargets.length > 0) {
145
+ query.target = { $in: selectedTargets };
146
+ }
147
+ if (selectedActions.length > 0) {
148
+ query.action = { $in: selectedActions };
149
+ }
150
+ }
151
+ /* ------------ Advanced Filter ----------- */
152
+ if (advancedFilterState.userFirstName) {
153
+ query.userFirstName = {
154
+ $regex: advancedFilterState.userFirstName,
155
+ $options: 'i',
156
+ };
157
+ }
158
+ if (advancedFilterState.userLastName) {
159
+ query.userLastName = {
160
+ $regex: advancedFilterState.userLastName,
161
+ $options: 'i',
162
+ };
163
+ }
164
+ if (advancedFilterState.userEmail) {
165
+ query.userEmail = {
166
+ $regex: advancedFilterState.userEmail,
167
+ $options: 'i',
168
+ };
169
+ }
170
+ if (advancedFilterState.userId) {
171
+ query.userId = Number.parseInt(advancedFilterState.userId, 10);
172
+ }
173
+ roles = [];
174
+ if (advancedFilterState.includeLearners) {
175
+ roles.push({ isLearner: true });
176
+ }
177
+ if (advancedFilterState.includeTTMs) {
178
+ roles.push({ isTTM: true });
179
+ }
180
+ if (advancedFilterState.includeAdmins) {
181
+ roles.push({ isAdmin: true });
182
+ }
183
+ // If any roles are selected, add them to the query
184
+ if (roles.length > 0) {
185
+ // The $or operator is used to match any of the roles
186
+ // The $and operator is to ensure that other conditions in the query are met
187
+ query.$and = [{ $or: roles }];
188
+ }
189
+ if (advancedFilterState.courseId) {
190
+ query.courseId = Number.parseInt(advancedFilterState.courseId, 10);
191
+ }
192
+ if (advancedFilterState.courseName) {
193
+ query.courseName = {
194
+ $regex: advancedFilterState.courseName,
195
+ $options: 'i',
196
+ };
197
+ }
198
+ if (advancedFilterState.isMobile !== undefined) {
199
+ query['device.isMobile'] = Boolean(advancedFilterState.isMobile);
200
+ }
201
+ if (advancedFilterState.source) {
202
+ query.source = advancedFilterState.source;
203
+ }
204
+ if (advancedFilterState.routePath) {
205
+ query.routePath = {
206
+ $regex: advancedFilterState.routePath,
207
+ $options: 'i',
208
+ };
209
+ }
210
+ if (advancedFilterState.routeTemplate) {
211
+ query.routeTemplate = {
212
+ $regex: advancedFilterState.routeTemplate,
213
+ $options: 'i',
214
+ };
215
+ }
216
+ return [4 /*yield*/, logCollection.findPaged({
217
+ query: query,
218
+ perPage: LOG_REVIEW_PAGE_SIZE_1.default,
219
+ pageNumber: pageNumber,
220
+ sortDescending: true,
221
+ })];
222
+ case 1:
223
+ response = _d.sent();
224
+ if (!countDocuments) return [3 /*break*/, 3];
225
+ _c = (_b = Math).ceil;
226
+ return [4 /*yield*/, logCollection.count(query)];
227
+ case 2:
228
+ numPages = _c.apply(_b, [(_d.sent())
229
+ / LOG_REVIEW_PAGE_SIZE_1.default]);
230
+ return [2 /*return*/, __assign(__assign({}, response), { numPages: numPages })];
231
+ case 3:
232
+ // Return response
233
+ return [2 /*return*/, response];
234
+ }
235
+ });
236
+ }); };
237
+ exports.default = getLogReviewerLogs;
238
+ //# sourceMappingURL=getLogReviewerLogs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLogReviewerLogs.js","sourceRoot":"","sources":["../../src/helpers/getLogReviewerLogs.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,21 @@
1
1
  import express from 'express';
2
2
  import { Collection } from 'dce-mango';
3
+ import { Log } from 'dce-reactkit';
4
+ import CrossServerCredential from '../types/CrossServerCredential';
3
5
  /**
4
6
  * Get log collection
5
7
  * @author Gabe Abrams
6
8
  * @returns log collection if one was included during launch or null if we don't
7
9
  * have a log collection (yet)
8
10
  */
9
- export declare const internalGetLogCollection: () => any;
11
+ export declare const internalGetLogCollection: () => Collection<Log>;
10
12
  /**
11
13
  * Get cross-server credential collection
12
14
  * @author Gabe Abrams
13
15
  * @return cross-server credential collection if one was included during launch or null
14
16
  * if we don't have a cross-server credential collection (yet)
15
17
  */
16
- export declare const internalGetCrossServerCredentialCollection: () => any;
18
+ export declare const internalGetCrossServerCredentialCollection: () => Collection<CrossServerCredential>;
17
19
  /**
18
20
  * Prepare dce-reactkit to run on the server
19
21
  * @author Gabe Abrams
@@ -37,7 +39,7 @@ export declare const internalGetCrossServerCredentialCollection: () => any;
37
39
  declare const initServer: (opts: {
38
40
  app: express.Application;
39
41
  logReviewAdmins?: (number[] | Collection<any>);
40
- logCollection?: Collection<any>;
41
- crossServerCredentialCollection?: Collection<any>;
42
+ logCollection?: Collection<Log>;
43
+ crossServerCredentialCollection?: Collection<CrossServerCredential>;
42
44
  }) => void;
43
45
  export default initServer;
@@ -55,7 +55,7 @@ exports.internalGetCrossServerCredentialCollection = exports.internalGetLogColle
55
55
  var dce_reactkit_1 = require("dce-reactkit");
56
56
  // Import shared helpers
57
57
  var genRouteHandler_1 = __importDefault(require("./genRouteHandler"));
58
- // Import shared types
58
+ var getLogReviewerLogs_1 = __importDefault(require("./getLogReviewerLogs"));
59
59
  var ExpressKitErrorCode_1 = __importDefault(require("../types/ExpressKitErrorCode"));
60
60
  // Stored copy of dce-mango log collection
61
61
  var _logCollection;
@@ -247,38 +247,36 @@ var initServer = function (opts) {
247
247
  }); },
248
248
  }));
249
249
  /**
250
- * Get all logs for a certain month
251
- * @author Gabe Abrams
252
- * @param {number} year the year to query (e.g. 2022)
253
- * @param {number} month the month to query (e.g. 1 = January)
254
- * @returns {Log[]} list of logs from the given month
250
+ * Get filtered logs based on provided filters
251
+ * @author Gabe Abrams, Yuen Ler Chow
252
+ * @param pageNumber the page number to get
253
+ * @param filters the filters to apply to the logs
254
+ * @returns {Log[]} list of logs that match the filters
255
255
  */
256
- opts.app.get("".concat(dce_reactkit_1.LOG_REVIEW_ROUTE_PATH_PREFIX, "/years/:year/months/:month"), (0, genRouteHandler_1.default)({
256
+ opts.app.get(dce_reactkit_1.LOG_REVIEW_GET_LOGS_ROUTE, (0, genRouteHandler_1.default)({
257
257
  paramTypes: {
258
- year: dce_reactkit_1.ParamType.Int,
259
- month: dce_reactkit_1.ParamType.Int,
260
258
  pageNumber: dce_reactkit_1.ParamType.Int,
259
+ filters: dce_reactkit_1.ParamType.JSON,
260
+ countDocuments: dce_reactkit_1.ParamType.Boolean,
261
261
  },
262
262
  handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
263
- var year, month, pageNumber, userId, isAdmin, canReview, response;
263
+ var pageNumber, userId, isAdmin, filters, countDocuments, canReview, response;
264
264
  var params = _b.params;
265
265
  return __generator(this, function (_c) {
266
266
  switch (_c.label) {
267
267
  case 0:
268
- year = params.year, month = params.month, pageNumber = params.pageNumber, userId = params.userId, isAdmin = params.isAdmin;
268
+ pageNumber = params.pageNumber, userId = params.userId, isAdmin = params.isAdmin, filters = params.filters, countDocuments = params.countDocuments;
269
269
  return [4 /*yield*/, canReviewLogs(userId, isAdmin)];
270
270
  case 1:
271
271
  canReview = _c.sent();
272
272
  if (!canReview) {
273
273
  throw new dce_reactkit_1.ErrorWithCode('You cannot access this resource because you do not have the appropriate permissions.', ExpressKitErrorCode_1.default.NotAllowedToReviewLogs);
274
274
  }
275
- return [4 /*yield*/, _logCollection.findPaged({
276
- query: {
277
- year: year,
278
- month: month,
279
- },
280
- perPage: 1000,
275
+ return [4 /*yield*/, (0, getLogReviewerLogs_1.default)({
281
276
  pageNumber: pageNumber,
277
+ filters: filters,
278
+ countDocuments: countDocuments,
279
+ logCollection: _logCollection,
282
280
  })];
283
281
  case 2:
284
282
  response = _c.sent();
@@ -1 +1 @@
1
- {"version":3,"file":"initServer.js","sourceRoot":"","sources":["../../src/helpers/initServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"initServer.js","sourceRoot":"","sources":["../../src/helpers/initServer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,sBAAsB;AACtB,6CAQsB;AAEtB,wBAAwB;AACxB,sEAAgD;AAChD,4EAAsD;AAItD,qFAA+D;AAE/D,0CAA0C;AAC1C,IAAI,cAA+B,CAAC;AAEpC,8DAA8D;AAC9D,IAAI,gCAAmE,CAAC;AAExE,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAE5E;;;;;GAKG;AACI,IAAM,wBAAwB,GAAG;IACtC,OAAO,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,IAAI,CAAC;AAChC,CAAC,CAAC;AAFW,QAAA,wBAAwB,4BAEnC;AAEF;;;;;GAKG;AACI,IAAM,0CAA0C,GAAG;IACxD,OAAO,gCAAgC,aAAhC,gCAAgC,cAAhC,gCAAgC,GAAI,IAAI,CAAC;AAClD,CAAC,CAAC;AAFW,QAAA,0CAA0C,8CAErD;AAEF,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAE5E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,IAAM,UAAU,GAAG,UACjB,IAKC;IAED,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC;IACpC,gCAAgC,GAAG,IAAI,CAAC,+BAA+B,CAAC;IAExE,4CAA4C;IAC5C,4CAA4C;IAC5C,4CAA4C;IAE5C;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,6BAAc,EACd,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,OAAO,EAAE,wBAAS,CAAC,MAAM;YACzB,UAAU,EAAE,wBAAS,CAAC,MAAM;YAC5B,IAAI,EAAE,wBAAS,CAAC,IAAI;YACpB,KAAK,EAAE,wBAAS,CAAC,MAAM;YACvB,QAAQ,EAAE,wBAAS,CAAC,IAAI;YACxB,YAAY,EAAE,wBAAS,CAAC,cAAc;YACtC,SAAS,EAAE,wBAAS,CAAC,cAAc;YACnC,UAAU,EAAE,wBAAS,CAAC,cAAc;YACpC,MAAM,EAAE,wBAAS,CAAC,cAAc;YAChC,MAAM,EAAE,wBAAS,CAAC,cAAc;SACjC;QACD,OAAO,EAAE,UAAC,EAA0B;gBAAxB,MAAM,YAAA,EAAE,cAAc,oBAAA;YAChC,kBAAkB;YAClB,IAAM,OAAO,GAA+B,CAC1C,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC;gBAC5D,QAAQ;gBACR,CAAC,CAAC;oBACA,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,KAAK,EAAE;wBACL,OAAO,EAAE,MAAM,CAAC,YAAY;wBAC5B,IAAI,EAAE,MAAM,CAAC,SAAS;wBACtB,KAAK,EAAE,MAAM,CAAC,UAAU;qBACzB;iBACF;gBACD,SAAS;gBACT,CAAC,CAAC;oBACA,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;iBACtB,CACJ,CAAC;YAEF,kDAAkD;YAClD,IAAM,uBAAuB,yBACxB,OAAO,KACV,qBAAqB,EAAE,IAAI,GAC5B,CAAC;YAEF,gBAAgB;YAChB,IAAM,GAAG,GAAG,cAAc,CAAC,uBAAuB,CAAC,CAAC;YAEpD,SAAS;YACT,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC,CACH,CAAC;IAEF,4CAA4C;IAC5C,4CAA4C;IAC5C,4CAA4C;IAE5C;;;;;;OAMG;IACH,IAAM,aAAa,GAAG,UACpB,MAAc,EACd,OAAgB;;;;;oBAEhB,kDAAkD;oBAClD,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,sBAAO,KAAK,EAAC;oBACf,CAAC;oBAED,wCAAwC;oBACxC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;wBAC1B,sBAAO,IAAI,EAAC;oBACd,CAAC;;;;oBAIC,mBAAmB;oBACnB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;wBACxC,sBAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAC,SAAS;gCACzC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;4BAChC,CAAC,CAAC,EAAC;oBACL,CAAC;oBAGe,qBAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,QAAA,EAAE,CAAC,EAAA;;oBAArD,OAAO,GAAG,SAA2C;oBAE3D,uCAAuC;oBACvC,sBAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAC;;;oBAE1B,4CAA4C;oBAC5C,sBAAO,KAAK,EAAC;;;;SAEhB,CAAC;IAEF;;;;OAIG;IACH,IAAI,CAAC,GAAG,CAAC,GAAG,CACV,sCAAuB,EACvB,IAAA,yBAAe,EAAC;QACd,OAAO,EAAE,iEAAO,EAAU;;gBAAR,MAAM,YAAA;;;;wBACd,MAAM,GAAc,MAAM,OAApB,EAAE,OAAO,GAAK,MAAM,QAAX,CAAY;wBACjB,qBAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAA;;wBAAhD,SAAS,GAAG,SAAoC;wBACtD,sBAAO,SAAS,EAAC;;;aAClB;KACF,CAAC,CACH,CAAC;IAEF;;;;;;OAMG;IACH,IAAI,CAAC,GAAG,CAAC,GAAG,CACV,wCAAyB,EACzB,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,UAAU,EAAE,wBAAS,CAAC,GAAG;YACzB,OAAO,EAAE,wBAAS,CAAC,IAAI;YACvB,cAAc,EAAE,wBAAS,CAAC,OAAO;SAClC;QACD,OAAO,EAAE,iEAAO,EAAU;;gBAAR,MAAM,YAAA;;;;wBAGpB,UAAU,GAKR,MAAM,WALE,EACV,MAAM,GAIJ,MAAM,OAJF,EACN,OAAO,GAGL,MAAM,QAHD,EACP,OAAO,GAEL,MAAM,QAFD,EACP,cAAc,GACZ,MAAM,eADM,CACL;wBAGO,qBAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAA;;wBAAhD,SAAS,GAAG,SAAoC;wBACtD,IAAI,CAAC,SAAS,EAAE,CAAC;4BACf,MAAM,IAAI,4BAAa,CACrB,sFAAsF,EACtF,6BAAmB,CAAC,sBAAsB,CAC3C,CAAC;wBACJ,CAAC;wBAGgB,qBAAM,IAAA,4BAAkB,EAAC;gCACxC,UAAU,YAAA;gCACV,OAAO,SAAA;gCACP,cAAc,gBAAA;gCACd,aAAa,EAAE,cAAc;6BAC9B,CAAC,EAAA;;wBALI,QAAQ,GAAG,SAKf;wBAEF,kBAAkB;wBAClB,sBAAO,QAAQ,EAAC;;;aACjB;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,UAAU,CAAC"}
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "dce-expresskit",
3
- "version": "4.0.0-beta.8",
3
+ "version": "4.0.0-log-reviewer-beta.10",
4
4
  "description": "Shared functions, helpers, and tools for Harvard DCE Express-based servers",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc --project ./tsconfig.json",
9
- "gen-cross-server-secret": "npx tsx genEncodedSecret.ts",
10
- "gen-cross-server-salt": "npx tsx genSalt.ts"
9
+ "gen-cross-server-secret": "npx tsx genEncodedSecret.ts"
11
10
  },
12
11
  "repository": {
13
12
  "type": "git",
@@ -25,7 +24,7 @@
25
24
  "@fortawesome/free-solid-svg-icons": "^6.7.2",
26
25
  "@fortawesome/react-fontawesome": "^0.2.2",
27
26
  "bootstrap": "^5.3.3",
28
- "dce-reactkit": "^4.0.0-beta.2",
27
+ "dce-reactkit": "^4.0.0-beta-logreviewer.1",
29
28
  "react": "^19.0.0"
30
29
  },
31
30
  "peerDependencies": {
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Log reviewer page size
3
+ * @author Yuen Ler Chow
4
+ */
5
+ const LOG_REVIEW_PAGE_SIZE = 100;
6
+
7
+ export default LOG_REVIEW_PAGE_SIZE;
@@ -172,6 +172,7 @@ export const signRequest = async (
172
172
  // Add signature to the augmented params
173
173
  augmentedParams.oauth_signature = signature;
174
174
 
175
+
175
176
  // Return the augmented params
176
177
  return augmentedParams;
177
178
  };
@@ -233,6 +234,7 @@ export const validateSignedRequest = async (
233
234
  method,
234
235
  path,
235
236
  params,
237
+ scope,
236
238
  } = opts;
237
239
 
238
240
  /* ------- Look Up Credential ------- */
@@ -247,19 +249,25 @@ export const validateSignedRequest = async (
247
249
  }
248
250
 
249
251
  // Get the cross-server credential
250
- const crossServerCredential: CrossServerCredential = await crossServerCredentialCollection.find({ key });
251
- console.log('Credential:', key, crossServerCredential);
252
- if (!crossServerCredential) {
252
+ const crossServerCredentialMatches: CrossServerCredential[] = await crossServerCredentialCollection.find({ key });
253
+ if (!crossServerCredentialMatches || crossServerCredentialMatches.length === 0) {
253
254
  throw new ErrorWithCode(
254
255
  'Could not validate a cross-server request because the credential was not found.',
255
256
  ExpressKitErrorCode.SignedRequestInvalidCredential,
256
257
  );
257
258
  }
259
+ const crossServerCredential = crossServerCredentialMatches[0];
258
260
 
259
261
  // Make sure the scope is included
260
262
  const allowedScopes = crossServerCredential.scopes;
261
- console.log('Scopes', allowedScopes);
262
- if (!allowedScopes || !Array.isArray(allowedScopes) || !allowedScopes.includes(opts.scope)) {
263
+ if (!allowedScopes || !Array.isArray(allowedScopes)) {
264
+ throw new ErrorWithCode(
265
+ 'Could not validate a cross-server request because the credential does not have access to any scopes.',
266
+ ExpressKitErrorCode.SignedRequestInvalidScope,
267
+ );
268
+
269
+ }
270
+ if (!allowedScopes.includes(scope)) {
263
271
  throw new ErrorWithCode(
264
272
  'Could not validate a cross-server request because the required scope was not approved for the credential.',
265
273
  ExpressKitErrorCode.SignedRequestInvalidScope,
@@ -268,15 +276,27 @@ export const validateSignedRequest = async (
268
276
 
269
277
  // Decode the secret
270
278
  const secret = await decrypt(crossServerCredential.encodedeSecret);
271
- console.log('Decoded secret:', secret);
272
279
 
273
280
  /* -------- Verify Signature -------- */
274
281
 
282
+ // Curate what goes into the params
283
+ const paramsToSign: {
284
+ [key: string]: any,
285
+ } = {
286
+ ...params,
287
+ };
288
+ Object.keys(paramsToSign).forEach((key) => {
289
+ // Delete oauth params
290
+ if (key.startsWith('oauth_')) {
291
+ delete paramsToSign[key];
292
+ }
293
+ });
294
+
275
295
  // Generate a new signature to compare
276
296
  const expectedSignature = await genSignature({
277
297
  method,
278
298
  path,
279
- params,
299
+ params: paramsToSign,
280
300
  secret,
281
301
  });
282
302
 
@@ -290,7 +310,7 @@ export const validateSignedRequest = async (
290
310
 
291
311
  // Make sure the timestamp was recent enough
292
312
  const elapsedMs = Math.abs(Date.now() - timestamp);
293
- if (elapsedMs < MINUTE_IN_MS) {
313
+ if (elapsedMs > MINUTE_IN_MS) {
294
314
  throw new ErrorWithCode(
295
315
  'Could not validate a cross-server request because the request was too old.',
296
316
  ExpressKitErrorCode.SignedRequestInvalidTimestamp,
@@ -0,0 +1,259 @@
1
+ // Import dce-reactkit
2
+ import {
3
+ DAY_IN_MS,
4
+ Log,
5
+ LogReviewerFilterState,
6
+ LogType
7
+ } from 'dce-reactkit';
8
+
9
+ // Import shared types
10
+ import LOG_REVIEW_PAGE_SIZE from '../constants/LOG_REVIEW_PAGE_SIZE';
11
+ import { Collection } from 'dce-mango';
12
+
13
+ /**
14
+ * Get logs for the log reviewer interface
15
+ * @author Yuen Ler Chow
16
+ * @param opts object containing all arguments
17
+ * @param opts.pageNumber the page number to retrieve (1-indexed)
18
+ * @param opts.filters filter criteria for logs
19
+ * @param opts.countDocuments if true, count number of documents matching
20
+ * filters and return num pages (not always required because if changing pages,
21
+ * we don't need to recount documents)
22
+ * @param opts.logCollection MongoDB collection containing logs
23
+ * @returns object with logs for the requested page and optionally total number of pages
24
+ */
25
+ const getLogReviewerLogs = async (
26
+ opts: {
27
+ pageNumber: number,
28
+ filters: LogReviewerFilterState,
29
+ countDocuments: boolean,
30
+ logCollection: Collection<Log>,
31
+ },
32
+ ) => {
33
+
34
+ // Destructure opts
35
+ const {
36
+ pageNumber,
37
+ filters,
38
+ countDocuments,
39
+ logCollection,
40
+ } = opts;
41
+
42
+
43
+ // Destructure filters
44
+ const {
45
+ dateFilterState,
46
+ contextFilterState,
47
+ tagFilterState,
48
+ actionErrorFilterState,
49
+ advancedFilterState,
50
+ } = filters as LogReviewerFilterState;
51
+
52
+ // Build MongoDB query based on filters
53
+ const query: { [k: string]: any } = {};
54
+
55
+ /* -------------- Date Filter ------------- */
56
+
57
+ // Convert start and end dates from the dateFilterState into timestamps
58
+ const { startDate, endDate } = dateFilterState;
59
+ const startTimestamp = new Date(
60
+ `${startDate.month}/${startDate.day}/${startDate.year}`,
61
+ ).getTime();
62
+ const endTimestamp = (
63
+ (new Date(`${endDate.month}/${endDate.day}/${endDate.year}`)).getTime()
64
+ + DAY_IN_MS
65
+ );
66
+
67
+ // Add a date range condition to the query
68
+ query.timestamp = {
69
+ $gte: startTimestamp,
70
+ $lt: endTimestamp,
71
+ };
72
+
73
+ /* ------------ Context Filter ------------ */
74
+
75
+ // Process context filters to include selected contexts and subcontexts
76
+ const contextConditions: { [k: string]: any }[] = [];
77
+ Object.keys(contextFilterState).forEach((context) => {
78
+ const value = contextFilterState[context];
79
+ if (typeof value === 'boolean') {
80
+ if (value) {
81
+ // The entire context is selected
82
+ contextConditions.push({ context });
83
+ }
84
+ } else {
85
+ // The context has subcontexts
86
+ const subcontexts = Object.keys(value).filter((subcontext) => {
87
+ return value[subcontext];
88
+ });
89
+
90
+ if (subcontexts.length > 0) {
91
+ contextConditions.push({
92
+ context,
93
+ subcontext: { $in: subcontexts },
94
+ });
95
+ }
96
+ }
97
+ });
98
+ if (contextConditions.length > 0) {
99
+ query.$or = contextConditions;
100
+ }
101
+
102
+ /* -------------- Tag Filter -------------- */
103
+
104
+ const selectedTags = Object.keys(tagFilterState).filter((tag) => { return tagFilterState[tag]; });
105
+ if (selectedTags.length > 0) {
106
+ query.tags = { $in: selectedTags };
107
+ }
108
+
109
+ /* --------- Action/Error Filter ---------- */
110
+
111
+ if (actionErrorFilterState.type) {
112
+ query.type = actionErrorFilterState.type;
113
+ }
114
+
115
+ if (actionErrorFilterState.type === LogType.Error) {
116
+ if (actionErrorFilterState.errorMessage) {
117
+ // Add error message to the query.
118
+ // $i is used for case-insensitive search, and $regex is used for partial matching
119
+ query.errorMessage = {
120
+ $regex: actionErrorFilterState.errorMessage,
121
+ $options: 'i',
122
+ };
123
+ }
124
+
125
+ if (actionErrorFilterState.errorCode) {
126
+ query.errorCode = {
127
+ $regex: actionErrorFilterState.errorCode,
128
+ $options: 'i',
129
+ };
130
+ }
131
+ }
132
+
133
+ if (actionErrorFilterState.type === LogType.Action) {
134
+ const selectedTargets = (
135
+ Object.keys(actionErrorFilterState.target)
136
+ .filter((target) => {
137
+ return actionErrorFilterState.target[target];
138
+ })
139
+ );
140
+ const selectedActions = (
141
+ Object.keys(actionErrorFilterState.action)
142
+ .filter((action) => {
143
+ return actionErrorFilterState.action[action];
144
+ })
145
+ );
146
+ if (selectedTargets.length > 0) {
147
+ query.target = { $in: selectedTargets };
148
+ }
149
+ if (selectedActions.length > 0) {
150
+ query.action = { $in: selectedActions };
151
+ }
152
+ }
153
+
154
+ /* ------------ Advanced Filter ----------- */
155
+
156
+ if (advancedFilterState.userFirstName) {
157
+ query.userFirstName = {
158
+ $regex: advancedFilterState.userFirstName,
159
+ $options: 'i',
160
+ };
161
+ }
162
+
163
+ if (advancedFilterState.userLastName) {
164
+ query.userLastName = {
165
+ $regex: advancedFilterState.userLastName,
166
+ $options: 'i',
167
+ };
168
+ }
169
+
170
+ if (advancedFilterState.userEmail) {
171
+ query.userEmail = {
172
+ $regex: advancedFilterState.userEmail,
173
+ $options: 'i',
174
+ };
175
+ }
176
+
177
+ if (advancedFilterState.userId) {
178
+ query.userId = Number.parseInt(advancedFilterState.userId, 10);
179
+ }
180
+
181
+ const roles: {
182
+ isLearner?: boolean,
183
+ isTTM?: boolean,
184
+ isAdmin?: boolean,
185
+ }[] = [];
186
+ if (advancedFilterState.includeLearners) {
187
+ roles.push({ isLearner: true });
188
+ }
189
+ if (advancedFilterState.includeTTMs) {
190
+ roles.push({ isTTM: true });
191
+ }
192
+ if (advancedFilterState.includeAdmins) {
193
+ roles.push({ isAdmin: true });
194
+ }
195
+ // If any roles are selected, add them to the query
196
+ if (roles.length > 0) {
197
+ // The $or operator is used to match any of the roles
198
+ // The $and operator is to ensure that other conditions in the query are met
199
+ query.$and = [{ $or: roles }];
200
+ }
201
+
202
+ if (advancedFilterState.courseId) {
203
+ query.courseId = Number.parseInt(advancedFilterState.courseId, 10);
204
+ }
205
+
206
+ if (advancedFilterState.courseName) {
207
+ query.courseName = {
208
+ $regex: advancedFilterState.courseName,
209
+ $options: 'i',
210
+ };
211
+ }
212
+
213
+ if (advancedFilterState.isMobile !== undefined) {
214
+ query['device.isMobile'] = Boolean(advancedFilterState.isMobile);
215
+ }
216
+
217
+ if (advancedFilterState.source) {
218
+ query.source = advancedFilterState.source;
219
+ }
220
+
221
+ if (advancedFilterState.routePath) {
222
+ query.routePath = {
223
+ $regex: advancedFilterState.routePath,
224
+ $options: 'i',
225
+ };
226
+ }
227
+
228
+ if (advancedFilterState.routeTemplate) {
229
+ query.routeTemplate = {
230
+ $regex: advancedFilterState.routeTemplate,
231
+ $options: 'i',
232
+ };
233
+ }
234
+
235
+ // Query for logs
236
+ const response = await logCollection.findPaged({
237
+ query,
238
+ perPage: LOG_REVIEW_PAGE_SIZE,
239
+ pageNumber,
240
+ sortDescending: true,
241
+ });
242
+
243
+ // Count documents if requested
244
+ if (countDocuments) {
245
+ const numPages = Math.ceil(
246
+ await logCollection.count(query)
247
+ / LOG_REVIEW_PAGE_SIZE
248
+ );
249
+ return {
250
+ ...response,
251
+ numPages,
252
+ };
253
+ }
254
+
255
+ // Return response
256
+ return response;
257
+ };
258
+
259
+ export default getLogReviewerLogs;
@@ -6,25 +6,28 @@ import { Collection } from 'dce-mango';
6
6
 
7
7
  // Import dce-reactkit
8
8
  import {
9
- ErrorWithCode,
10
9
  ParamType,
11
10
  LogFunction,
12
- LOG_REVIEW_ROUTE_PATH_PREFIX,
13
11
  LOG_ROUTE_PATH,
14
12
  LOG_REVIEW_STATUS_ROUTE,
13
+ Log,
14
+ LOG_REVIEW_GET_LOGS_ROUTE,
15
+ ErrorWithCode,
15
16
  } from 'dce-reactkit';
16
17
 
17
18
  // Import shared helpers
18
19
  import genRouteHandler from './genRouteHandler';
20
+ import getLogReviewerLogs from './getLogReviewerLogs';
19
21
 
20
22
  // Import shared types
23
+ import CrossServerCredential from '../types/CrossServerCredential';
21
24
  import ExpressKitErrorCode from '../types/ExpressKitErrorCode';
22
25
 
23
26
  // Stored copy of dce-mango log collection
24
- let _logCollection: any;
27
+ let _logCollection: Collection<Log>;
25
28
 
26
29
  // Stored copy of dce-mango cross-server credential collection
27
- let _crossServerCredentialCollection: any;
30
+ let _crossServerCredentialCollection: Collection<CrossServerCredential>;
28
31
 
29
32
  /*------------------------------------------------------------------------*/
30
33
  /* Helpers */
@@ -78,8 +81,8 @@ const initServer = (
78
81
  opts: {
79
82
  app: express.Application,
80
83
  logReviewAdmins?: (number[] | Collection<any>),
81
- logCollection?: Collection<any>,
82
- crossServerCredentialCollection?: Collection<any>,
84
+ logCollection?: Collection<Log>,
85
+ crossServerCredentialCollection?: Collection<CrossServerCredential>,
83
86
  },
84
87
  ) => {
85
88
  _logCollection = opts.logCollection;
@@ -229,28 +232,28 @@ const initServer = (
229
232
  );
230
233
 
231
234
  /**
232
- * Get all logs for a certain month
233
- * @author Gabe Abrams
234
- * @param {number} year the year to query (e.g. 2022)
235
- * @param {number} month the month to query (e.g. 1 = January)
236
- * @returns {Log[]} list of logs from the given month
235
+ * Get filtered logs based on provided filters
236
+ * @author Gabe Abrams, Yuen Ler Chow
237
+ * @param pageNumber the page number to get
238
+ * @param filters the filters to apply to the logs
239
+ * @returns {Log[]} list of logs that match the filters
237
240
  */
238
241
  opts.app.get(
239
- `${LOG_REVIEW_ROUTE_PATH_PREFIX}/years/:year/months/:month`,
242
+ LOG_REVIEW_GET_LOGS_ROUTE,
240
243
  genRouteHandler({
241
244
  paramTypes: {
242
- year: ParamType.Int,
243
- month: ParamType.Int,
244
245
  pageNumber: ParamType.Int,
246
+ filters: ParamType.JSON,
247
+ countDocuments: ParamType.Boolean,
245
248
  },
246
249
  handler: async ({ params }) => {
247
- // Get user info
250
+ // Destructure params
248
251
  const {
249
- year,
250
- month,
251
252
  pageNumber,
252
253
  userId,
253
254
  isAdmin,
255
+ filters,
256
+ countDocuments,
254
257
  } = params;
255
258
 
256
259
  // Validate user
@@ -262,14 +265,12 @@ const initServer = (
262
265
  );
263
266
  }
264
267
 
265
- // Query for logs
266
- const response = await _logCollection.findPaged({
267
- query: {
268
- year,
269
- month,
270
- },
271
- perPage: 1000,
268
+ // Get logs
269
+ const response = await getLogReviewerLogs({
272
270
  pageNumber,
271
+ filters,
272
+ countDocuments,
273
+ logCollection: _logCollection,
273
274
  });
274
275
 
275
276
  // Return response
package/genSalt.ts DELETED
@@ -1,15 +0,0 @@
1
- // All chars for randomizer
2
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
3
-
4
- // Generate a random salt
5
- let salt = '';
6
- for (let i = 0; i < 32; i++) {
7
- salt += chars.charAt(Math.floor(Math.random() * chars.length));
8
- }
9
- salt = Buffer.from(salt).toString('base64');
10
-
11
- // Generates 32 byte salt
12
- console.log('New *receiving* server salt:')
13
-
14
- Buffer.from("Hello World").toString('base64')
15
- console.log(salt);
@@ -1,9 +0,0 @@
1
- import ROUTE_PATH_PREFIX from './ROUTE_PATH_PREFIX';
2
-
3
- /**
4
- * Path of the route for storing client-side logs
5
- * @author Gabe Abrams
6
- */
7
- const LOG_REVIEW_ROUTE_PATH_PREFIX = `/admin${ROUTE_PATH_PREFIX}/logs`;
8
-
9
- export default LOG_REVIEW_ROUTE_PATH_PREFIX;
@@ -1,10 +0,0 @@
1
- import ROUTE_PATH_PREFIX from './ROUTE_PATH_PREFIX';
2
-
3
- /**
4
- * Route for checking the status of the current user's
5
- * access to log review
6
- * @author Gabe Abrams
7
- */
8
- const LOG_REVIEW_STATUS_ROUTE = `${ROUTE_PATH_PREFIX}/logs/access_allowed`;
9
-
10
- export default LOG_REVIEW_STATUS_ROUTE;
@@ -1,9 +0,0 @@
1
- import ROUTE_PATH_PREFIX from './ROUTE_PATH_PREFIX';
2
-
3
- /**
4
- * Path of the route for storing client-side logs
5
- * @author Gabe Abrams
6
- */
7
- const LOG_ROUTE_PATH = `${ROUTE_PATH_PREFIX}/log`;
8
-
9
- export default LOG_ROUTE_PATH;
@@ -1,7 +0,0 @@
1
- /**
2
- * Path that all routes start with
3
- * @author Gabe Abrams
4
- */
5
- const ROUTE_PATH_PREFIX = '/dce-expresskit';
6
-
7
- export default ROUTE_PATH_PREFIX;
@@ -1,15 +0,0 @@
1
- /**
2
- * An error with a code
3
- * @author Gabe Abrams
4
- */
5
- class ErrorWithCode extends Error {
6
- code: string;
7
-
8
- constructor(message: string, code: string) {
9
- super(message);
10
- this.name = 'ErrorWithCode';
11
- this.code = code;
12
- }
13
- }
14
-
15
- export default ErrorWithCode;