@dotenvx/dotenvx 1.55.1 → 1.57.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/CHANGELOG.md +18 -1
- package/README.md +43 -45
- package/package.json +3 -3
- package/src/cli/actions/decrypt.js +2 -2
- package/src/cli/actions/encrypt.js +10 -14
- package/src/cli/actions/ext/genexample.js +3 -2
- package/src/cli/actions/ext/gitignore.js +2 -2
- package/src/cli/actions/get.js +4 -2
- package/src/cli/actions/keypair.js +3 -2
- package/src/cli/actions/rotate.js +19 -21
- package/src/cli/actions/run.js +1 -14
- package/src/cli/actions/set.js +16 -16
- package/src/cli/commands/ext.js +0 -3
- package/src/cli/dotenvx.js +29 -25
- package/src/cli/examples.js +2 -2
- package/src/db/session.js +21 -0
- package/src/lib/extensions/ops.js +98 -0
- package/src/lib/helpers/buildEnvs.js +2 -15
- package/src/lib/helpers/{decryptKeyValue.js → cryptography/decryptKeyValue.js} +1 -1
- package/src/lib/helpers/cryptography/index.js +14 -0
- package/src/lib/helpers/{isPublicKey.js → cryptography/isPublicKey.js} +1 -1
- package/src/lib/helpers/{keypair.js → cryptography/localKeypair.js} +2 -2
- package/src/lib/helpers/cryptography/mutateKeysSrc.js +38 -0
- package/src/lib/helpers/cryptography/mutateSrc.js +24 -0
- package/src/lib/helpers/cryptography/opsKeypair.js +14 -0
- package/src/lib/helpers/cryptography/provision.js +47 -0
- package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +26 -0
- package/src/lib/helpers/envResolution/determine.js +46 -0
- package/src/lib/helpers/{guessEnvironment.js → envResolution/environment.js} +4 -6
- package/src/lib/helpers/envResolution/index.js +8 -0
- package/src/lib/helpers/errors.js +13 -0
- package/src/lib/helpers/executeDynamic.js +11 -14
- package/src/lib/helpers/findEnvFiles.js +1 -1
- package/src/lib/helpers/isFullyEncrypted.js +3 -3
- package/src/lib/helpers/keyResolution/index.js +13 -0
- package/src/lib/helpers/keyResolution/keyNames.js +24 -0
- package/src/lib/helpers/keyResolution/keyValues.js +85 -0
- package/src/lib/helpers/keyResolution/readFileKey.js +15 -0
- package/src/lib/helpers/keyResolution/readProcessKey.js +7 -0
- package/src/lib/helpers/localDisplayPath.js +11 -0
- package/src/lib/helpers/parse.js +1 -1
- package/src/lib/helpers/prependPublicKey.js +17 -0
- package/src/lib/helpers/preserveShebang.js +16 -0
- package/src/lib/main.d.ts +19 -3
- package/src/lib/main.js +23 -32
- package/src/lib/services/decrypt.js +23 -19
- package/src/lib/services/encrypt.js +41 -136
- package/src/lib/services/get.js +3 -3
- package/src/lib/services/keypair.js +12 -16
- package/src/lib/services/prebuild.js +2 -2
- package/src/lib/services/precommit.js +2 -2
- package/src/lib/services/rotate.js +59 -42
- package/src/lib/services/run.js +29 -112
- package/src/lib/services/sets.js +40 -124
- package/src/shared/colors.js +10 -0
- package/src/shared/logger.js +4 -3
- package/src/lib/helpers/decrypt.js +0 -31
- package/src/lib/helpers/deprecationNotice.js +0 -17
- package/src/lib/helpers/determineEnvs.js +0 -65
- package/src/lib/helpers/encrypt.js +0 -29
- package/src/lib/helpers/findPrivateKey.js +0 -25
- package/src/lib/helpers/findPublicKey.js +0 -15
- package/src/lib/helpers/guessPrivateKeyName.js +0 -18
- package/src/lib/helpers/guessPublicKeyName.js +0 -18
- package/src/lib/helpers/parseEncryptionKeyFromDotenvKey.js +0 -19
- package/src/lib/helpers/parseEnvironmentFromDotenvKey.js +0 -19
- package/src/lib/helpers/smartDotenvPrivateKey.js +0 -89
- package/src/lib/helpers/smartDotenvPublicKey.js +0 -42
- package/src/lib/services/ops.js +0 -136
- /package/src/lib/helpers/{encryptValue.js → cryptography/encryptValue.js} +0 -0
- /package/src/lib/helpers/{isEncrypted.js → cryptography/isEncrypted.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const dotenvParse = require('./dotenvParse')
|
|
2
|
-
const isEncrypted = require('./isEncrypted')
|
|
3
|
-
const isPublicKey = require('./isPublicKey')
|
|
2
|
+
const isEncrypted = require('./cryptography/isEncrypted')
|
|
3
|
+
const isPublicKey = require('./cryptography/isPublicKey')
|
|
4
4
|
|
|
5
5
|
function isFullyEncrypted (src) {
|
|
6
6
|
const parsed = dotenvParse(src, false, false, true) // collect all values
|
|
@@ -14,7 +14,7 @@ function isFullyEncrypted (src) {
|
|
|
14
14
|
//
|
|
15
15
|
// key => [value1, ...]
|
|
16
16
|
for (const value of values) {
|
|
17
|
-
const result = isEncrypted(value) || isPublicKey(key
|
|
17
|
+
const result = isEncrypted(value) || isPublicKey(key)
|
|
18
18
|
if (!result) {
|
|
19
19
|
return false
|
|
20
20
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
keyNames: require('./keyNames'),
|
|
3
|
+
keyValues: require('./keyValues'),
|
|
4
|
+
|
|
5
|
+
// private
|
|
6
|
+
// private keys are resolved via keyValues()
|
|
7
|
+
|
|
8
|
+
// other
|
|
9
|
+
readProcessKey: require('./readProcessKey'),
|
|
10
|
+
readFileKey: require('./readFileKey'),
|
|
11
|
+
guessPrivateKeyFilename: require('./../guessPrivateKeyFilename'),
|
|
12
|
+
dotenvPrivateKeyNames: require('./../dotenvPrivateKeyNames')
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const environment = require('./../envResolution/environment')
|
|
3
|
+
|
|
4
|
+
function keyNames (filepath) {
|
|
5
|
+
const filename = path.basename(filepath).toLowerCase()
|
|
6
|
+
|
|
7
|
+
// .env
|
|
8
|
+
if (filename === '.env') {
|
|
9
|
+
return {
|
|
10
|
+
publicKeyName: 'DOTENV_PUBLIC_KEY',
|
|
11
|
+
privateKeyName: 'DOTENV_PRIVATE_KEY'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// .env.ENVIRONMENT
|
|
16
|
+
const resolvedEnvironment = environment(filename).toUpperCase()
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
publicKeyName: `DOTENV_PUBLIC_KEY_${resolvedEnvironment}`,
|
|
20
|
+
privateKeyName: `DOTENV_PRIVATE_KEY_${resolvedEnvironment}`
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = keyNames
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
|
|
3
|
+
const fsx = require('./../fsx')
|
|
4
|
+
const dotenvParse = require('./../dotenvParse')
|
|
5
|
+
const keyNames = require('./keyNames')
|
|
6
|
+
const readProcessKey = require('./readProcessKey')
|
|
7
|
+
const readFileKey = require('./readFileKey')
|
|
8
|
+
const opsKeypair = require('../cryptography/opsKeypair')
|
|
9
|
+
|
|
10
|
+
function invertForPrivateKeyName (filepath) {
|
|
11
|
+
const PUBLIC_KEY_SCHEMA = 'DOTENV_PUBLIC_KEY'
|
|
12
|
+
const PRIVATE_KEY_SCHEMA = 'DOTENV_PRIVATE_KEY'
|
|
13
|
+
|
|
14
|
+
if (!fsx.existsSync(filepath)) {
|
|
15
|
+
return null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const envSrc = fsx.readFileX(filepath)
|
|
19
|
+
const envParsed = dotenvParse(envSrc)
|
|
20
|
+
|
|
21
|
+
let publicKeyName
|
|
22
|
+
for (const keyName of Object.keys(envParsed)) {
|
|
23
|
+
if (keyName === PUBLIC_KEY_SCHEMA || keyName.startsWith(PUBLIC_KEY_SCHEMA)) {
|
|
24
|
+
publicKeyName = keyName // find DOTENV_PUBLIC_KEY* in filename
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (publicKeyName) {
|
|
29
|
+
return publicKeyName.replace(PUBLIC_KEY_SCHEMA, PRIVATE_KEY_SCHEMA) // return inverted (DOTENV_PUBLIC_KEY* -> DOTENV_PRIVATE_KEY*) if found
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function keyValues (filepath, opts = {}) {
|
|
36
|
+
let keysFilepath = opts.keysFilepath || null
|
|
37
|
+
const opsOn = opts.opsOn === true
|
|
38
|
+
const names = keyNames(filepath)
|
|
39
|
+
const publicKeyName = names.publicKeyName // DOTENV_PUBLIC_KEY_${ENVIRONMENT}
|
|
40
|
+
let privateKeyName = names.privateKeyName // DOTENV_PRIVATE_KEY_${ENVIRONMENT}
|
|
41
|
+
|
|
42
|
+
let publicKey = null
|
|
43
|
+
let privateKey = null
|
|
44
|
+
|
|
45
|
+
// public key: process.env first, then .env*
|
|
46
|
+
publicKey = readProcessKey(publicKeyName)
|
|
47
|
+
if (!publicKey) {
|
|
48
|
+
publicKey = readFileKey(publicKeyName, filepath) || null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// private key: process.env first, then .env.keys, then invert public key
|
|
52
|
+
privateKey = readProcessKey(privateKeyName)
|
|
53
|
+
if (!privateKey) {
|
|
54
|
+
if (keysFilepath) { // user specified -fk flag
|
|
55
|
+
keysFilepath = path.resolve(keysFilepath)
|
|
56
|
+
} else {
|
|
57
|
+
keysFilepath = path.resolve(path.dirname(filepath), '.env.keys') // typical scenario
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
privateKey = readFileKey(privateKeyName, keysFilepath)
|
|
61
|
+
}
|
|
62
|
+
// invert
|
|
63
|
+
if (!privateKey) {
|
|
64
|
+
privateKeyName = invertForPrivateKeyName(filepath)
|
|
65
|
+
if (privateKeyName) {
|
|
66
|
+
privateKey = readProcessKey(privateKeyName)
|
|
67
|
+
if (!privateKey) {
|
|
68
|
+
privateKey = readFileKey(privateKeyName, keysFilepath)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ops
|
|
74
|
+
if (opsOn && !privateKey && publicKey && publicKey.length > 0) {
|
|
75
|
+
const kp = opsKeypair(publicKey)
|
|
76
|
+
privateKey = kp.privateKey
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
publicKeyValue: publicKey || null, // important to make sure name is rendered
|
|
81
|
+
privateKeyValue: privateKey || null // importan to make sure name is rendered
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = keyValues
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const fsx = require('./../fsx')
|
|
2
|
+
const dotenvParse = require('./../dotenvParse')
|
|
3
|
+
|
|
4
|
+
function readFileKey (keyName, filepath) {
|
|
5
|
+
if (fsx.existsSync(filepath)) {
|
|
6
|
+
const src = fsx.readFileX(filepath)
|
|
7
|
+
const parsed = dotenvParse(src)
|
|
8
|
+
|
|
9
|
+
if (parsed[keyName] && parsed[keyName].length > 0) {
|
|
10
|
+
return parsed[keyName]
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = readFileKey
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
|
|
3
|
+
function localDisplayPath (filepath) {
|
|
4
|
+
if (!filepath) return '.env.keys'
|
|
5
|
+
if (!path.isAbsolute(filepath)) return filepath
|
|
6
|
+
|
|
7
|
+
const relative = path.relative(process.cwd(), filepath)
|
|
8
|
+
return relative || path.basename(filepath)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = localDisplayPath
|
package/src/lib/helpers/parse.js
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function prependPublicKey (publicKeyName, publicKey, filename, relativeFilepath = '.env.keys') {
|
|
2
|
+
const comment = relativeFilepath === '.env.keys'
|
|
3
|
+
? ''
|
|
4
|
+
: ` # -fk ${relativeFilepath}`
|
|
5
|
+
|
|
6
|
+
return [
|
|
7
|
+
'#/-------------------[DOTENV_PUBLIC_KEY]--------------------/',
|
|
8
|
+
'#/ public-key encryption for .env files /',
|
|
9
|
+
'#/ [how it works](https://dotenvx.com/encryption) /',
|
|
10
|
+
'#/----------------------------------------------------------/',
|
|
11
|
+
`${publicKeyName}="${publicKey}"${comment}`,
|
|
12
|
+
'',
|
|
13
|
+
`# ${filename}`
|
|
14
|
+
].join('\n')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = prependPublicKey
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function preserveShebang (envSrc) {
|
|
2
|
+
const [firstLine, ...remainingLines] = envSrc.split('\n')
|
|
3
|
+
let firstLinePreserved = ''
|
|
4
|
+
|
|
5
|
+
if (firstLine.startsWith('#!')) {
|
|
6
|
+
firstLinePreserved = firstLine + '\n'
|
|
7
|
+
envSrc = remainingLines.join('\n')
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
firstLinePreserved,
|
|
12
|
+
envSrc
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = preserveShebang
|
package/src/lib/main.d.ts
CHANGED
|
@@ -113,10 +113,10 @@ export interface DotenvConfigOptions {
|
|
|
113
113
|
envKeysFile?: string;
|
|
114
114
|
|
|
115
115
|
/**
|
|
116
|
-
*
|
|
116
|
+
* Legacy option retained for compatibility.
|
|
117
117
|
*
|
|
118
118
|
* @default undefined
|
|
119
|
-
* @example require('@dotenvx/dotenvx').config({ DOTENV_KEY: 'dotenv://:key_1234
|
|
119
|
+
* @example require('@dotenvx/dotenvx').config({ DOTENV_KEY: 'dotenv://:key_1234…' })
|
|
120
120
|
*/
|
|
121
121
|
DOTENV_KEY?: string;
|
|
122
122
|
|
|
@@ -166,7 +166,7 @@ export interface DotenvPopulateInput {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
|
-
* Loads `.env` file contents into process.env by default.
|
|
169
|
+
* Loads `.env` file contents into process.env by default.
|
|
170
170
|
*
|
|
171
171
|
* @see https://dotenvx.com/docs
|
|
172
172
|
*
|
|
@@ -205,6 +205,14 @@ export interface SetOptions {
|
|
|
205
205
|
* @example require('@dotenvx/dotenvx').config(key, value, { encrypt: false } })
|
|
206
206
|
*/
|
|
207
207
|
encrypt?: boolean;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Turn off Dotenvx Ops features - https://dotenvx.com/ops
|
|
211
|
+
*
|
|
212
|
+
* @default false
|
|
213
|
+
* @example require('@dotenvx/dotenvx').set(key, value, { opsOff: true })
|
|
214
|
+
*/
|
|
215
|
+
opsOff?: boolean;
|
|
208
216
|
}
|
|
209
217
|
|
|
210
218
|
export type SetProcessedEnv = {
|
|
@@ -272,6 +280,14 @@ export interface GetOptions {
|
|
|
272
280
|
* @example require('@dotenvx/dotenvx').get('KEY', { strict: true })
|
|
273
281
|
*/
|
|
274
282
|
strict?: boolean;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Turn off Dotenvx Ops features - https://dotenvx.com/ops
|
|
286
|
+
*
|
|
287
|
+
* @default false
|
|
288
|
+
* @example require('@dotenvx/dotenvx').get('KEY', { opsOff: true })
|
|
289
|
+
*/
|
|
290
|
+
opsOff?: boolean;
|
|
275
291
|
}
|
|
276
292
|
|
|
277
293
|
/**
|
package/src/lib/main.js
CHANGED
|
@@ -17,7 +17,7 @@ const Genexample = require('./services/genexample')
|
|
|
17
17
|
const buildEnvs = require('./helpers/buildEnvs')
|
|
18
18
|
const Parse = require('./helpers/parse')
|
|
19
19
|
const fsx = require('./helpers/fsx')
|
|
20
|
-
const
|
|
20
|
+
const localDisplayPath = require('./helpers/localDisplayPath')
|
|
21
21
|
|
|
22
22
|
/** @type {import('./main').config} */
|
|
23
23
|
const config = function (options = {}) {
|
|
@@ -39,12 +39,6 @@ const config = function (options = {}) {
|
|
|
39
39
|
// envKeysFile
|
|
40
40
|
const envKeysFile = options.envKeysFile
|
|
41
41
|
|
|
42
|
-
// DOTENV_KEY (DEPRECATED)
|
|
43
|
-
let DOTENV_KEY = process.env.DOTENV_KEY
|
|
44
|
-
if (options && options.DOTENV_KEY) {
|
|
45
|
-
DOTENV_KEY = options.DOTENV_KEY
|
|
46
|
-
}
|
|
47
|
-
|
|
48
42
|
// dotenvx-ops related
|
|
49
43
|
const opsOn = options.opsOff !== true
|
|
50
44
|
|
|
@@ -55,12 +49,12 @@ const config = function (options = {}) {
|
|
|
55
49
|
}
|
|
56
50
|
|
|
57
51
|
try {
|
|
58
|
-
const envs = buildEnvs(options
|
|
52
|
+
const envs = buildEnvs(options)
|
|
59
53
|
const {
|
|
60
54
|
processedEnvs,
|
|
61
55
|
readableFilepaths,
|
|
62
56
|
uniqueInjectedKeys
|
|
63
|
-
} = new Run(envs, overload,
|
|
57
|
+
} = new Run(envs, overload, processEnv, envKeysFile, opsOn).run()
|
|
64
58
|
|
|
65
59
|
if (opsOn) {
|
|
66
60
|
// removed radar feature for now. contact me at mot@dotenvx.com if still needed for your organization.
|
|
@@ -71,11 +65,6 @@ const config = function (options = {}) {
|
|
|
71
65
|
/** @type {Record<string, string>} */
|
|
72
66
|
const parsedAll = {}
|
|
73
67
|
for (const processedEnv of processedEnvs) {
|
|
74
|
-
if (processedEnv.type === 'envVaultFile') {
|
|
75
|
-
logger.verbose(`loading env from encrypted ${processedEnv.filepath} (${path.resolve(processedEnv.filepath)})`)
|
|
76
|
-
logger.debug(`decrypting encrypted env from ${processedEnv.filepath} (${path.resolve(processedEnv.filepath)})`)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
68
|
if (processedEnv.type === 'envFile') {
|
|
80
69
|
logger.verbose(`loading env from ${processedEnv.filepath} (${path.resolve(processedEnv.filepath)})`)
|
|
81
70
|
}
|
|
@@ -192,12 +181,13 @@ const set = function (key, value, options = {}) {
|
|
|
192
181
|
|
|
193
182
|
const envs = buildEnvs(options)
|
|
194
183
|
const envKeysFilepath = options.envKeysFile
|
|
184
|
+
const opsOn = options.opsOff !== true
|
|
195
185
|
|
|
196
186
|
const {
|
|
197
187
|
processedEnvs,
|
|
198
188
|
changedFilepaths,
|
|
199
189
|
unchangedFilepaths
|
|
200
|
-
} = new Sets(key, value, envs, encrypt, envKeysFilepath).run()
|
|
190
|
+
} = new Sets(key, value, envs, encrypt, envKeysFilepath, opsOn).run()
|
|
201
191
|
|
|
202
192
|
let withEncryption = ''
|
|
203
193
|
|
|
@@ -226,26 +216,25 @@ const set = function (key, value, options = {}) {
|
|
|
226
216
|
}
|
|
227
217
|
}
|
|
228
218
|
|
|
219
|
+
const keyAddedEnv = processedEnvs.find((processedEnv) => processedEnv.privateKeyAdded)
|
|
220
|
+
const keyAddedSuffix = keyAddedEnv ? ` + key (${localDisplayPath(keyAddedEnv.envKeysFilepath)})` : ''
|
|
221
|
+
|
|
229
222
|
if (changedFilepaths.length > 0) {
|
|
230
|
-
|
|
223
|
+
if (encrypt) {
|
|
224
|
+
logger.success(`◈ encrypted ${key} (${changedFilepaths.join(',')})${keyAddedSuffix}`)
|
|
225
|
+
} else {
|
|
226
|
+
logger.success(`◇ set ${key} (${changedFilepaths.join(',')})`)
|
|
227
|
+
}
|
|
228
|
+
} else if (encrypt && keyAddedEnv) {
|
|
229
|
+
const keyAddedEnvFilepath = keyAddedEnv.envFilepath || changedFilepaths[0] || '.env'
|
|
230
|
+
logger.success(`◈ encrypted ${key} (${keyAddedEnvFilepath})${keyAddedSuffix}`)
|
|
231
231
|
} else if (unchangedFilepaths.length > 0) {
|
|
232
|
-
logger.info(
|
|
232
|
+
logger.info(`○ no changes (${unchangedFilepaths})`)
|
|
233
233
|
} else {
|
|
234
234
|
// do nothing
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
if (processedEnv.privateKeyAdded) {
|
|
239
|
-
logger.success(`✔ key added to ${processedEnv.envKeysFilepath} (${processedEnv.privateKeyName})`)
|
|
240
|
-
// logger.help('⮕ optional: [dotenvx ops backup] to securely backup private key')
|
|
241
|
-
|
|
242
|
-
if (!isIgnoringDotenvKeys()) {
|
|
243
|
-
logger.help('⮕ next run: [dotenvx ext gitignore --pattern .env.keys] to gitignore .env.keys')
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
logger.help(`⮕ next run: [${processedEnv.privateKeyName}='${processedEnv.privateKey}' dotenvx get ${key}] to test decryption locally`)
|
|
247
|
-
}
|
|
248
|
-
}
|
|
237
|
+
// intentionally quiet: success line communicates key creation
|
|
249
238
|
|
|
250
239
|
return {
|
|
251
240
|
processedEnvs,
|
|
@@ -257,11 +246,12 @@ const set = function (key, value, options = {}) {
|
|
|
257
246
|
/* @type {import('./main').get} */
|
|
258
247
|
const get = function (key, options = {}) {
|
|
259
248
|
const envs = buildEnvs(options)
|
|
249
|
+
const opsOn = options.opsOff !== true
|
|
260
250
|
|
|
261
251
|
// ignore
|
|
262
252
|
const ignore = options.ignore || []
|
|
263
253
|
|
|
264
|
-
const { parsed, errors } = new Get(key, envs, options.overload,
|
|
254
|
+
const { parsed, errors } = new Get(key, envs, options.overload, options.all, options.envKeysFile, opsOn).run()
|
|
265
255
|
|
|
266
256
|
for (const error of errors || []) {
|
|
267
257
|
if (ignore.includes(error.code)) {
|
|
@@ -317,8 +307,9 @@ const genexample = function (directory, envFile) {
|
|
|
317
307
|
}
|
|
318
308
|
|
|
319
309
|
/** @type {import('./main').keypair} */
|
|
320
|
-
const keypair = function (envFile, key, envKeysFile = null) {
|
|
321
|
-
const
|
|
310
|
+
const keypair = function (envFile, key, envKeysFile = null, opsOff = false) {
|
|
311
|
+
const opsOn = opsOff !== true
|
|
312
|
+
const keypairs = new Keypair(envFile, envKeysFile, opsOn).run()
|
|
322
313
|
if (key) {
|
|
323
314
|
return keypairs[key]
|
|
324
315
|
} else {
|
|
@@ -5,19 +5,28 @@ const picomatch = require('picomatch')
|
|
|
5
5
|
const TYPE_ENV_FILE = 'envFile'
|
|
6
6
|
|
|
7
7
|
const Errors = require('./../helpers/errors')
|
|
8
|
-
|
|
9
|
-
const {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
determine
|
|
11
|
+
} = require('./../helpers/envResolution')
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
keyNames,
|
|
15
|
+
keyValues
|
|
16
|
+
} = require('./../helpers/keyResolution')
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
decryptKeyValue,
|
|
20
|
+
isEncrypted
|
|
21
|
+
} = require('./../helpers/cryptography')
|
|
22
|
+
|
|
14
23
|
const replace = require('./../helpers/replace')
|
|
24
|
+
const dotenvParse = require('./../helpers/dotenvParse')
|
|
15
25
|
const detectEncoding = require('./../helpers/detectEncoding')
|
|
16
|
-
const determineEnvs = require('./../helpers/determineEnvs')
|
|
17
26
|
|
|
18
27
|
class Decrypt {
|
|
19
|
-
constructor (envs = [], key = [], excludeKey = [], envKeysFilepath = null, opsOn =
|
|
20
|
-
this.envs =
|
|
28
|
+
constructor (envs = [], key = [], excludeKey = [], envKeysFilepath = null, opsOn = false) {
|
|
29
|
+
this.envs = determine(envs, process.env)
|
|
21
30
|
this.key = key
|
|
22
31
|
this.excludeKey = excludeKey
|
|
23
32
|
this.envKeysFilepath = envKeysFilepath
|
|
@@ -63,15 +72,14 @@ class Decrypt {
|
|
|
63
72
|
row.envFilepath = envFilepath
|
|
64
73
|
|
|
65
74
|
try {
|
|
66
|
-
const encoding =
|
|
75
|
+
const encoding = detectEncoding(filepath)
|
|
67
76
|
let envSrc = fsx.readFileX(filepath, { encoding })
|
|
68
77
|
const envParsed = dotenvParse(envSrc)
|
|
69
78
|
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
const privateKeyName = guessPrivateKeyName(envFilepath)
|
|
79
|
+
const { privateKeyName } = keyNames(envFilepath)
|
|
80
|
+
const { privateKeyValue } = keyValues(envFilepath, { keysFilepath: this.envKeysFilepath, opsOn: this.opsOn })
|
|
73
81
|
|
|
74
|
-
row.privateKey =
|
|
82
|
+
row.privateKey = privateKeyValue
|
|
75
83
|
row.privateKeyName = privateKeyName
|
|
76
84
|
row.changed = false // track possible changes
|
|
77
85
|
|
|
@@ -90,7 +98,7 @@ class Decrypt {
|
|
|
90
98
|
if (encrypted) {
|
|
91
99
|
row.keys.push(key) // track key(s)
|
|
92
100
|
|
|
93
|
-
const decryptedValue = decryptKeyValue(key, value, privateKeyName,
|
|
101
|
+
const decryptedValue = decryptKeyValue(key, value, privateKeyName, privateKeyValue)
|
|
94
102
|
// once newSrc is built write it out
|
|
95
103
|
envSrc = replace(envSrc, key, decryptedValue)
|
|
96
104
|
|
|
@@ -130,10 +138,6 @@ class Decrypt {
|
|
|
130
138
|
|
|
131
139
|
return this.excludeKey
|
|
132
140
|
}
|
|
133
|
-
|
|
134
|
-
_detectEncoding (filepath) {
|
|
135
|
-
return detectEncoding(filepath)
|
|
136
|
-
}
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
module.exports = Decrypt
|