UNPKG

2.85 kBPlain TextView Raw
1import * as path from 'path'
2import { _assert, _stringMapEntries, StringMap } from '@naturalcycles/js-lib'
3import * as fs from 'fs-extra'
4import globby = require('globby')
5import { dimGrey, yellow } from '../colors'
6import { decryptRandomIVBuffer, decryptString } from '../security/crypto.util'
7
8export interface DecryptCLIOptions {
9 dir: string[]
10 file?: string
11 encKey: string
12 del?: boolean
13 jsonMode?: boolean
14}
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
20/**
21 * Decrypts all files in given directory (*.enc), saves decrypted versions without ending `.enc`.
22 * Using provided encKey.
23 */
24export 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`)
33
34 const filenames = globby.sync(patterns)
35
36 filenames.forEach(filename => {
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')
46
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 }
59
60 if (del) {
61 fs.unlinkSync(filename)
62 }
63
64 console.log(` ${path.basename(filename)} > ${path.basename(plainFilename)}`)
65 })
66
67 console.log(`decrypted ${yellow(filenames.length)} files in ${dimGrey(dir.join(' '))}`)
68}