dce-reactkit 3.12.1-beta-cross-server.2 → 3.12.3

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 (51) hide show
  1. package/.vscode/settings.json +3 -1
  2. package/README.md +0 -20
  3. package/dist/cjs/index.js +356 -406
  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/Modal/ModalProps.d.ts +2 -0
  7. package/dist/cjs/types/components/TabBox.d.ts +1 -0
  8. package/dist/cjs/types/helpers/genRouteHandler.d.ts +10 -10
  9. package/dist/cjs/types/helpers/getWordCount.d.ts +10 -0
  10. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/index.d.ts +13 -15
  11. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +6 -0
  12. package/dist/cjs/types/index.d.ts +2 -3
  13. package/dist/cjs/types/server/initServer.d.ts +0 -11
  14. package/dist/cjs/types/types/ReactKitErrorCode.d.ts +1 -13
  15. package/dist/esm/index.js +357 -406
  16. package/dist/esm/index.js.map +1 -1
  17. package/dist/esm/types/components/ItemPicker/index.d.ts +1 -0
  18. package/dist/esm/types/components/Modal/ModalProps.d.ts +2 -0
  19. package/dist/esm/types/components/TabBox.d.ts +1 -0
  20. package/dist/esm/types/helpers/genRouteHandler.d.ts +10 -10
  21. package/dist/esm/types/helpers/getWordCount.d.ts +10 -0
  22. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/index.d.ts +13 -15
  23. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +6 -0
  24. package/dist/esm/types/index.d.ts +2 -3
  25. package/dist/esm/types/server/initServer.d.ts +0 -11
  26. package/dist/esm/types/types/ReactKitErrorCode.d.ts +1 -13
  27. package/dist/index.d.ts +39 -62
  28. package/package.json +2 -5
  29. package/src/components/IntelliTable.tsx +1 -1
  30. package/src/components/ItemPicker/NestableItemList.tsx +1 -0
  31. package/src/components/ItemPicker/index.tsx +96 -0
  32. package/src/components/Modal/ModalProps.ts +4 -0
  33. package/src/components/Modal/index.tsx +59 -20
  34. package/src/components/TabBox.tsx +27 -9
  35. package/src/helpers/genRouteHandler.ts +95 -55
  36. package/src/helpers/getWordCount.ts +26 -0
  37. package/src/helpers/visitEndpointOnAnotherServer/index.ts +41 -42
  38. package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +5 -3
  39. package/src/index.ts +2 -4
  40. package/src/server/initServer.ts +0 -18
  41. package/src/types/ReactKitErrorCode.tsx +1 -13
  42. package/dist/cjs/types/helpers/dataSigner.d.ts +0 -38
  43. package/dist/cjs/types/server/initCrossServerCredentialCollection.d.ts +0 -8
  44. package/dist/cjs/types/types/CrossServerCredential.d.ts +0 -11
  45. package/dist/esm/types/helpers/dataSigner.d.ts +0 -38
  46. package/dist/esm/types/server/initCrossServerCredentialCollection.d.ts +0 -8
  47. package/dist/esm/types/types/CrossServerCredential.d.ts +0 -11
  48. package/genEncodedSecret.ts +0 -28
  49. package/src/helpers/dataSigner.ts +0 -232
  50. package/src/server/initCrossServerCredentialCollection.ts +0 -16
  51. package/src/types/CrossServerCredential.ts +0 -16
@@ -27,9 +27,6 @@ let _cacclGetLaunchInfo: GetLaunchInfoFunction;
27
27
  // Stored copy of dce-mango log collection
28
28
  let _logCollection: any;
29
29
 
30
- // Stored copy of dce-mango cross-server credential collection
31
- let _crossServerCredentialCollection: any;
32
-
33
30
  /*------------------------------------------------------------------------*/
34
31
  /* Helpers */
35
32
  /*------------------------------------------------------------------------*/
@@ -61,16 +58,6 @@ export const internalGetLogCollection = () => {
61
58
  return _logCollection ?? null;
62
59
  };
63
60
 
