dce-expresskit 4.0.0-beta.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 (94) hide show
  1. package/.eslintrc.js +93 -0
  2. package/LICENSE +21 -0
  3. package/README.md +17 -0
  4. package/genEncodedSecret.ts +84 -0
  5. package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.d.ts +6 -0
  6. package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.js +13 -0
  7. package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.js.map +1 -0
  8. package/lib/constants/LOG_REVIEW_STATUS_ROUTE.d.ts +7 -0
  9. package/lib/constants/LOG_REVIEW_STATUS_ROUTE.js +14 -0
  10. package/lib/constants/LOG_REVIEW_STATUS_ROUTE.js.map +1 -0
  11. package/lib/constants/LOG_ROUTE_PATH.d.ts +6 -0
  12. package/lib/constants/LOG_ROUTE_PATH.js +13 -0
  13. package/lib/constants/LOG_ROUTE_PATH.js.map +1 -0
  14. package/lib/constants/ROUTE_PATH_PREFIX.d.ts +6 -0
  15. package/lib/constants/ROUTE_PATH_PREFIX.js +9 -0
  16. package/lib/constants/ROUTE_PATH_PREFIX.js.map +1 -0
  17. package/lib/errors/ErrorWithCode.d.ts +9 -0
  18. package/lib/errors/ErrorWithCode.js +33 -0
  19. package/lib/errors/ErrorWithCode.js.map +1 -0
  20. package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.d.ts +9 -0
  21. package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.js +17 -0
  22. package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.js.map +1 -0
  23. package/lib/helpers/addDBEditorEndpoints/index.d.ts +41 -0
  24. package/lib/helpers/addDBEditorEndpoints/index.js +134 -0
  25. package/lib/helpers/addDBEditorEndpoints/index.js.map +1 -0
  26. package/lib/helpers/dataSigner.d.ts +40 -0
  27. package/lib/helpers/dataSigner.js +231 -0
  28. package/lib/helpers/dataSigner.js.map +1 -0
  29. package/lib/helpers/genRouteHandler.d.ts +75 -0
  30. package/lib/helpers/genRouteHandler.js +661 -0
  31. package/lib/helpers/genRouteHandler.js.map +1 -0
  32. package/lib/helpers/handleError.d.ts +18 -0
  33. package/lib/helpers/handleError.js +51 -0
  34. package/lib/helpers/handleError.js.map +1 -0
  35. package/lib/helpers/handleSuccess.d.ts +8 -0
  36. package/lib/helpers/handleSuccess.js +20 -0
  37. package/lib/helpers/handleSuccess.js.map +1 -0
  38. package/lib/helpers/initCrossServerCredentialCollection.d.ts +11 -0
  39. package/lib/helpers/initCrossServerCredentialCollection.js +15 -0
  40. package/lib/helpers/initCrossServerCredentialCollection.js.map +1 -0
  41. package/lib/helpers/initLogCollection.d.ts +11 -0
  42. package/lib/helpers/initLogCollection.js +26 -0
  43. package/lib/helpers/initLogCollection.js.map +1 -0
  44. package/lib/helpers/initServer.d.ts +43 -0
  45. package/lib/helpers/initServer.js +297 -0
  46. package/lib/helpers/initServer.js.map +1 -0
  47. package/lib/helpers/parseUserAgent.d.ts +17 -0
  48. package/lib/helpers/parseUserAgent.js +108 -0
  49. package/lib/helpers/parseUserAgent.js.map +1 -0
  50. package/lib/helpers/visitEndpointOnAnotherServer/index.d.ts +18 -0
  51. package/lib/helpers/visitEndpointOnAnotherServer/index.js +156 -0
  52. package/lib/helpers/visitEndpointOnAnotherServer/index.js.map +1 -0
  53. package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +23 -0
  54. package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.js +168 -0
  55. package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.js.map +1 -0
  56. package/lib/html/genErrorPage.d.ts +19 -0
  57. package/lib/html/genErrorPage.js +27 -0
  58. package/lib/html/genErrorPage.js.map +1 -0
  59. package/lib/html/genInfoPage.d.ts +13 -0
  60. package/lib/html/genInfoPage.js +16 -0
  61. package/lib/html/genInfoPage.js.map +1 -0
  62. package/lib/index.d.ts +11 -0
  63. package/lib/index.js +68 -0
  64. package/lib/index.js.map +1 -0
  65. package/lib/types/CrossServerCredential.d.ts +11 -0
  66. package/lib/types/CrossServerCredential.js +3 -0
  67. package/lib/types/CrossServerCredential.js.map +1 -0
  68. package/lib/types/ExpressKitErrorCode.d.ts +31 -0
  69. package/lib/types/ExpressKitErrorCode.js +38 -0
  70. package/lib/types/ExpressKitErrorCode.js.map +1 -0
  71. package/package.json +52 -0
  72. package/src/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.ts +9 -0
  73. package/src/constants/LOG_REVIEW_STATUS_ROUTE.ts +10 -0
  74. package/src/constants/LOG_ROUTE_PATH.ts +9 -0
  75. package/src/constants/ROUTE_PATH_PREFIX.ts +7 -0
  76. package/src/errors/ErrorWithCode.tsx +15 -0
  77. package/src/helpers/addDBEditorEndpoints/generateEndpointPath.ts +16 -0
  78. package/src/helpers/addDBEditorEndpoints/index.ts +130 -0
  79. package/src/helpers/dataSigner.ts +296 -0
  80. package/src/helpers/genRouteHandler.ts +914 -0
  81. package/src/helpers/handleError.ts +66 -0
  82. package/src/helpers/handleSuccess.ts +18 -0
  83. package/src/helpers/initCrossServerCredentialCollection.ts +19 -0
  84. package/src/helpers/initLogCollection.ts +31 -0
  85. package/src/helpers/initServer.ts +284 -0
  86. package/src/helpers/parseUserAgent.ts +108 -0
  87. package/src/helpers/visitEndpointOnAnotherServer/index.ts +157 -0
  88. package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +164 -0
  89. package/src/html/genErrorPage.ts +144 -0
  90. package/src/html/genInfoPage.ts +101 -0
  91. package/src/index.ts +125 -0
  92. package/src/types/CrossServerCredential.ts +16 -0
  93. package/src/types/ExpressKitErrorCode.ts +37 -0
  94. package/tsconfig.json +19 -0
