dce-expresskit 4.0.0-beta.2 → 4.0.0-beta.4
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/genEncodedSecret.ts +98 -75
- package/genSalt.ts +15 -0
- package/package.json +3 -2
package/genEncodedSecret.ts
CHANGED
|
@@ -1,84 +1,107 @@
|
|
|
1
1
|
// Import crypto lib
|
|
2
2
|
import crypto from 'crypto';
|
|
3
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
|
|
4
33
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
5
34
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
console.log('
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
console.log('
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
console.log('
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
+
|
|
30
59
|
// Generate a random secret
|
|
31
|
-
secret = '';
|
|
60
|
+
let secret = '';
|
|
32
61
|
for (let i = 0; i < 32; i++) {
|
|
33
62
|
secret += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
34
63
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
ciphertext
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
console.log(
|
|
76
|
-
console.log('
|
|
77
|
-
console.log('');
|
|
78
|
-
|
|
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.');
|
|
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);
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dce-expresskit",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.4",
|
|
4
4
|
"description": "Shared functions, helpers, and tools for Harvard DCE Express-based servers",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc --project ./tsconfig.json",
|
|
9
|
-
"gen-cross-server-secret": "npx tsx genEncodedSecret.ts"
|
|
9
|
+
"gen-cross-server-secret": "npx tsx genEncodedSecret.ts",
|
|
10
|
+
"gen-cross-server-salt": "npx tsx genSalt.ts"
|
|
10
11
|
},
|
|
11
12
|
"repository": {
|
|
12
13
|
"type": "git",
|