@dotenvx/dotenvx 1.69.1 → 1.70.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 (38) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +21 -15
  3. package/package.json +7 -6
  4. package/src/cli/actions/decrypt.js +8 -6
  5. package/src/cli/actions/encrypt.js +16 -22
  6. package/src/cli/actions/get.js +4 -4
  7. package/src/cli/actions/keypair.js +4 -4
  8. package/src/cli/actions/normalizeArmorOptions.js +11 -0
  9. package/src/cli/actions/rotate.js +6 -12
  10. package/src/cli/actions/run.js +8 -8
  11. package/src/cli/actions/set.js +6 -10
  12. package/src/cli/commands/ext.js +1 -1
  13. package/src/cli/dotenvx.js +33 -35
  14. package/src/db/session.js +9 -9
  15. package/src/lib/extensions/{vlt.js → armor.js} +4 -4
  16. package/src/lib/helpers/cryptography/{vltKeypair.js → armorKeypair.js} +4 -4
  17. package/src/lib/helpers/cryptography/armorKeypairSync.js +14 -0
  18. package/src/lib/helpers/cryptography/index.js +2 -2
  19. package/src/lib/helpers/cryptography/mutateKeysSrc.js +2 -2
  20. package/src/lib/helpers/cryptography/mutateKeysSrcSync.js +2 -2
  21. package/src/lib/helpers/cryptography/provision.js +8 -8
  22. package/src/lib/helpers/cryptography/provisionSync.js +6 -6
  23. package/src/lib/helpers/cryptography/provisionWithPrivateKey.js +1 -1
  24. package/src/lib/helpers/executeDynamic.js +57 -19
  25. package/src/lib/helpers/keyResolution/keyValues.js +13 -6
  26. package/src/lib/helpers/keyResolution/keyValuesFromEnvSrc.js +12 -5
  27. package/src/lib/helpers/keyResolution/keyValuesSync.js +15 -8
  28. package/src/lib/main.d.ts +37 -13
  29. package/src/lib/main.js +12 -16
  30. package/src/lib/services/decrypt.js +5 -3
  31. package/src/lib/services/encrypt.js +4 -4
  32. package/src/lib/services/get.js +4 -4
  33. package/src/lib/services/keypair.js +4 -4
  34. package/src/lib/services/rotate.js +9 -9
  35. package/src/lib/services/run.js +21 -8
  36. package/src/lib/services/sets.js +6 -6
  37. package/src/cli/actions/normalizeVltOptions.js +0 -10
  38. package/src/lib/helpers/cryptography/vltKeypairSync.js +0 -14
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /* c8 ignore start */
4
- const { Command } = require('commander')
4
+ const { Command, Option } = require('commander')
5
5
  const program = new Command()
6
6
 
7
7
  const { setLogLevel, logger } = require('../shared/logger')
@@ -43,7 +43,7 @@ program
43
43
  setLogLevel(options)
44
44
  })
45
45
 
46
- // for dynamic loading of dotenvx-vlt, etc
46
+ // for dynamic loading of dotenvx-armor, etc
47
47
  program
48
48
  .argument('[command]', 'dynamic command')
49
49
  .argument('[args...]', 'dynamic command arguments')
@@ -70,8 +70,9 @@ program.command('run')
70
70
  .option('--strict', 'process.exit(1) on any errors', false)
71
71
  .option('--convention <name>', 'load a .env convention (available conventions: [\'nextjs\', \'flow\'])')
72
72
  .option('--ignore <errorCodes...>', 'error code(s) to ignore (example: --ignore=MISSING_ENV_FILE)')
