@dotenvx/dotenvx 1.55.0 → 1.56.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/package.json +3 -3
  3. package/src/cli/actions/encrypt.js +0 -3
  4. package/src/cli/actions/get.js +4 -2
  5. package/src/cli/actions/keypair.js +3 -2
  6. package/src/cli/actions/rotate.js +10 -5
  7. package/src/cli/actions/run.js +1 -14
  8. package/src/cli/actions/set.js +3 -2
  9. package/src/cli/commands/ext.js +0 -3
  10. package/src/cli/dotenvx.js +12 -9
  11. package/src/db/session.js +21 -0
  12. package/src/lib/extensions/ops.js +98 -0
  13. package/src/lib/helpers/buildEnvs.js +2 -15
  14. package/src/lib/helpers/{decryptKeyValue.js → cryptography/decryptKeyValue.js} +1 -1
  15. package/src/lib/helpers/cryptography/index.js +14 -0
  16. package/src/lib/helpers/{isPublicKey.js → cryptography/isPublicKey.js} +1 -1
  17. package/src/lib/helpers/{keypair.js → cryptography/localKeypair.js} +2 -2
  18. package/src/lib/helpers/cryptography/mutateKeysSrc.js +38 -0
  19. package/src/lib/helpers/cryptography/mutateSrc.js +24 -0
  20. package/src/lib/helpers/cryptography/opsKeypair.js +14 -0
  21. package/src/lib/helpers/cryptography/provision.js +47 -0
  22. package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +26 -0
  23. package/src/lib/helpers/envResolution/determine.js +46 -0
  24. package/src/lib/helpers/{guessEnvironment.js → envResolution/environment.js} +4 -6
  25. package/src/lib/helpers/envResolution/index.js +8 -0
  26. package/src/lib/helpers/errors.js +13 -0
  27. package/src/lib/helpers/findEnvFiles.js +1 -1
  28. package/src/lib/helpers/isFullyEncrypted.js +3 -3
  29. package/src/lib/helpers/keyResolution/index.js +13 -0
  30. package/src/lib/helpers/keyResolution/keyNames.js +24 -0
  31. package/src/lib/helpers/keyResolution/keyValues.js +85 -0
  32. package/src/lib/helpers/keyResolution/readFileKey.js +15 -0
  33. package/src/lib/helpers/keyResolution/readProcessKey.js +7 -0
  34. package/src/lib/helpers/parse.js +1 -1
  35. package/src/lib/helpers/prependPublicKey.js +17 -0
  36. package/src/lib/helpers/preserveShebang.js +16 -0
  37. package/src/lib/main.d.ts +19 -3
  38. package/src/lib/main.js +9 -17
  39. package/src/lib/services/decrypt.js +23 -19
  40. package/src/lib/services/encrypt.js +41 -136
  41. package/src/lib/services/get.js +3 -3
  42. package/src/lib/services/keypair.js +12 -16
  43. package/src/lib/services/prebuild.js +2 -2
  44. package/src/lib/services/precommit.js +2 -2
  45. package/src/lib/services/rotate.js +59 -42
  46. package/src/lib/services/run.js +29 -112
  47. package/src/lib/services/sets.js +40 -124
  48. package/src/lib/helpers/decrypt.js +0 -31
  49. package/src/lib/helpers/deprecationNotice.js +0 -17
  50. package/src/lib/helpers/determineEnvs.js +0 -65
  51. package/src/lib/helpers/encrypt.js +0 -29
  52. package/src/lib/helpers/findPrivateKey.js +0 -25
  53. package/src/lib/helpers/findPublicKey.js +0 -15
  54. package/src/lib/helpers/guessPrivateKeyName.js +0 -18
  55. package/src/lib/helpers/guessPublicKeyName.js +0 -18
  56. package/src/lib/helpers/parseEncryptionKeyFromDotenvKey.js +0 -19
  57. package/src/lib/helpers/parseEnvironmentFromDotenvKey.js +0 -19
  58. package/src/lib/helpers/smartDotenvPrivateKey.js +0 -89
  59. package/src/lib/helpers/smartDotenvPublicKey.js +0 -42
  60. package/src/lib/services/ops.js +0 -111
  61. /package/src/lib/helpers/{encryptValue.js → cryptography/encryptValue.js} +0 -0
  62. /package/src/lib/helpers/{isEncrypted.js → cryptography/isEncrypted.js} +0 -0
