@dotenvx/dotenvx 1.71.2 → 1.72.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 (49) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/README.md +2 -2
  3. package/package.json +8 -3
  4. package/src/cli/actions/decrypt.js +7 -3
  5. package/src/cli/actions/encrypt.js +9 -3
  6. package/src/cli/actions/get.js +3 -1
  7. package/src/cli/actions/keypair.js +3 -1
  8. package/src/cli/actions/login.js +63 -0
  9. package/src/cli/actions/logout.js +36 -0
  10. package/src/cli/actions/normalizeArmorOptions.js +1 -2
  11. package/src/cli/actions/rotate.js +6 -2
  12. package/src/cli/actions/run.js +2 -1
  13. package/src/cli/actions/set.js +4 -2
  14. package/src/cli/dotenvx.js +14 -19
  15. package/src/db/device.js +73 -0
  16. package/src/db/session.js +186 -0
  17. package/src/lib/api/postLogout.js +34 -0
  18. package/src/lib/api/postOauthDeviceCode.js +38 -0
  19. package/src/lib/api/postOauthToken.js +35 -0
  20. package/src/lib/extensions/armor.js +13 -0
  21. package/src/lib/helpers/buildApiError.js +16 -0
  22. package/src/lib/helpers/buildOauthError.js +14 -0
  23. package/src/lib/helpers/createSpinner.js +1 -1
  24. package/src/lib/helpers/cryptography/armorKeypair.js +2 -1
  25. package/src/lib/helpers/cryptography/provision.js +2 -2
  26. package/src/lib/helpers/cryptography/provisionSync.js +2 -2
  27. package/src/lib/helpers/decryptDeviceValue.js +10 -0
  28. package/src/lib/helpers/encryptDeviceValue.js +9 -0
  29. package/src/lib/helpers/formatCode.js +11 -0
  30. package/src/lib/helpers/http.js +7 -0
  31. package/src/lib/helpers/jsonToEnv.js +7 -0
  32. package/src/lib/helpers/keyResolution/keyValues.js +3 -0
  33. package/src/lib/helpers/keyResolution/keyValuesFromEnvSrc.js +3 -0
  34. package/src/lib/helpers/keyResolution/keyValuesSync.js +3 -0
  35. package/src/lib/helpers/listenForOpenKey.js +46 -0
  36. package/src/lib/helpers/normalizeToken.js +5 -0
  37. package/src/lib/helpers/openUrl.js +7 -0
  38. package/src/lib/main.d.ts +0 -24
  39. package/src/lib/main.js +1 -1
  40. package/src/lib/services/decrypt.js +7 -2
  41. package/src/lib/services/encrypt.js +5 -2
  42. package/src/lib/services/get.js +8 -3
  43. package/src/lib/services/keypair.js +12 -3
  44. package/src/lib/services/login.js +26 -0
  45. package/src/lib/services/loginPoll.js +35 -0
  46. package/src/lib/services/logout.js +26 -0
  47. package/src/lib/services/rotate.js +10 -3
  48. package/src/lib/services/run.js +12 -3
  49. package/src/lib/services/sets.js +26 -5
