@dotenvx/dotenvx 1.39.0 → 1.40.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 CHANGED
@@ -2,7 +2,21 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- [Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.39.0...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.40.0...main)
6
+
7
+ ## [1.40.0](https://github.com/dotenvx/dotenvx/compare/v1.39.1...v1.40.0)
8
+
9
+ ### Added
10
+
11
+ * Smarter `ext precommit` and `ext prebuild` – catch duplicate KEYs in the same .env file where one is mistakenly left unencrypted ([#567](https://github.com/dotenvx/dotenvx/pull/567))
12
+
13
+ ## [1.39.1](https://github.com/dotenvx/dotenvx/compare/v1.39.0...v1.39.1)
14
+
15
+ ### Added
16
+
17
+ * Add `version` to homebrew formula ([#564](https://github.com/dotenvx/dotenvx/pull/564))
18
+
19
+ ## [1.39.0](https://github.com/dotenvx/dotenvx/compare/v1.38.5...v1.39.0)
6
20
 
7
21
  ### Added
8
22
 
package/README.md CHANGED
@@ -614,6 +614,9 @@ More examples
614
614
 
615
615
  $ dotenvx run --convention=nextjs -- node index.js
616
616
  Hello development local
617
+
618
+ $ dotenvx run --convention=flow -- node index.js
619
+ Hello development local
617
620
  ```
618
621
 
619
622
  (more conventions available upon request)
@@ -1156,6 +1159,29 @@ Advanced CLI commands.
1156
1159
  development local
1157
1160
  ```
1158
1161
 
1162
+ </details>
1163
+ * <details><summary>`get KEY --convention=flow`</summary><br>
1164
+
1165
+ Return a single environment variable's value using [dotenv-flow's convention](https://www.npmjs.com/package/dotenv-flow). Set `--convention` to `flow`:
1166
+
1167
+ ```sh
1168
+ $ echo "HELLO=development local" > .env.development.local
1169
+ $ echo "HELLO=development" > .env.development
1170
+ $ echo "HELLO=local" > .env.local
1171
+ $ echo "HELLO=env" > .env
1172
+ $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
1173
+
1174
+ $ NODE_ENV=development dotenvx get HELLO --convention=flow
1175
+ development local
1176
+ ```
1177
+
1178
+ Further, we recommend using `DOTENV_ENV` over `NODE_ENV`– as `dotenvx` works everywhere, not just node.
1179
+
1180
+ ```sh
1181
+ $ DOTENV_ENV=development dotenvx get HELLO --convention=flow
1182
+ development local
1183
+ ```
1184
+
1159
1185
  </details>
1160
1186
  * <details><summary>`get` (json)</summary><br>
1161
1187
 
@@ -2261,6 +2287,128 @@ Use dotenvx directly in code.
2261
2287
 
2262
2288
  </details>
2263
2289
 
2290
+ ### Pro 🏆
2291
+
2292
+ *Secrets Management – Done Right. Encrypted, Cloaked, Secrets as Code.*
2293
+
2294
+ * <details><summary>`pro keypair`</summary><br>
2295
+
2296
+ Print fully managed public/private keys for `.env` file.
2297
+
2298
+ ```sh
2299
+ $ echo "HELLO=World" > .env
2300
+ $ dotenvx encrypt
2301
+
2302
+ $ dotenvx pro push
2303
+
2304
+ $ dotenvx pro keypair
2305
+ {"DOTENV_PUBLIC_KEY":"<publicKey>","DOTENV_PRIVATE_KEY":"<privateKey>"}
2306
+ ```
2307
+
2308
+ </details>
2309
+ * <details><summary>`pro keypair -f`</summary><br>
2310
+
2311
+ Print fully managed public/private keys for `.env.production` file.
2312
+
2313
+ ```sh
2314
+ $ echo "HELLO=Production" > .env.production
2315
+ $ dotenvx encrypt -f .env.production
2316
+
2317
+ $ dotenvx pro push
2318
+
2319
+ $ dotenvx pro keypair -f .env.production
2320
+ {"DOTENV_PUBLIC_KEY_PRODUCTION":"<publicKey>","DOTENV_PRIVATE_KEY_PRODUCTION":"<privateKey>"}
2321
+ ```
2322
+
2323
+ </details>
2324
+ * <details><summary>`pro keypair DOTENV_PRIVATE_KEY`</summary><br>
2325
+
2326
+ Print specific fully managed keypair for `.env` file.
2327
+
2328
+ ```sh
2329
+ $ echo "HELLO=World" > .env
2330
+ $ dotenvx encrypt
2331
+
2332
+ $ dotenvx pro push
2333
+
2334
+ $ dotenvx pro keypair DOTENV_PRIVATE_KEY
2335
+ <privateKey>
2336
+ ```
2337
+
2338
+ </details>
2339
+ * <details><summary>`pro settings org`</summary><br>
2340
+
2341
+ Print organization.
2342
+
2343
+ ```sh
2344
+ $ dotenvx pro settings org
2345
+ motdotla
2346
+ ```
2347
+
2348
+ </details>
2349
+ * <details><summary>`pro settings orgpublickey`</summary><br>
2350
+
2351
+ Print organization public key–used for encrypting project private keys.
2352
+
2353
+ ```sh
2354
+ $ dotenvx pro settings orgpublickey
2355
+ 02761eccd2a442ebbfa14ac2e72762d885a1e96b8949428deea62db305947d6408
2356
+ ```
2357
+
2358
+ </details>
2359
+ * <details><summary>`pro settings orgprivatekey`</summary><br>
2360
+
2361
+ Print masked organization private key–used for decrypting project private keys.
2362
+
2363
+ ```sh
2364
+ $ dotenvx pro settings orgprivatekey
2365
+ 322c004*********************************************************
2366
+ ```
2367
+
2368
+ </details>
2369
+ * <details><summary>`pro settings orgprivatekey --unmask`</summary><br>
2370
+
2371
+ Print unmasked organization private key–used for decrypting project private keys.
2372
+
2373
+ ```sh
2374
+ $ dotenvx pro settings orgprivatekey --unmask
2375
+ 322c004271ac6ad1b548df3f316ff4e8f08e17e0b15f459db64f3f3b48b0efb7
2376
+ ```
2377
+
2378
+ </details>
2379
+ * <details><summary>`pro settings orgteam`</summary><br>
2380
+
2381
+ Print team status in tabular format.
2382
+
2383
+ ```sh
2384
+ $ dotenvx pro settings orgteam
2385
+ ╔═══════════╤════════╗
2386
+ ║ username │ synced ║
2387
+ ╟───────────┼────────╢
2388
+ ║ motdotla │ ✔ ║
2389
+ ╟───────────┼────────╢
2390
+ ║ motdotenv │ ✔ ║
2391
+ ╚═══════════╧════════╝
2392
+ ```
2393
+
2394
+ </details>
2395
+ * <details><summary>`pro settings storetree`</summary><br>
2396
+
2397
+ Print encrypted store tree–backing your dotenvx pro installation.
2398
+
2399
+ ```sh
2400
+ $ dotenvx pro settings storetree
2401
+ ├─ .env
2402
+ └─ pro.dotenvx.com
2403
+ ├─ user-1-organization-1.json
2404
+ ├─ user-1-private-key.json
2405
+ └─ user-1.json
2406
+ ```
2407
+
2408
+ </details>
2409
+
2410
+ &nbsp;
2411
+
2264
2412
  ## Whitepaper
2265
2413
 
2266
2414
  > **Dotenvx: Reducing Secrets Risk with Cryptographic Separation**
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.39.0",
2
+ "version": "1.40.0",
3
3
  "name": "@dotenvx/dotenvx",
4
4
  "description": "a better dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",
@@ -1,7 +1,7 @@
1
1
  // historical dotenv.parse - https://github.com/motdotla/dotenv)
2
2
  const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
3
3
 
4
- function dotenvParse (src, skipExpandForDoubleQuotes = false, skipConvertingWindowsNewlines = false) {
4
+ function dotenvParse (src, skipExpandForDoubleQuotes = false, skipConvertingWindowsNewlines = false, collectAllValues = false) {
5
5
  const obj = {}
6
6
 
7
7
  // Convert buffer to string
@@ -35,8 +35,18 @@ function dotenvParse (src, skipExpandForDoubleQuotes = false, skipConvertingWind
35
35
  value = value.replace(/\\t/g, '\t') // tabs
36
36
  }
37
37
 
38
- // Add to object
39
- obj[key] = value
38
+ if (collectAllValues) {
39
+ // handle scenario where user mistakenly includes plaintext duplicate in .env:
40
+ //
41
+ // # .env
42
+ // HELLO="World"
43
+ // HELLO="enrypted:1234"
44
+ obj[key] = obj[key] || []
45
+ obj[key].push(value)
46
+ } else {
47
+ // Add to object
48
+ obj[key] = value
49
+ }
40
50
  }
41
51
 
42
52
  return obj
@@ -23,12 +23,9 @@ function executeDynamic (program, command, rawArgs) {
23
23
  const result = childProcess.spawnSync(`dotenvx-${command}`, forwardedArgs, { stdio: 'inherit', env })
24
24
  if (result.error) {
25
25
  if (command === 'pro') {
26
- // logger.warn(`[INSTALLATION_NEEDED] install dotenvx-${command} to use [dotenvx ${command}] commands 🏆`)
27
- // logger.help('? see installation instructions [https://github.com/dotenvx/dotenvx-pro]')
28
-
29
26
  const pro = `_______________________________________________________________
30
27
  | |
31
- | coming soon! (for small business) |
28
+ | For small and medium businesses |
32
29
  | |
33
30
  | | | | | |
34
31
  | __| | ___ | |_ ___ _ ____ ____ __ _ __ _ __ ___ |
@@ -37,9 +34,9 @@ function executeDynamic (program, command, rawArgs) {
37
34
  | \\__,_|\\___/ \\__\\___|_| |_|\\_/ /_/\\_\\ | .__/|_| \\___/ |
38
35
  | | | |
39
36
  | |_| |
40
- | ## learn more on github 🐙 |
37
+ | ## learn more on dotenvx 🟨 |
41
38
  | |
42
- | >> https://github.com/dotenvx/dotenvx/issues/259 |
39
+ | >> https://dotenvx.com/pricing |
43
40
  | |
44
41
  | ## subscribe on github to be notified 📣 |
45
42
  | |
@@ -50,6 +47,9 @@ function executeDynamic (program, command, rawArgs) {
50
47
  |_____________________________________________________________|`
51
48
 
52
49
  console.log(pro)
50
+ console.log('')
51
+ logger.warn(`[INSTALLATION_NEEDED] install dotenvx-${command} to use [dotenvx ${command}] commands 🏆`)
52
+ logger.help('? see installation instructions [https://github.com/dotenvx/dotenvx-pro]')
53
53
  } else {
54
54
  logger.info(`error: unknown command '${command}'`)
55
55
  }
@@ -3,12 +3,21 @@ const isEncrypted = require('./isEncrypted')
3
3
  const isPublicKey = require('./isPublicKey')
4
4
 
5
5
  function isFullyEncrypted (src) {
6
- const parsed = dotenvParse(src)
6
+ const parsed = dotenvParse(src, false, false, true) // collect all values
7
7
 
8
- for (const [key, value] of Object.entries(parsed)) {
9
- const result = isEncrypted(value) || isPublicKey(key, value)
10
- if (!result) {
11
- return false
8
+ for (const [key, values] of Object.entries(parsed)) {
9
+ // handle scenario where user mistakenly includes plaintext duplicate in .env:
10
+ //
11
+ // # .env
12
+ // HELLO="World"
13
+ // HELLO="enrypted:1234"
14
+ //
15
+ // key => [value1, ...]
16
+ for (const value of values) {
17
+ const result = isEncrypted(value) || isPublicKey(key, value)
18
+ if (!result) {
19
+ return false
20
+ }
12
21
  }
13
22
  }
14
23
 
@@ -93,11 +93,24 @@ class Precommit {
93
93
  }
94
94
  }
95
95
 
96
+ _isInGitRepo () {
97
+ try {
98
+ childProcess.execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' })
99
+ return true
100
+ } catch {
101
+ return false
102
+ }
103
+ }
104
+
96
105
  _isFileToBeCommitted (filePath) {
97
106
  try {
107
+ if (!this._isInGitRepo()) {
108
+ // consider file to be committed if there is an error (not a git repo)
109
+ return true
110
+ }
111
+
98
112
  const output = childProcess.execSync('git diff HEAD --name-only').toString()
99
113
  const files = output.split('\n')
100
-
101
114
  return files.includes(filePath)
102
115
  } catch (error) {
103
116
  // consider file to be committed if there is an error (not using git)