dce-reactkit 3.12.1-beta-cross-server.4 → 3.12.1-beta-cross-server.5

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.
@@ -1,5 +1,5 @@
1
1
  // Import crypto lib
2
- import Cryptr from 'cryptr';
2
+ import crypto from 'crypto';
3
3
 
4
4
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
5
5
 
@@ -42,9 +42,34 @@ if (!host) {
42
42
  process.exit(1);
43
43
  }
44
44
 
45
- // Encrypt the secret
46
- const cryptr = new Cryptr(REACTKIT_CRED_ENCODING_SALT);
47
- const encodedSecret = cryptr.encrypt(secret);
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
+ }));
48
73
 
49
74
  // Show the encrypted data
50
75
  console.log('\n\n');
@@ -54,6 +79,6 @@ console.log('On the server *sending* the requests, append the following to the R
54
79
  console.log(`|${host}:${key}:${secret}|`);
55
80
  console.log('');
56
81
  console.log('On the server *receiving* the requests, add an entry to the "CrossServerCredential" collection:');
57
- console.log(`{ "description": "${description}", "key": "${key}", "encodedeSecret": "${encodedSecret}", "scopes": [] }`);
82
+ console.log(`{ "description": "${description}", "key": "${key}", "encodedeSecret": "${encryptionPack}", "scopes": [] }`);
58
83
  console.log('');
59
84
  console.log('For all scopes that the server should have access to, add them to the "scopes" array.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.12.1-beta-cross-server.4",
3
+ "version": "3.12.1-beta-cross-server.5",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -25,6 +25,7 @@
25
25
  },
26
26
  "homepage": "https://github.com/harvard-edtech/dce-reactkit#readme",
27
27
  "dependencies": {
28
+ "crypto-browserify": "^3.12.1",
28
29
  "cryptr": "^6.3.0",
29
30
  "qs": "^6.x.x",
30
31
  "react-select": "^5.7.3"
@@ -1,6 +1,3 @@
1
- // Import cryptography lib
2
- import Cryptr from 'cryptr';
3
-
4
1
  // Import shared helpers
5
2
  // eslint-disable-next-line import/no-cycle
6
3
  import { internalGetCrossServerCredentialCollection } from '../server/initServer';
@@ -38,6 +35,27 @@ const getOauthLib = async () => {
38
35
  }
39
36
  };
40
37
 
38
+ /**
39
+ * Get a copy of the crypto lib
40
+ * @author Gabe Abrams
41
+ * @return the crypto lib
42
+ */
43
+ const getCryptoLib = async () => {
44
+ // Get the crypto library (included on the server)
45
+ // Ignore because this is assumed to be included with typescript
46
+ // @ts-ignore
47
+ try {
48
+ // @ts-ignore
49
+ const crypto = (await import('crypto-browserify') as any);
50
+ return crypto;
51
+ } catch (err) {
52
+ throw new ErrorWithCode(
53
+ 'Could not sign a cross-server request because we could not load the crypto library. Please make sure this operation is running on the server.',
54
+ ReactKitErrorCode.NoCryptoLib,
55
+ );
56
+ }
57
+ };
58
+
41
59
  /*------------------------------------------------------------------------*/
42
60
  /* ------------------------------- Helpers ------------------------------ */
43
61
  /*------------------------------------------------------------------------*/
@@ -105,6 +123,9 @@ const genSignature = async (
105
123
  const decrypt = async (
106
124
  encryptedPack: string,
107
125
  ): Promise<string> => {
126
+ // Decryption process based on:
127
+ // https://medium.com/@tony.infisical/guide-to-nodes-crypto-module-for-encryption-decryption-65c077176980
128
+
108
129
  // Get the encryption secret
109
130
  const { REACTKIT_CRED_ENCODING_SALT } = process.env;
110
131
  if (!REACTKIT_CRED_ENCODING_SALT) {
@@ -114,9 +135,29 @@ const decrypt = async (
114
135
  );
115
136
  }
116
137
 
138
+ // Get the crypto library
139
+ const crypto = await getCryptoLib();
140
+
141
+ // Separate encrypted pack
142
+ const {
143
+ ciphertext,
144
+ iv,
145
+ tag,
146
+ } = JSON.parse(decodeURIComponent(encryptedPack));
147
+
148
+ // Parse the encrypted data
149
+ const decipher = crypto.createDecipheriv(
150
+ 'aes-256-gcm',
151
+ Buffer.from(REACTKIT_CRED_ENCODING_SALT, 'base64'),
152
+ Buffer.from(iv, 'base64'),
153
+ );
154
+
155
+ // Set the authentication tag
156
+ decipher.setAuthTag(Buffer.from(tag, 'base64'));
157
+
117
158
  // Decrypt the string
118
- const cryptr = new Cryptr(REACTKIT_CRED_ENCODING_SALT);
119
- const str = cryptr.decrypt(encryptedPack);
159
+ let str = decipher.update(ciphertext, 'base64', 'utf8');
160
+ str += decipher.final('utf8');
120
161
 
121
162
  // Return the decrypted string
122
163
  return str;