dce-reactkit 3.12.1-beta-cross-server.8 → 4.0.0-beta-date-and-time.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 (92) hide show
  1. package/.vscode/settings.json +3 -1
  2. package/README.md +0 -20
  3. package/dist/cjs/index.js +7838 -15905
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/types/components/ItemPicker/index.d.ts +1 -0
  6. package/dist/cjs/types/components/LoadingSpinner.d.ts +2 -2
  7. package/dist/cjs/types/components/Modal/ModalProps.d.ts +2 -0
  8. package/dist/cjs/types/components/SimpleDateChooser.d.ts +3 -1
  9. package/dist/cjs/types/components/SimpleTimeChooser.d.ts +20 -0
  10. package/dist/cjs/types/components/TabBox.d.ts +1 -0
  11. package/dist/cjs/types/components/Tooltip.d.ts +1 -1
  12. package/dist/cjs/types/helpers/getWordCount.d.ts +10 -0
  13. package/dist/cjs/types/index.d.ts +13 -13
  14. package/dist/cjs/types/types/ParamType.d.ts +10 -10
  15. package/dist/cjs/types/types/ReactKitErrorCode.d.ts +2 -28
  16. package/dist/esm/index.js +6661 -14723
  17. package/dist/esm/index.js.map +1 -1
  18. package/dist/esm/types/components/ItemPicker/index.d.ts +1 -0
  19. package/dist/esm/types/components/LoadingSpinner.d.ts +2 -2
  20. package/dist/esm/types/components/Modal/ModalProps.d.ts +2 -0
  21. package/dist/esm/types/components/SimpleDateChooser.d.ts +3 -1
  22. package/dist/esm/types/components/SimpleTimeChooser.d.ts +20 -0
  23. package/dist/esm/types/components/TabBox.d.ts +1 -0
  24. package/dist/esm/types/components/Tooltip.d.ts +1 -1
  25. package/dist/esm/types/helpers/getWordCount.d.ts +10 -0
  26. package/dist/esm/types/index.d.ts +13 -13
  27. package/dist/esm/types/types/ParamType.d.ts +10 -10
  28. package/dist/esm/types/types/ReactKitErrorCode.d.ts +2 -28
  29. package/dist/index.d.ts +189 -379
  30. package/package.json +5 -11
  31. package/src/components/AppWrapper.tsx +3 -1
  32. package/src/components/CheckboxButton.tsx +1 -1
  33. package/src/components/Dropdown.tsx +1 -1
  34. package/src/components/IntelliTable.tsx +1 -1
  35. package/src/components/ItemPicker/NestableItemList.tsx +1 -0
  36. package/src/components/ItemPicker/index.tsx +96 -0
  37. package/src/components/LogReviewer.tsx +2 -2
  38. package/src/components/Modal/ModalProps.ts +4 -0
  39. package/src/components/Modal/index.tsx +60 -21
  40. package/src/components/RadioButton.tsx +3 -1
  41. package/src/components/SimpleDateChooser.tsx +62 -26
  42. package/src/components/SimpleTimeChooser.tsx +195 -0
  43. package/src/components/TabBox.tsx +27 -9
  44. package/src/components/Tooltip.tsx +1 -1
  45. package/src/helpers/getWordCount.ts +26 -0
  46. package/src/{client → helpers}/initClient.tsx +5 -1
  47. package/src/helpers/logClientEvent.tsx +3 -1
  48. package/src/helpers/visitServerEndpoint.tsx +1 -1
  49. package/src/index.ts +22 -24
  50. package/src/types/ParamType.ts +10 -10
  51. package/src/types/ReactKitErrorCode.tsx +3 -31
  52. package/dist/cjs/types/components/ItemPicker/index.test.d.ts +0 -1
  53. package/dist/cjs/types/helpers/addDBEditorEndpoints.d.ts +0 -41
  54. package/dist/cjs/types/helpers/dataSigner.d.ts +0 -40
  55. package/dist/cjs/types/helpers/genRouteHandler.d.ts +0 -76
  56. package/dist/cjs/types/helpers/handleError.d.ts +0 -18
  57. package/dist/cjs/types/helpers/handleSuccess.d.ts +0 -8
  58. package/dist/cjs/types/helpers/parseUserAgent.d.ts +0 -17
  59. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/index.d.ts +0 -20
  60. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +0 -27
  61. package/dist/cjs/types/server/initCrossServerCredentialCollection.d.ts +0 -8
  62. package/dist/cjs/types/server/initLogCollection.d.ts +0 -8
  63. package/dist/cjs/types/server/initServer.d.ts +0 -53
  64. package/dist/cjs/types/types/CrossServerCredential.d.ts +0 -11
  65. package/dist/esm/types/components/ItemPicker/index.test.d.ts +0 -1
  66. package/dist/esm/types/helpers/addDBEditorEndpoints.d.ts +0 -41
  67. package/dist/esm/types/helpers/dataSigner.d.ts +0 -40
  68. package/dist/esm/types/helpers/genRouteHandler.d.ts +0 -76
  69. package/dist/esm/types/helpers/handleError.d.ts +0 -18
  70. package/dist/esm/types/helpers/handleSuccess.d.ts +0 -8
  71. package/dist/esm/types/helpers/parseUserAgent.d.ts +0 -17
  72. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/index.d.ts +0 -20
  73. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +0 -27
  74. package/dist/esm/types/server/initCrossServerCredentialCollection.d.ts +0 -8
  75. package/dist/esm/types/server/initLogCollection.d.ts +0 -8
  76. package/dist/esm/types/server/initServer.d.ts +0 -53
  77. package/dist/esm/types/types/CrossServerCredential.d.ts +0 -11
  78. package/src/components/ItemPicker/index.test.tsx +0 -783
  79. package/src/helpers/addDBEditorEndpoints.ts +0 -128
  80. package/src/helpers/dataSigner.ts +0 -342
  81. package/src/helpers/genRouteHandler.ts +0 -911
  82. package/src/helpers/handleError.ts +0 -65
  83. package/src/helpers/handleSuccess.ts +0 -18
  84. package/src/helpers/parseUserAgent.ts +0 -108
  85. package/src/helpers/visitEndpointOnAnotherServer/index.ts +0 -152
  86. package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +0 -162
  87. package/src/server/initCrossServerCredentialCollection.ts +0 -16
  88. package/src/server/initLogCollection.ts +0 -27
  89. package/src/server/initServer.ts +0 -305
  90. package/src/types/CrossServerCredential.ts +0 -16
  91. /package/dist/cjs/types/{client → helpers}/initClient.d.ts +0 -0
  92. /package/dist/esm/types/{client → helpers}/initClient.d.ts +0 -0
