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

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 (41) hide show
  1. package/.vscode/settings.json +1 -3
  2. package/README.md +20 -0
  3. package/dist/cjs/index.js +294 -162
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/types/helpers/dataSigner.d.ts +38 -0
  6. package/dist/cjs/types/helpers/genRouteHandler.d.ts +10 -10
  7. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/index.d.ts +15 -13
  8. package/dist/cjs/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +0 -6
  9. package/dist/cjs/types/index.d.ts +3 -2
  10. package/dist/cjs/types/server/initCrossServerCredentialCollection.d.ts +8 -0
  11. package/dist/cjs/types/server/initServer.d.ts +11 -0
  12. package/dist/cjs/types/types/CrossServerCredential.d.ts +11 -0
  13. package/dist/cjs/types/types/ReactKitErrorCode.d.ts +13 -1
  14. package/dist/esm/index.js +293 -162
  15. package/dist/esm/index.js.map +1 -1
  16. package/dist/esm/types/helpers/dataSigner.d.ts +38 -0
  17. package/dist/esm/types/helpers/genRouteHandler.d.ts +10 -10
  18. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/index.d.ts +15 -13
  19. package/dist/esm/types/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +0 -6
  20. package/dist/esm/types/index.d.ts +3 -2
  21. package/dist/esm/types/server/initCrossServerCredentialCollection.d.ts +8 -0
  22. package/dist/esm/types/server/initServer.d.ts +11 -0
  23. package/dist/esm/types/types/CrossServerCredential.d.ts +11 -0
  24. package/dist/esm/types/types/ReactKitErrorCode.d.ts +13 -1
  25. package/dist/index.d.ts +62 -35
  26. package/genEncodedSecret.ts +28 -0
  27. package/package.json +5 -2
  28. package/src/components/IntelliTable.tsx +1 -1
  29. package/src/components/ItemPicker/NestableItemList.tsx +0 -1
  30. package/src/helpers/dataSigner.ts +232 -0
  31. package/src/helpers/genRouteHandler.ts +55 -95
  32. package/src/helpers/visitEndpointOnAnotherServer/index.ts +42 -41
  33. package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +3 -5
  34. package/src/index.ts +4 -2
  35. package/src/server/initCrossServerCredentialCollection.ts +16 -0
  36. package/src/server/initServer.ts +18 -0
  37. package/src/types/CrossServerCredential.ts +16 -0
  38. package/src/types/ReactKitErrorCode.tsx +13 -1
  39. package/dist/cjs/types/helpers/getWordCount.d.ts +0 -10
  40. package/dist/esm/types/helpers/getWordCount.d.ts +0 -10
  41. package/src/helpers/getWordCount.ts +0 -26
@@ -0,0 +1,38 @@
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
+ }>;
@@ -7,14 +7,15 @@ import LogFunction from '../types/LogFunction';
7
7
  * @param opts.paramTypes map containing the types for each parameter that is
8
8
  * included in the request (map: param name => type)
9
9
  * @param opts.handler function that processes the request
10
- * @param [opts.skipSessionCheck] if true, skip the session check (allow users
11
- * to not be logged in and launched via LTI)
12
- * @param [opts.allowedHosts] if included, only allow requests from these hosts
13
- * (start a hostname with a "*" to only check the end of the hostname)
14
- * you can include just one string instead of an array
15
- * @param [opts.bannedHosts] if included, do not allow requests from these hosts
16
- * (start a hostname with a "*" to only check the end of the hostname)
17
- * you can include just one string instead of an array
10
+ * @param [opts.crossServerScope] the scope associated with this endpoint.
11
+ * If defined, this is a cross-server endpoint, which will never
12
+ * have any launch data, will never check Canvas roles or launch status, and will
13
+ * instead use scopes and reactkit credentials to sign and validate requests.
14
+ * Never start the path with /api/ttm or /api/admin if the endpoint is a cross-server
15
+ * endpoint because those roles will not be validated
16
+ * @param [opts.skipSessionCheck=true if crossServerScope defined] if true, skip
17
+ * the session check (allow users to not be logged in and launched via LTI).
18
+ * If crossServerScope is defined, this is always true
18
19
  * @param [opts.unhandledErrorMessagePrefix] if included, when an error that