@@ -4,27 +4,36 @@ const path = require('path')
4
4
  const TYPE_ENV_FILE = 'envFile'
5
5
 
6
6
  const Errors = require('./../helpers/errors')
7
- const guessPrivateKeyName = require('./../helpers/guessPrivateKeyName')
8
- const guessPublicKeyName = require('./../helpers/guessPublicKeyName')
9
- const encryptValue = require('./../helpers/encryptValue')
10
- const decryptKeyValue = require('./../helpers/decryptKeyValue')
7
+
8
+ const {
9
+ determine
10
+ } = require('./../helpers/envResolution')
11
+
12
+ const {
13
+ keyNames,
14
+ keyValues
15
+ } = require('./../helpers/keyResolution')
16
+
17
+ const {
18
+ encryptValue,
19
+ decryptKeyValue,
20
+ isEncrypted,
21
+ provision,
22
+ provisionWithPrivateKey
23
+ } = require('./../helpers/cryptography')
24
+
11
25
  const replace = require('./../helpers/replace')
12
26
  const dotenvParse = require('./../helpers/dotenvParse')
13
27
  const detectEncoding = require('./../helpers/detectEncoding')
14
- const determineEnvs = require('./../helpers/determineEnvs')
15
- const { findPrivateKey } = require('./../helpers/findPrivateKey')
16
- const findPublicKey = require('./../helpers/findPublicKey')
17
- const keypair = require('./../helpers/keypair')
18
- const truncate = require('./../helpers/truncate')
19
- const isEncrypted = require('./../helpers/isEncrypted')
20
28
 