@@ -1,128 +0,0 @@
1
- // Import express
2
- import express from 'express';
3
-
4
- // Import shared helpers
5
- import genRouteHandler from './genRouteHandler';
6
- import generateEndpointPath from '../components/DBEntryManagerPanel/helpers/generateEndpointPath';
7
-
8
- // Import shared types
9
- import ParamType from '../types/ParamType';
10
-
11
- /**
12
- * Interface for a collection in the database
13
- * @author Yuen Ler Chow
14
- */
15
- type DCEMangoCollection = {
16
- /**
17
- * Find all items in the collection that match the filter query
18
- * @param filterQuery query for the filter
19
- * @returns list of items that match the filter query
20
- */
21
- find: (filterQuery: any) => Promise<any[]>,
22
- /**
23
- * Insert an item into the collection
24
- * @param item the item to insert
25
- */
26
- insert: (item: any) => Promise<void>,
27
- /**
28
- * Delete an item in the collection
29
- * @param id the id of the item to delete
30
- */
31
- delete: (filterQuery: { id: string }) => Promise<void>,
32
- };
33
-
34
- /**
35
- * Add all routes for the DBEditor
36
- * @author Yuen Ler Chow
37
- * @param opts object containing all arguments
38
- * @param opts.app express app to add routes too
39
- * @param opts.collectionName the name of the collection
40
- * @param opts.adminsOnly true if the endpoint is for admins only
41
- * @param opts.collection dce-mango db collection
42
- */
43
- const addDBEditorEndpoints = (
44
- opts: {
45
- app: express.Application,
46
- collectionName: string,
47
- adminsOnly: boolean,
48
- collection: DCEMangoCollection,
49
- },
50
- ) => {
51
- const {
52
- app,
53
- collectionName,
54
- adminsOnly,
55
- collection,
56
- } = opts;
57
-
58
- // Generate the endpoint path
59
- const endpointPath = generateEndpointPath(collectionName, adminsOnly);
60
-
61
- /**
62
- * List all items in the collection
63
- * @author Yuen Ler Chow
64
- * @returns {any[]} the list of items in the collection
65
- */
66
- app.get(
67
- endpointPath,
68
- genRouteHandler({
69
- paramTypes: {
70
- filterQuery: ParamType.JSONOptional,
71
- },
72
- handler: async ({ params }) => {
73
- const filterQuery = params.filterQuery ?? {};
74
- const categories = await collection.find(filterQuery);
75
- return categories;
76
- },
77
- }),
78
- );
79
-
80
- /**
81
- * Create a new item in the collection
82
- * @author Yuen Ler Chow
83
- * @param {any} item the item to create
84
- */
85
- app.post(
86
- endpointPath,
87
- genRouteHandler({
88
- paramTypes: {
89
- item: ParamType.JSON,
90
- },
91
- handler: async ({
92
- params,
93
- }) => {
94
- // Destructure params
95
- const {
96
- item,
97
- } = params;
98
-
99
- await collection.insert(item);
100
- },
101
- }),
102
- );
103
-
104
- /**
105
- * Remove an item from the collection by id
106
- * @author Yuen Ler Chow
107
- */
108
- app.delete(
109
- `${endpointPath}/:id`,
110
- genRouteHandler({
111
- paramTypes: {
112
- id: ParamType.String,
113
- },
114
- handler: async ({
115
- params,
116
- }) => {
117
- // Destructure params
118
- const {
119
- id,
120
- } = params;
121
-
122
- await collection.delete({ id });
123
- },
124
- }),
125
- );
126
- };
127
-
128
- export default addDBEditorEndpoints;
@@ -1,342 +0,0 @@
1
- // Import shared helpers
2
- // eslint-disable-next-line import/no-cycle
3
- import { internalGetCrossServerCredentialCollection } from '../server/initServer';
4
-
5
- // Import shared types
6
- import ErrorWithCode from '../errors/ErrorWithCode';
7
- import ReactKitErrorCode from '../types/ReactKitErrorCode';
8
- import CrossServerCredential from '../types/CrossServerCredential';
9
-
10
- // Import shared constants
11
- import MINUTE_IN_MS from '../constants/MINUTE_IN_MS';
12
-
13
- /*------------------------------------------------------------------------*/
14
- /* --------------------------- Dynamic Imports -------------------------- */
15
- /*------------------------------------------------------------------------*/
16
-
17
- /**
18
- * Get a copy of the oauth lib
19
- * @author Gabe Abrams
20
- * @return the oauth lib
21
- */
22
- const getOauthLib = async () => {
23
- // Get the oauth signing library (included with caccl)
24
- // Ignore because this is assumed to be included with caccl
25
- try {
26
- // @ts-ignore
27
- // eslint-disable-next-line import/no-extraneous-dependencies
28
- const oauth = await import('oauth-signature');
29
- return oauth;
30
- } catch (err) {
31
- throw new ErrorWithCode(
32
- 'Could not sign a cross-server request because we could not load the oauth library. Please make sure this app has caccl as one of its dependencies.',
33
- ReactKitErrorCode.NoOauthLib,
34
- );
35
- }
36
- };
37
-
38
- /**
39
- * Get a copy of the crypto lib
40
- * @author Gabe Abrams
41
- * @return the crypto lib
42
- */
43
- const getCryptoLib = async () => {
44
- // Get the crypto library (included on the server)
45
- // Ignore because this is assumed to be included with typescript
46
- // @ts-ignore
47
- try {
48
- // @ts-ignore
49
- // eslint-disable-next-line global-require
50
- const crypto = await require('crypto');
51
- return crypto;
52
- } catch (err) {
53
- throw new ErrorWithCode(
54
- 'Could not sign a cross-server request because we could not load the crypto library. Please make sure this operation is running on the server.',
55
- ReactKitErrorCode.NoCryptoLib,
56
- );
57
- }
58
- };
59
-
60
- /*------------------------------------------------------------------------*/
61
- /* ------------------------------- Helpers ------------------------------ */
62
- /*------------------------------------------------------------------------*/
63
-
64
- /**
65
- * Generate an oauth signature
66
- * @author Gabe Abrams
67
- * @param opts object containing all arguments
68
- * @param opts.method the http method
69
- * @param opts.path the http request path
70
- * @param opts.params the data in the body to sign
71
- * @param opts.secret the secret to sign with
72
- * @return the signature
73
- */
74
- const genSignature = async (
75
- opts: {
76
- method?: string,
77
- path?: string,
78
- params?: { [key: string]: any },
79
- secret: string,
80
- },
81
- ): Promise<string> => {
82
- // Destructure opts
83
- const {
84
- method,
85
- path,
86
- params,
87
- secret,
88
- } = opts;
89
-
90
- // Get the oauth library
91
- const oauth = await getOauthLib();
92
-
93
- // Order the params alphabetically by key
94
- const keys = Object.keys(params ?? {});
95
- keys.sort();
96
- const orderedParams: {
97
- [key: string]: any,
98
- } = {};
99
- keys.forEach((key) => {
100
- // Skip oauth_signature
101
- if (key === 'oauth_signature') {
102
- return;
103
- }
104
-
105
- // Add the param
106
- orderedParams[key] = (params ?? {})[key];
107
- });
108
-
109
- // Generate the signature
110
- return decodeURIComponent(oauth.generate(
111
- method ?? 'GET',
112
- path ?? 'no-path',
113
- orderedParams,
114
- secret,
115
- ));
116
- };
117
-
118
- /**
119
- * Decrypt an encrypted string using a secret
120
- * @author Gabe Abrams
121
- * @param str the encrypted string
122
- * @return the decrypted string
123
- */
124
- const decrypt = async (
125
- encryptedPack: string,
126
- ): Promise<string> => {
127
- // Decryption process based on:
128
- // https://medium.com/@tony.infisical/guide-to-nodes-crypto-module-for-encryption-decryption-65c077176980
129
-
130
- // Get the encryption secret
131
- const { REACTKIT_CRED_ENCODING_SALT } = process.env;
132
- if (!REACTKIT_CRED_ENCODING_SALT) {
133
- throw new ErrorWithCode(
134
- 'Could not decrypt a string because the encryption salt was not set.',
135
- ReactKitErrorCode.CrossServerNoCredentialEncodingSalt,
136
- );
137
- }
138
-
139
- // Get the crypto library
140
- const crypto = await getCryptoLib();
141
-
142
- // Separate encrypted pack
143
- const {
144
- ciphertext,
145
- iv,
146
- tag,
147
- } = JSON.parse(decodeURIComponent(encryptedPack));
148
-
149
- // Parse the encrypted data
150
- const decipher = crypto.createDecipheriv(
151
- 'aes-256-gcm',
152
- Buffer.from(REACTKIT_CRED_ENCODING_SALT, 'base64'),
153
- Buffer.from(iv, 'base64'),
154
- );
155
-
156
- // Set the authentication tag
157
- decipher.setAuthTag(Buffer.from(tag, 'base64'));
158
-
159
- // Decrypt the string
160
- let str = decipher.update(ciphertext, 'base64', 'utf8');
161
- str += decipher.final('utf8');
162
-
163
- // Return the decrypted string
164
- return str;
165
- };
166
-
167
- /*------------------------------------------------------------------------*/
168
- /* ------------------------------- Signing ------------------------------ */
169
- /*------------------------------------------------------------------------*/
170
-
171
- /**
172
- * Sign a request and get the new request params
173
- * @author Gabe Abrams
174
- * @param opts object containing all arguments
175
- * @param opts.method the method to sign
176
- * @param opts.path the http request path
177
- * @param opts.params the data in the body to sign
178
- * @param opts.key the reactkit key to sign with
179
- * @param opts.secret the reactkit secret to sign with
180
- * @return augmented params for the request, including a signature, timestamp, and key
181
- */
182
- export const signRequest = async (
183
- opts: {
184
- method: string,
185
- path: string,
186
- params: { [key: string]: any },
187
- key: string,
188
- secret: string,
189
- },
190
- ): Promise<{ [key: string]: any }> => {
191
- // Destructure opts
192
- const method = opts.method.toUpperCase();
193
- const {
194
- path,
195
- params,
196
- key,
197
- secret,
198
- } = opts;
199
-
200
- // Augment the params
201
- const augmentedParams: {
202
- [key: string]: any,
203
- } = {
204
- ...params,
205
- oauth_consumer_key: key,
206
- oauth_nonce: Math.random().toString(36),
207
- oauth_timestamp: Date.now(),
208
- };
209
-
210
- // Generate a signature
211
- const signature = await genSignature({
212
- method,
213
- path,
214
- params,
215
- secret,
216
- });
217
-
218
- // Add signature to the augmented params
219
- augmentedParams.oauth_signature = signature;
220
-
221
- // Return the augmented params
222
- return augmentedParams;
223
- };
224
-
225
- /**
226
- * Validate a signed request. Throws an error if invalid
227
- * @author Gabe Abrams
228
- * @param opts object containing all arguments
229
- * @param opts.method the method of the data validate
230
- * @param opts.path the http request path to validate
231
- * @param opts.scope the name of the scope to validate
232
- * @param opts.params the request data to validate
233
- * @returns parsed and validated params
234
- */
235
- export const validateSignedRequest = async (
236
- opts: {
237
- method: string,
238
- path: string,
239
- scope: string,
240
- params: { [key: string]: any },
241
- },
242
- ) => {
243
- /* ---------- Collect Info ---------- */
244
-
245
- // Get the signature
246
- if (!opts.params.oauth_signature) {
247
- throw new ErrorWithCode(
248
- 'Could not validate a cross-server request there was no oauth signature.',
249
- ReactKitErrorCode.CrossServerMissingSignedRequestInfo,
250
- );
251
- }
252
- const signature = opts.params.oauth_signature;
253
-
254
- // Get the timestamp
255
- if (
256
- // No timestamp
257
- !opts.params.oauth_timestamp
258
- // Invalid timestamp
259
- || Number.isNaN(Number.parseInt(opts.params.oauth_timestamp, 10))
260
- ) {
261
- throw new ErrorWithCode(
262
- 'Could not validate a cross-server request there was no valid oauth timestamp.',
263
- ReactKitErrorCode.CrossServerMissingSignedRequestInfo,
264
- );
265
- }
266
- const timestamp = Number.parseInt(opts.params.oauth_timestamp, 10);
267
-
268
- // Get the key
269
- if (!opts.params.oauth_consumer_key) {
270
- throw new ErrorWithCode(
271
- 'Could not validate a cross-server request there was no oauth consumer key.',
272
- ReactKitErrorCode.CrossServerMissingSignedRequestInfo,
273
- );
274
- }
275
- const key = opts.params.oauth_consumer_key;
276
-
277
- // Get the rest of the info
278
- const {
279
- method,
280
- path,
281
- params,
282
- } = opts;
283
-
284
- /* ------- Look Up Credential ------- */
285
-
286
- // Get the cross-server credential collection
287
- const crossServerCredentialCollection = internalGetCrossServerCredentialCollection();
288
- if (!crossServerCredentialCollection) {
289
- throw new ErrorWithCode(
290
- 'Could not validate a cross-server request because the cross-server credential collection was not ready in time.',
291
- ReactKitErrorCode.SignedRequestInvalidCollection,
292
- );
293
- }
294
-
295
- // Get the cross-server credential
296
- const crossServerCredential: CrossServerCredential = await crossServerCredentialCollection.find({ key });
297
- if (!crossServerCredential) {
298
- throw new ErrorWithCode(
299
- 'Could not validate a cross-server request because the credential was not found.',
300
- ReactKitErrorCode.SignedRequestInvalidCredential,
301
- );
302
- }
303
-
304
- // Make sure the scope is included
305
- const allowedScopes = crossServerCredential.scopes;
306
- if (!allowedScopes.includes(opts.scope)) {
307
- throw new ErrorWithCode(
308
- 'Could not validate a cross-server request because the scope was not included.',
309
- ReactKitErrorCode.SignedRequestInvalidScope,
310
- );
311
- }
312
-
313
- // Decode the secret
314
- const secret = await decrypt(crossServerCredential.encodedeSecret);
315
-
316
- /* -------- Verify Signature -------- */
317
-
318
- // Generate a new signature to compare
319
- const expectedSignature = await genSignature({
320
- method,
321
- path,
322
- params,
323
- secret,
324
- });
325
-
326
- // Make sure the signatures match
327
- if (signature !== expectedSignature) {
328
- throw new ErrorWithCode(
329
- 'Could not validate a cross-server request because the signature did not match.',
330
- ReactKitErrorCode.SignedRequestInvalidSignature,
331
- );
332
- }
333
-
334
- // Make sure the timestamp was recent enough
335
- const elapsedMs = Math.abs(Date.now() - timestamp);
336
- if (elapsedMs < MINUTE_IN_MS) {
337
- throw new ErrorWithCode(
338
- 'Could not validate a cross-server request because the request was too old.',
339
- ReactKitErrorCode.SignedRequestInvalidTimestamp,
340
- );
341
- }
342
- };