19
20
  * is not of type ErrorWithCode is thrown, the client will receive an error
20
21
  * where the error message is prefixed with this string. For example,
@@ -68,9 +69,8 @@ declare const genRouteHandler: (opts: {
68
69
  }) => void;
69
70
  logServerEvent: LogFunction;
70
71
  }) => any;
72
+ crossServerScope?: string | undefined;
71
73
  skipSessionCheck?: boolean | undefined;
72
- allowedHosts?: string | string[] | undefined;
73
- bannedHosts?: string | string[] | undefined;
74
74
  unhandledErrorMessagePrefix?: string | undefined;
75
75
  }) => (req: any, res: any, next: () => void) => Promise<undefined>;
76
76
  export default genRouteHandler;
@@ -1,24 +1,26 @@
1
1
  /**
2
- * Send a server-to-server request from this sever to another server that uses
3
- * dce-reactkit [for server only]
2
+ * Visit an endpoint on another server
4
3
  * @author Gabe Abrams
5
4
  * @param opts object containing all arguments
6
- * @param opts.host - the host of the other server
7
- * @param opts.path - the path of the other server's endpoint
8
- * @param [opts.method=GET] - the method of the endpoint
9
- * @param [opts.params] - query/body parameters to include
10
- * @param [opts.headers] - headers to include
11
- * @returns response from server
5
+ * @param opts.method the method of the endpoint
6
+ * @param opts.path the path of the other server's endpoint
7
+ * @param opts.host the host of the other server
8
+ * @param [opts.key=process.env.REACTKIT_CROSS_SERVER_CREDENTIAL_KEY] reactkit cross-server
9
+ * credential key
10
+ * @param [opts.secret=process.env.REACTKIT_CROSS_SERVER_CREDENTIAL_SECRET reactkit cross-server
11
+ * credential secret
12
+ * @param [opts.params={}] query/body parameters to include
13
+ * @param [opts.responseType=JSON] the response type from the other server
12
14
  */
13
15
  declare const visitEndpointOnAnotherServer: (opts: {
14
- host: string;
16
+ method: 'GET' | 'POST' | 'DELETE' | 'PUT';
15
17
  path: string;
16
- method?: "GET" | "POST" | "DELETE" | "PUT" | undefined;
18
+ host: string;
19
+ key?: string | undefined;
20
+ secret?: string | undefined;
17
21
  params?: {
18
22
  [x: string]: any;
19
23
  } | undefined;
20
- headers?: {
21
- [x: string]: any;
22
- } | undefined;
24
+ responseType?: "Text" | "JSON" | undefined;
23
25
  }) => Promise<any>;
24
26
  export default visitEndpointOnAnotherServer;
@@ -6,9 +6,6 @@
6
6
  * @param [opts.host] host to send request to
7
7
  * @param [opts.method=GET] http method to use
8
8
  * @param [opts.params] body/data to include in the request
9
- * @param [opts.headers] headers to include in the request
10
- * @param [opts.sendCrossDomainCredentials=true if in development mode] if true,
11
- * send cross-domain credentials even if not in dev mode
12
9
  * @param [opts.responseType=JSON] expected response type
13
10
  * @returns { body, status, headers } on success
14
11
  */