21
29
  class Sets {
22
- constructor (key, value, envs = [], encrypt = true, envKeysFilepath = null) {
23
- this.envs = determineEnvs(envs, process.env)
30
+ constructor (key, value, envs = [], encrypt = true, envKeysFilepath = null, opsOn = false) {
31
+ this.envs = determine(envs, process.env)
24
32
  this.key = key
25
33
  this.value = value
26
34
  this.encrypt = encrypt
27
35
  this.envKeysFilepath = envKeysFilepath
36
+ this.opsOn = opsOn
28
37
 
29
38
  this.processedEnvs = []
30
39
  this.changedFilepaths = new Set()
@@ -57,14 +66,13 @@ class Sets {
57
66
  row.value = this.value || null
58
67
  row.type = TYPE_ENV_FILE
59
68
 
60
- const filename = path.basename(envFilepath)
61
69
  const filepath = path.resolve(envFilepath)
62
70
  row.filepath = filepath
63
71
  row.envFilepath = envFilepath
64
72
  row.changed = false
65
73
 
66
74
  try {
67
- const encoding = this._detectEncoding(filepath)
75
+ const encoding = detectEncoding(filepath)
68
76
  let envSrc = fsx.readFileX(filepath, { encoding })
69
77
  const envParsed = dotenvParse(envSrc)
70
78
  row.originalValue = envParsed[row.key] || null
@@ -75,86 +83,28 @@ class Sets {
75
83
  let publicKey
76
84
  let privateKey
77
85
 
78
- const publicKeyName = guessPublicKeyName(envFilepath)
79
- const privateKeyName = guessPrivateKeyName(envFilepath)
80
- const existingPublicKey = findPublicKey(envFilepath)
81
- const existingPrivateKey = findPrivateKey(envFilepath, this.envKeysFilepath, false, existingPublicKey)
82
-
83
- let envKeysFilepath = path.join(path.dirname(filepath), '.env.keys')
84
- if (this.envKeysFilepath) {
85
- envKeysFilepath = path.resolve(this.envKeysFilepath)
86
- }
87
- const relativeFilepath = path.relative(path.dirname(filepath), envKeysFilepath)
88
-
89
- if (existingPrivateKey) {
90
- const kp = keypair(existingPrivateKey)
91
- publicKey = kp.publicKey
92
- privateKey = kp.privateKey
86
+ const { publicKeyName, privateKeyName } = keyNames(filepath)
87
+ const { publicKeyValue, privateKeyValue } = keyValues(filepath, { keysFilepath: this.envKeysFilepath, opsOn: this.opsOn })
88
+
89
+ // first pass - provision
90
+ if (!privateKeyValue && !publicKeyValue) {
91
+ const prov = provision({ envSrc, envFilepath, keysFilepath: this.envKeysFilepath, opsOn: this.opsOn })
92
+ envSrc = prov.envSrc
93
+ publicKey = prov.publicKey
94
+ privateKey = prov.privateKey
95
+ row.privateKeyAdded = prov.privateKeyAdded
96
+ row.envKeysFilepath = prov.envKeysFilepath
97
+ } else if (privateKeyValue) {
98
+ const prov = provisionWithPrivateKey({ envSrc, envFilepath, keysFilepath: this.envKeysFilepath, privateKeyValue, publicKeyValue, publicKeyName })
99
+ publicKey = prov.publicKey
100
+ privateKey = prov.privateKey
101
+ envSrc = prov.envSrc
93
102
 
94
103
  if (row.originalValue) {
95
104
  row.originalValue = decryptKeyValue(row.key, row.originalValue, privateKeyName, privateKey)
96
105
  }
97
-
98
- // if derivation doesn't match what's in the file (or preset in env)
99
- if (existingPublicKey && existingPublicKey !== publicKey) {
100
- const error = new Error(`derived public key (${truncate(publicKey)}) does not match the existing public key (${truncate(existingPublicKey)})`)
101
- error.code = 'INVALID_DOTENV_PRIVATE_KEY'
102
- error.help = `debug info: ${privateKeyName}=${truncate(existingPrivateKey)} (derived ${publicKeyName}=${truncate(publicKey)} vs existing ${publicKeyName}=${truncate(existingPublicKey)})`
103
- throw error
104
- }
105
-
106
- // typical scenario when encrypting a monorepo second .env file from a prior generated -fk .env.keys file
107
- if (!existingPublicKey) {
108
- const ps = this._preserveShebang(envSrc)
109
- const firstLinePreserved = ps.firstLinePreserved
110
- envSrc = ps.envSrc
111
-
112
- const prependPublicKey = this._prependPublicKey(publicKeyName, publicKey, filename, relativeFilepath)
113
-
114
- envSrc = `${firstLinePreserved}${prependPublicKey}\n${envSrc}`
115
- }
116
- } else if (existingPublicKey) {
117
- publicKey = existingPublicKey
118
- } else {
119
- // .env.keys
120
- let keysSrc = ''
121
- if (fsx.existsSync(envKeysFilepath)) {
122
- keysSrc = fsx.readFileX(envKeysFilepath)
123
- }
124
-
125
- const ps = this._preserveShebang(envSrc)
126
- const firstLinePreserved = ps.firstLinePreserved
127
- envSrc = ps.envSrc
128
-
129
- const kp = keypair() // generates a fresh keypair in memory
130
- publicKey = kp.publicKey
131
- privateKey = kp.privateKey
132
-
133
- const prependPublicKey = this._prependPublicKey(publicKeyName, publicKey, filename, relativeFilepath)
134
-
135
- // privateKey
136
- const firstTimeKeysSrc = [
137
- '#/------------------!DOTENV_PRIVATE_KEYS!-------------------/',
138
- '#/ private decryption keys. DO NOT commit to source control /',
139
- '#/ [how it works](https://dotenvx.com/encryption) /',
140
- // '#/ backup with: `dotenvx ops backup` /',
141
- '#/----------------------------------------------------------/'
142
- ].join('\n')
143
- const appendPrivateKey = [
144
- `# ${filename}`,
145
- `${privateKeyName}=${privateKey}`,
146
- ''
147
- ].join('\n')
148
-
149
- envSrc = `${firstLinePreserved}${prependPublicKey}\n${envSrc}`
150
- keysSrc = keysSrc.length > 1 ? keysSrc : `${firstTimeKeysSrc}\n`
151
- keysSrc = `${keysSrc}\n${appendPrivateKey}`
152
-
153
- // write to .env.keys
154
- fsx.writeFileX(envKeysFilepath, keysSrc)
155
-
156
- row.privateKeyAdded = true
157
- row.envKeysFilepath = this.envKeysFilepath || path.join(path.dirname(envFilepath), path.basename(envKeysFilepath))
106
+ } else if (publicKeyValue) {
107
+ publicKey = publicKeyValue
158
108
  }
159
109
 
160
110
  row.publicKey = publicKey
@@ -184,40 +134,6 @@ class Sets {
184
134
 
185
135
  this.processedEnvs.push(row)
186
136
  }
187
-
188
- _detectEncoding (filepath) {
189
- return detectEncoding(filepath)
190
- }
191
-
192
- _prependPublicKey (publicKeyName, publicKey, filename, relativeFilepath = '.env.keys') {
193
- const comment = relativeFilepath === '.env.keys' ? '' : ` # -fk ${relativeFilepath}`
194
-
195
- return [
196
- '#/-------------------[DOTENV_PUBLIC_KEY]--------------------/',
197
- '#/ public-key encryption for .env files /',
198
- '#/ [how it works](https://dotenvx.com/encryption) /',
199
- '#/----------------------------------------------------------/',
200
- `${publicKeyName}="${publicKey}"${comment}`,
201
- '',
202
- `# ${filename}`
203
- ].join('\n')
204
- }
205
-
206
- _preserveShebang (envSrc) {
207
- // preserve shebang
208
- const [firstLine, ...remainingLines] = envSrc.split('\n')
209
- let firstLinePreserved = ''
210
-
211
- if (firstLine.startsWith('#!')) {
212
- firstLinePreserved = firstLine + '\n'
213
- envSrc = remainingLines.join('\n')
214
- }
215
-
216
- return {
217
- firstLinePreserved,
218
- envSrc
219
- }
220
- }
221
137
  }
222
138
 
223
139
  module.exports = Sets
@@ -1,31 +0,0 @@
1
- const dotenv = require('dotenv')
2
-
3
- const parseEncryptionKeyFromDotenvKey = require('./parseEncryptionKeyFromDotenvKey')
4
-
5
- function decrypt (ciphertext, dotenvKey) {
6
- const key = parseEncryptionKeyFromDotenvKey(dotenvKey)
7
-
8
- try {
9
- return dotenv.decrypt(ciphertext, key)
10
- } catch (e) {
11
- if (e.code === 'DECRYPTION_FAILED') {
12
- const error = new Error('[DECRYPTION_FAILED] Unable to decrypt .env.vault with DOTENV_KEY.')
13
- error.code = 'DECRYPTION_FAILED'
14
- error.help = '[DECRYPTION_FAILED] Run with debug flag [dotenvx run --debug -- yourcommand] or manually run [echo $DOTENV_KEY] to compare it to the one in .env.keys.'
15
- error.debug = `[DECRYPTION_FAILED] DOTENV_KEY is ${dotenvKey}`
16
- throw error
17
- }
18
-
19
- if (e.code === 'ERR_CRYPTO_INVALID_AUTH_TAG') {
20
- const error = new Error('[INVALID_CIPHERTEXT] Unable to decrypt what appears to be invalid ciphertext.')
21
- error.code = 'INVALID_CIPHERTEXT'
22
- error.help = '[INVALID_CIPHERTEXT] Run with debug flag [dotenvx run --debug -- yourcommand] or manually check .env.vault.'
23
- error.debug = `[INVALID_CIPHERTEXT] ciphertext is '${ciphertext}'`
24
- throw error
25
- }
26
-
27
- throw e
28
- }
29
- }
30
-
31
- module.exports = decrypt
@@ -1,17 +0,0 @@
1
- const { logger } = require('./../../shared/logger')
2
-
3
- class DeprecationNotice {
4
- constructor (options = {}) {
5
- this.DOTENV_KEY = options.DOTENV_KEY || process.env.DOTENV_KEY
6
- }
7
-
8
- dotenvKey () {
9
- if (this.DOTENV_KEY) {
10
- logger.warn('[DEPRECATION NOTICE] Setting DOTENV_KEY with .env.vault is deprecated.')
11
- logger.warn('[DEPRECATION NOTICE] Run [dotenvx ext vault migrate] for instructions on converting your .env.vault file to encrypted .env files (using public key encryption algorithm secp256k1)')
12
- logger.warn('[DEPRECATION NOTICE] Read more at [https://github.com/dotenvx/dotenvx/blob/main/CHANGELOG.md#0380]')
13
- }
14
- }
15
- }
16
-
17
- module.exports = DeprecationNotice
@@ -1,65 +0,0 @@
1
- const dotenvPrivateKeyNames = require('./dotenvPrivateKeyNames')
2
- const guessPrivateKeyFilename = require('./guessPrivateKeyFilename')
3
-
4
- const TYPE_ENV_FILE = 'envFile'
5
- const TYPE_ENV_VAULT_FILE = 'envVaultFile'
6
- const DEFAULT_ENVS = [{ type: TYPE_ENV_FILE, value: '.env' }]
7
- const DEFAULT_ENV_VAULTS = [{ type: TYPE_ENV_VAULT_FILE, value: '.env.vault' }]
8
-
9
- function determineEnvsFromDotenvPrivateKey (privateKeyNames) {
10
- const envs = []
11
-
12
- for (const privateKeyName of privateKeyNames) {
13
- const filename = guessPrivateKeyFilename(privateKeyName)
14
- envs.push({ type: TYPE_ENV_FILE, value: filename })
15
- }
16
-
17
- return envs
18
- }
19
-
20
- function determineEnvs (envs = [], processEnv, DOTENV_KEY = '') {
21
- const privateKeyNames = dotenvPrivateKeyNames(processEnv)
22
- if (!envs || envs.length <= 0) {
23
- // if process.env.DOTENV_PRIVATE_KEY or process.env.DOTENV_PRIVATE_KEY_${environment} is set, assume inline encryption methodology
24
- if (privateKeyNames.length > 0) {
25
- return determineEnvsFromDotenvPrivateKey(privateKeyNames)
26
- }
27
-
28
- if (DOTENV_KEY.length > 0) {
29
- // if DOTENV_KEY is set then default to look for .env.vault file
30
- return DEFAULT_ENV_VAULTS
31
- } else {
32
- return DEFAULT_ENVS // default to .env file expectation
33
- }
34
- } else {
35
- let fileAlreadySpecified = false // can be .env or .env.vault type
36
-
37
- for (const env of envs) {
38
- // if DOTENV_KEY set then we are checking if a .env.vault file is already specified
39
- if (DOTENV_KEY.length > 0 && env.type === TYPE_ENV_VAULT_FILE) {
40
- fileAlreadySpecified = true
41
- }
42
-
43
- // if DOTENV_KEY not set then we are checking if a .env file is already specified
44
- if (DOTENV_KEY.length <= 0 && env.type === TYPE_ENV_FILE) {
45
- fileAlreadySpecified = true
46
- }
47
- }
48
-
49
- // return early since envs array objects already contain 1 .env.vault or .env file
50
- if (fileAlreadySpecified) {
51
- return envs
52
- }
53
-
54
- // no .env.vault or .env file specified as a flag so we assume either .env.vault (if dotenv key is set) or a .env file
55
- if (DOTENV_KEY.length > 0) {
56
- // if DOTENV_KEY is set then default to look for .env.vault file
57
- return [...DEFAULT_ENV_VAULTS, ...envs]
58
- } else {
59
- // if no DOTENV_KEY then default to look for .env file
60
- return [...DEFAULT_ENVS, ...envs]
61
- }
62
- }
63
- }
64
-
65
- module.exports = determineEnvs
@@ -1,29 +0,0 @@
1
- const crypto = require('crypto')
2
-
3
- const parseEncryptionKeyFromDotenvKey = require('./parseEncryptionKeyFromDotenvKey')
4
-
5
- const NONCE_BYTES = 12
6
-
7
- function encrypt (raw, dotenvKey) {
8
- const key = parseEncryptionKeyFromDotenvKey(dotenvKey)
9
-
10
- // set up nonce
11
- const nonce = crypto.randomBytes(NONCE_BYTES)
12
-
13
- // set up cipher
14
- const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce)
15
-
16
- // generate ciphertext
17
- let ciphertext = ''
18
- ciphertext += cipher.update(raw, 'utf8', 'hex')
19
- ciphertext += cipher.final('hex')
20
- ciphertext += cipher.getAuthTag().toString('hex')
21
-
22
- // prepend nonce
23
- ciphertext = nonce.toString('hex') + ciphertext
24
-
25
- // base64 encode output
26
- return Buffer.from(ciphertext, 'hex').toString('base64')
27
- }
28
-
29
- module.exports = encrypt
@@ -1,25 +0,0 @@
1
- // helpers
2
- const guessPrivateKeyName = require('./guessPrivateKeyName')
3
- const findPublicKey = require('./findPublicKey')
4
-
5
- // services
6
- const Keypair = require('./../services/keypair')
7
- const Ops = require('./../services/ops')
8
-
9
- function findPrivateKey (envFilepath, envKeysFilepath = null, opsOn = false, publicKey = null) {
10
- // use path/to/.env.${environment} to generate privateKeyName
11
- const privateKeyName = guessPrivateKeyName(envFilepath)
12
-
13
- if (opsOn) {
14
- const resolvedPublicKey = publicKey || findPublicKey(envFilepath)
15
- const opsPrivateKey = new Ops().keypair(resolvedPublicKey)
16
- if (opsPrivateKey) {
17
- return opsPrivateKey
18
- }
19
- }
20
-
21
- const keypairs = new Keypair(envFilepath, envKeysFilepath).run()
22
- return keypairs[privateKeyName]
23
- }
24
-
25
- module.exports = { findPrivateKey }
@@ -1,15 +0,0 @@
1
- // helpers
2
- const guessPublicKeyName = require('./guessPublicKeyName')
3
-
4
- // services
5
- const Keypair = require('./../services/keypair')
6
-
7
- function findPublicKey (envFilepath) {
8
- const publicKeyName = guessPublicKeyName(envFilepath)
9
-
10
- const keypairs = new Keypair(envFilepath).run()
11
-
12
- return keypairs[publicKeyName]
13
- }
14
-
15
- module.exports = findPublicKey
@@ -1,18 +0,0 @@
1
- const path = require('path')
2
- const guessEnvironment = require('./guessEnvironment')
3
-
4
- function guessPrivateKeyName (filepath) {
5
- const filename = path.basename(filepath).toLowerCase()
6
-
7
- // .env
8
- if (filename === '.env') {
9
- return 'DOTENV_PRIVATE_KEY'
10
- }
11
-
12
- // .env.ENVIRONMENT
13
- const environment = guessEnvironment(filename)
14
-
15
- return `DOTENV_PRIVATE_KEY_${environment.toUpperCase()}`
16
- }
17
-
18
- module.exports = guessPrivateKeyName
@@ -1,18 +0,0 @@
1
- const path = require('path')
2
- const guessEnvironment = require('./guessEnvironment')
3
-
4
- function guessPublicKeyName (filepath) {
5
- const filename = path.basename(filepath).toLowerCase()
6
-
7
- // .env
8
- if (filename === '.env') {
9
- return 'DOTENV_PUBLIC_KEY'
10
- }
11
-
12
- // .env.ENVIRONMENT
13
- const environment = guessEnvironment(filename)
14
-
15
- return `DOTENV_PUBLIC_KEY_${environment.toUpperCase()}`
16
- }
17
-
18
- module.exports = guessPublicKeyName
@@ -1,19 +0,0 @@
1
- function parseEncryptionKeyFromDotenvKey (dotenvKey) {
2
- // Parse DOTENV_KEY. Format is a URI
3
- let uri
4
- try {
5
- uri = new URL(dotenvKey)
6
- } catch (e) {
7
- throw new Error('INVALID_DOTENV_KEY: Incomplete format. It should be a dotenv uri. (dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development)')
8
- }
9
-
10
- // Get decrypt key
11
- const key = uri.password
12
- if (!key) {
13
- throw new Error('INVALID_DOTENV_KEY: Missing key part')
14
- }
15
-
16
- return Buffer.from(key.slice(-64), 'hex')
17
- }
18
-
19
- module.exports = parseEncryptionKeyFromDotenvKey
@@ -1,19 +0,0 @@
1
- function parseEnvironmentFromDotenvKey (dotenvKey) {
2
- // Parse DOTENV_KEY. Format is a URI
3
- let uri
4
- try {
5
- uri = new URL(dotenvKey)
6
- } catch (e) {
7
- throw new Error(`INVALID_DOTENV_KEY: ${e.message}`)
8
- }
9
-
10
- // Get environment
11
- const environment = uri.searchParams.get('environment')
12
- if (!environment) {
13
- throw new Error('INVALID_DOTENV_KEY: Missing environment part')
14
- }
15
-
16
- return environment
17
- }
18
-
19
- module.exports = parseEnvironmentFromDotenvKey
@@ -1,89 +0,0 @@
1
- const fsx = require('./fsx')
2
- const path = require('path')
3
-
4
- const PUBLIC_KEY_SCHEMA = 'DOTENV_PUBLIC_KEY'
5
- const PRIVATE_KEY_SCHEMA = 'DOTENV_PRIVATE_KEY'
6
-
7
- const dotenvParse = require('./dotenvParse')
8
- const guessPrivateKeyName = require('./guessPrivateKeyName')
9
-
10
- function searchProcessEnv (privateKeyName) {
11
- if (process.env[privateKeyName] && process.env[privateKeyName].length > 0) {
12
- return process.env[privateKeyName]
13
- }
14
- }
15
-
16
- function searchKeysFile (privateKeyName, envFilepath, envKeysFilepath = null) {
17
- let keysFilepath = path.resolve(path.dirname(envFilepath), '.env.keys') // typical scenario
18
- if (envKeysFilepath) { // user specified -fk flag
19
- keysFilepath = path.resolve(envKeysFilepath)
20
- }
21
-
22
- if (fsx.existsSync(keysFilepath)) {
23
- const keysSrc = fsx.readFileX(keysFilepath)
24
- const keysParsed = dotenvParse(keysSrc)
25
-
26
- if (keysParsed[privateKeyName] && keysParsed[privateKeyName].length > 0) {
27
- return keysParsed[privateKeyName]
28
- }
29
- }
30
- }
31
-
32
- function invertForPrivateKeyName (envFilepath) {
33
- if (!fsx.existsSync(envFilepath)) {
34
- return null
35
- }
36
-
37
- const envSrc = fsx.readFileX(envFilepath)
38
- const envParsed = dotenvParse(envSrc)
39
-
40
- let publicKeyName
41
- for (const keyName of Object.keys(envParsed)) {
42
- if (keyName === PUBLIC_KEY_SCHEMA || keyName.startsWith(PUBLIC_KEY_SCHEMA)) {
43
- publicKeyName = keyName // find DOTENV_PUBLIC_KEY* in filename
44
- }
45
- }
46
-
47
- if (publicKeyName) {
48
- return publicKeyName.replace(PUBLIC_KEY_SCHEMA, PRIVATE_KEY_SCHEMA) // return inverted (DOTENV_PUBLIC_KEY* -> DOTENV_PRIVATE_KEY*) if found
49
- }
50
-
51
- return null
52
- }
53
-
54
- function smartDotenvPrivateKey (envFilepath, envKeysFilepath = null) {
55
- let privateKey = null
56
- let privateKeyName = guessPrivateKeyName(envFilepath) // DOTENV_PRIVATE_KEY_${ENVIRONMENT}
57
-
58
- // 1. attempt process.env first
59
- privateKey = searchProcessEnv(privateKeyName)
60
- if (privateKey) {
61
- return privateKey
62
- }
63
-
64
- // 2. attempt .env.keys second (path/to/.env.keys)
65
- privateKey = searchKeysFile(privateKeyName, envFilepath, envKeysFilepath)
66
- if (privateKey) {
67
- return privateKey
68
- }
69
-
70
- // 3. attempt inverting `DOTENV_PUBLIC_KEY*` name inside file (unlocks custom filenames not matching .env.${ENVIRONMENT} pattern)
71
- privateKeyName = invertForPrivateKeyName(envFilepath)
72
- if (privateKeyName) {
73
- // 3.1 attempt process.env first
74
- privateKey = searchProcessEnv(privateKeyName)
75
- if (privateKey) {
76
- return privateKey
77
- }
78
-
79
- // 3.2. attempt .env.keys second (path/to/.env.keys)
80
- privateKey = searchKeysFile(privateKeyName, envFilepath, envKeysFilepath)
81
- if (privateKey) {
82
- return privateKey
83
- }
84
- }
85
-
86
- return null
87
- }
88
-
89
- module.exports = smartDotenvPrivateKey
@@ -1,42 +0,0 @@
1
- const fsx = require('./fsx')
2
- const dotenvParse = require('./dotenvParse')
3
-
4
- const guessPublicKeyName = require('./guessPublicKeyName')
5
-
6
- function searchProcessEnv (publicKeyName) {
7
- if (process.env[publicKeyName] && process.env[publicKeyName].length > 0) {
8
- return process.env[publicKeyName]
9
- }
10
- }
11
-
12
- function searchEnvFile (publicKeyName, envFilepath) {
13
- if (fsx.existsSync(envFilepath)) {
14
- const keysSrc = fsx.readFileX(envFilepath)
15
- const keysParsed = dotenvParse(keysSrc)
16
-
17
- if (keysParsed[publicKeyName] && keysParsed[publicKeyName].length > 0) {
18
- return keysParsed[publicKeyName]
19
- }
20
- }
21
- }
22
-
23
- function smartDotenvPublicKey (envFilepath) {
24
- let publicKey = null
25
- const publicKeyName = guessPublicKeyName(envFilepath) // DOTENV_PUBLIC_KEY_${ENVIRONMENT}
26
-
27
- // 1. attempt process.env first
28
- publicKey = searchProcessEnv(publicKeyName)
29
- if (publicKey) {
30
- return publicKey
31
- }
32
-
33
- // 2. attempt .env.keys second (path/to/.env.keys)
34
- publicKey = searchEnvFile(publicKeyName, envFilepath)
35
- if (publicKey) {
36
- return publicKey
37
- }
38
-
39
- return null
40
- }
41
-
42
- module.exports = smartDotenvPublicKey