dce-expresskit 4.0.0-beta-logreviewer.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.
- package/.eslintrc.js +93 -0
- package/LICENSE +21 -0
- package/README.md +17 -0
- package/genEncodedSecret.ts +107 -0
- package/genSalt.ts +15 -0
- package/lib/constants/LOG_REVIEW_PAGE_SIZE.d.ts +6 -0
- package/lib/constants/LOG_REVIEW_PAGE_SIZE.js +9 -0
- package/lib/constants/LOG_REVIEW_PAGE_SIZE.js.map +1 -0
- package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.d.ts +6 -0
- package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.js +13 -0
- package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.js.map +1 -0
- package/lib/constants/LOG_REVIEW_STATUS_ROUTE.d.ts +7 -0
- package/lib/constants/LOG_REVIEW_STATUS_ROUTE.js +14 -0
- package/lib/constants/LOG_REVIEW_STATUS_ROUTE.js.map +1 -0
- package/lib/constants/LOG_ROUTE_PATH.d.ts +6 -0
- package/lib/constants/LOG_ROUTE_PATH.js +13 -0
- package/lib/constants/LOG_ROUTE_PATH.js.map +1 -0
- package/lib/constants/ROUTE_PATH_PREFIX.d.ts +6 -0
- package/lib/constants/ROUTE_PATH_PREFIX.js +9 -0
- package/lib/constants/ROUTE_PATH_PREFIX.js.map +1 -0
- package/lib/errors/ErrorWithCode.d.ts +9 -0
- package/lib/errors/ErrorWithCode.js +33 -0
- package/lib/errors/ErrorWithCode.js.map +1 -0
- package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.d.ts +9 -0
- package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.js +17 -0
- package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.js.map +1 -0
- package/lib/helpers/addDBEditorEndpoints/index.d.ts +41 -0
- package/lib/helpers/addDBEditorEndpoints/index.js +134 -0
- package/lib/helpers/addDBEditorEndpoints/index.js.map +1 -0
- package/lib/helpers/dataSigner.d.ts +40 -0
- package/lib/helpers/dataSigner.js +242 -0
- package/lib/helpers/dataSigner.js.map +1 -0
- package/lib/helpers/genRouteHandler.d.ts +75 -0
- package/lib/helpers/genRouteHandler.js +662 -0
- package/lib/helpers/genRouteHandler.js.map +1 -0
- package/lib/helpers/getLogReviewerLogs.d.ts +27 -0
- package/lib/helpers/getLogReviewerLogs.js +238 -0
- package/lib/helpers/getLogReviewerLogs.js.map +1 -0
- package/lib/helpers/handleError.d.ts +18 -0
- package/lib/helpers/handleError.js +51 -0
- package/lib/helpers/handleError.js.map +1 -0
- package/lib/helpers/handleSuccess.d.ts +8 -0
- package/lib/helpers/handleSuccess.js +20 -0
- package/lib/helpers/handleSuccess.js.map +1 -0
- package/lib/helpers/initCrossServerCredentialCollection.d.ts +11 -0
- package/lib/helpers/initCrossServerCredentialCollection.js +15 -0
- package/lib/helpers/initCrossServerCredentialCollection.js.map +1 -0
- package/lib/helpers/initLogCollection.d.ts +11 -0
- package/lib/helpers/initLogCollection.js +26 -0
- package/lib/helpers/initLogCollection.js.map +1 -0
- package/lib/helpers/initServer.d.ts +45 -0
- package/lib/helpers/initServer.js +292 -0
- package/lib/helpers/initServer.js.map +1 -0
- package/lib/helpers/parseUserAgent.d.ts +17 -0
- package/lib/helpers/parseUserAgent.js +108 -0
- package/lib/helpers/parseUserAgent.js.map +1 -0
- package/lib/helpers/visitEndpointOnAnotherServer/index.d.ts +18 -0
- package/lib/helpers/visitEndpointOnAnotherServer/index.js +89 -0
- package/lib/helpers/visitEndpointOnAnotherServer/index.js.map +1 -0
- package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +23 -0
- package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.js +236 -0
- package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.js.map +1 -0
- package/lib/html/genErrorPage.d.ts +19 -0
- package/lib/html/genErrorPage.js +27 -0
- package/lib/html/genErrorPage.js.map +1 -0
- package/lib/html/genInfoPage.d.ts +13 -0
- package/lib/html/genInfoPage.js +16 -0
- package/lib/html/genInfoPage.js.map +1 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +68 -0
- package/lib/index.js.map +1 -0
- package/lib/types/CrossServerCredential.d.ts +11 -0
- package/lib/types/CrossServerCredential.js +3 -0
- package/lib/types/CrossServerCredential.js.map +1 -0
- package/lib/types/ExpressKitErrorCode.d.ts +31 -0
- package/lib/types/ExpressKitErrorCode.js +38 -0
- package/lib/types/ExpressKitErrorCode.js.map +1 -0
- package/package.json +53 -0
- package/src/constants/LOG_REVIEW_PAGE_SIZE.ts +7 -0
- package/src/errors/ErrorWithCode.tsx +15 -0
- package/src/helpers/addDBEditorEndpoints/generateEndpointPath.ts +16 -0
- package/src/helpers/addDBEditorEndpoints/index.ts +130 -0
- package/src/helpers/dataSigner.ts +319 -0
- package/src/helpers/genRouteHandler.ts +920 -0
- package/src/helpers/getLogReviewerLogs.ts +259 -0
- package/src/helpers/handleError.ts +66 -0
- package/src/helpers/handleSuccess.ts +18 -0
- package/src/helpers/initCrossServerCredentialCollection.ts +19 -0
- package/src/helpers/initLogCollection.ts +30 -0
- package/src/helpers/initServer.ts +283 -0
- package/src/helpers/parseUserAgent.ts +108 -0
- package/src/helpers/visitEndpointOnAnotherServer/index.ts +70 -0
- package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +257 -0
- package/src/html/genErrorPage.ts +144 -0
- package/src/html/genInfoPage.ts +101 -0
- package/src/index.ts +125 -0
- package/src/types/CrossServerCredential.ts +16 -0
- package/src/types/ExpressKitErrorCode.ts +37 -0
- 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,107 @@
|
|
|
1
|
+
// Import crypto lib
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
|
|
4
|
+
// Prompt
|
|
5
|
+
import readline from 'readline';
|
|
6
|
+
|
|
7
|
+
// Create a readline interface
|
|
8
|
+
const readlineInterface = readline.createInterface({
|
|
9
|
+
input: process.stdin,
|
|
10
|
+
output: process.stdout
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Prompt user for input
|
|
15
|
+
* @author Gabe Abrams
|
|
16
|
+
* @param question the question to ask the user
|
|
17
|
+
* @returns the text from the user
|
|
18
|
+
*/
|
|
19
|
+
const prompt = (question: string): Promise<string> => {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
readlineInterface.question(question, (answer: string) => {
|
|
22
|
+
if (!answer || answer.trim().length === 0) {
|
|
23
|
+
console.log('\nValue cannot be empty. Exiting...');
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
resolve(answer);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// All chars for randomizer
|
|
33
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
34
|
+
|
|
35
|
+
(async () => {
|
|
36
|
+
console.log('––––– Generate Encoded Secret –––––');
|
|
37
|
+
console.log('\nFirst, we need info on the *receiving* server');
|
|
38
|
+
console.log('This is the server that hosts the cross-server endpoint, the one that receives requests from the sending server.\n');
|
|
39
|
+
|
|
40
|
+
// Get salt
|
|
41
|
+
console.log('Encoding salt on the *receiving* server')
|
|
42
|
+
const salt = await prompt('Salt: ');
|
|
43
|
+
|
|
44
|
+
// Get host
|
|
45
|
+
console.log('Hostname of the *receiving* server');
|
|
46
|
+
const host = await prompt('Host: ');
|
|
47
|
+
|
|
48
|
+
console.log('\n\nSecond, we need info on the *sending* server');
|
|
49
|
+
console.log('This is the server that sends requests to the receiving server.\n');
|
|
50
|
+
|
|
51
|
+
// Get key
|
|
52
|
+
console.log('Short unique key for the *sending* server (only letters and dashes, no whitespace)')
|
|
53
|
+
const key = (await prompt('Key: ')).trim();
|
|
54
|
+
|
|
55
|
+
// Get description
|
|
56
|
+
console.log('Human-readable description of the *sending* server')
|
|
57
|
+
const description = await prompt('Description: ');
|
|
58
|
+
|
|
59
|
+
// Generate a random secret
|
|
60
|
+
let secret = '';
|
|
61
|
+
for (let i = 0; i < 32; i++) {
|
|
62
|
+
secret += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
63
|
+
}
|
|
64
|
+
secret = Buffer.from(secret).toString('base64');
|
|
65
|
+
|
|
66
|
+
// Encryption process based on:
|
|
67
|
+
// https://medium.com/@tony.infisical/guide-to-nodes-crypto-module-for-encryption-decryption-65c077176980
|
|
68
|
+
|
|
69
|
+
// Create a random initialization vector
|
|
70
|
+
const iv = crypto.randomBytes(12).toString('base64');
|
|
71
|
+
|
|
72
|
+
// Create a cipher
|
|
73
|
+
console.log('salt', salt, Buffer.from(salt, 'base64'));
|
|
74
|
+
const cipher = crypto.createCipheriv(
|
|
75
|
+
'aes-256-gcm',
|
|
76
|
+
Buffer.from(salt, 'base64'),
|
|
77
|
+
Buffer.from(iv, 'base64'),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// Encrypt the string
|
|
81
|
+
let ciphertext = cipher.update(secret, 'utf8', 'base64');
|
|
82
|
+
|
|
83
|
+
// Finalize the encryption
|
|
84
|
+
ciphertext += cipher.final('base64');
|
|
85
|
+
|
|
86
|
+
// Get the authentication tag
|
|
87
|
+
const tag = cipher.getAuthTag();
|
|
88
|
+
|
|
89
|
+
// JSONify the encrypted data
|
|
90
|
+
const encryptionPack = encodeURIComponent(JSON.stringify({
|
|
91
|
+
ciphertext,
|
|
92
|
+
iv,
|
|
93
|
+
tag,
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
// Show the encrypted data
|
|
97
|
+
console.log('\n\n');
|
|
98
|
+
console.log('––––– Done! What\'s Next: –––––');
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log('On the *sending* server, !!APPEND!! the following to the DCEKIT_CROSS_SERVER_CREDENTIALS env var:');
|
|
101
|
+
console.log(`|${host}:${key}:${secret}|`);
|
|
102
|
+
console.log('');
|
|
103
|
+
console.log('On the *receiving* server, add an entry to its "CrossServerCredential" collection:');
|
|
104
|
+
console.log(`{ "description": "${description}", "key": "${key}", "encodedeSecret": "${encryptionPack}", "scopes": [] }`);
|
|
105
|
+
console.log('');
|
|
106
|
+
console.log('For all scopes that the server should have access to, add them to the "scopes" array.');
|
|
107
|
+
})();
|
package/genSalt.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// All chars for randomizer
|
|
2
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
3
|
+
|
|
4
|
+
// Generate a random salt
|
|
5
|
+
let salt = '';
|
|
6
|
+
for (let i = 0; i < 32; i++) {
|
|
7
|
+
salt += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
8
|
+
}
|
|
9
|
+
salt = Buffer.from(salt).toString('base64');
|
|
10
|
+
|
|
11
|
+
// Generates 32 byte salt
|
|
12
|
+
console.log('New *receiving* server salt:')
|
|
13
|
+
|
|
14
|
+
Buffer.from("Hello World").toString('base64')
|
|
15
|
+
console.log(salt);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Log reviewer page size
|
|
5
|
+
* @author Yuen Ler Chow
|
|
6
|
+
*/
|
|
7
|
+
var LOG_REVIEW_PAGE_SIZE = 100;
|
|
8
|
+
exports.default = LOG_REVIEW_PAGE_SIZE;
|
|
9
|
+
//# sourceMappingURL=LOG_REVIEW_PAGE_SIZE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LOG_REVIEW_PAGE_SIZE.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_PAGE_SIZE.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,IAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,kBAAe,oBAAoB,CAAC"}
|
|
@@ -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,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,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,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,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"}
|