@dotenvx/dotenvx 2.1.5 → 2.2.1

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.
@@ -0,0 +1,81 @@
1
+ const { execFileSync } = require('child_process')
2
+
3
+ const keynames = require('../conventions/keynames')
4
+ const readEnvKey = require('../helpers/readEnvKey')
5
+ const removeEnvKey = require('../helpers/removeEnvKey')
6
+ const armoredKeyDisplay = require('../helpers/armoredKeyDisplay')
7
+
8
+ const SECURITY_BIN = '/usr/bin/security'
9
+ const SERVICE = 'dotenvx'
10
+
11
+ function addGenericPassword (publicKey, label, privateKey) {
12
+ try {
13
+ execFileSync(SECURITY_BIN, ['add-generic-password', '-U', '-s', SERVICE, '-a', publicKey, '-l', label, '-w', privateKey], { stdio: 'ignore' })
14
+ } catch {
15
+ throw new Error('failed to save private key to macOS Keychain')
16
+ }
17
+ }
18
+
19
+ class KeychainUp {
20
+ constructor (envFile = '.env', envKeysFile = '.env.keys') {
21
+ this.envFile = envFile
22
+ this.envKeysFile = envKeysFile
23
+ }
24
+
25
+ run () {
26
+ const envFile = this.envFile
27
+ const envKeysFile = this.envKeysFile
28
+
29
+ const {
30
+ publicKeyName,
31
+ privateKeyName
32
+ } = keynames(envFile)
33
+
34
+ const publicKey = readEnvKey(publicKeyName, envFile, { strict: true, ignore: ['MISSING_PRIVATE_KEY'] })
35
+ const label = `dotenvx (${armoredKeyDisplay(publicKey)})`
36
+ let existingPrivateKey
37
+
38
+ try {
39
+ existingPrivateKey = execFileSync(SECURITY_BIN, ['find-generic-password', '-s', SERVICE, '-a', publicKey, '-w'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim()
40
+ } catch {}
41
+
42
+ const privateKey = readEnvKey(privateKeyName, envKeysFile, { strict: !existingPrivateKey })
43
+
44
+ if (existingPrivateKey) {
45
+ if (!privateKey) {
46
+ return {
47
+ changed: false,
48
+ label,
49
+ privateKeyName,
50
+ privateKeyValue: existingPrivateKey,
51
+ publicKeyValue: publicKey
52
+ }
53
+ }
54
+
55
+ if (existingPrivateKey === privateKey) {
56
+ const result = removeEnvKey(privateKeyName, envKeysFile)
57
+
58
+ return {
59
+ changed: result.changed,
60
+ label,
61
+ privateKeyName,
62
+ privateKeyValue: privateKey,
63
+ publicKeyValue: publicKey
64
+ }
65
+ }
66
+ }
67
+
68
+ addGenericPassword(publicKey, label, privateKey)
69
+ removeEnvKey(privateKeyName, envKeysFile)
70
+
71
+ return {
72
+ changed: true,
73
+ label,
74
+ privateKeyName,
75
+ privateKeyValue: privateKey,
76
+ publicKeyValue: publicKey
77
+ }
78
+ }
79
+ }
80
+
81
+ module.exports = KeychainUp
@@ -22,7 +22,7 @@ async function decrypt (options = {}) {
22
22
  const ik = options.ik
23
23
  const ek = options.ek
24
24
  const fk = options.fk
25
- const provider = options.noArmor ? null : await providers(options)
25
+ const provider = await providers(options)
26
26
 
27
27
  const processedEnvs = []
28
28
  const changedFilepaths = []
@@ -36,6 +36,7 @@ async function setTransform (options = {}) {
36
36
  const value = options.value
37
37
  const fk = options.fk || '.env.keys'
38
38
  let noArmor = options.noArmor // key storage selector below
39
+ const noKeychain = options.noKeychain
39
40
  const noCreate = options.noCreate
40
41
  const noEncrypt = !options.encrypt || isPlainKey(key)
41
42
 
@@ -149,7 +150,8 @@ async function setTransform (options = {}) {
149
150
  envs: [env],
150
151
  all: true,
151
152
  envKeysFile: fk,
152
- noArmor
153
+ noArmor,
154
+ noKeychain
153
155
  })
154
156
 
155
157
  const before = parsed[key]