@@ -19,9 +16,6 @@ declare const sendServerToServerRequest: (opts: {
19
16
  params?: {
20
17
  [x: string]: any;
21
18
  } | undefined;
22
- headers?: {
23
- [x: string]: any;
24
- } | undefined;
25
19
  responseType?: "Text" | "JSON" | undefined;
26
20
  }) => Promise<{
27
21
  body: any;
@@ -54,6 +54,7 @@ import onlyKeepLetters from './helpers/onlyKeepLetters';
54
54
  import parallelLimit from './helpers/parallelLimit';
55
55
  import logClientEvent, { setClientEventMetadataPopulator } from './helpers/logClientEvent';
56
56
  import initLogCollection from './server/initLogCollection';
57
+ import initCrossServerCredentialCollection from './server/initCrossServerCredentialCollection';
57
58
  import getMonthName from './helpers/getMonthName';
58
59
  import genCSV from './helpers/genCSV';
59
60
  import canReviewLogs from './helpers/canReviewLogs';
@@ -79,7 +80,6 @@ import someAsync from './helpers/asyncArrayFunctions/someAsync';
79
80
  import capitalize from './helpers/capitalize';
80
81
  import shuffleArray from './helpers/shuffleArray';
81
82
  import visitEndpointOnAnotherServer from './helpers/visitEndpointOnAnotherServer';
82
- import getWordCount from './helpers/getWordCount';
83
83
  import ModalButtonType from './types/ModalButtonType';
84
84
  import ModalSize from './types/ModalSize';
85
85
  import ModalType from './types/ModalType';
@@ -96,8 +96,9 @@ import LogMetadataType from './types/LogMetadataType';
96
96
  import LogFunction from './types/LogFunction';
97
97
  import IntelliTableColumn from './types/IntelliTableColumn';
98
98
  import DropdownItemType from './types/DropdownItemType';
99
+ import CrossServerCredential from './types/CrossServerCredential';
99
100
  import PickableItem from './components/ItemPicker/types/PickableItem';
100
101
  import DBEntry from './components/DBEntryManagerPanel/types/DBEntry';
101
102
  import DBEntryField from './components/DBEntryManagerPanel/types/DBEntryField';
102
103
  import DBEntryFieldType from './components/DBEntryManagerPanel/types/DBEntryFieldType';
103
- export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, Dropdown, alert, prompt, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, DynamicWord, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, canReviewLogs, isMobileOrTablet, extractProp, compareArraysByProp, genCommaList, validateEmail, validatePhoneNumber, validateString, getLocalTimeInfo, idify, makeLinksClickable, prefixWithAOrAn, everyAsync, filterAsync, forEachAsync, mapAsync, someAsync, capitalize, shuffleArray, getWordCount, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, setClientEventMetadataPopulator, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, addDBEditorEndpoints, visitEndpointOnAnotherServer, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, IntelliTableColumn, DropdownItemType, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ParamType, };
104
+ export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, Dropdown, alert, prompt, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, DynamicWord, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, canReviewLogs, isMobileOrTablet, extractProp, compareArraysByProp, genCommaList, validateEmail, validatePhoneNumber, validateString, getLocalTimeInfo, idify, makeLinksClickable, prefixWithAOrAn, everyAsync, filterAsync, forEachAsync, mapAsync, someAsync, capitalize, shuffleArray, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, setClientEventMetadataPopulator, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, initCrossServerCredentialCollection, addDBEditorEndpoints, visitEndpointOnAnotherServer, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, IntelliTableColumn, DropdownItemType, CrossServerCredential, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ParamType, };
@@ -0,0 +1,8 @@
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;
@@ -16,6 +16,13 @@ export declare const cacclGetLaunchInfo: GetLaunchInfoFunction;
16
16
  * have a log collection (yet)
17
17
  */
18
18
  export declare const internalGetLogCollection: () => any;
19
+ /**
20
+ * Get cross-server credential collection
21
+ * @author Gabe Abrams
22
+ * @return cross-server credential collection if one was included during launch or null
23
+ * if we don't have a cross-server credential collection (yet)
24
+ */
25
+ export declare const internalGetCrossServerCredentialCollection: () => any;
19
26
  /**
20
27
  * Prepare dce-reactkit to run on the server
21
28
  * @author Gabe Abrams
@@ -32,11 +39,15 @@ export declare const internalGetLogCollection: () => any;
32
39
  * userIds are allowed to review logs. If a dce-mango collection, only
33
40
  * Canvas admins with entries in that collection ({ userId, ...}) are allowed
34
41
  * to review logs
42
+ * @param [opts.crossServerCredentialCollection] mongo collection from dce-mango to use for
43
+ * storing cross-server credentials. If none is included, cross-server credentials
44
+ * are not supported
35
45
  */
