dce-reactkit 3.12.3 → 4.0.0-beta.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 (71) hide show
  1. package/.vscode/settings.json +1 -3
  2. package/README.md +20 -0
  3. package/dist/cjs/index.js +156 -1792
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/types/components/ItemPicker/index.d.ts +0 -1
  6. package/dist/cjs/types/components/Modal/ModalProps.d.ts +0 -2
  7. package/dist/cjs/types/components/TabBox.d.ts +0 -1
  8. package/dist/cjs/types/index.d.ts +8 -12
  9. package/dist/cjs/types/types/ParamType.d.ts +10 -10
  10. package/dist/cjs/types/types/ReactKitErrorCode.d.ts +1 -15
  11. package/dist/esm/index.js +157 -1785
  12. package/dist/esm/index.js.map +1 -1
  13. package/dist/esm/types/components/ItemPicker/index.d.ts +0 -1
  14. package/dist/esm/types/components/Modal/ModalProps.d.ts +0 -2
  15. package/dist/esm/types/components/TabBox.d.ts +0 -1
  16. package/dist/esm/types/index.d.ts +8 -12
  17. package/dist/esm/types/types/ParamType.d.ts +10 -10
  18. package/dist/esm/types/types/ReactKitErrorCode.d.ts +1 -15
  19. package/dist/index.d.ts +122 -351
  20. package/genEncodedSecret.ts +84 -0
  21. package/package.json +7 -5
  22. package/rollup.config.js +2 -0
  23. package/src/components/AppWrapper.tsx +3 -1
  24. package/src/components/CheckboxButton.tsx +1 -1
  25. package/src/components/Dropdown.tsx +1 -1
  26. package/src/components/IntelliTable.tsx +1 -1
  27. package/src/components/ItemPicker/NestableItemList.tsx +0 -1
  28. package/src/components/ItemPicker/index.tsx +0 -96
  29. package/src/components/Modal/ModalProps.ts +0 -4
  30. package/src/components/Modal/index.tsx +21 -60
  31. package/src/components/RadioButton.tsx +3 -1
  32. package/src/components/TabBox.tsx +9 -27
  33. package/src/{client → helpers}/initClient.tsx +5 -1
  34. package/src/helpers/logClientEvent.tsx +3 -1
  35. package/src/helpers/visitServerEndpoint.tsx +1 -1
  36. package/src/index.ts +12 -22
  37. package/src/types/ParamType.ts +10 -10
  38. package/src/types/ReactKitErrorCode.tsx +1 -17
  39. package/dist/cjs/types/helpers/addDBEditorEndpoints.d.ts +0 -41
  40. package/dist/cjs/types/helpers/genRouteHandler.d.ts +0 -76
  41. package/dist/cjs/types/helpers/getWordCount.d.ts +0 -10
  42. package/dist/cjs/types/helpers/handleError.d.ts +0 -18
  43. package/dist/cjs/types/helpers/handleSuccess.d.ts +0 -8
  44. package/dist/cjs/types/helpers/parseUserAgent.d.ts +0 -17
  45. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/index.d.ts +0 -24
  46. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +0 -33
  47. package/dist/cjs/types/server/initLogCollection.d.ts +0 -8
  48. package/dist/cjs/types/server/initServer.d.ts +0 -42
  49. package/dist/esm/types/helpers/addDBEditorEndpoints.d.ts +0 -41
  50. package/dist/esm/types/helpers/genRouteHandler.d.ts +0 -76
  51. package/dist/esm/types/helpers/getWordCount.d.ts +0 -10
  52. package/dist/esm/types/helpers/handleError.d.ts +0 -18
  53. package/dist/esm/types/helpers/handleSuccess.d.ts +0 -8
  54. package/dist/esm/types/helpers/parseUserAgent.d.ts +0 -17
  55. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/index.d.ts +0 -24
  56. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +0 -33
  57. package/dist/esm/types/server/initLogCollection.d.ts +0 -8
  58. package/dist/esm/types/server/initServer.d.ts +0 -42
  59. package/src/components/ItemPicker/index.test.tsx +0 -783
  60. package/src/helpers/addDBEditorEndpoints.ts +0 -128
  61. package/src/helpers/genRouteHandler.ts +0 -948
  62. package/src/helpers/getWordCount.ts +0 -26
  63. package/src/helpers/handleError.ts +0 -65
  64. package/src/helpers/handleSuccess.ts +0 -18
  65. package/src/helpers/parseUserAgent.ts +0 -108
  66. package/src/helpers/visitEndpointOnAnotherServer/index.ts +0 -93
  67. package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +0 -164
  68. package/src/server/initLogCollection.ts +0 -27
  69. package/src/server/initServer.ts +0 -287
  70. /package/dist/cjs/types/{client → helpers}/initClient.d.ts +0 -0
  71. /package/dist/esm/types/{client → helpers}/initClient.d.ts +0 -0
