@naturalcycles/nodejs-lib 12.66.0 → 12.67.0
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/dist/bin/secrets-decrypt.js +13 -4
- package/dist/bin/secrets-encrypt.js +14 -4
- package/dist/secret/secrets-decrypt.util.d.ts +3 -2
- package/dist/secret/secrets-decrypt.util.js +24 -6
- package/dist/secret/secrets-encrypt.util.d.ts +3 -2
- package/dist/secret/secrets-encrypt.util.js +24 -9
- package/package.json +1 -1
- package/src/bin/secrets-decrypt.ts +13 -4
- package/src/bin/secrets-encrypt.ts +14 -4
- package/src/secret/secrets-decrypt.util.ts +38 -8
- package/src/secret/secrets-encrypt.util.ts +37 -11
|
@@ -6,18 +6,22 @@ const colors_1 = require("../colors");
|
|
|
6
6
|
const script_1 = require("../script");
|
|
7
7
|
const secrets_decrypt_util_1 = require("../secret/secrets-decrypt.util");
|
|
8
8
|
(0, script_1.runScript)(() => {
|
|
9
|
-
const { dir, encKey, del } = getDecryptCLIOptions();
|
|
10
|
-
(0, secrets_decrypt_util_1.secretsDecrypt)(dir, encKey, del);
|
|
9
|
+
const { dir, file, encKey, del, jsonMode } = getDecryptCLIOptions();
|
|
10
|
+
(0, secrets_decrypt_util_1.secretsDecrypt)(dir, file, encKey, del, jsonMode);
|
|
11
11
|
});
|
|
12
12
|
function getDecryptCLIOptions() {
|
|
13
13
|
require('dotenv').config();
|
|
14
|
-
let { dir, encKey, encKeyVar, del } = yargs.options({
|
|
14
|
+
let { dir, file, encKey, encKeyVar, del, jsonMode } = yargs.options({
|
|
15
15
|
dir: {
|
|
16
16
|
type: 'array',
|
|
17
17
|
desc: 'Directory with secrets. Can be many',
|
|
18
18
|
// demandOption: true,
|
|
19
19
|
default: './secret',
|
|
20
20
|
},
|
|
21
|
+
file: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
desc: 'Single file to decrypt. Useful in jsonMode',
|
|
24
|
+
},
|
|
21
25
|
encKey: {
|
|
22
26
|
type: 'string',
|
|
23
27
|
desc: 'Encryption key',
|
|
@@ -37,6 +41,11 @@ function getDecryptCLIOptions() {
|
|
|
37
41
|
type: 'boolean',
|
|
38
42
|
desc: 'Delete source files after encryption/decryption. Be careful!',
|
|
39
43
|
},
|
|
44
|
+
jsonMode: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
desc: 'JSON mode. Encrypts only json values, not the whole file',
|
|
47
|
+
default: false,
|
|
48
|
+
},
|
|
40
49
|
}).argv;
|
|
41
50
|
if (!encKey) {
|
|
42
51
|
encKey = process.env[encKeyVar];
|
|
@@ -48,5 +57,5 @@ function getDecryptCLIOptions() {
|
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
// `as any` because @types/yargs can't handle string[] type properly
|
|
51
|
-
return { dir: dir, encKey, del };
|
|
60
|
+
return { dir: dir, file, encKey, del, jsonMode };
|
|
52
61
|
}
|
|
@@ -6,12 +6,12 @@ const colors_1 = require("../colors");
|
|
|
6
6
|
const script_1 = require("../script");
|
|
7
7
|
const secrets_encrypt_util_1 = require("../secret/secrets-encrypt.util");
|
|
8
8
|
(0, script_1.runScript)(() => {
|
|
9
|
-
const { pattern, encKey, del } = getEncryptCLIOptions();
|
|
10
|
-
(0, secrets_encrypt_util_1.secretsEncrypt)(pattern, encKey, del);
|
|
9
|
+
const { pattern, file, encKey, del, jsonMode } = getEncryptCLIOptions();
|
|
10
|
+
(0, secrets_encrypt_util_1.secretsEncrypt)(pattern, file, encKey, del, jsonMode);
|
|
11
11
|
});
|
|
12
12
|
function getEncryptCLIOptions() {
|
|
13
13
|
require('dotenv').config();
|
|
14
|
-
let { pattern, encKey, encKeyVar, del } = yargs.options({
|
|
14
|
+
let { pattern, file, encKey, encKeyVar, del, jsonMode } = yargs.options({
|
|
15
15
|
pattern: {
|
|
16
16
|
type: 'string',
|
|
17
17
|
array: true,
|
|
@@ -19,6 +19,10 @@ function getEncryptCLIOptions() {
|
|
|
19
19
|
// demandOption: true,
|
|
20
20
|
default: './secret/**',
|
|
21
21
|
},
|
|
22
|
+
file: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
desc: 'Single file to decrypt. Useful in jsonMode',
|
|
25
|
+
},
|
|
22
26
|
encKey: {
|
|
23
27
|
type: 'string',
|
|
24
28
|
desc: 'Encryption key',
|
|
@@ -37,6 +41,12 @@ function getEncryptCLIOptions() {
|
|
|
37
41
|
del: {
|
|
38
42
|
type: 'boolean',
|
|
39
43
|
desc: 'Delete source files after encryption/decryption. Be careful!',
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
jsonMode: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
desc: 'JSON mode. Encrypts only json values, not the whole file',
|
|
49
|
+
default: false,
|
|
40
50
|
},
|
|
41
51
|
}).argv;
|
|
42
52
|
if (!encKey) {
|
|
@@ -49,5 +59,5 @@ function getEncryptCLIOptions() {
|
|
|
49
59
|
}
|
|
50
60
|
}
|
|
51
61
|
// `as any` because @types/yargs can't handle string[] type properly
|
|
52
|
-
return { pattern: pattern, encKey, del };
|
|
62
|
+
return { pattern: pattern, file, encKey, del, jsonMode };
|
|
53
63
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export interface DecryptCLIOptions {
|
|
2
2
|
dir: string[];
|
|
3
|
+
file?: string;
|
|
3
4
|
encKey: string;
|
|
4
|
-
algorithm?: string;
|
|
5
5
|
del?: boolean;
|
|
6
|
+
jsonMode?: boolean;
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* Decrypts all files in given directory (*.enc), saves decrypted versions without ending `.enc`.
|
|
9
10
|
* Using provided encKey.
|
|
10
11
|
*/
|
|
11
|
-
export declare function secretsDecrypt(dir: string[], encKey: string, del?: boolean): void;
|
|
12
|
+
export declare function secretsDecrypt(dir: string[], file: string | undefined, encKey: string, del?: boolean, jsonMode?: boolean): void;
|
|
@@ -2,22 +2,40 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.secretsDecrypt = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
|
+
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
6
|
const fs = require("fs-extra");
|
|
6
7
|
const globby = require("globby");
|
|
7
8
|
const colors_1 = require("../colors");
|
|
8
9
|
const crypto_util_1 = require("../security/crypto.util");
|
|
10
|
+
// Debug it like this:
|
|
11
|
+
// yarn tsn ./src/bin/secrets-decrypt.ts --file ./src/test/secrets2.json --jsonMode --encKey MPd/30v0Zcce4I5mfwF4NSXrpTYD9OO4/fIqw6rjNiWp2b1GN9Xm8nQZqr7c9kKSsATqtwe0HkJFDUGzDSow44GDgDICgB1u1rGa5eNqtxnOVGRR+lIinCvN/1OnpjzeoJy2bStXPj1DKx8anMqgA8SoOZdlWRNSkEeZlolru8Ey0ujZo22dfwMyRIEniLcqvBm/iMiAkV82fn/TxYw05GarAoJcrfPeDBvuOXsARnMCyX18qTFL0iojxeTU8JHxr8TX3eXDq9cJJmridEKlwRIAzADwtetI4ttlP8lwJj1pmgsBIN3iqYssZYCkZ3HMV6BoEc7LTI5z/45rKrAT1A==
|
|
12
|
+
// yarn tsn ./src/bin/secrets-encrypt.ts --file ./src/test/secrets2.plain.json --jsonMode --encKey MPd/30v0Zcce4I5mfwF4NSXrpTYD9OO4/fIqw6rjNiWp2b1GN9Xm8nQZqr7c9kKSsATqtwe0HkJFDUGzDSow44GDgDICgB1u1rGa5eNqtxnOVGRR+lIinCvN/1OnpjzeoJy2bStXPj1DKx8anMqgA8SoOZdlWRNSkEeZlolru8Ey0ujZo22dfwMyRIEniLcqvBm/iMiAkV82fn/TxYw05GarAoJcrfPeDBvuOXsARnMCyX18qTFL0iojxeTU8JHxr8TX3eXDq9cJJmridEKlwRIAzADwtetI4ttlP8lwJj1pmgsBIN3iqYssZYCkZ3HMV6BoEc7LTI5z/45rKrAT1A==
|
|
9
13
|
/**
|
|
10
14
|
* Decrypts all files in given directory (*.enc), saves decrypted versions without ending `.enc`.
|
|
11
15
|
* Using provided encKey.
|
|
12
16
|
*/
|
|
13
|
-
function secretsDecrypt(dir, encKey, del) {
|
|
14
|
-
|
|
17
|
+
function secretsDecrypt(dir, file, encKey, del = false, jsonMode = false) {
|
|
18
|
+
// If `file` is provided - only this one file is used
|
|
19
|
+
const patterns = file ? [file] : dir.map(d => `${d}/**/*.enc`);
|
|
15
20
|
const filenames = globby.sync(patterns);
|
|
16
21
|
filenames.forEach(filename => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
let plainFilename;
|
|
23
|
+
if (jsonMode) {
|
|
24
|
+
(0, js_lib_1._assert)(filename.endsWith('.json'), `${path.basename(filename)} MUST end with '.json'`);
|
|
25
|
+
(0, js_lib_1._assert)(!filename.endsWith('.plain.json'), `${path.basename(filename)} MUST NOT end with '.plain.json'`);
|
|
26
|
+
plainFilename = filename.replace('.json', '.plain.json');
|
|
27
|
+
const json = JSON.parse(fs.readFileSync(filename, 'utf8'));
|
|
28
|
+
(0, js_lib_1._stringMapEntries)(json).forEach(([k, v]) => {
|
|
29
|
+
json[k] = (0, crypto_util_1.decryptString)(v, encKey);
|
|
30
|
+
});
|
|
31
|
+
fs.writeFileSync(plainFilename, JSON.stringify(json, null, 2));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const enc = fs.readFileSync(filename);
|
|
35
|
+
const plain = (0, crypto_util_1.decryptRandomIVBuffer)(enc, encKey);
|
|
36
|
+
plainFilename = filename.slice(0, filename.length - '.enc'.length);
|
|
37
|
+
fs.writeFileSync(plainFilename, plain);
|
|
38
|
+
}
|
|
21
39
|
if (del) {
|
|
22
40
|
fs.unlinkSync(filename);
|
|
23
41
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export interface EncryptCLIOptions {
|
|
2
2
|
pattern: string[];
|
|
3
|
+
file?: string;
|
|
3
4
|
encKey: string;
|
|
4
|
-
algorithm?: string;
|
|
5
5
|
del?: boolean;
|
|
6
|
+
jsonMode?: boolean;
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* Encrypts all files in given directory (except *.enc), saves encrypted versions as filename.ext.enc.
|
|
9
10
|
* Using provided encKey.
|
|
10
11
|
*/
|
|
11
|
-
export declare function secretsEncrypt(pattern: string[], encKey: string, del?: boolean): void;
|
|
12
|
+
export declare function secretsEncrypt(pattern: string[], file: string | undefined, encKey: string, del?: boolean, jsonMode?: boolean): void;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.secretsEncrypt = void 0;
|
|
4
4
|
const path = require("path");
|
|
5
|
+
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
6
|
const fs = require("fs-extra");
|
|
6
7
|
const globby = require("globby");
|
|
7
8
|
const colors_1 = require("../colors");
|
|
@@ -10,17 +11,31 @@ const crypto_util_1 = require("../security/crypto.util");
|
|
|
10
11
|
* Encrypts all files in given directory (except *.enc), saves encrypted versions as filename.ext.enc.
|
|
11
12
|
* Using provided encKey.
|
|
12
13
|
*/
|
|
13
|
-
function secretsEncrypt(pattern, encKey, del) {
|
|
14
|
-
const patterns =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
function secretsEncrypt(pattern, file, encKey, del = false, jsonMode = false) {
|
|
15
|
+
const patterns = file
|
|
16
|
+
? [file]
|
|
17
|
+
: [
|
|
18
|
+
...pattern,
|
|
19
|
+
`!**/*.enc`, // excluding already encoded
|
|
20
|
+
];
|
|
18
21
|
const filenames = globby.sync(patterns);
|
|
22
|
+
let encFilename;
|
|
19
23
|
filenames.forEach(filename => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
if (jsonMode) {
|
|
25
|
+
(0, js_lib_1._assert)(filename.endsWith('.plain.json'), `${path.basename(filename)} MUST end with '.plain.json'`);
|
|
26
|
+
encFilename = filename.replace('.plain', '');
|
|
27
|
+
const json = JSON.parse(fs.readFileSync(filename, 'utf8'));
|
|
28
|
+
(0, js_lib_1._stringMapEntries)(json).forEach(([k, plain]) => {
|
|
29
|
+
json[k] = (0, crypto_util_1.encryptString)(plain, encKey);
|
|
30
|
+
});
|
|
31
|
+
fs.writeFileSync(encFilename, JSON.stringify(json, null, 2));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const plain = fs.readFileSync(filename);
|
|
35
|
+
const enc = (0, crypto_util_1.encryptRandomIVBuffer)(plain, encKey);
|
|
36
|
+
encFilename = `${filename}.enc`;
|
|
37
|
+
fs.writeFileSync(encFilename, enc);
|
|
38
|
+
}
|
|
24
39
|
if (del) {
|
|
25
40
|
fs.unlinkSync(filename);
|
|
26
41
|
}
|
package/package.json
CHANGED
|
@@ -6,21 +6,25 @@ import { runScript } from '../script'
|
|
|
6
6
|
import { DecryptCLIOptions, secretsDecrypt } from '../secret/secrets-decrypt.util'
|
|
7
7
|
|
|
8
8
|
runScript(() => {
|
|
9
|
-
const { dir, encKey, del } = getDecryptCLIOptions()
|
|
9
|
+
const { dir, file, encKey, del, jsonMode } = getDecryptCLIOptions()
|
|
10
10
|
|
|
11
|
-
secretsDecrypt(dir, encKey, del)
|
|
11
|
+
secretsDecrypt(dir, file, encKey, del, jsonMode)
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
function getDecryptCLIOptions(): DecryptCLIOptions {
|
|
15
15
|
require('dotenv').config()
|
|
16
16
|
|
|
17
|
-
let { dir, encKey, encKeyVar, del } = yargs.options({
|
|
17
|
+
let { dir, file, encKey, encKeyVar, del, jsonMode } = yargs.options({
|
|
18
18
|
dir: {
|
|
19
19
|
type: 'array',
|
|
20
20
|
desc: 'Directory with secrets. Can be many',
|
|
21
21
|
// demandOption: true,
|
|
22
22
|
default: './secret',
|
|
23
23
|
},
|
|
24
|
+
file: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
desc: 'Single file to decrypt. Useful in jsonMode',
|
|
27
|
+
},
|
|
24
28
|
encKey: {
|
|
25
29
|
type: 'string',
|
|
26
30
|
desc: 'Encryption key',
|
|
@@ -40,6 +44,11 @@ function getDecryptCLIOptions(): DecryptCLIOptions {
|
|
|
40
44
|
type: 'boolean',
|
|
41
45
|
desc: 'Delete source files after encryption/decryption. Be careful!',
|
|
42
46
|
},
|
|
47
|
+
jsonMode: {
|
|
48
|
+
type: 'boolean',
|
|
49
|
+
desc: 'JSON mode. Encrypts only json values, not the whole file',
|
|
50
|
+
default: false,
|
|
51
|
+
},
|
|
43
52
|
}).argv
|
|
44
53
|
|
|
45
54
|
if (!encKey) {
|
|
@@ -55,5 +64,5 @@ function getDecryptCLIOptions(): DecryptCLIOptions {
|
|
|
55
64
|
}
|
|
56
65
|
|
|
57
66
|
// `as any` because @types/yargs can't handle string[] type properly
|
|
58
|
-
return { dir: dir as any, encKey, del }
|
|
67
|
+
return { dir: dir as any, file, encKey, del, jsonMode }
|
|
59
68
|
}
|
|
@@ -6,15 +6,15 @@ import { runScript } from '../script'
|
|
|
6
6
|
import { EncryptCLIOptions, secretsEncrypt } from '../secret/secrets-encrypt.util'
|
|
7
7
|
|
|
8
8
|
runScript(() => {
|
|
9
|
-
const { pattern, encKey, del } = getEncryptCLIOptions()
|
|
9
|
+
const { pattern, file, encKey, del, jsonMode } = getEncryptCLIOptions()
|
|
10
10
|
|
|
11
|
-
secretsEncrypt(pattern, encKey, del)
|
|
11
|
+
secretsEncrypt(pattern, file, encKey, del, jsonMode)
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
function getEncryptCLIOptions(): EncryptCLIOptions {
|
|
15
15
|
require('dotenv').config()
|
|
16
16
|
|
|
17
|
-
let { pattern, encKey, encKeyVar, del } = yargs.options({
|
|
17
|
+
let { pattern, file, encKey, encKeyVar, del, jsonMode } = yargs.options({
|
|
18
18
|
pattern: {
|
|
19
19
|
type: 'string',
|
|
20
20
|
array: true,
|
|
@@ -22,6 +22,10 @@ function getEncryptCLIOptions(): EncryptCLIOptions {
|
|
|
22
22
|
// demandOption: true,
|
|
23
23
|
default: './secret/**',
|
|
24
24
|
},
|
|
25
|
+
file: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
desc: 'Single file to decrypt. Useful in jsonMode',
|
|
28
|
+
},
|
|
25
29
|
encKey: {
|
|
26
30
|
type: 'string',
|
|
27
31
|
desc: 'Encryption key',
|
|
@@ -40,6 +44,12 @@ function getEncryptCLIOptions(): EncryptCLIOptions {
|
|
|
40
44
|
del: {
|
|
41
45
|
type: 'boolean',
|
|
42
46
|
desc: 'Delete source files after encryption/decryption. Be careful!',
|
|
47
|
+
default: false,
|
|
48
|
+
},
|
|
49
|
+
jsonMode: {
|
|
50
|
+
type: 'boolean',
|
|
51
|
+
desc: 'JSON mode. Encrypts only json values, not the whole file',
|
|
52
|
+
default: false,
|
|
43
53
|
},
|
|
44
54
|
}).argv
|
|
45
55
|
|
|
@@ -56,5 +66,5 @@ function getEncryptCLIOptions(): EncryptCLIOptions {
|
|
|
56
66
|
}
|
|
57
67
|
|
|
58
68
|
// `as any` because @types/yargs can't handle string[] type properly
|
|
59
|
-
return { pattern: pattern as any, encKey, del }
|
|
69
|
+
return { pattern: pattern as any, file, encKey, del, jsonMode }
|
|
60
70
|
}
|
|
@@ -1,31 +1,61 @@
|
|
|
1
1
|
import * as path from 'path'
|
|
2
|
+
import { _assert, _stringMapEntries, StringMap } from '@naturalcycles/js-lib'
|
|
2
3
|
import * as fs from 'fs-extra'
|
|
3
4
|
import globby = require('globby')
|
|
4
5
|
import { dimGrey, yellow } from '../colors'
|
|
5
|
-
import { decryptRandomIVBuffer } from '../security/crypto.util'
|
|
6
|
+
import { decryptRandomIVBuffer, decryptString } from '../security/crypto.util'
|
|
6
7
|
|
|
7
8
|
export interface DecryptCLIOptions {
|
|
8
9
|
dir: string[]
|
|
10
|
+
file?: string
|
|
9
11
|
encKey: string
|
|
10
|
-
algorithm?: string
|
|
11
12
|
del?: boolean
|
|
13
|
+
jsonMode?: boolean
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
// Debug it like this:
|
|
17
|
+
// yarn tsn ./src/bin/secrets-decrypt.ts --file ./src/test/secrets2.json --jsonMode --encKey MPd/30v0Zcce4I5mfwF4NSXrpTYD9OO4/fIqw6rjNiWp2b1GN9Xm8nQZqr7c9kKSsATqtwe0HkJFDUGzDSow44GDgDICgB1u1rGa5eNqtxnOVGRR+lIinCvN/1OnpjzeoJy2bStXPj1DKx8anMqgA8SoOZdlWRNSkEeZlolru8Ey0ujZo22dfwMyRIEniLcqvBm/iMiAkV82fn/TxYw05GarAoJcrfPeDBvuOXsARnMCyX18qTFL0iojxeTU8JHxr8TX3eXDq9cJJmridEKlwRIAzADwtetI4ttlP8lwJj1pmgsBIN3iqYssZYCkZ3HMV6BoEc7LTI5z/45rKrAT1A==
|
|
18
|
+
// yarn tsn ./src/bin/secrets-encrypt.ts --file ./src/test/secrets2.plain.json --jsonMode --encKey MPd/30v0Zcce4I5mfwF4NSXrpTYD9OO4/fIqw6rjNiWp2b1GN9Xm8nQZqr7c9kKSsATqtwe0HkJFDUGzDSow44GDgDICgB1u1rGa5eNqtxnOVGRR+lIinCvN/1OnpjzeoJy2bStXPj1DKx8anMqgA8SoOZdlWRNSkEeZlolru8Ey0ujZo22dfwMyRIEniLcqvBm/iMiAkV82fn/TxYw05GarAoJcrfPeDBvuOXsARnMCyX18qTFL0iojxeTU8JHxr8TX3eXDq9cJJmridEKlwRIAzADwtetI4ttlP8lwJj1pmgsBIN3iqYssZYCkZ3HMV6BoEc7LTI5z/45rKrAT1A==
|
|
19
|
+
|
|
14
20
|
/**
|
|
15
21
|
* Decrypts all files in given directory (*.enc), saves decrypted versions without ending `.enc`.
|
|
16
22
|
* Using provided encKey.
|
|
17
23
|
*/
|
|
18
|
-
export function secretsDecrypt(
|
|
19
|
-
|
|
24
|
+
export function secretsDecrypt(
|
|
25
|
+
dir: string[],
|
|
26
|
+
file: string | undefined,
|
|
27
|
+
encKey: string,
|
|
28
|
+
del = false,
|
|
29
|
+
jsonMode = false,
|
|
30
|
+
): void {
|
|
31
|
+
// If `file` is provided - only this one file is used
|
|
32
|
+
const patterns = file ? [file] : dir.map(d => `${d}/**/*.enc`)
|
|
20
33
|
|
|
21
34
|
const filenames = globby.sync(patterns)
|
|
22
35
|
|
|
23
36
|
filenames.forEach(filename => {
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
let plainFilename
|
|
38
|
+
|
|
39
|
+
if (jsonMode) {
|
|
40
|
+
_assert(filename.endsWith('.json'), `${path.basename(filename)} MUST end with '.json'`)
|
|
41
|
+
_assert(
|
|
42
|
+
!filename.endsWith('.plain.json'),
|
|
43
|
+
`${path.basename(filename)} MUST NOT end with '.plain.json'`,
|
|
44
|
+
)
|
|
45
|
+
plainFilename = filename.replace('.json', '.plain.json')
|
|
26
46
|
|
|
27
|
-
|
|
28
|
-
|
|
47
|
+
const json: StringMap = JSON.parse(fs.readFileSync(filename, 'utf8'))
|
|
48
|
+
_stringMapEntries(json).forEach(([k, v]) => {
|
|
49
|
+
json[k] = decryptString(v, encKey)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
fs.writeFileSync(plainFilename, JSON.stringify(json, null, 2))
|
|
53
|
+
} else {
|
|
54
|
+
const enc = fs.readFileSync(filename)
|
|
55
|
+
const plain = decryptRandomIVBuffer(enc, encKey)
|
|
56
|
+
plainFilename = filename.slice(0, filename.length - '.enc'.length)
|
|
57
|
+
fs.writeFileSync(plainFilename, plain)
|
|
58
|
+
}
|
|
29
59
|
|
|
30
60
|
if (del) {
|
|
31
61
|
fs.unlinkSync(filename)
|
|
@@ -1,33 +1,59 @@
|
|
|
1
1
|
import * as path from 'path'
|
|
2
|
+
import { _assert, _stringMapEntries, StringMap } from '@naturalcycles/js-lib'
|
|
2
3
|
import * as fs from 'fs-extra'
|
|
3
4
|
import globby = require('globby')
|
|
4
5
|
import { dimGrey, yellow } from '../colors'
|
|
5
|
-
import { encryptRandomIVBuffer } from '../security/crypto.util'
|
|
6
|
+
import { encryptRandomIVBuffer, encryptString } from '../security/crypto.util'
|
|
6
7
|
|
|
7
8
|
export interface EncryptCLIOptions {
|
|
8
9
|
pattern: string[]
|
|
10
|
+
file?: string
|
|
9
11
|
encKey: string
|
|
10
|
-
algorithm?: string
|
|
11
12
|
del?: boolean
|
|
13
|
+
jsonMode?: boolean
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Encrypts all files in given directory (except *.enc), saves encrypted versions as filename.ext.enc.
|
|
16
18
|
* Using provided encKey.
|
|
17
19
|
*/
|
|
18
|
-
export function secretsEncrypt(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
export function secretsEncrypt(
|
|
21
|
+
pattern: string[],
|
|
22
|
+
file: string | undefined,
|
|
23
|
+
encKey: string,
|
|
24
|
+
del = false,
|
|
25
|
+
jsonMode = false,
|
|
26
|
+
): void {
|
|
27
|
+
const patterns = file
|
|
28
|
+
? [file]
|
|
29
|
+
: [
|
|
30
|
+
...pattern,
|
|
31
|
+
`!**/*.enc`, // excluding already encoded
|
|
32
|
+
]
|
|
23
33
|
const filenames = globby.sync(patterns)
|
|
34
|
+
let encFilename
|
|
24
35
|
|
|
25
36
|
filenames.forEach(filename => {
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
if (jsonMode) {
|
|
38
|
+
_assert(
|
|
39
|
+
filename.endsWith('.plain.json'),
|
|
40
|
+
`${path.basename(filename)} MUST end with '.plain.json'`,
|
|
41
|
+
)
|
|
42
|
+
encFilename = filename.replace('.plain', '')
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
const json: StringMap = JSON.parse(fs.readFileSync(filename, 'utf8'))
|
|
45
|
+
|
|
46
|
+
_stringMapEntries(json).forEach(([k, plain]) => {
|
|
47
|
+
json[k] = encryptString(plain, encKey)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
fs.writeFileSync(encFilename, JSON.stringify(json, null, 2))
|
|
51
|
+
} else {
|
|
52
|
+
const plain = fs.readFileSync(filename)
|
|
53
|
+
const enc = encryptRandomIVBuffer(plain, encKey)
|
|
54
|
+
encFilename = `${filename}.enc`
|
|
55
|
+
fs.writeFileSync(encFilename, enc)
|
|
56
|
+
}
|
|
31
57
|
|
|
32
58
|
if (del) {
|
|
33
59
|
fs.unlinkSync(filename)
|