@@ -38,6 +38,7 @@ class Encrypt {
38
38
  this.noCreate = noCreate
39
39
  this.token = token
40
40
  this.selectKeyStorage = options.selectKeyStorage
41
+ this.command = options.command
41
42
 
42
43
  this.processedEnvs = []
43
44
  this.changedFilepaths = new Set()
@@ -104,7 +105,8 @@ class Encrypt {
104
105
  const { publicKeyName, privateKeyName } = keyNames(envFilepath)
105
106
  const { publicKeyValue, privateKeyValue } = await keyValues(envFilepath, {
106
107
  keysFilepath: this.envKeysFilepath,
107
- noArmor: this.noArmor
108
+ noArmor: this.noArmor,
109
+ command: this.command
108
110
  })
109
111
 
110
112
  // first pass - provision
@@ -115,7 +117,8 @@ class Encrypt {
115
117
  keysFilepath: this.envKeysFilepath,
116
118
  noArmor: this.noArmor,
117
119
  token: this.token,
118
- selectKeyStorage: this.selectKeyStorage
120
+ selectKeyStorage: this.selectKeyStorage,
121
+ command: this.command
119
122
  })
120
123
  envSrc = prov.envSrc
121
124
  publicKey = prov.publicKey
@@ -3,26 +3,31 @@ const Errors = require('./../helpers/errors')
3
3
  const { determine } = require('./../helpers/envResolution')
4
4
 
5
5
  class Get {
6
- constructor (key, envs = [], overload = false, all = false, envKeysFilepath = null, noArmor = false) {
6
+ constructor (key, envs = [], overload = false, all = false, envKeysFilepath = null, noArmor = false, options = {}) {
7
7
  this.key = key
8
8
  this.envs = envs
9
9
  this.overload = overload
10
10
  this.all = all
11
11
  this.envKeysFilepath = envKeysFilepath
12
12
  this.noArmor = noArmor
13
+ this.command = options.command
13
14
  }
14
15
 
15
16
  runSync () {
16
17
  const processEnv = { ...process.env }
17
18
  const envs = determine(this.envs, processEnv)
18
- const { processedEnvs } = new Run(envs, this.overload, processEnv, this.envKeysFilepath, this.noArmor).runSync()
19
+ const { processedEnvs } = new Run(envs, this.overload, processEnv, this.envKeysFilepath, this.noArmor, {
20
+ command: this.command
21
+ }).runSync()
19
22
  return this._result(processedEnvs, processEnv)
20
23
  }
21
24
 
22
25
  async run () {
23
26
  const processEnv = { ...process.env }
24
27
  const envs = determine(this.envs, processEnv)
25
- const { processedEnvs } = await new Run(envs, this.overload, processEnv, this.envKeysFilepath, this.noArmor).run()
28
+ const { processedEnvs } = await new Run(envs, this.overload, processEnv, this.envKeysFilepath, this.noArmor, {
29
+ command: this.command
30
+ }).run()
26
31
  return this._result(processedEnvs, processEnv)
27
32
  }
28
33
 
@@ -5,10 +5,11 @@ const {
5
5
  } = require('./../helpers/keyResolution')
6
6
 
7
7
  class Keypair {
8
- constructor (envFile = '.env', envKeysFilepath = null, noArmor = false) {
8
+ constructor (envFile = '.env', envKeysFilepath = null, noArmor = false, options = {}) {
9
9
  this.envFile = envFile
10
10
  this.envKeysFilepath = envKeysFilepath
11
11
  this.noArmor = noArmor
12
+ this.command = options.command
12
13
  }
13
14
 
14
15
  runSync () {
@@ -17,7 +18,11 @@ class Keypair {
17
18
  const filepaths = this._filepaths()
18
19
  for (const filepath of filepaths) {
19
20
  const { publicKeyName, privateKeyName } = keyNames(filepath)
20
- const { publicKeyValue, privateKeyValue } = keyValuesSync(filepath, { keysFilepath: this.envKeysFilepath, noArmor: this.noArmor })
21
+ const { publicKeyValue, privateKeyValue } = keyValuesSync(filepath, {
22
+ keysFilepath: this.envKeysFilepath,
23
+ noArmor: this.noArmor,
24
+ command: this.command
25
+ })
21
26
 
22
27
  out[publicKeyName] = publicKeyValue
23
28
  out[privateKeyName] = privateKeyValue
@@ -32,7 +37,11 @@ class Keypair {
32
37
  const filepaths = this._filepaths()
33
38
  for (const filepath of filepaths) {
34
39
  const { publicKeyName, privateKeyName } = keyNames(filepath)
35
- const { publicKeyValue, privateKeyValue } = await keyValues(filepath, { keysFilepath: this.envKeysFilepath, noArmor: this.noArmor })
40
+ const { publicKeyValue, privateKeyValue } = await keyValues(filepath, {
41
+ keysFilepath: this.envKeysFilepath,
42
+ noArmor: this.noArmor,
43
+ command: this.command
44
+ })
36
45
 
37
46
  out[publicKeyName] = publicKeyValue
38
47
  out[privateKeyName] = privateKeyValue
@@ -0,0 +1,26 @@
1
+ const Session = require('../../db/session')
2
+ const PostOauthDeviceCode = require('../api/postOauthDeviceCode')
3
+
4
+ class Login {
5
+ constructor (hostname) {
6
+ this.hostname = hostname
7
+ }
8
+
9
+ async run () {
10
+ const sesh = new Session()
11
+ const devicePublicKey = sesh.devicePublicKey()
12
+ const systemInformation = await sesh.systemInformation()
13
+
14
+ const data = await new PostOauthDeviceCode(this.hostname, devicePublicKey, systemInformation).run()
15
+
16
+ return {
17
+ deviceCode: data.device_code,
18
+ userCode: data.user_code,
19
+ verificationUri: data.verification_uri,
20
+ verificationUriComplete: data.verification_uri_complete,
21
+ interval: data.interval
22
+ }
23
+ }
24
+ }
25
+
26
+ module.exports = Login
@@ -0,0 +1,35 @@
1
+ const Session = require('../../db/session')
2
+ const PostOauthToken = require('../api/postOauthToken')
3
+
4
+ class LoginPoll {
5
+ constructor (hostname, deviceCode, interval) {
6
+ this.hostname = hostname
7
+ this.deviceCode = deviceCode
8
+ this.interval = interval
9
+ }
10
+
11
+ async run () {
12
+ const sesh = new Session()
13
+
14
+ while (true) {
15
+ try {
16
+ const data = await new PostOauthToken(this.hostname, this.deviceCode).run()
17
+
18
+ if (data.access_token) {
19
+ sesh.login(this.hostname, data.id, data.username, data.access_token)
20
+ return data
21
+ }
22
+
23
+ await new Promise(resolve => setTimeout(resolve, this.interval * 1000))
24
+ } catch (error) {
25
+ if (error.code === 'authorization_pending') {
26
+ await new Promise(resolve => setTimeout(resolve, (this.interval + 1) * 1000))
27
+ } else {
28
+ throw error
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ module.exports = LoginPoll
@@ -0,0 +1,26 @@
1
+ const Session = require('../../db/session')
2
+ const PostLogout = require('../api/postLogout')
3
+
4
+ class Logout {
5
+ constructor (hostname) {
6
+ this.hostname = hostname
7
+ }
8
+
9
+ async run () {
10
+ const sesh = new Session()
11
+ const token = sesh.token()
12
+
13
+ const data = await new PostLogout(this.hostname, token).run()
14
+
15
+ const id = data.id
16
+ const username = data.username
17
+ const accessToken = data.access_token
18
+ const settingsDevicesUrl = `${this.hostname}/settings/devices`
19
+
20
+ sesh.logout(this.hostname, id, accessToken)
21
+
22
+ return { username, accessToken, settingsDevicesUrl }
23
+ }
24
+ }
25
+
26
+ module.exports = Logout
@@ -29,12 +29,13 @@ const dotenvParse = require('./../helpers/dotenvParse')
29
29
  const detectEncoding = require('./../helpers/detectEncoding')
30
30
 
31
31
  class Rotate {
32
- constructor (envs = [], key = [], excludeKey = [], envKeysFilepath = null, noArmor = false) {
32
+ constructor (envs = [], key = [], excludeKey = [], envKeysFilepath = null, noArmor = false, options = {}) {
33
33
  this.envs = determine(envs, process.env)
34
34
  this.key = key
35
35
  this.excludeKey = excludeKey
36
36
  this.envKeysFilepath = envKeysFilepath
37
37
  this.noArmor = noArmor
38
+ this.command = options.command
38
39
 
39
40
  this.processedEnvs = []
40
41
  this.changedFilepaths = new Set()
@@ -83,7 +84,11 @@ class Rotate {
83
84
  const envParsed = dotenvParse(envSrc, false, false, true)
84
85
 
85
86
  const { publicKeyName, privateKeyName } = keyNames(envFilepath)
86
- const { privateKeyValue } = await keyValues(envFilepath, { keysFilepath: this.envKeysFilepath, noArmor: this.noArmor })
87
+ const { privateKeyValue } = await keyValues(envFilepath, {
88
+ keysFilepath: this.envKeysFilepath,
89
+ noArmor: this.noArmor,
90
+ command: this.command
91
+ })
87
92
 
88
93
  let newPublicKey
89
94
  let newPrivateKey
@@ -91,7 +96,9 @@ class Rotate {
91
96
  let envKeysSrc
92
97
 
93
98
  if (!this.noArmor) {
94
- const kp = await armorKeypair()
99
+ const kp = await armorKeypair(undefined, {
100
+ command: this.command
101
+ })
95
102
  newPublicKey = kp.publicKey
96
103
  newPrivateKey = kp.privateKey
97
104
 
@@ -25,6 +25,7 @@ class Run {
25
25
  this.noArmor = noArmor
26
26
  this.noSpinner = options.noSpinner
27
27
  this.token = options.token
28
+ this.command = options.command
28
29
 
29
30
  this.processedEnvs = []
30
31
  this.readableFilepaths = new Set()
@@ -95,7 +96,13 @@ class Run {
95
96
  privateKeyName: resolvedPrivateKeyName,
96
97
  privateKeyValue,
97
98
  privateKeySource
98
- } = keyValuesFromEnvSrc(env, privateKeyName, { keysFilepath: this.envKeysFilepath, noArmor: this.noArmor, processEnv: this.processEnv, token: this.token })
99
+ } = keyValuesFromEnvSrc(env, privateKeyName, {
100
+ keysFilepath: this.envKeysFilepath,
101
+ noArmor: this.noArmor,
102
+ processEnv: this.processEnv,
103
+ token: this.token,
104
+ command: this.command
105
+ })
99
106
 
100
107
  const {
101
108
  parsed,
@@ -145,7 +152,8 @@ class Run {
145
152
  keysFilepath: this.envKeysFilepath,
146
153
  noArmor: this.noArmor,
147
154
  noSpinner: this.noSpinner,
148
- token: this.token
155
+ token: this.token,
156
+ command: this.command
149
157
  })
150
158
 
151
159
  const {
@@ -198,7 +206,8 @@ class Run {
198
206
  const { privateKeyValue, privateKeySource } = await keyValues(filepath, {
199
207
  keysFilepath: this.envKeysFilepath,
200
208
  noArmor: this.noArmor,
201
- token: this.token
209
+ token: this.token,
210
+ command: this.command
202
211
  })
203
212
 
204
213
  const {
@@ -34,7 +34,7 @@ function allValuesForKey (envSrc, key) {
34
34
  }
35
35
 
36
36
  class Sets {
37
- constructor (key, value, envs = [], encrypt = true, envKeysFilepath = null, noArmor = false, noCreate = false) {
37
+ constructor (key, value, envs = [], encrypt = true, envKeysFilepath = null, noArmor = false, noCreate = false, options = {}) {
38
38
  this.envs = determine(envs, process.env)
39
39
  this.key = key
40
40
  this.value = value
@@ -42,6 +42,7 @@ class Sets {
42
42
  this.envKeysFilepath = envKeysFilepath
43
43
  this.noArmor = noArmor
44
44
  this.noCreate = noCreate
45
+ this.command = options.command
45
46
 
46
47
  this.processedEnvs = []
47
48
  this.changedFilepaths = new Set()
@@ -131,11 +132,21 @@ class Sets {
131
132
  let privateKey
132
133
 
133
134
  const { publicKeyName, privateKeyName } = keyNames(filepath)
134
- const { publicKeyValue, privateKeyValue } = keyValuesSync(filepath, { keysFilepath: this.envKeysFilepath, noArmor: this.noArmor })
135
+ const { publicKeyValue, privateKeyValue } = keyValuesSync(filepath, {
136
+ keysFilepath: this.envKeysFilepath,
137
+ noArmor: this.noArmor,
138
+ command: this.command
139
+ })
135
140
 
136
141
  // first pass - provisionSync
137
142
  if (!privateKeyValue && !publicKeyValue) {
138
- const prov = provisionSync({ envSrc, envFilepath, keysFilepath: this.envKeysFilepath, noArmor: this.noArmor })
143
+ const prov = provisionSync({
144
+ envSrc,
145
+ envFilepath,
146
+ keysFilepath: this.envKeysFilepath,
147
+ noArmor: this.noArmor,
148
+ command: this.command
149
+ })
139
150
  envSrc = prov.envSrc
140
151
  publicKey = prov.publicKey
141
152
  privateKey = prov.privateKey
@@ -238,11 +249,21 @@ class Sets {
238
249
  let privateKey
239
250
 
240
251
  const { publicKeyName, privateKeyName } = keyNames(filepath)
241
- const { publicKeyValue, privateKeyValue } = await keyValues(filepath, { keysFilepath: this.envKeysFilepath, noArmor: this.noArmor })
252
+ const { publicKeyValue, privateKeyValue } = await keyValues(filepath, {
253
+ keysFilepath: this.envKeysFilepath,
254
+ noArmor: this.noArmor,
255
+ command: this.command
256
+ })
242
257
 
243
258
  // first pass - provision
244
259
  if (!privateKeyValue && !publicKeyValue) {
245
- const prov = await provision({ envSrc, envFilepath, keysFilepath: this.envKeysFilepath, noArmor: this.noArmor })
260
+ const prov = await provision({
261
+ envSrc,
262
+ envFilepath,
263
+ keysFilepath: this.envKeysFilepath,
264
+ noArmor: this.noArmor,
265
+ command: this.command
266
+ })
246
267
  envSrc = prov.envSrc
247
268
  publicKey = prov.publicKey
248
269
  privateKey = prov.privateKey