73
- .option('--no-ops', 'disable dotenvx-ops features')
74
- .option('--no-vlt', 'disable dotenvx-vlt features')
73
+ .option('--no-armor', 'disable dotenvx-armor features')
74
+ .addOption(new Option('--no-vlt', 'disable dotenvx-vlt features (deprecated. use --no-armor)').hideHelp())
75
+ .addOption(new Option('--no-ops', 'disable dotenvx-ops features (deprecated. use --no-armor)').hideHelp())
75
76
  .action(function (...args) {
76
77
  this.envs = envs
77
78
  return require('./actions/run').apply(this, args)
@@ -93,8 +94,9 @@ program.command('get')
93
94
  .option('-pp, --pretty-print', 'pretty print output')
94
95
  .option('--pp', 'pretty print output (alias)')
95
96
  .option('--format <type>', 'format of the output (json, shell, colon, eval)', 'json')
96
- .option('--no-ops', 'disable dotenvx-ops features')
97
- .option('--no-vlt', 'disable dotenvx-vlt features')
97
+ .option('--no-armor', 'disable dotenvx-armor features')
98
+ .addOption(new Option('--no-vlt', 'disable dotenvx-vlt features (deprecated. use --no-armor)').hideHelp())
99
+ .addOption(new Option('--no-ops', 'disable dotenvx-ops features (deprecated. use --no-armor)').hideHelp())
98
100
  .action(function (...args) {
99
101
  this.envs = envs
100
102
  return require('./actions/get').apply(this, args)
@@ -113,8 +115,9 @@ program.command('set')
113
115
  .option('-c, --encrypt', 'encrypt value', true)
114
116
  .option('-p, --plain', 'store value as plain text', false)
115
117
  .option('--no-create', 'do not create .env file(s) when missing')
116
- .option('--no-ops', 'disable dotenvx-ops features')
117
- .option('--no-vlt', 'disable dotenvx-vlt features')
118
+ .option('--no-armor', 'disable dotenvx-armor features')
119
+ .addOption(new Option('--no-vlt', 'disable dotenvx-vlt features (deprecated. use --no-armor)').hideHelp())
120
+ .addOption(new Option('--no-ops', 'disable dotenvx-ops features (deprecated. use --no-armor)').hideHelp())
118
121
  .action(function (...args) {
119
122
  this.envs = envs
120
123
  return require('./actions/set').apply(this, args)
@@ -128,10 +131,11 @@ program.command('encrypt')
128
131
  .option('-k, --key <keys...>', 'keys(s) to encrypt (default: all keys in file)')
129
132
  .option('-ek, --exclude-key <excludeKeys...>', 'keys(s) to exclude from encryption (default: none)')
130
133
  .option('--stdout', 'send to stdout')
131
- .option('--token <token>', 'set Vlt Ops token')
134
+ .option('--token <token>', 'set Armor token')
132
135
  .option('--no-create', 'do not create .env file(s) when missing')
133
- .option('--no-ops', 'disable dotenvx-ops features')
134
- .option('--no-vlt', 'disable dotenvx-vlt features')
136
+ .option('--no-armor', 'disable dotenvx-armor features')
137
+ .addOption(new Option('--no-vlt', 'disable dotenvx-vlt features (deprecated. use --no-armor)').hideHelp())
138
+ .addOption(new Option('--no-ops', 'disable dotenvx-ops features (deprecated. use --no-armor)').hideHelp())
135
139
  .action(function (...args) {
136
140
  this.envs = envs
137
141
  return require('./actions/encrypt').apply(this, args)
@@ -144,8 +148,9 @@ program.command('decrypt')
144
148
  .option('-fk, --env-keys-file <path>', 'path to your .env.keys file (default: same path as your env file)')
145
149
  .option('-k, --key <keys...>', 'keys(s) to decrypt (default: all keys in file)')
146
150
  .option('-ek, --exclude-key <excludeKeys...>', 'keys(s) to exclude from decryption (default: none)')
147
- .option('--no-ops', 'disable dotenvx-ops features')
148
- .option('--no-vlt', 'disable dotenvx-vlt features')
151
+ .option('--no-armor', 'disable dotenvx-armor features')
152
+ .addOption(new Option('--no-vlt', 'disable dotenvx-vlt features (deprecated. use --no-armor)').hideHelp())
153
+ .addOption(new Option('--no-ops', 'disable dotenvx-ops features (deprecated. use --no-armor)').hideHelp())
149
154
  .option('--stdout', 'send to stdout')
150
155
  .action(function (...args) {
151
156
  this.envs = envs
@@ -159,8 +164,9 @@ program.command('rotate')
159
164
  .option('-fk, --env-keys-file <path>', 'path to your .env.keys file (default: same path as your env file)')
160
165
  .option('-k, --key <keys...>', 'keys(s) to encrypt (default: all keys in file)')
161
166
  .option('-ek, --exclude-key <excludeKeys...>', 'keys(s) to exclude from encryption (default: none)')
162
- .option('--no-ops', 'disable dotenvx-ops features')
163
- .option('--no-vlt', 'disable dotenvx-vlt features')
167
+ .option('--no-armor', 'disable dotenvx-armor features')
168
+ .addOption(new Option('--no-vlt', 'disable dotenvx-vlt features (deprecated. use --no-armor)').hideHelp())
169
+ .addOption(new Option('--no-ops', 'disable dotenvx-ops features (deprecated. use --no-armor)').hideHelp())
164
170
  .option('--stdout', 'send to stdout')
165
171
  .action(function (...args) {
166
172
  this.envs = envs
@@ -174,8 +180,9 @@ program.command('keypair')
174
180
  .argument('[KEY]', 'environment variable key name')
175
181
  .option('-f, --env-file <paths...>', 'path(s) to your env file(s)')
176
182
  .option('-fk, --env-keys-file <path>', 'path to your .env.keys file (default: same path as your env file)')
177
- .option('--no-ops', 'disable dotenvx-ops features')
178
- .option('--no-vlt', 'disable dotenvx-vlt features')
183
+ .option('--no-armor', 'disable dotenvx-armor features')
184
+ .addOption(new Option('--no-vlt', 'disable dotenvx-vlt features (deprecated. use --no-armor)').hideHelp())
185
+ .addOption(new Option('--no-ops', 'disable dotenvx-ops features (deprecated. use --no-armor)').hideHelp())
179
186
  .option('-pp, --pretty-print', 'pretty print output')
180
187
  .option('--pp', 'pretty print output (alias)')
181
188
  .option('--format <type>', 'format of the output (json, shell, colon)', 'json')
@@ -202,12 +209,12 @@ program.command('doctor', { hidden: true })
202
209
  })
203
210
 
204
211
  // dotenvx login
205
- program.command('login')
206
- .description('log in to unlock ⛨ ARMORED KEYS ✦ BETA')
212
+ program.command('login', { hidden: true })
213
+ .description('')
207
214
  .allowUnknownOption()
208
215
  .action(() => {
209
- const rawArgs = ['ops', 'login', ...process.argv.slice(3)]
210
- executeDynamic(program, 'ops', rawArgs)
216
+ const rawArgs = ['armor', 'login', ...process.argv.slice(3)]
217
+ executeDynamic(program, 'armor', rawArgs)
211
218
  })
212
219
 
213
220
  // dotenvx logout
@@ -215,17 +222,8 @@ program.command('logout', { hidden: true })
215
222
  .description('log out of your dotenvx account')
216
223
  .allowUnknownOption()
217
224
  .action(() => {
218
- const rawArgs = ['ops', 'logout', ...process.argv.slice(3)]
219
- executeDynamic(program, 'ops', rawArgs)
220
- })
221
-
222
- // dotenvx armor
223
- program.command('armor', { hidden: true })
224
- .description('ARMORED KEYS ⛨')
225
- .allowUnknownOption()
226
- .action((args) => {
227
- const rawArgs = ['ops', 'armor', ...process.argv.slice(3)]
228
- executeDynamic(program, 'ops', rawArgs)
225
+ const rawArgs = ['armor', 'logout', ...process.argv.slice(3)]
226
+ executeDynamic(program, 'armor', rawArgs)
229
227
  })
230
228
 
231
229
  // dotenvx help
@@ -244,11 +242,11 @@ program.command('help [command]')
244
242
  }
245
243
  })
246
244
 
247
- // dotenvx vlt ops
245
+ // dotenvx armor
248
246
  program.addHelpText('after', ' ')
249
247
  program.addHelpText('after', 'Advanced: ')
250
- program.addHelpText('after', ' vlt Vlt Ops [www.dotenvx.com/vlt]')
251
- program.addHelpText('after', ' ext 🔌 extensions')
248
+ program.addHelpText('after', ' armor ARMORED KEYS [www.dotenvx.com/armor]')
249
+ program.addHelpText('after', ' ext extensions')
252
250
 
253
251
  // dotenvx ext
254
252
  program.addCommand(require('./commands/ext'))
package/src/db/session.js CHANGED
@@ -1,23 +1,23 @@
1
- const Vlt = require('./../lib/extensions/vlt')
1
+ const Armor = require('./../lib/extensions/armor')
2
2
  const { logger } = require('./../shared/logger')
3
3
 
4
4
  class Session {
5
5
  constructor () {
6
- this.vlt = new Vlt()
6
+ this.armor = new Armor()
7
7
  }
8
8
 
9
9
  //
10
- // vlt status helpers
10
+ // armor status helpers
11
11
  //
12
- async noVlt () {
13
- const status = await this.vlt.status()
14
- logger.debug(`vlt: ${status}`)
12
+ async noArmor () {
13
+ const status = await this.armor.status()
14
+ logger.debug(`armor: ${status}`)
15
15
  return status === 'off'
16
16
  }
17
17
 
18
- noVltSync () {
19
- const status = this.vlt.statusSync()
20
- logger.debug(`vlt: ${status}`)
18
+ noArmorSync () {
19
+ const status = this.armor.statusSync()
20
+ logger.debug(`armor: ${status}`)
21
21
  return status === 'off'
22
22
  }
23
23
  }
@@ -4,9 +4,9 @@ const util = require('util')
4
4
  const { logger } = require('../../shared/logger')
5
5
 
6
6
  const execFile = util.promisify(childProcess.execFile)
7
- const BINARY_NAMES = ['dotenvx-vlt', 'dotenvx-ops']
7
+ const BINARY_NAMES = ['dotenvx-armor', 'dotenvx-vlt', 'dotenvx-ops']
8
8
 
9
- class Vlt {
9
+ class Armor {
10
10
  async status () {
11
11
  if (this._isForcedOff()) return 'off'
12
12
 
@@ -195,8 +195,8 @@ class Vlt {
195
195
  }
196
196
 
197
197
  _isForcedOff () {
198
- return process.env.DOTENVX_NO_OPS === 'true' || process.env.DOTENVX_NO_VLT === 'true'
198
+ return process.env.DOTENVX_NO_ARMOR === 'true' || process.env.DOTENVX_NO_VLT === 'true' || process.env.DOTENVX_NO_OPS === 'true'
199
199
  }
200
200
  }
201
201
 
202
- module.exports = Vlt
202
+ module.exports = Armor
@@ -1,6 +1,6 @@
1
- const Vlt = require('../../extensions/vlt')
1
+ const Armor = require('../../extensions/armor')
2
2
 
3
- async function vltKeypair (existingPublicKey, options = {}) {
3
+ async function armorKeypair (existingPublicKey, options = {}) {
4
4
  const hooks = options.hooks || {}
5
5
  if (hooks.before) await hooks.before()
6
6
 
@@ -13,7 +13,7 @@ async function vltKeypair (existingPublicKey, options = {}) {
13
13
 
14
14
  let kp
15
15
  try {
16
- kp = await new Vlt().keypair(existingPublicKey, keypairOptions)
16
+ kp = await new Armor().keypair(existingPublicKey, keypairOptions)
17
17
  } finally {
18
18
  if (hooks.after) await hooks.after()
19
19
  }
@@ -27,4 +27,4 @@ async function vltKeypair (existingPublicKey, options = {}) {
27
27
  }
28
28
  }
29
29
 
30
- module.exports = vltKeypair
30
+ module.exports = armorKeypair
@@ -0,0 +1,14 @@
1
+ const Armor = require('../../extensions/armor')
2
+
3
+ function armorKeypairSync (existingPublicKey, options = {}) {
4
+ const kp = new Armor().keypairSync(existingPublicKey, options)
5
+ const publicKey = kp.public_key
6
+ const privateKey = kp.private_key
7
+
8
+ return {
9
+ publicKey,
10
+ privateKey
11
+ }
12
+ }
13
+
14
+ module.exports = armorKeypairSync
@@ -1,6 +1,6 @@
1
1
  module.exports = {
2
- vltKeypair: require('./vltKeypair'),
3
- vltKeypairSync: require('./vltKeypairSync'),
2
+ armorKeypair: require('./armorKeypair'),
3
+ armorKeypairSync: require('./armorKeypairSync'),
4
4
  localKeypair: require('./localKeypair'),
5
5
  encryptValue: require('./encryptValue'),
6
6
  decryptKeyValue: require('./decryptKeyValue'),
@@ -2,7 +2,7 @@ const FIRST_TIME_KEYS_SRC = [
2
2
  '#/------------------!DOTENV_PRIVATE_KEYS!-------------------/',
3
3
  '#/ private decryption keys. DO NOT commit to source control /',
4
4
  '#/ [how it works](https://dotenvx.com/encryption) /',
5
- '#/ harden private keys: `dotenvx armor up` /',
5
+ '#/ ARMORED KEYS: `dotenvx armor up` /',
6
6
  '#/----------------------------------------------------------/'
7
7
  ].join('\n')
8
8
 
@@ -25,7 +25,7 @@ async function mutateKeysSrc ({ envFilepath, keysFilepath, privateKeyName, priva
25
25
  keysSrc = keysSrc.length > 1 ? keysSrc : `${FIRST_TIME_KEYS_SRC}\n`
26
26
  keysSrc = `${keysSrc}\n${appendPrivateKey}`
27
27
 
28
- await fsx.writeFileX(resolvedKeysFilepath, keysSrc) // TODO: don't write if ops
28
+ await fsx.writeFileX(resolvedKeysFilepath, keysSrc) // TODO: don't write if armor
29
29
 
30
30
  const envKeysFilepath = keysFilepath || path.join(path.dirname(envFilepath), path.basename(resolvedKeysFilepath))
31
31
 
@@ -2,7 +2,7 @@ const FIRST_TIME_KEYS_SRC = [
2
2
  '#/------------------!DOTENV_PRIVATE_KEYS!-------------------/',
3
3
  '#/ private decryption keys. DO NOT commit to source control /',
4
4
  '#/ [how it works](https://dotenvx.com/encryption) /',
5
- '#/ harden private keys: `dotenvx armor up` /',
5
+ '#/ ARMORED KEYS: `dotenvx armor up` /',
6
6
  '#/----------------------------------------------------------/'
7
7
  ].join('\n')
8
8
 
@@ -25,7 +25,7 @@ function mutateKeysSrcSync ({ envFilepath, keysFilepath, privateKeyName, private
25
25
  keysSrc = keysSrc.length > 1 ? keysSrc : `${FIRST_TIME_KEYS_SRC}\n`
26
26
  keysSrc = `${keysSrc}\n${appendPrivateKey}`
27
27
 
28
- fsx.writeFileXSync(resolvedKeysFilepath, keysSrc) // TODO: don't write if ops
28
+ fsx.writeFileXSync(resolvedKeysFilepath, keysSrc) // TODO: don't write if armor
29
29
 
30
30
  const envKeysFilepath = keysFilepath || path.join(path.dirname(envFilepath), path.basename(resolvedKeysFilepath))
31
31
 
@@ -1,13 +1,13 @@
1
1
  const mutateSrc = require('./mutateSrc')
2
2
  const mutateKeysSrc = require('./mutateKeysSrc')
3
- const vltKeypair = require('./vltKeypair')
3
+ const armorKeypair = require('./armorKeypair')
4
4
  const localKeypair = require('./localKeypair')
5
5
  const { keyNames } = require('../keyResolution')
6
6
 
7
- async function provision ({ envSrc, envFilepath, keysFilepath, noVlt, token, keypairHooks, selectKeyStorage }) {
8
- noVlt = noVlt !== false
9
- if (!noVlt && selectKeyStorage) {
10
- noVlt = await selectKeyStorage() !== 'armored'
7
+ async function provision ({ envSrc, envFilepath, keysFilepath, noArmor, token, keypairHooks, selectKeyStorage }) {
8
+ noArmor = noArmor !== false
9
+ if (!noArmor && selectKeyStorage) {
10
+ noArmor = await selectKeyStorage() !== 'armored'
11
11
  }
12
12
 
13
13
  const { publicKeyName, privateKeyName } = keyNames(envFilepath)
@@ -19,12 +19,12 @@ async function provision ({ envSrc, envFilepath, keysFilepath, noVlt, token, key
19
19
  let localPrivateKeyAdded = false
20
20
  let remotePrivateKeyAdded = false
21
21
 
22
- if (noVlt) {
22
+ if (noArmor) {
23
23
  const kp = localKeypair()
24
24
  publicKey = kp.publicKey
25
25
  privateKey = kp.privateKey
26
26
  } else {
27
- const kp = await vltKeypair(undefined, { token, envFilepath, hooks: keypairHooks })
27
+ const kp = await armorKeypair(undefined, { token, envFilepath, hooks: keypairHooks })
28
28
  publicKey = kp.publicKey
29
29
  privateKey = kp.privateKey
30
30
  }
@@ -32,7 +32,7 @@ async function provision ({ envSrc, envFilepath, keysFilepath, noVlt, token, key
32
32
  const mutated = mutateSrc({ envSrc, envFilepath, keysFilepath, publicKeyName, publicKeyValue: publicKey })
33
33
  envSrc = mutated.envSrc
34
34
 
35
- if (noVlt) {
35
+ if (noArmor) {
36
36
  const mutated = await mutateKeysSrc({ envFilepath, keysFilepath, privateKeyName, privateKeyValue: privateKey })
37
37
  keysSrc = mutated.keysSrc
38
38
  envKeysFilepath = mutated.envKeysFilepath
@@ -1,11 +1,11 @@
1
1
  const mutateSrc = require('./mutateSrc')
2
2
  const mutateKeysSrcSync = require('./mutateKeysSrcSync')
3
- const vltKeypairSync = require('./vltKeypairSync')
3
+ const armorKeypairSync = require('./armorKeypairSync')
4
4
  const localKeypair = require('./localKeypair')
5
5
  const { keyNames } = require('../keyResolution')
6
6
 
7
- function provisionSync ({ envSrc, envFilepath, keysFilepath, noVlt }) {
8
- noVlt = noVlt !== false
7
+ function provisionSync ({ envSrc, envFilepath, keysFilepath, noArmor }) {
8
+ noArmor = noArmor !== false
9
9
  const { publicKeyName, privateKeyName } = keyNames(envFilepath)
10
10
 
11
11
  let publicKey
@@ -15,12 +15,12 @@ function provisionSync ({ envSrc, envFilepath, keysFilepath, noVlt }) {
15
15
  let localPrivateKeyAdded = false
16
16
  let remotePrivateKeyAdded = false
17
17
 
18
- if (noVlt) {
18
+ if (noArmor) {
19
19
  const kp = localKeypair()
20
20
  publicKey = kp.publicKey
21
21
  privateKey = kp.privateKey
22
22
  } else {
23
- const kp = vltKeypairSync(undefined, { envFilepath })
23
+ const kp = armorKeypairSync(undefined, { envFilepath })
24
24
  publicKey = kp.publicKey
25
25
  privateKey = kp.privateKey
26
26
  }
@@ -28,7 +28,7 @@ function provisionSync ({ envSrc, envFilepath, keysFilepath, noVlt }) {
28
28
  const mutated = mutateSrc({ envSrc, envFilepath, keysFilepath, publicKeyName, publicKeyValue: publicKey })
29
29
  envSrc = mutated.envSrc
30
30
 
31
- if (noVlt) {
31
+ if (noArmor) {
32
32
  const mutated = mutateKeysSrcSync({ envFilepath, keysFilepath, privateKeyName, privateKeyValue: privateKey })
33
33
  keysSrc = mutated.keysSrc
34
34
  envKeysFilepath = mutated.envKeysFilepath
@@ -3,7 +3,7 @@ const mutateSrc = require('./mutateSrc')
3
3
  const localKeypair = require('./localKeypair')
4
4
 
5
5
  function provisionWithPrivateKey ({ envSrc, envFilepath, keysFilepath, privateKeyValue, publicKeyValue, publicKeyName }) {
6
- const { publicKey, privateKey } = localKeypair(privateKeyValue) // noVlt doesn't matter here since privateKeyValue was already discovered prior (via vlt and local) and passed as privateKeyValue
6
+ const { publicKey, privateKey } = localKeypair(privateKeyValue) // noArmor doesn't matter here since privateKeyValue was already discovered prior (via armor and local) and passed as privateKeyValue
7
7
 
8
8
  // if derivation doesn't match what's in the file (or preset in env)
9
9
  if (publicKeyValue && publicKeyValue !== publicKey) {
@@ -2,23 +2,35 @@ const path = require('path')
2
2
  const childProcess = require('child_process')
3
3
  const { logger } = require('../../shared/logger')
4
4
 
5
- function installCommandForVlt () {
6
- return 'curl -sfS https://dotenvx.sh/vlt | sh'
7
- }
8
-
9
- function vltBanner (installCommand) {
5
+ function armorBanner () {
10
6
  const lines = [
7
+ ' [www.dotenvx.com/armor]',
8
+ '–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––',
9
+ ' __ ____ __ ',
10
+ ' | || |',
11
+ ' | __||__ |',
12
+ ' | ‾‾||‾‾ |',
13
+ ' | || |',
14
+ ' \\ || /',
15
+ ' \\ __ /',
16
+ '',
17
+ ' Dotenvx Armor ⛨',
18
+ '',
19
+ ' ARMORED KEYS',
20
+ ' Private keys. Off device. Under guard.',
11
21
  '',
12
- ' ██╗ ██╗██╗ ████████╗',
13
- ' ██║ ██║██║ ╚══██╔══╝',
14
- ' ██║ ██║██║ ██║ ',
15
- ' ╚██╗ ██╔╝██║ ██║ [www.dotenvx.com/vlt]',
16
- ' ╚████╔╝ ███████╗██║ ',
17
- ' ╚═══╝ ╚══════╝╚═╝ ',
22
+ ' -',
18
23
  '',
19
- ' ⛨ ARMORED KEYS: Harden your private keys.',
20
- ` ⮕ install [${installCommand}]`,
21
- ' ⮕ then run [dotenvx-vlt login]'
24
+ ' Install one',
25
+ ' [curl -sfS https://dotenvx.sh/armor | sh]',
26
+ ' [npm i @dotenvx/dotenvx-armor --save]',
27
+ '',
28
+ ' -',
29
+ '',
30
+ ' Then',
31
+ ' [dotenvx armor up]',
32
+ ' (sign in when prompted)',
33
+ ''
22
34
  ]
23
35
 
24
36
  const innerWidth = Math.max(67, ...lines.map((line) => line.length))
@@ -29,6 +41,26 @@ function vltBanner (installCommand) {
29
41
  return `${top}\n${middle}\n${bottom}`
30
42
  }
31
43
 
44
+ function dynamicAttempts (command, forwardedArgs) {
45
+ if (command === 'vlt') {
46
+ return [
47
+ ['dotenvx-armor', forwardedArgs],
48
+ ['dotenvx-vlt', forwardedArgs],
49
+ ['dotenvx-ops', forwardedArgs]
50
+ ]
51
+ }
52
+
53
+ if (command === 'ops') {
54
+ return [
55
+ ['dotenvx-armor', forwardedArgs],
56
+ ['dotenvx-ops', forwardedArgs],
57
+ ['dotenvx-vlt', forwardedArgs]
58
+ ]
59
+ }
60
+
61
+ return [[`dotenvx-${command}`, forwardedArgs]]
62
+ }
63
+
32
64
  function executeDynamic (program, command, rawArgs) {
33
65
  if (!command) {
34
66
  program.outputHelp()
@@ -47,14 +79,20 @@ function executeDynamic (program, command, rawArgs) {
47
79
  const newPath = `${binPath}:${process.env.PATH}`
48
80
  const env = { ...process.env, PATH: newPath }
49
81
 
50
- const result = childProcess.spawnSync(`dotenvx-${command}`, forwardedArgs, { stdio: 'inherit', env })
82
+ const spawnOptions = { stdio: 'inherit', env }
83
+ let result
84
+ for (const [spawnCommand, spawnArgs] of dynamicAttempts(command, forwardedArgs)) {
85
+ result = childProcess.spawnSync(spawnCommand, spawnArgs, spawnOptions)
86
+ if (!result.error) break
87
+ }
88
+
51
89
  if (result.error) {
52
90
  if (command === 'vlt') {
53
- const installCommand = installCommandForVlt()
54
- console.log(vltBanner(installCommand))
91
+ console.log(armorBanner())
55
92
  } else if (command === 'ops') {
56
- const installCommand = installCommandForVlt()
57
- console.log(vltBanner(installCommand))
93
+ console.log(armorBanner())
94
+ } else if (command === 'armor') {
95
+ console.log(armorBanner())
58
96
  } else {
59
97
  logger.info(`error: unknown command '${command}'`)
60
98
  }
@@ -5,7 +5,7 @@ const dotenvParse = require('./../dotenvParse')
5
5
  const keyNames = require('./keyNames')
6
6
  const readProcessKey = require('./readProcessKey')
7
7
  const readFileKey = require('./readFileKey')
8
- const vltKeypair = require('../cryptography/vltKeypair')
8
+ const armorKeypair = require('../cryptography/armorKeypair')
9
9
 
10
10
  async function invertForPrivateKeyName (filepath) {
11
11
  const PUBLIC_KEY_SCHEMA = 'DOTENV_PUBLIC_KEY'
@@ -34,13 +34,14 @@ async function invertForPrivateKeyName (filepath) {
34
34
 
35
35
  async function keyValues (filepath, opts = {}) {
36
36
  let keysFilepath = opts.keysFilepath || null
37
- const noVlt = opts.noVlt === true
37
+ const noArmor = opts.noArmor === true
38
38
  const names = keyNames(filepath)
39
39
  const publicKeyName = names.publicKeyName // DOTENV_PUBLIC_KEY_${ENVIRONMENT}
40
40
  let privateKeyName = names.privateKeyName // DOTENV_PRIVATE_KEY_${ENVIRONMENT}
41
41
 
42
42
  let publicKey = null
43
43
  let privateKey = null
44
+ let privateKeySource = null
44
45
 
45
46
  // public key: process.env first, then .env*
46
47
  publicKey = readProcessKey(publicKeyName)
@@ -70,16 +71,22 @@ async function keyValues (filepath, opts = {}) {
70
71
  }
71
72
  }
72
73
 
73
- // vlt
74
- if (!noVlt && !privateKey && publicKey && publicKey.length > 0) {
75
- const kp = await vltKeypair(publicKey, { envFilepath: filepath, hooks: opts.keypairHooks })
74
+ // armor
75
+ if (!noArmor && !privateKey && publicKey && publicKey.length > 0) {
76
+ const kp = await armorKeypair(publicKey, { envFilepath: filepath, hooks: opts.keypairHooks })
76
77
  privateKey = kp.privateKey
78
+ privateKeySource = 'armor'
77
79
  }
78
80
 
79
- return {
81
+ const result = {
80
82
  publicKeyValue: publicKey || null, // important to make sure name is rendered
81
83
  privateKeyValue: privateKey || null // important to make sure name is rendered
82
84
  }
85
+ if (privateKeySource) {
86
+ result.privateKeySource = privateKeySource
87
+ }
88
+
89
+ return result
83
90
  }
84
91
 
85
92
  module.exports = keyValues
@@ -2,7 +2,7 @@ const path = require('path')
2
2
 
3
3
  const dotenvParse = require('./../dotenvParse')
4
4
  const readFileKeySync = require('./readFileKeySync')
5
- const vltKeypairSync = require('../cryptography/vltKeypairSync')
5
+ const armorKeypairSync = require('../cryptography/armorKeypairSync')
6
6
 
7
7
  const PUBLIC_KEY_SCHEMA = 'DOTENV_PUBLIC_KEY'
8
8
  const PRIVATE_KEY_SCHEMA = 'DOTENV_PRIVATE_KEY'
@@ -25,7 +25,7 @@ function publicKeyNameFromEnvSrc (envParsed) {
25
25
 
26
26
  function keyValuesFromEnvSrc (src, privateKeyName = null, opts = {}) {
27
27
  let keysFilepath = opts.keysFilepath || null
28
- const noVlt = opts.noVlt === true
28
+ const noArmor = opts.noArmor === true
29
29
  const processEnv = opts.processEnv || process.env
30
30
  const envParsed = dotenvParse(src)
31
31
 
@@ -37,6 +37,7 @@ function keyValuesFromEnvSrc (src, privateKeyName = null, opts = {}) {
37
37
  }
38
38
 
39
39
  let privateKeyValue = null
40
+ let privateKeySource = null
40
41
  if (privateKeyName) {
41
42
  privateKeyValue = readProcessKey(processEnv, privateKeyName)
42
43
 
@@ -51,16 +52,22 @@ function keyValuesFromEnvSrc (src, privateKeyName = null, opts = {}) {
51
52
  }
52
53
  }
53
54
 
54
- if (!noVlt && !privateKeyValue && publicKeyValue && publicKeyValue.length > 0) {
55
- const kp = vltKeypairSync(publicKeyValue)
55
+ if (!noArmor && !privateKeyValue && publicKeyValue && publicKeyValue.length > 0) {
56
+ const kp = armorKeypairSync(publicKeyValue)
56
57
  privateKeyValue = kp.privateKey
58
+ privateKeySource = 'armor'
57
59
  }
58
60
 
59
- return {
61
+ const result = {
60
62
  publicKeyValue: publicKeyValue || null,
61
63
  privateKeyValue: privateKeyValue || null,
62
64
  privateKeyName: privateKeyName || null
63
65
  }
66
+ if (privateKeySource) {
67
+ result.privateKeySource = privateKeySource
68
+ }
69
+
70
+ return result
64
71
  }
65
72
 
66
73
  module.exports = keyValuesFromEnvSrc
@@ -5,7 +5,7 @@ const dotenvParse = require('./../dotenvParse')
5
5
  const keyNames = require('./keyNames')
6
6
  const readProcessKey = require('./readProcessKey')
7
7
  const readFileKeySync = require('./readFileKeySync')
8
- const vltKeypairSync = require('../cryptography/vltKeypairSync')
8
+ const armorKeypairSync = require('../cryptography/armorKeypairSync')
9
9
 
10
10
  function invertForPrivateKeyName (filepath) {
11
11
  const PUBLIC_KEY_SCHEMA = 'DOTENV_PUBLIC_KEY'
@@ -34,13 +34,14 @@ function invertForPrivateKeyName (filepath) {
34
34
 
35
35
  function keyValuesSync (filepath, opts = {}) {
36
36
  let keysFilepath = opts.keysFilepath || null
37
- const noVlt = opts.noVlt === true
37
+ const noArmor = opts.noArmor === true
38
38
  const names = keyNames(filepath)
39
39
  const publicKeyName = names.publicKeyName // DOTENV_PUBLIC_KEY_${ENVIRONMENT}
40
40
  let privateKeyName = names.privateKeyName // DOTENV_PRIVATE_KEY_${ENVIRONMENT}
41
41
 
42
42
  let publicKey = null
43
43
  let privateKey = null
44
+ let privateKeySource = null
44
45
 
45
46
  // public key: process.env first, then .env*
46
47
  publicKey = readProcessKey(publicKeyName)
@@ -70,21 +71,27 @@ function keyValuesSync (filepath, opts = {}) {
70
71
  }
71
72
  }
72
73
 
73
- // vlt
74
- if (!noVlt && !privateKey && publicKey && publicKey.length > 0) {
75
- const vltOptions = { envFilepath: filepath }
74
+ // armor
75
+ if (!noArmor && !privateKey && publicKey && publicKey.length > 0) {
76
+ const armorOptions = { envFilepath: filepath }
76
77
  if (opts.noSpinner) {
77
- vltOptions.noSpinner = true
78
+ armorOptions.noSpinner = true
78
79
  }
79
80
 
80
- const kp = vltKeypairSync(publicKey, vltOptions)
81
+ const kp = armorKeypairSync(publicKey, armorOptions)
81
82
  privateKey = kp.privateKey
83
+ privateKeySource = 'armor'
82
84
  }
83
85
 
84
- return {
86
+ const result = {
85
87
  publicKeyValue: publicKey || null, // important to make sure name is rendered
86
88
  privateKeyValue: privateKey || null // important to make sure name is rendered
87
89
  }
90
+ if (privateKeySource) {
91
+ result.privateKeySource = privateKeySource
92
+ }
93
+
94
+ return result
88
95
  }
89
96
 
90
97
  module.exports = keyValuesSync