@@ -1,287 +0,0 @@
1
- // Import custom error
2
- import ErrorWithCode from '../errors/ErrorWithCode';
3
-
4
- // Import shared constants
5
- import LOG_REVIEW_ROUTE_PATH_PREFIX from '../constants/LOG_REVIEW_ROUTE_PATH_PREFIX';
6
- import LOG_ROUTE_PATH from '../constants/LOG_ROUTE_PATH';
7
- import LOG_REVIEW_STATUS_ROUTE from '../constants/LOG_REVIEW_STATUS_ROUTE';
8
-
9
- // Import shared helpers
10
- import genRouteHandler from '../helpers/genRouteHandler';
11
-
12
- // Import shared types
13
- import Log from '../types/Log';
14
- import LogFunction from '../types/LogFunction';
15
- import ParamType from '../types/ParamType';
16
- import ReactKitErrorCode from '../types/ReactKitErrorCode';
17
-
18
- // Types
19
- type GetLaunchInfoFunction = (req: any) => {
20
- launched: boolean,
21
- launchInfo?: any,
22
- };
23
-
24
- // Stored copy of caccl functions
25
- let _cacclGetLaunchInfo: GetLaunchInfoFunction;
26
-
27
- // Stored copy of dce-mango log collection
28
- let _logCollection: any;
29
-
30
- /*------------------------------------------------------------------------*/
31
- /* Helpers */
32
- /*------------------------------------------------------------------------*/
33
-
34
- /**
35
- * Get launch info via CACCL
36
- * @author Gabe Abrams
37
- * @param req express request object
38
- * @returns object { launched, launchInfo }
39
- */
40
- export const cacclGetLaunchInfo: GetLaunchInfoFunction = (req: any) => {
41
- if (!_cacclGetLaunchInfo) {
42
- throw new ErrorWithCode(
43
- 'Could not get launch info because server was not initialized with dce-reactkit\'s initServer function',
44
- ReactKitErrorCode.NoCACCLGetLaunchInfoFunction,
45
- );
46
- }
47
-
48
- return _cacclGetLaunchInfo(req);
49
- };
50
-
51
- /**
52
- * Get log collection
53
- * @author Gabe Abrams
54
- * @returns log collection if one was included during launch or null if we don't
55
- * have a log collection (yet)
56
- */
57
- export const internalGetLogCollection = () => {
58
- return _logCollection ?? null;
59
- };
60
-
61
- /*------------------------------------------------------------------------*/
62
- /* Main */
63
- /*------------------------------------------------------------------------*/
64
-
65
- /**
66
- * Prepare dce-reactkit to run on the server
67
- * @author Gabe Abrams
68
- * @param opts object containing all arguments
69
- * @param opts.app express app from inside of the postprocessor function that
70
- * we will add routes to
71
- * @param opts.getLaunchInfo CACCL LTI's get launch info function
72
- * @param [opts.logCollection] mongo collection from dce-mango to use for
73
- * storing logs. If none is included, logs are written to the console
74
- * @param [opts.logReviewAdmins=all] info on which admins can review
75
- * logs from the client. If not included, all Canvas admins are allowed to
76
- * review logs. If null, no Canvas admins are allowed to review logs.
77
- * If an array of Canvas userIds (numbers), only Canvas admins with those
78
- * userIds are allowed to review logs. If a dce-mango collection, only
79
- * Canvas admins with entries in that collection ({ userId, ...}) are allowed
80
- * to review logs
81
- */
82
- const initServer = (
83
- opts: {
84
- app: any,
85
- getLaunchInfo: GetLaunchInfoFunction,
86
- logCollection?: any,
87
- logReviewAdmins?: (number[] | any),
88
- },
89
- ) => {
90
- _cacclGetLaunchInfo = opts.getLaunchInfo;
91
- _logCollection = opts.logCollection;
92
-
93
- /*----------------------------------------*/
94
- /* Logging */
95
- /*----------------------------------------*/
96
-
97
- /**
98
- * Log an event
99
- * @author Gabe Abrams
100
- * @param {string} context Context of the event (each app determines how to
101
- * organize its contexts)
102
- * @param {string} subcontext Subcontext of the event (each app determines
103
- * how to organize its subcontexts)
104
- * @param {string} tags stringified list of tags that apply to this action
105
- * (each app determines tag usage)
106
- * @param {string} metadata stringified object containing optional custom metadata
107
- * @param {string} level log level
108
- * @param {string} [errorMessage] error message if type is an error
109
- * @param {string} [errorCode] error code if type is an error
110
- * @param {string} [errorStack] error stack if type is an error
111
- * @param {string} [target] Target of the action (each app determines the list
112
- * of targets) These are usually buttons, panels, elements, etc.
113
- * @param {LogAction} [action] the type of action performed on the target
114
- * @returns {Log}
115
- */
116
- opts.app.post(
117
- LOG_ROUTE_PATH,
118
- genRouteHandler({
119
- paramTypes: {
120
- context: ParamType.String,
121
- subcontext: ParamType.String,
122
- tags: ParamType.JSON,
123
- level: ParamType.String,
124
- metadata: ParamType.JSON,
125
- errorMessage: ParamType.StringOptional,
126
- errorCode: ParamType.StringOptional,
127
- errorStack: ParamType.StringOptional,
128
- target: ParamType.StringOptional,
129
- action: ParamType.StringOptional,
130
- },
131
- handler: ({ params, logServerEvent }) => {
132
- // Create log info
133
- const logInfo: Parameters<LogFunction>[0] = (
134
- (params.errorMessage || params.errorCode || params.errorStack)
135
- // Error
136
- ? {
137
- context: params.context,
138
- subcontext: params.subcontext,
139
- tags: params.tags,
140
- level: params.level,
141
- metadata: params.metadata,
142
- error: {
143
- message: params.errorMessage,
144
- code: params.errorCode,
145
- stack: params.errorStack,
146
- },
147
- }
148
- // Action
149
- : {
150
- context: params.context,
151
- subcontext: params.subcontext,
152
- tags: params.tags,
153
- level: params.level,
154
- metadata: params.metadata,
155
- target: params.target,
156
- action: params.action,
157
- }
158
- );
159
-
160
- // Add hidden boolean to change source to "client"
161
- const logInfoForcedFromClient = {
162
- ...logInfo,
163
- overrideAsClientEvent: true,
164
- };
165
-
166
- // Write the log
167
- const log = logServerEvent(logInfoForcedFromClient);
168
-
169
- // Return
170
- return log;
171
- },
172
- }),
173
- );
174
-
175
- /*----------------------------------------*/
176
- /* Log Reviewer */
177
- /*----------------------------------------*/
178
-
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
-
195
- // If all admins are allowed, we're done
196
- if (!opts.logReviewAdmins) {
197
- return true;
198
- }
199
-
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
- });
207
- }
208
-
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
- );
235
-
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
- pageNumber: ParamType.Int,
250
- },
251
- handler: async ({ params }) => {
252
- // Get user info
253
- const {
254
- year,
255
- month,
256
- pageNumber,
257
- userId,
258
- isAdmin,
259
- } = params;
260
-
261
- // Validate user
262
- const canReview = await canReviewLogs(userId, isAdmin);
263
- if (!canReview) {
264
- throw new ErrorWithCode(
265
- 'You cannot access this resource because you do not have the appropriate permissions.',
266
- ReactKitErrorCode.NotAllowedToReviewLogs,
267
- );
268
- }
269
-
270
- // Query for logs
271
- const response = await _logCollection.findPaged({
272
- query: {
273
- year,
274
- month,
275
- },
276
- perPage: 1000,
277
- pageNumber,
278
- });
279
-
280
- // Return response
281
- return response;
282
- },
283
- }),
284
- );
285
- };
286
-
287
- export default initServer;