36
46
  declare const initServer: (opts: {
37
47
  app: any;
38
48
  getLaunchInfo: GetLaunchInfoFunction;
39
49
  logCollection?: any;
40
50
  logReviewAdmins?: (number[] | any);
51
+ crossServerCredentialCollection?: any;
41
52
  }) => void;
42
53
  export default initServer;
@@ -0,0 +1,11 @@
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;
@@ -20,6 +20,18 @@ declare enum ReactKitErrorCode {
20
20
  SessionExpiredMessageGottenBeforeReactKitReady = "DRK13",
21
21
  NotConnected = "DRK14",
22
22
  SelfSigned = "DRK15",
23
- ResponseParseError = "DRK16"
23
+ ResponseParseError = "DRK16",
24
+ PackUnparseable = "DRK28",
25
+ PackInvalidMethod = "DRK19",
26
+ PackInvalidPath = "DRK20",
27
+ PackInvalidCollection = "DRK21",
28
+ PackInvalidCredential = "DRK23",
29
+ PackInvalidScope = "DRK22",
30
+ PackInvalidTimestamp = "DRK24",
31
+ PackInvalidSignature = "DRK25",
32
+ PackInvalidBody = "DRK26",
33
+ CrossServerNoCredentialsToSignWith = "DRK27",
34
+ CrossServerNoPack = "DRK29",
35
+ CrossServerNoCredentialEncodingSalt = "DRK30"
24
36
  }
25
37
  export default ReactKitErrorCode;
package/dist/index.d.ts CHANGED
@@ -1086,14 +1086,15 @@ type LogFunction = (opts: ({
1086
1086
  * @param opts.paramTypes map containing the types for each parameter that is
1087
1087
  * included in the request (map: param name => type)
1088
1088
  * @param opts.handler function that processes the request
1089
- * @param [opts.skipSessionCheck] if true, skip the session check (allow users
1090
- * to not be logged in and launched via LTI)
1091
- * @param [opts.allowedHosts] if included, only allow requests from these hosts
1092
- * (start a hostname with a "*" to only check the end of the hostname)
1093
- * you can include just one string instead of an array
1094
- * @param [opts.bannedHosts] if included, do not allow requests from these hosts
1095
- * (start a hostname with a "*" to only check the end of the hostname)
1096
- * you can include just one string instead of an array
1089
+ * @param [opts.crossServerScope] the scope associated with this endpoint.
1090
+ * If defined, this is a cross-server endpoint, which will never
1091
+ * have any launch data, will never check Canvas roles or launch status, and will
1092
+ * instead use scopes and reactkit credentials to sign and validate requests.
1093
+ * Never start the path with /api/ttm or /api/admin if the endpoint is a cross-server
1094
+ * endpoint because those roles will not be validated
1095
+ * @param [opts.skipSessionCheck=true if crossServerScope defined] if true, skip
1096
+ * the session check (allow users to not be logged in and launched via LTI).
1097
+ * If crossServerScope is defined, this is always true
1097
1098
  * @param [opts.unhandledErrorMessagePrefix] if included, when an error that
1098
1099
  * is not of type ErrorWithCode is thrown, the client will receive an error
1099
1100
  * where the error message is prefixed with this string. For example,
@@ -1147,9 +1148,8 @@ declare const genRouteHandler: (opts: {
1147
1148
  }) => void;
1148
1149
  logServerEvent: LogFunction;
1149
1150
  }) => any;
1151
+ crossServerScope?: string | undefined;
1150
1152
  skipSessionCheck?: boolean | undefined;
1151
- allowedHosts?: string | string[] | undefined;
1152
- bannedHosts?: string | string[] | undefined;
1153
1153
  unhandledErrorMessagePrefix?: string | undefined;
1154
1154
  }) => (req: any, res: any, next: () => void) => Promise<undefined>;
1155
1155
 