package/.eslintrc.js ADDED
@@ -0,0 +1,93 @@
1
+ const config = {
2
+ extends: [
3
+ 'airbnb',
4
+ 'airbnb/hooks',
5
+ ],
6
+ overrides: [
7
+ {
8
+ files: [
9
+ '*.ts',
10
+ '*.tsx',
11
+ ],
12
+ extends: [
13
+ 'airbnb-typescript',
14
+ ],
15
+ parserOptions: {
16
+ project: './tsconfig.json',
17
+ tsconfigRootDir: __dirname,
18
+ sourceType: 'module',
19
+ },
20
+ rules: {
21
+ '@typescript-eslint/lines-between-class-members': 'off',
22
+ '@typescript-eslint/no-unused-expressions': 'off',
23
+ },
24
+ },
25
+ ],
26
+ rules: {
27
+ 'arrow-body-style': [
28
+ 'warn',
29
+ 'always',
30
+ ],
31
+ 'react/prop-types': 'off',
32
+ 'react/function-component-definition': [
33
+ 2,
34
+ {
35
+ namedComponents: 'arrow-function',
36
+ },
37
+ ],
38
+ 'no-spaced-func': 'off',
39
+ 'react-hooks/exhaustive-deps': 'off',
40
+ 'lines-between-class-members': 'off',
41
+ 'no-case-declarations': 'off',
42
+ 'react/require-default-props': 'off',
43
+ 'react/react-in-jsx-scope': 'off',
44
+ 'arrow-parens': [
45
+ 'warn',
46
+ 'always',
47
+ ],
48
+ 'comma-dangle': [
49
+ 'error',
50
+ {
51
+ arrays: 'always-multiline',
52
+ objects: 'always-multiline',
53
+ imports: 'always-multiline',
54
+ exports: 'always-multiline',
55
+ functions: 'always-multiline',
56
+ },
57
+ ],
58
+ 'consistent-return': 'off',
59
+ 'id-length': 'off',
60
+ 'max-len': [
61
+ 'error',
62
+ {
63
+ code: 125,
64
+ ignoreStrings: true,
65
+ ignoreTemplateLiterals: true,
66
+ ignoreUrls: true,
67
+ },
68
+ ],
69
+ 'newline-per-chained-call': [
70
+ 'error',
71
+ {
72
+ ignoreChainWithDepth: 2,
73
+ },
74
+ ],
75
+ 'no-plusplus': [
76
+ 'warn',
77
+ {
78
+ allowForLoopAfterthoughts: true,
79
+ },
80
+ ],
81
+ 'prefer-template': 1,
82
+ radix: 'error',
83
+ 'no-await-in-loop': 'off',
84
+ 'max-params': [
85
+ 'warn',
86
+ {
87
+ max: 3,
88
+ },
89
+ ],
90
+ },
91
+ };
92
+
93
+ module.exports = config;
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Harvard Edtech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # dce-expresskit
2
+
3
+ Shared functions, helpers, and tools for Harvard DCE Express-based servers
4
+
5
+ ## Quickstart
6
+
7
+ 1. Install `dce-expresskit` into your React project:
8
+
9
+ ```bash
10
+ npm install dce-expresskit --save
11
+ ```
12
+
13
+ 2. Import `dce-expresskit` components into your React component:
14
+
15
+ ```js
16
+ import { genRouteHandler } from 'dce-expresskit';
17
+ ```
@@ -0,0 +1,84 @@
1
+ // Import crypto lib
2
+ import crypto from 'crypto';
3
+
4
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
5
+
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) {
30
+ // Generate a random secret
31
+ secret = '';
32
+ for (let i = 0; i < 32; i++) {
33
+ secret += chars.charAt(Math.floor(Math.random() * chars.length));
34
+ }
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
+ * Path of the route for storing client-side logs
3
+ * @author Gabe Abrams
4
+ */
5
+ declare const LOG_REVIEW_ROUTE_PATH_PREFIX = "/admin/dce-expresskit/logs";
6
+ export default LOG_REVIEW_ROUTE_PATH_PREFIX;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var ROUTE_PATH_PREFIX_1 = __importDefault(require("./ROUTE_PATH_PREFIX"));
7
+ /**
8
+ * Path of the route for storing client-side logs
9
+ * @author Gabe Abrams
10
+ */
11
+ var LOG_REVIEW_ROUTE_PATH_PREFIX = "/admin".concat(ROUTE_PATH_PREFIX_1.default, "/logs");
12
+ exports.default = LOG_REVIEW_ROUTE_PATH_PREFIX;
13
+ //# sourceMappingURL=LOG_REVIEW_ROUTE_PATH_PREFIX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_REVIEW_ROUTE_PATH_PREFIX.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.ts"],"names":[],"mappings":";;;;;AAAA,0EAAoD;AAEpD;;;GAGG;AACH,IAAM,4BAA4B,GAAG,gBAAS,2BAAiB,UAAO,CAAC;AAEvE,kBAAe,4BAA4B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Route for checking the status of the current user's
3
+ * access to log review
4
+ * @author Gabe Abrams
5
+ */
6
+ declare const LOG_REVIEW_STATUS_ROUTE = "/dce-expresskit/logs/access_allowed";
7
+ export default LOG_REVIEW_STATUS_ROUTE;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var ROUTE_PATH_PREFIX_1 = __importDefault(require("./ROUTE_PATH_PREFIX"));
7
+ /**
8
+ * Route for checking the status of the current user's
9
+ * access to log review
10
+ * @author Gabe Abrams
11
+ */
12
+ var LOG_REVIEW_STATUS_ROUTE = "".concat(ROUTE_PATH_PREFIX_1.default, "/logs/access_allowed");
13
+ exports.default = LOG_REVIEW_STATUS_ROUTE;
14
+ //# sourceMappingURL=LOG_REVIEW_STATUS_ROUTE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_REVIEW_STATUS_ROUTE.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_STATUS_ROUTE.ts"],"names":[],"mappings":";;;;;AAAA,0EAAoD;AAEpD;;;;GAIG;AACH,IAAM,uBAAuB,GAAG,UAAG,2BAAiB,yBAAsB,CAAC;AAE3E,kBAAe,uBAAuB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Path of the route for storing client-side logs
3
+ * @author Gabe Abrams
4
+ */
5
+ declare const LOG_ROUTE_PATH = "/dce-expresskit/log";
6
+ export default LOG_ROUTE_PATH;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var ROUTE_PATH_PREFIX_1 = __importDefault(require("./ROUTE_PATH_PREFIX"));
7
+ /**
8
+ * Path of the route for storing client-side logs
9
+ * @author Gabe Abrams
10
+ */
11
+ var LOG_ROUTE_PATH = "".concat(ROUTE_PATH_PREFIX_1.default, "/log");
12
+ exports.default = LOG_ROUTE_PATH;
13
+ //# sourceMappingURL=LOG_ROUTE_PATH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_ROUTE_PATH.js","sourceRoot":"","sources":["../../src/constants/LOG_ROUTE_PATH.ts"],"names":[],"mappings":";;;;;AAAA,0EAAoD;AAEpD;;;GAGG;AACH,IAAM,cAAc,GAAG,UAAG,2BAAiB,SAAM,CAAC;AAElD,kBAAe,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Path that all routes start with
3
+ * @author Gabe Abrams
4
+ */
5
+ declare const ROUTE_PATH_PREFIX = "/dce-expresskit";
6
+ export default ROUTE_PATH_PREFIX;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Path that all routes start with
5
+ * @author Gabe Abrams
6
+ */
7
+ var ROUTE_PATH_PREFIX = '/dce-expresskit';
8
+ exports.default = ROUTE_PATH_PREFIX;
9
+ //# sourceMappingURL=ROUTE_PATH_PREFIX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ROUTE_PATH_PREFIX.js","sourceRoot":"","sources":["../../src/constants/ROUTE_PATH_PREFIX.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,IAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C,kBAAe,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * An error with a code
3
+ * @author Gabe Abrams
4
+ */
5
+ declare class ErrorWithCode extends Error {
6
+ code: string;
7
+ constructor(message: string, code: string);
8
+ }
9
+ export default ErrorWithCode;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ /**
19
+ * An error with a code
20
+ * @author Gabe Abrams
21
+ */
22
+ var ErrorWithCode = /** @class */ (function (_super) {
23
+ __extends(ErrorWithCode, _super);
24
+ function ErrorWithCode(message, code) {
25
+ var _this = _super.call(this, message) || this;
26
+ _this.name = 'ErrorWithCode';
27
+ _this.code = code;
28
+ return _this;
29
+ }
30
+ return ErrorWithCode;
31
+ }(Error));
32
+ exports.default = ErrorWithCode;
33
+ //# sourceMappingURL=ErrorWithCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorWithCode.js","sourceRoot":"","sources":["../../src/errors/ErrorWithCode.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA;;;GAGG;AACH;IAA4B,iCAAK;IAG/B,uBAAY,OAAe,EAAE,IAAY;QACvC,YAAA,MAAK,YAAC,OAAO,CAAC,SAAC;QACf,KAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,KAAI,CAAC,IAAI,GAAG,IAAI,CAAC;;IACnB,CAAC;IACH,oBAAC;AAAD,CAAC,AARD,CAA4B,KAAK,GAQhC;AAED,kBAAe,aAAa,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Generates the endpoint path for the given collection name
3
+ * @author Yuen Ler Chow
4
+ * @param collectionName the name of the collection
5
+ * @param [adminsOnly] true if the endpoint is for admins only
6
+ * @returns the endpoint path
7
+ */
8
+ declare const generateEndpointPath: (collectionName: string, adminsOnly?: boolean) => string;
9
+ export default generateEndpointPath;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Generates the endpoint path for the given collection name
5
+ * @author Yuen Ler Chow
6
+ * @param collectionName the name of the collection
7
+ * @param [adminsOnly] true if the endpoint is for admins only
8
+ * @returns the endpoint path
9
+ */
10
+ var generateEndpointPath = function (collectionName, adminsOnly) {
11
+ // Determine prefix based on whether the endpoint is for admins only
12
+ var userPath = adminsOnly ? 'admin' : 'ttm';
13
+ // Return the endpoint path
14
+ return "/api/".concat(userPath, "/dce-reactkit/dbeditor/").concat(collectionName);
15
+ };
16
+ exports.default = generateEndpointPath;
17
+ //# sourceMappingURL=generateEndpointPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateEndpointPath.js","sourceRoot":"","sources":["../../../src/helpers/addDBEditorEndpoints/generateEndpointPath.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,IAAM,oBAAoB,GAAG,UAAC,cAAsB,EAAE,UAAoB;IACxE,oEAAoE;IACpE,IAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAE9C,2BAA2B;IAC3B,OAAO,eAAQ,QAAQ,oCAA0B,cAAc,CAAE,CAAC;AACpE,CAAC,CAAC;AAEF,kBAAe,oBAAoB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import express from 'express';
2
+ /**
3
+ * Interface for a collection in the database
4
+ * @author Yuen Ler Chow
5
+ */
6
+ type DCEMangoCollection = {
7
+ /**
8
+ * Find all items in the collection that match the filter query
9
+ * @param filterQuery query for the filter
10
+ * @returns list of items that match the filter query
11
+ */
12
+ find: (filterQuery: any) => Promise<any[]>;
13
+ /**
14
+ * Insert an item into the collection
15
+ * @param item the item to insert
16
+ */
17
+ insert: (item: any) => Promise<void>;
18
+ /**
19
+ * Delete an item in the collection
20
+ * @param id the id of the item to delete
21
+ */
22
+ delete: (filterQuery: {
23
+ id: string;
24
+ }) => Promise<void>;
25
+ };
26
+ /**
27
+ * Add all routes for the DBEditor
28
+ * @author Yuen Ler Chow
29
+ * @param opts object containing all arguments
30
+ * @param opts.app express app to add routes too
31
+ * @param opts.collectionName the name of the collection
32
+ * @param opts.adminsOnly true if the endpoint is for admins only
33
+ * @param opts.collection dce-mango db collection
34
+ */
35
+ declare const addDBEditorEndpoints: (opts: {
36
+ app: express.Application;
37
+ collectionName: string;
38
+ adminsOnly: boolean;
39
+ collection: DCEMangoCollection;
40
+ }) => void;
41
+ export default addDBEditorEndpoints;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ 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);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ 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;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ // Import dce-reactkit
43
+ var dce_reactkit_1 = require("dce-reactkit");
44
+ // Import shared helpers
45
+ var genRouteHandler_1 = __importDefault(require("../genRouteHandler"));
46
+ var generateEndpointPath_1 = __importDefault(require("./generateEndpointPath"));
47
+ /**
48
+ * Add all routes for the DBEditor
49
+ * @author Yuen Ler Chow
50
+ * @param opts object containing all arguments
51
+ * @param opts.app express app to add routes too
52
+ * @param opts.collectionName the name of the collection
53
+ * @param opts.adminsOnly true if the endpoint is for admins only
54
+ * @param opts.collection dce-mango db collection
55
+ */
56
+ var addDBEditorEndpoints = function (opts) {
57
+ var app = opts.app, collectionName = opts.collectionName, adminsOnly = opts.adminsOnly, collection = opts.collection;
58
+ // Generate the endpoint path
59
+ var endpointPath = (0, generateEndpointPath_1.default)(collectionName, adminsOnly);
60
+ /**
61
+ * List all items in the collection
62
+ * @author Yuen Ler Chow
63
+ * @returns {any[]} the list of items in the collection
64
+ */
65
+ app.get(endpointPath, (0, genRouteHandler_1.default)({
66
+ paramTypes: {
67
+ filterQuery: dce_reactkit_1.ParamType.JSONOptional,
68
+ },
69
+ handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
70
+ var filterQuery, categories;
71
+ var _c;
72
+ var params = _b.params;
73
+ return __generator(this, function (_d) {
74
+ switch (_d.label) {
75
+ case 0:
76
+ filterQuery = (_c = params.filterQuery) !== null && _c !== void 0 ? _c : {};
77
+ return [4 /*yield*/, collection.find(filterQuery)];
78
+ case 1:
79
+ categories = _d.sent();
80
+ return [2 /*return*/, categories];
81
+ }
82
+ });
83
+ }); },
84
+ }));
85
+ /**
86
+ * Create a new item in the collection
87
+ * @author Yuen Ler Chow
88
+ * @param {any} item the item to create
89
+ */
90
+ app.post(endpointPath, (0, genRouteHandler_1.default)({
91
+ paramTypes: {
92
+ item: dce_reactkit_1.ParamType.JSON,
93
+ },
94
+ handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
95
+ var item;
96
+ var params = _b.params;
97
+ return __generator(this, function (_c) {
98
+ switch (_c.label) {
99
+ case 0:
100
+ item = params.item;
101
+ return [4 /*yield*/, collection.insert(item)];
102
+ case 1:
103
+ _c.sent();
104
+ return [2 /*return*/];
105
+ }
106
+ });
107
+ }); },
108
+ }));
109
+ /**
110
+ * Remove an item from the collection by id
111
+ * @author Yuen Ler Chow
112
+ */
113
+ app.delete("".concat(endpointPath, "/:id"), (0, genRouteHandler_1.default)({
114
+ paramTypes: {
115
+ id: dce_reactkit_1.ParamType.String,
116
+ },
117
+ handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
118
+ var id;
119
+ var params = _b.params;
120
+ return __generator(this, function (_c) {
121
+ switch (_c.label) {
122
+ case 0:
123
+ id = params.id;
124
+ return [4 /*yield*/, collection.delete({ id: id })];
125
+ case 1:
126
+ _c.sent();
127
+ return [2 /*return*/];
128
+ }
129
+ });
130
+ }); },
131
+ }));
132
+ };
133
+ exports.default = addDBEditorEndpoints;
134
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/helpers/addDBEditorEndpoints/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,sBAAsB;AACtB,6CAEsB;AAEtB,wBAAwB;AACxB,uEAAiD;AACjD,gFAA0D;AAyB1D;;;;;;;;GAQG;AACH,IAAM,oBAAoB,GAAG,UAC3B,IAKC;IAGC,IAAA,GAAG,GAID,IAAI,IAJH,EACH,cAAc,GAGZ,IAAI,eAHQ,EACd,UAAU,GAER,IAAI,WAFI,EACV,UAAU,GACR,IAAI,WADI,CACH;IAET,6BAA6B;IAC7B,IAAM,YAAY,GAAG,IAAA,8BAAoB,EAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAEtE;;;;OAIG;IACH,GAAG,CAAC,GAAG,CACL,YAAY,EACZ,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,WAAW,EAAE,wBAAS,CAAC,YAAY;SACpC;QACD,OAAO,EAAE,iEAAO,EAAU;;;gBAAR,MAAM,YAAA;;;;wBAChB,WAAW,GAAG,MAAA,MAAM,CAAC,WAAW,mCAAI,EAAE,CAAC;wBAC1B,qBAAM,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAA;;wBAA/C,UAAU,GAAG,SAAkC;wBACrD,sBAAO,UAAU,EAAC;;;aACnB;KACF,CAAC,CACH,CAAC;IAEF;;;;OAIG;IACH,GAAG,CAAC,IAAI,CACN,YAAY,EACZ,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,IAAI,EAAE,wBAAS,CAAC,IAAI;SACrB;QACD,OAAO,EAAE,iEAAO,EAEf;;gBADC,MAAM,YAAA;;;;wBAIJ,IAAI,GACF,MAAM,KADJ,CACK;wBAEX,qBAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAA;;wBAA7B,SAA6B,CAAC;;;;aAC/B;KACF,CAAC,CACH,CAAC;IAEF;;;OAGG;IACH,GAAG,CAAC,MAAM,CACR,UAAG,YAAY,SAAM,EACrB,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,EAAE,EAAE,wBAAS,CAAC,MAAM;SACrB;QACD,OAAO,EAAE,iEAAO,EAEf;;gBADC,MAAM,YAAA;;;;wBAIJ,EAAE,GACA,MAAM,GADN,CACO;wBAEX,qBAAM,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,IAAA,EAAE,CAAC,EAAA;;wBAA/B,SAA+B,CAAC;;;;aACjC;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,oBAAoB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Sign a request and get the new request params
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 dcekit key to sign with
9
+ * @param opts.secret the dcekit secret to sign with
10
+ * @return augmented params for the request, including a signature, timestamp, and key
11
+ */
12
+ export declare const signRequest: (opts: {
13
+ method: string;
14
+ path: string;
15
+ params: {
16
+ [key: string]: any;
17
+ };
18
+ key: string;
19
+ secret: string;
20
+ }) => Promise<{
21
+ [key: string]: any;
22
+ }>;
23
+ /**
24
+ * Validate a signed request. Throws an error if invalid
25
+ * @author Gabe Abrams
26
+ * @param opts object containing all arguments
27
+ * @param opts.method the method of the data validate
28
+ * @param opts.path the http request path to validate
29
+ * @param opts.scope the name of the scope to validate
30
+ * @param opts.params the request data to validate
31
+ * @returns parsed and validated params
32
+ */
33
+ export declare const validateSignedRequest: (opts: {
34
+ method: string;
35
+ path: string;
36
+ scope: string;
37
+ params: {
38
+ [key: string]: any;
39
+ };
40
+ }) => Promise<void>;