64
- /**
65
- * Get cross-server credential collection
66
- * @author Gabe Abrams
67
- * @return cross-server credential collection if one was included during launch or null
68
- * if we don't have a cross-server credential collection (yet)
69
- */
70
- export const internalGetCrossServerCredentialCollection = () => {
71
- return _crossServerCredentialCollection ?? null;
72
- };
73
-
74
61
  /*------------------------------------------------------------------------*/
75
62
  /* Main */
76
63
  /*------------------------------------------------------------------------*/
@@ -91,9 +78,6 @@ export const internalGetCrossServerCredentialCollection = () => {
91
78
  * userIds are allowed to review logs. If a dce-mango collection, only
92
79
  * Canvas admins with entries in that collection ({ userId, ...}) are allowed
93
80
  * to review logs
94
- * @param [opts.crossServerCredentialCollection] mongo collection from dce-mango to use for
95
- * storing cross-server credentials. If none is included, cross-server credentials
96
- * are not supported
97
81
  */
98
82
  const initServer = (
99
83
  opts: {
@@ -101,12 +85,10 @@ const initServer = (
101
85
  getLaunchInfo: GetLaunchInfoFunction,
102
86
  logCollection?: any,
103
87
  logReviewAdmins?: (number[] | any),
104
- crossServerCredentialCollection?: any,
105
88
  },
106
89
  ) => {
107
90
  _cacclGetLaunchInfo = opts.getLaunchInfo;
108
91
  _logCollection = opts.logCollection;
109
- _crossServerCredentialCollection = opts.crossServerCredentialCollection;
110
92
 
111
93
  /*----------------------------------------*/
112
94
  /* Logging */
@@ -1,4 +1,4 @@
1
- // Highest error code = DRK30
1
+ // Highest error code = DRK18
2
2
 
3
3
  /**
4
4
  * List of error codes built into the react kit
@@ -25,18 +25,6 @@ enum ReactKitErrorCode {
25
25
  NotConnected = 'DRK14',
26
26
  SelfSigned = 'DRK15',
27
27
  ResponseParseError = 'DRK16',
28
- PackUnparseable = 'DRK28',
29
- PackInvalidMethod = 'DRK19',
30
- PackInvalidPath = 'DRK20',
31
- PackInvalidCollection = 'DRK21',
32
- PackInvalidCredential = 'DRK23',
33
- PackInvalidScope = 'DRK22',
34
- PackInvalidTimestamp = 'DRK24',
35
- PackInvalidSignature = 'DRK25',
36
- PackInvalidBody = 'DRK26',
37
- CrossServerNoCredentialsToSignWith = 'DRK27',
38
- CrossServerNoPack = 'DRK29',
39
- CrossServerNoCredentialEncodingSalt = 'DRK30',
40
28
  }
41
29
 
42
30
  export default ReactKitErrorCode;
@@ -1,38 +0,0 @@
1
- /**
2
- * Sign data with a private reactkit key, package it into a signed data pack
3
- * @author Gabe Abrams
4
- * @param opts object containing all arguments
5
- * @param opts.method the method to sign
6
- * @param opts.path the http request path
7
- * @param opts.params the data in the body to sign
8
- * @param opts.key the reactkit key to sign with
9
- * @param opts.secret the reactkit secret to sign with
10
- * @return the signed data
11
- */
12
- export declare const createSignedPack: (opts: {
13
- method: string;
14
- path: string;
15
- params: {
16
- [key: string]: any;
17
- };
18
- key: string;
19
- secret: string;
20
- }) => string;
21
- /**
22
- * Parse signed pack. Throws an error if invalid
23
- * @author Gabe Abrams
24
- * @param opts object containing all arguments
25
- * @param opts.method the method of the data validate
26
- * @param opts.path the http request path to validate
27
- * @param opts.scope the name of the scope to validate
28
- * @param opts.signedPack the signed data pack to validate
29
- * @returns parsed and validated params
30
- */
31
- export declare const parseSignedPack: (opts: {
32
- method: string;
33
- path: string;
34
- scope: string;
35
- signedPack: string;
36
- }) => Promise<{
37
- [key: string]: any;
38
- }>;
@@ -1,8 +0,0 @@
1
- /**
2
- * Initialize a cross-server credential collection given the dce-mango Collection class
3
- * @author Gabe Abrams
4
- * @param Collection the Collection class from dce-mango
5
- * @returns initialized logCollection
6
- */
7
- declare const initCrossServerCredentialCollection: (Collection: any) => any;
8
- export default initCrossServerCredentialCollection;
@@ -1,11 +0,0 @@
1
- /**
2
- * Single cross-server credential
3
- * @author Gabe Abrams
4
- */
5
- type CrossServerCredential = {
6
- description: string;
7
- key: string;
8
- encodedeSecret: string;
9
- scopes: string[];
10
- };
11
- export default CrossServerCredential;
@@ -1,38 +0,0 @@
1
- /**
2
- * Sign data with a private reactkit key, package it into a signed data pack
3
- * @author Gabe Abrams
4
- * @param opts object containing all arguments
5
- * @param opts.method the method to sign
6
- * @param opts.path the http request path
7
- * @param opts.params the data in the body to sign
8
- * @param opts.key the reactkit key to sign with
9
- * @param opts.secret the reactkit secret to sign with
10
- * @return the signed data
11
- */
12
- export declare const createSignedPack: (opts: {
13
- method: string;
14
- path: string;
15
- params: {
16
- [key: string]: any;
17
- };
18
- key: string;
19
- secret: string;
20
- }) => string;
21
- /**
22
- * Parse signed pack. Throws an error if invalid
23
- * @author Gabe Abrams
24
- * @param opts object containing all arguments
25
- * @param opts.method the method of the data validate
26
- * @param opts.path the http request path to validate
27
- * @param opts.scope the name of the scope to validate
28
- * @param opts.signedPack the signed data pack to validate
29
- * @returns parsed and validated params
30
- */
31
- export declare const parseSignedPack: (opts: {
32
- method: string;
33
- path: string;
34
- scope: string;
35
- signedPack: string;
36
- }) => Promise<{
37
- [key: string]: any;
38
- }>;
@@ -1,8 +0,0 @@
1
- /**
2
- * Initialize a cross-server credential collection given the dce-mango Collection class
3
- * @author Gabe Abrams
4
- * @param Collection the Collection class from dce-mango
5
- * @returns initialized logCollection
6
- */
7
- declare const initCrossServerCredentialCollection: (Collection: any) => any;
8
- export default initCrossServerCredentialCollection;
@@ -1,11 +0,0 @@
1
- /**
2
- * Single cross-server credential
3
- * @author Gabe Abrams
4
- */
5
- type CrossServerCredential = {
6
- description: string;
7
- key: string;
8
- encodedeSecret: string;
9
- scopes: string[];
10
- };
11
- export default CrossServerCredential;
@@ -1,28 +0,0 @@
1
- // Import jwt
2
- import jwt from 'jwt-simple';
3
-
4
- // Get args
5
- let { REACTKIT_CRED_ENCODING_SALT } = process.env;
6
- if (!REACTKIT_CRED_ENCODING_SALT) {
7
- REACTKIT_CRED_ENCODING_SALT = process.env.npm_config_salt;
8
- }
9
- if (!REACTKIT_CRED_ENCODING_SALT) {
10
- console.log('REACTKIT_CRED_ENCODING_SALT is required either as an environment variable or as: --salt=...');
11
- process.exit(1);
12
- }
13
-
14
- // Get secret
15
- let secret = process.env.npm_config_secret;
16
- if (!secret) {
17
- // Generate a random secret
18
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
19
- secret = '';
20
- for (let i = 0; i < 64; i++) {
21
- secret += chars.charAt(Math.floor(Math.random() * chars.length));
22
- }
23
- console.log('Generated a random secret. If you have one in mind, use --secret=...');
24
- }
25
-
26
- // Encode the secret
27
- const encodedSecret = jwt.encode(secret, REACTKIT_CRED_ENCODING_SALT);
28
- console.log(`\nNew Secret Generated!\n\nSecret: ${secret}\n\nEncoded Secret: ${encodedSecret}`);
@@ -1,232 +0,0 @@
1
- // Import crypto
2
- import { createHash } from 'crypto';
3
-
4
- // Import jwt
5
- import jwt from 'jwt-simple';
6
-
7
- // Import shared helpers
8
- import { internalGetCrossServerCredentialCollection } from '../server/initServer';
9
-
10
- // Import shared types
11
- import ErrorWithCode from '../errors/ErrorWithCode';
12
- import ReactKitErrorCode from '../types/ReactKitErrorCode';
13
- import CrossServerCredential from '../types/CrossServerCredential';
14
-
15
- // Import shared constants
16
- import MINUTE_IN_MS from '../constants/MINUTE_IN_MS';
17
-
18
- /*------------------------------------------------------------------------*/
19
- /* ------------------------------ Encoding ------------------------------ */
20
- /*------------------------------------------------------------------------*/
21
-
22
- /**
23
- * Validate a JWT token
24
- * @author Gabe Abrams
25
- * @param encodedSecret the encoded secret
26
- * @return the secret
27
- */
28
- const decodeCredentialSecret = (encodedSecret: string): string => {
29
- // Get the credential encoding salt
30
- const credentialEncodingSalt = process.env.REACTKIT_CRED_ENCODING_SALT;
31
- if (!credentialEncodingSalt) {
32
- throw new ErrorWithCode(
33
- 'Cannot decode a cross-server credential secret because the credential encoding salt was not found in env.',
34
- ReactKitErrorCode.CrossServerNoCredentialEncodingSalt,
35
- );
36
- }
37
-
38
- // Decode the secret
39
- return jwt.decode(encodedSecret, credentialEncodingSalt);
40
- };
41
-
42
- /*------------------------------------------------------------------------*/
43
- /* ------------------------------- Signing ------------------------------ */
44
- /*------------------------------------------------------------------------*/
45
-
46
- /**
47
- * Sign using sha 256
48
- * @author Gabe Abrams
49
- * @param opts object containing all arguments
50
- * @param opts.pack the pack to sign
51
- * @param opts.secret the reactkit secret to sign with
52
- * @return the signed hash
53
- */
54
- const genSignature = (
55
- opts: {
56
- pack: string,
57
- secret: string,
58
- },
59
- ): string => {
60
- // Generate signature
61
- return (
62
- createHash('sha256')
63
- .update(JSON.stringify({ pack: opts.pack, secret: opts.secret }))
64
- .digest('base64')
65
- );
66
- };
67
-
68
- /**
69
- * Sign data with a private reactkit key, package it into a signed data pack
70
- * @author Gabe Abrams
71
- * @param opts object containing all arguments
72
- * @param opts.method the method to sign
73
- * @param opts.path the http request path
74
- * @param opts.params the data in the body to sign
75
- * @param opts.key the reactkit key to sign with
76
- * @param opts.secret the reactkit secret to sign with
77
- * @return the signed data
78
- */
79
- export const createSignedPack = (
80
- opts: {
81
- method: string,
82
- path: string,
83
- params: { [key: string]: any },
84
- key: string,
85
- secret: string,
86
- },
87
- ): string => {
88
- // Create a timestamp
89
- const timestamp = Date.now();
90
-
91
- // Create the pack
92
- const pack = JSON.stringify({
93
- method: opts.method,
94
- path: opts.path,
95
- params: opts.params,
96
- key: opts.key,
97
- timestamp,
98
- });
99
-
100
- // Generate signature
101
- const signature = genSignature({
102
- pack,
103
- secret: opts.secret,
104
- });
105
-
106
- // Create a signed pack
107
- const signedPack = encodeURIComponent(JSON.stringify({
108
- pack,
109
- signature,
110
- }));
111
-
112
- // Return the signed pack
113
- return signedPack;
114
- };
115
-
116
- /**
117
- * Parse signed pack. Throws an error if invalid
118
- * @author Gabe Abrams
119
- * @param opts object containing all arguments
120
- * @param opts.method the method of the data validate
121
- * @param opts.path the http request path to validate
122
- * @param opts.scope the name of the scope to validate
123
- * @param opts.signedPack the signed data pack to validate
124
- * @returns parsed and validated params
125
- */
126
- export const parseSignedPack = async (
127
- opts: {
128
- method: string,
129
- path: string,
130
- scope: string,
131
- signedPack: string,
132
- },
133
- ): Promise<{ [key: string]: any }> => {
134
- // Extract signature
135
- let pack: string;
136
- let signature: string;
137
- let method: string;
138
- let path: string;
139
- let key: string;
140
- let timestamp: number;
141
- let params: { [k: string]: any };
142
- try {
143
- ({
144
- pack,
145
- signature,
146
- } = JSON.parse(decodeURIComponent(opts.signedPack)));
147
-
148
- // Unpack
149
- ({
150
- method,
151
- path,
152
- params,
153
- key,
154
- timestamp,
155
- } = JSON.parse(pack));
156
- } catch (err) {
157
- throw new ErrorWithCode(
158
- 'Could not validate a cross-server request because the request could not be parsed.',
159
- ReactKitErrorCode.PackUnparseable,
160
- );
161
- }
162
-
163
- // Make sure the method and path match
164
- if (method !== opts.method) {
165
- throw new ErrorWithCode(
166
- 'Could not validate a cross-server request because the method did not match.',
167
- ReactKitErrorCode.PackInvalidMethod,
168
- );
169
- }
170
- if (path !== opts.path) {
171
- throw new ErrorWithCode(
172
- 'Could not validate a cross-server request because the path did not match.',
173
- ReactKitErrorCode.PackInvalidPath,
174
- );
175
- }
176
-
177
- // Make sure the timestamp was recent enough
178
- const elapsedMs = Math.abs(Date.now() - timestamp);
179
- if (elapsedMs < MINUTE_IN_MS) {
180
- throw new ErrorWithCode(
181
- 'Could not validate a cross-server request because the request was too old.',
182
- ReactKitErrorCode.PackInvalidTimestamp,
183
- );
184
- }
185
-
186
- // Get the cross-server credential collection
187
- const crossServerCredentialCollection = internalGetCrossServerCredentialCollection();
188
- if (!crossServerCredentialCollection) {
189
- throw new ErrorWithCode(
190
- 'Could not validate a cross-server request because the cross-server credential collection was not ready in time.',
191
- ReactKitErrorCode.PackInvalidCollection,
192
- );
193
- }
194
-
195
- // Get the cross-server credential
196
- const crossServerCredential: CrossServerCredential = await crossServerCredentialCollection.find({ key });
197
- if (!crossServerCredential) {
198
- throw new ErrorWithCode(
199
- 'Could not validate a cross-server request because the credential was not found.',
200
- ReactKitErrorCode.PackInvalidCredential,
201
- );
202
- }
203
-
204
- // Make sure the scope is included
205
- const allowedScopes = crossServerCredential.scopes;
206
- if (!allowedScopes.includes(opts.scope)) {
207
- throw new ErrorWithCode(
208
- 'Could not validate a cross-server request because the scope was not included.',
209
- ReactKitErrorCode.PackInvalidScope,
210
- );
211
- }
212
-
213
- // Decode the secret
214
- const secret = decodeCredentialSecret(crossServerCredential.encodedeSecret);
215
-
216
- // Generate signature
217
- const expectedSignature = genSignature({
218
- pack,
219
- secret,
220
- });
221
-
222
- // Make sure the signature matches
223
- if (signature !== expectedSignature) {
224
- throw new ErrorWithCode(
225
- 'Could not validate a cross-server request because the signature did not match.',
226
- ReactKitErrorCode.PackInvalidSignature,
227
- );
228
- }
229
-
230
- // Return body
231
- return params ?? {};
232
- };
@@ -1,16 +0,0 @@
1
- /**
2
- * Initialize a cross-server credential collection given the dce-mango Collection class
3
- * @author Gabe Abrams
4
- * @param Collection the Collection class from dce-mango
5
- * @returns initialized logCollection
6
- */
7
- const initCrossServerCredentialCollection = (Collection: any) => {
8
- return new Collection(
9
- 'CrossServerCredential',
10
- {
11
- uniqueIndexKey: 'key',
12
- },
13
- );
14
- };
15
-
16
- export default initCrossServerCredentialCollection;
@@ -1,16 +0,0 @@
1
- /**
2
- * Single cross-server credential
3
- * @author Gabe Abrams
4
- */
5
- type CrossServerCredential = {
6
- // Description of the credential (human-readable)
7
- description: string,
8
- // The key of the credential
9
- key: string,
10
- // The encoded secret of the credential
11
- encodedeSecret: string,
12
- // The list of scopes for the credential
13
- scopes: string[],
14
- };
15
-
16
- export default CrossServerCredential;