@@ -1199,12 +1199,16 @@ type GetLaunchInfoFunction = (req: any) => {
1199
1199
  * userIds are allowed to review logs. If a dce-mango collection, only
1200
1200
  * Canvas admins with entries in that collection ({ userId, ...}) are allowed
1201
1201
  * to review logs
1202
+ * @param [opts.crossServerCredentialCollection] mongo collection from dce-mango to use for
1203
+ * storing cross-server credentials. If none is included, cross-server credentials
1204
+ * are not supported
1202
1205
  */
1203
1206
  declare const initServer: (opts: {
1204
1207
  app: any;
1205
1208
  getLaunchInfo: GetLaunchInfoFunction;
1206
1209
  logCollection?: any;
1207
1210
  logReviewAdmins?: (number[] | any);
1211
+ crossServerCredentialCollection?: any;
1208
1212
  }) => void;
1209
1213
 
1210
1214
  /**
@@ -1335,6 +1339,14 @@ declare const logClientEvent: LogFunction;
1335
1339
  */
1336
1340
  declare const initLogCollection: (Collection: any) => any;
1337
1341
 
1342
+ /**
1343
+ * Initialize a cross-server credential collection given the dce-mango Collection class
1344
+ * @author Gabe Abrams
1345
+ * @param Collection the Collection class from dce-mango
1346
+ * @returns initialized logCollection
1347
+ */
1348
+ declare const initCrossServerCredentialCollection: (Collection: any) => any;
1349
+
1338
1350
  /**
1339
1351
  * Get the name of a month given the month number (1 = January, etc.)
1340
1352
  * If an invalid number is provided, we will treat it like January
@@ -1656,39 +1668,31 @@ declare const capitalize: (str: string) => string;
1656
1668
  declare const shuffleArray: <T>(arr: T[]) => T[];
1657
1669
 
1658
1670
  /**
1659
- * Send a server-to-server request from this sever to another server that uses
1660
- * dce-reactkit [for server only]
1671
+ * Visit an endpoint on another server
1661
1672
  * @author Gabe Abrams
1662
1673
  * @param opts object containing all arguments
1663
- * @param opts.host - the host of the other server
1664
- * @param opts.path - the path of the other server's endpoint
1665
- * @param [opts.method=GET] - the method of the endpoint
1666
- * @param [opts.params] - query/body parameters to include
1667
- * @param [opts.headers] - headers to include
1668
- * @returns response from server
1674
+ * @param opts.method the method of the endpoint
1675
+ * @param opts.path the path of the other server's endpoint
1676
+ * @param opts.host the host of the other server
1677
+ * @param [opts.key=process.env.REACTKIT_CROSS_SERVER_CREDENTIAL_KEY] reactkit cross-server
1678
+ * credential key
1679
+ * @param [opts.secret=process.env.REACTKIT_CROSS_SERVER_CREDENTIAL_SECRET reactkit cross-server
1680
+ * credential secret
1681
+ * @param [opts.params={}] query/body parameters to include
1682
+ * @param [opts.responseType=JSON] the response type from the other server
1669
1683
  */
1670
1684
  declare const visitEndpointOnAnotherServer: (opts: {
1671
- host: string;
1685
+ method: 'GET' | 'POST' | 'DELETE' | 'PUT';
1672
1686
  path: string;
1673
- method?: "GET" | "POST" | "DELETE" | "PUT" | undefined;
1687
+ host: string;
1688
+ key?: string | undefined;
1689
+ secret?: string | undefined;
1674
1690
  params?: {
1675
1691
  [x: string]: any;
1676
1692
  } | undefined;
1677
- headers?: {
1678
- [x: string]: any;
1679
- } | undefined;
1693
+ responseType?: "Text" | "JSON" | undefined;
1680
1694
  }) => Promise<any>;
1681
1695
 
1682
- /**
1683
- * Get number of words in string
1684
- * @author Gardenia Liu
1685
- * @author Allison Zhang
1686
- * @author Gabe Abrams
1687
- * @param text the string to check
1688
- * @returns number of words in the string
1689
- */
1690
- declare const getWordCount: (text: string) => number;
1691
-
1692
1696
  /**
1693
1697
  * List of error codes built into the react kit
1694
1698
  * @author Gabe Abrams
@@ -1711,7 +1715,19 @@ declare enum ReactKitErrorCode {
1711
1715
  SessionExpiredMessageGottenBeforeReactKitReady = "DRK13",
1712
1716
  NotConnected = "DRK14",
1713
1717
  SelfSigned = "DRK15",
1714
- ResponseParseError = "DRK16"
1718
+ ResponseParseError = "DRK16",
1719
+ PackUnparseable = "DRK28",
1720
+ PackInvalidMethod = "DRK19",
1721
+ PackInvalidPath = "DRK20",
1722
+ PackInvalidCollection = "DRK21",
1723
+ PackInvalidCredential = "DRK23",
1724
+ PackInvalidScope = "DRK22",
1725
+ PackInvalidTimestamp = "DRK24",
1726
+ PackInvalidSignature = "DRK25",
1727
+ PackInvalidBody = "DRK26",
1728
+ CrossServerNoCredentialsToSignWith = "DRK27",
1729
+ CrossServerNoPack = "DRK29",
1730
+ CrossServerNoCredentialEncodingSalt = "DRK30"
1715
1731
  }
1716
1732
 
1717
1733
  /**
@@ -1744,4 +1760,15 @@ declare const LogBuiltInMetadata: {
1744
1760
  };
1745
1761
  };
1746
1762
 
1747
- export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, DayOfWeek, Drawer, Dropdown, DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogFunction, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, getWordCount, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitEndpointOnAnotherServer, visitServerEndpoint, waitMs };
1763
+ /**
1764
+ * Single cross-server credential
1765
+ * @author Gabe Abrams
1766
+ */
1767
+ type CrossServerCredential = {
1768
+ description: string;
1769
+ key: string;
1770
+ encodedeSecret: string;
1771
+ scopes: string[];
1772
+ };
1773
+
1774
+ export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, CrossServerCredential, DAY_IN_MS, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, DayOfWeek, Drawer, Dropdown, DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogFunction, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initCrossServerCredentialCollection, initLogCollection, initServer, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitEndpointOnAnotherServer, visitServerEndpoint, waitMs };
@@ -0,0 +1,28 @@
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}`);
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.11.4",
3
+ "version": "3.12.1-beta-cross-server.2",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
9
  "build": "rm -rf dist && rollup -c",
10
- "test": "jest --runInBand"
10
+ "test": "jest --runInBand",
11
+ "gen-reactkit-cross-server-secret": "npx tsx genEncodedSecret.ts"
11
12
  },
12
13
  "jest": {
13
14
  "preset": "ts-jest",
@@ -24,6 +25,7 @@
24
25
  },
25
26
  "homepage": "https://github.com/harvard-edtech/dce-reactkit#readme",
26
27
  "dependencies": {
28
+ "jwt-simple": "^0.5.6",
27
29
  "qs": "^6.x.x",
28
30
  "react-select": "^5.7.3"
29
31
  },
@@ -45,6 +47,7 @@
45
47
  "@types/bootstrap": "^5.2.8",
46
48
  "@types/express": "^4.17.17",
47
49
  "@types/jest": "^28.1.7",
50
+ "@types/jwt-simple": "^0.5.36",
48
51
  "@types/node": "^20.2.5",
49
52
  "@types/react": "^17.0.7",
50
53
  "@typescript-eslint/eslint-plugin": "^5.59.9",
@@ -315,7 +315,7 @@ const IntelliTable: React.FC<Props> = (props) => {
315
315
  checked={columnVisibilityMap[column.param]}
316
316
  ariaLabel={`show "${column.title}" column in the ${title} table`}
317
317
  checkedVariant={Variant.Light}
318
- uncheckedVariant={Variant.Light}
318
+ uncheckedVariant={Variant.Secondary}
319
319
  />
320
320
  );
321
321
  })
@@ -272,7 +272,6 @@ const NestableItemList: React.FC<Props> = (props) => {
272
272
  }}
273
273
  ariaLabel={`Select ${item.name}`}
274
274
  checkedVariant={Variant.Light}
275
- uncheckedVariant={Variant.Light}
276
275
  />
277
276
 
278
277
  {/* Children */}