@dotenvx/dotenvx-vlt 0.49.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 (125) hide show
  1. package/CHANGELOG.md +652 -0
  2. package/LICENSE +71 -0
  3. package/README.md +11 -0
  4. package/package.json +77 -0
  5. package/src/cli/actions/armor/down.js +37 -0
  6. package/src/cli/actions/armor/move.js +42 -0
  7. package/src/cli/actions/armor/pull.js +37 -0
  8. package/src/cli/actions/armor/push.js +37 -0
  9. package/src/cli/actions/armor/rotate.js +25 -0
  10. package/src/cli/actions/armor/up.js +37 -0
  11. package/src/cli/actions/backup.js +93 -0
  12. package/src/cli/actions/gateway/start.js +17 -0
  13. package/src/cli/actions/get.js +34 -0
  14. package/src/cli/actions/keypair.js +59 -0
  15. package/src/cli/actions/login.js +110 -0
  16. package/src/cli/actions/logout.js +36 -0
  17. package/src/cli/actions/observe.js +36 -0
  18. package/src/cli/actions/open.js +37 -0
  19. package/src/cli/actions/rotate/github/connect.js +84 -0
  20. package/src/cli/actions/rotate/npm/connect.js +84 -0
  21. package/src/cli/actions/rotate/openai/connect.js +84 -0
  22. package/src/cli/actions/rotate.js +44 -0
  23. package/src/cli/actions/set.js +34 -0
  24. package/src/cli/actions/settings/device.js +24 -0
  25. package/src/cli/actions/settings/hostname.js +20 -0
  26. package/src/cli/actions/settings/off.js +17 -0
  27. package/src/cli/actions/settings/on.js +17 -0
  28. package/src/cli/actions/settings/path.js +21 -0
  29. package/src/cli/actions/settings/token.js +24 -0
  30. package/src/cli/actions/settings/username.js +22 -0
  31. package/src/cli/actions/status.js +13 -0
  32. package/src/cli/actions/sync.js +104 -0
  33. package/src/cli/commands/armor.js +73 -0
  34. package/src/cli/commands/gateway.js +16 -0
  35. package/src/cli/commands/rotate/github.js +26 -0
  36. package/src/cli/commands/rotate/npm.js +26 -0
  37. package/src/cli/commands/rotate/openai.js +26 -0
  38. package/src/cli/commands/rotate.js +32 -0
  39. package/src/cli/commands/settings.js +60 -0
  40. package/src/cli/dotenvx-ops.js +163 -0
  41. package/src/cli/postinstall.js +16 -0
  42. package/src/db/device.js +73 -0
  43. package/src/db/session.js +193 -0
  44. package/src/lib/api/getAccount.js +32 -0
  45. package/src/lib/api/getSynchronization.js +34 -0
  46. package/src/lib/api/getVersion.js +24 -0
  47. package/src/lib/api/postArmorDown.js +48 -0
  48. package/src/lib/api/postArmorMove.js +48 -0
  49. package/src/lib/api/postArmorPull.js +48 -0
  50. package/src/lib/api/postArmorPush.js +48 -0
  51. package/src/lib/api/postArmorUp.js +51 -0
  52. package/src/lib/api/postBackup.js +68 -0
  53. package/src/lib/api/postGet.js +37 -0
  54. package/src/lib/api/postKeypair.js +60 -0
  55. package/src/lib/api/postLogout.js +34 -0
  56. package/src/lib/api/postOauthDeviceCode.js +45 -0
  57. package/src/lib/api/postOauthToken.js +38 -0
  58. package/src/lib/api/postObserve.js +62 -0
  59. package/src/lib/api/postRotate.js +39 -0
  60. package/src/lib/api/postRotateConnect.js +54 -0
  61. package/src/lib/api/postSet.js +43 -0
  62. package/src/lib/api/postSync.js +68 -0
  63. package/src/lib/helpers/armoredKeyDisplay.js +10 -0
  64. package/src/lib/helpers/buildApiError.js +16 -0
  65. package/src/lib/helpers/buildOauthError.js +13 -0
  66. package/src/lib/helpers/canonicalEnvFilename.js +13 -0
  67. package/src/lib/helpers/clipboardy/fallbacks/linux/xsel +0 -0
  68. package/src/lib/helpers/clipboardy/fallbacks/windows/clipboard_i686.exe +0 -0
  69. package/src/lib/helpers/clipboardy/fallbacks/windows/clipboard_x86_64.exe +0 -0
  70. package/src/lib/helpers/clipboardy/linux.js +57 -0
  71. package/src/lib/helpers/clipboardy/macos.js +14 -0
  72. package/src/lib/helpers/clipboardy/termux.js +41 -0
  73. package/src/lib/helpers/clipboardy/windows.js +16 -0
  74. package/src/lib/helpers/clipboardy.js +51 -0
  75. package/src/lib/helpers/confirm.js +17 -0
  76. package/src/lib/helpers/createSpinner.js +101 -0
  77. package/src/lib/helpers/createSpinner2.js +24 -0
  78. package/src/lib/helpers/decryptValue.js +10 -0
  79. package/src/lib/helpers/dotenvxProjectId.js +36 -0
  80. package/src/lib/helpers/encryptValue.js +9 -0
  81. package/src/lib/helpers/errors.js +30 -0
  82. package/src/lib/helpers/formatCode.js +11 -0
  83. package/src/lib/helpers/gitBranch.js +13 -0
  84. package/src/lib/helpers/gitUrl.js +13 -0
  85. package/src/lib/helpers/http.js +17 -0
  86. package/src/lib/helpers/jsonToEnv.js +7 -0
  87. package/src/lib/helpers/keyNamesForEnvFile.js +43 -0
  88. package/src/lib/helpers/keypairMetadata.js +88 -0
  89. package/src/lib/helpers/likelyUpdateCommand.js +33 -0
  90. package/src/lib/helpers/localKeypair.js +12 -0
  91. package/src/lib/helpers/mask.js +12 -0
  92. package/src/lib/helpers/normalizePath.js +5 -0
  93. package/src/lib/helpers/normalizeToken.js +5 -0
  94. package/src/lib/helpers/openUrl.js +7 -0
  95. package/src/lib/helpers/packageJson.js +3 -0
  96. package/src/lib/helpers/playwrightConnect.js +29 -0
  97. package/src/lib/helpers/pluralize.js +10 -0
  98. package/src/lib/helpers/prompts.js +68 -0
  99. package/src/lib/helpers/removeEnvKey.js +50 -0
  100. package/src/lib/helpers/safeRealpath.js +13 -0
  101. package/src/lib/helpers/sha256File.js +9 -0
  102. package/src/lib/helpers/smartMask.js +11 -0
  103. package/src/lib/helpers/truncate.js +10 -0
  104. package/src/lib/helpers/upsertEnvKey.js +61 -0
  105. package/src/lib/main.d.ts +152 -0
  106. package/src/lib/main.js +114 -0
  107. package/src/lib/services/armorDown.js +77 -0
  108. package/src/lib/services/armorMove.js +54 -0
  109. package/src/lib/services/armorPull.js +77 -0
  110. package/src/lib/services/armorPush.js +82 -0
  111. package/src/lib/services/armorUp.js +79 -0
  112. package/src/lib/services/backup.js +105 -0
  113. package/src/lib/services/gatewayStart.js +132 -0
  114. package/src/lib/services/keypair.js +59 -0
  115. package/src/lib/services/loggedIn.js +24 -0
  116. package/src/lib/services/login.js +28 -0
  117. package/src/lib/services/loginPoll.js +43 -0
  118. package/src/lib/services/logout.js +28 -0
  119. package/src/lib/services/rotate.js +28 -0
  120. package/src/lib/services/rotateGithubConnect.js +56 -0
  121. package/src/lib/services/rotateNpmConnect.js +56 -0
  122. package/src/lib/services/rotateOpenaiConnect.js +60 -0
  123. package/src/lib/services/status.js +11 -0
  124. package/src/lib/services/sync.js +70 -0
  125. package/src/lib/services/syncConflict.js +36 -0
@@ -0,0 +1,22 @@
1
+ const { logger } = require('@dotenvx/dotenvx')
2
+
3
+ const Session = require('./../../../db/session')
4
+
5
+ async function username () {
6
+ try {
7
+ const sesh = new Session()
8
+ const username = sesh.username()
9
+
10
+ if (username) {
11
+ console.log(username)
12
+ } else {
13
+ logger.error('login required. Try running [dotenvx-pro login].')
14
+ process.exit(1)
15
+ }
16
+ } catch (error) {
17
+ logger.error(error.message)
18
+ process.exit(1)
19
+ }
20
+ }
21
+
22
+ module.exports = username
@@ -0,0 +1,13 @@
1
+ const { logger } = require('@dotenvx/dotenvx')
2
+
3
+ const Status = require('./../../lib/services/status')
4
+
5
+ async function status () {
6
+ const options = this.opts()
7
+ logger.debug(`options: ${JSON.stringify(options)}`)
8
+
9
+ const { status } = new Status().run()
10
+ console.log(status)
11
+ }
12
+
13
+ module.exports = status
@@ -0,0 +1,104 @@
1
+ const fs = require('fs')
2
+
3
+ const { logger } = require('@dotenvx/dotenvx')
4
+ const Session = require('./../../db/session')
5
+
6
+ const { createSpinner } = require('./../../lib/helpers/createSpinner')
7
+ const pluralize = require('./../../lib/helpers/pluralize')
8
+ const sha256File = require('./../../lib/helpers/sha256File')
9
+
10
+ const Sync = require('./../../lib/services/sync')
11
+ const SyncConflict = require('./../../lib/services/syncConflict')
12
+
13
+ const spinner = createSpinner('syncing')
14
+
15
+ async function sync () {
16
+ // debug opts
17
+ const options = this.opts()
18
+ const sesh = new Session()
19
+ const hostname = options.hostname || sesh.hostname()
20
+
21
+ try {
22
+ logger.debug(`options: ${JSON.stringify(options)}`)
23
+
24
+ spinner.start()
25
+
26
+ const {
27
+ projectUsernameName,
28
+ files
29
+ } = await new Sync(hostname, options.force).run()
30
+ logger.debug(`files: ${JSON.stringify(files)}`)
31
+
32
+ // write output files
33
+ for (const file of files) {
34
+ const { filepath, src, sha } = file
35
+
36
+ let needsWrite = true
37
+ if (fs.existsSync(filepath)) {
38
+ const localSha = sha256File(filepath)
39
+ needsWrite = localSha !== sha
40
+ }
41
+
42
+ if (needsWrite) {
43
+ logger.debug(`writing ${filepath}`)
44
+ fs.writeFileSync(filepath, src, 'utf8')
45
+ } else {
46
+ logger.debug(`unchanged ${filepath} (skipped)`)
47
+ }
48
+ }
49
+
50
+ spinner.stop()
51
+
52
+ logger.success(`✔ synced [${projectUsernameName}]`)
53
+ } catch (error) {
54
+ spinner.stop()
55
+ if (error.message) {
56
+ logger.error(error.message)
57
+ } else {
58
+ logger.error(error)
59
+ }
60
+ if (error.help) {
61
+ logger.help(error.help)
62
+ }
63
+ if (error.stack) {
64
+ logger.debug(error.stack)
65
+ }
66
+
67
+ try {
68
+ if (error.code === 'DOTENVX_SYNC_CONFLICT') {
69
+ spinner.start()
70
+
71
+ const synchronizationId = error.meta.synchronization_id
72
+ const { conflictedFiles } = await new SyncConflict(hostname, synchronizationId).run()
73
+
74
+ spinner.stop()
75
+
76
+ // loop through any conflicted files
77
+ for (const conflictedFile of conflictedFiles) {
78
+ logger.info('')
79
+ logger.info(`✖ conflict [${conflictedFile.filepath}]`)
80
+ console.log(conflictedFile.diffAnsi)
81
+ }
82
+
83
+ logger.info(`Review and edit the ${pluralize('file', conflictedFiles.length)} as needed, then confirm your version with [dotenvx-ops sync --force]`)
84
+ }
85
+ } catch (error) {
86
+ spinner.stop()
87
+ if (error.message) {
88
+ logger.error(error.message)
89
+ } else {
90
+ logger.error(error)
91
+ }
92
+ if (error.help) {
93
+ logger.help(error.help)
94
+ }
95
+ if (error.stack) {
96
+ logger.debug(error.stack)
97
+ }
98
+ }
99
+
100
+ process.exit(1)
101
+ }
102
+ }
103
+
104
+ module.exports = sync
@@ -0,0 +1,73 @@
1
+ const { Command } = require('commander')
2
+ const Session = require('./../../db/session')
3
+
4
+ const armor = new Command('armor')
5
+
6
+ armor
7
+ .description('ARMORED KEYS ⛨')
8
+ .allowUnknownOption()
9
+ .action(async function () {
10
+ const sesh = new Session()
11
+ await sesh.notifyUpdate()
12
+ this.help()
13
+ })
14
+
15
+ // dotenvx-ops armor up
16
+ const upAction = require('./../actions/armor/up')
17
+ armor
18
+ .command('up')
19
+ .description('armor private key')
20
+ .option('-f, --env-file <path>', 'path to your env file')
21
+ .option('--token <token>', 'set token')
22
+ .option('--team <team>', 'team to armor private key for')
23
+ .action(upAction)
24
+
25
+ // dotenvx-ops armor down
26
+ const downAction = require('./../actions/armor/down')
27
+ armor
28
+ .command('down')
29
+ .description('dearmor private key')
30
+ .option('-f, --env-file <path>', 'path to your env file')
31
+ .option('--token <token>', 'set token')
32
+ .option('--team <team>', 'team to dearmor private key from')
33
+ .action(downAction)
34
+
35
+ // dotenvx-ops armor push
36
+ const pushAction = require('./../actions/armor/push')
37
+ armor
38
+ .command('push')
39
+ .description('push armored key (from .env.keys)')
40
+ .option('-f, --env-file <path>', 'path to your env file')
41
+ .option('--token <token>', 'set token')
42
+ .option('--team <team>', 'team to push armored private key for')
43
+ .action(pushAction)
44
+
45
+ // dotenvx-ops armor pull
46
+ const pullAction = require('./../actions/armor/pull')
47
+ armor
48
+ .command('pull')
49
+ .description('pull armored key (into .env.keys)')
50
+ .option('-f, --env-file <path>', 'path to your env file')
51
+ .option('--token <token>', 'set token')
52
+ .option('--team <team>', 'team to pull armored private key from')
53
+ .action(pullAction)
54
+
55
+ // dotenvx-ops armor rotate
56
+ const rotateAction = require('./../actions/armor/rotate')
57
+ armor
58
+ .command('rotate')
59
+ .description('rotate armored key and re-encrypt .env file')
60
+ .option('-f, --env-file <path>', 'path to your env file')
61
+ .option('--token <token>', 'set token')
62
+ .action(rotateAction)
63
+
64
+ // dotenvx-ops armor move
65
+ const moveAction = require('./../actions/armor/move')
66
+ armor
67
+ .command('move')
68
+ .description('move armored key (to other team)')
69
+ .option('-f, --env-file <path>', 'path to your env file')
70
+ .option('--token <token>', 'set token')
71
+ .action(moveAction)
72
+
73
+ module.exports = armor
@@ -0,0 +1,16 @@
1
+ const { Command } = require('commander')
2
+
3
+ const gateway = new Command('gateway')
4
+
5
+ gateway
6
+ .description('[INTERNAL] ⛩ gateway')
7
+ .allowUnknownOption()
8
+
9
+ // dotenvx-ops gateway start
10
+ const startAction = require('./../actions/gateway/start')
11
+ gateway
12
+ .command('start')
13
+ .description('start gateway')
14
+ .action(startAction)
15
+
16
+ module.exports = gateway
@@ -0,0 +1,26 @@
1
+ const { Command } = require('commander')
2
+
3
+ const github = new Command('github')
4
+
5
+ const Session = require('./../../../db/session')
6
+ const sesh = new Session()
7
+
8
+ github
9
+ .description('github')
10
+ .allowUnknownOption()
11
+
12
+ github
13
+ .command('connect')
14
+ .description('connect passcard')
15
+ .option('--org <organizationSlug>')
16
+ .option('--username <username>')
17
+ .option('--password <password>')
18
+ .option('--email <email>')
19
+ .option('--hostname <url>', 'set hostname', sesh.hostname())
20
+ .option('--token <token>', 'set token')
21
+ .action(async function (...args) {
22
+ const connectAction = require('./../../actions/rotate/github/connect')
23
+ await connectAction.apply(this, args)
24
+ })
25
+
26
+ module.exports = github
@@ -0,0 +1,26 @@
1
+ const { Command } = require('commander')
2
+
3
+ const npm = new Command('npm')
4
+
5
+ const Session = require('./../../../db/session')
6
+ const sesh = new Session()
7
+
8
+ npm
9
+ .description('npm')
10
+ .allowUnknownOption()
11
+
12
+ npm
13
+ .command('connect')
14
+ .description('connect passcard')
15
+ .option('--org <organizationSlug>')
16
+ .option('--username <username>')
17
+ .option('--password <password>')
18
+ .option('--email <email>')
19
+ .option('--hostname <url>', 'set hostname', sesh.hostname())
20
+ .option('--token <token>', 'set token')
21
+ .action(async function (...args) {
22
+ const connectAction = require('./../../actions/rotate/npm/connect')
23
+ await connectAction.apply(this, args)
24
+ })
25
+
26
+ module.exports = npm
@@ -0,0 +1,26 @@
1
+ const { Command } = require('commander')
2
+
3
+ const openai = new Command('openai')
4
+
5
+ const Session = require('./../../../db/session')
6
+ const sesh = new Session()
7
+
8
+ openai
9
+ .description('openai')
10
+ .allowUnknownOption()
11
+
12
+ openai
13
+ .command('connect')
14
+ .description('connect passcard')
15
+ .option('--org <organizationSlug>')
16
+ .option('--username <username>')
17
+ .option('--password <password>')
18
+ .option('--email <email>')
19
+ .option('--hostname <url>', 'set hostname', sesh.hostname())
20
+ .option('--token <token>', 'set token')
21
+ .action(async function (...args) {
22
+ const connectAction = require('./../../actions/rotate/openai/connect')
23
+ await connectAction.apply(this, args)
24
+ })
25
+
26
+ module.exports = openai
@@ -0,0 +1,32 @@
1
+ const { Command } = require('commander')
2
+
3
+ const rotate = new Command('rotate')
4
+
5
+ const Session = require('./../../db/session')
6
+ const sesh = new Session()
7
+
8
+ rotate
9
+ .description('[INTERNAL] rotate secret')
10
+ .allowUnknownOption()
11
+
12
+ rotate.addCommand(require('./rotate/github'))
13
+ rotate.addCommand(require('./rotate/npm'))
14
+ rotate.addCommand(require('./rotate/openai'))
15
+
16
+ // dotenvx-ops rotate (fallback positional argument handler)
17
+ const rotateAction = require('../actions/rotate')
18
+ rotate
19
+ .argument('[URI]', 'URI') // brackets = optional
20
+ .option('--hostname <url>', 'set hostname', sesh.hostname())
21
+ .option('--token <token>', 'set token')
22
+ .action(async function (uri, options, command) {
23
+ if (!uri) {
24
+ command.help()
25
+ return
26
+ }
27
+
28
+ // Call external action with correct "this" binding
29
+ await rotateAction.call(this, uri)
30
+ })
31
+
32
+ module.exports = rotate
@@ -0,0 +1,60 @@
1
+ const { Command } = require('commander')
2
+
3
+ const settings = new Command('settings')
4
+
5
+ settings
6
+ .description('settings')
7
+ .allowUnknownOption()
8
+
9
+ // dotenvx-ops settings username
10
+ const usernameAction = require('./../actions/settings/username')
11
+ settings
12
+ .command('username')
13
+ .description('print your username')
14
+ .action(usernameAction)
15
+
16
+ // dotenvx-ops settings token
17
+ const tokenAction = require('./../actions/settings/token')
18
+ settings
19
+ .command('token')
20
+ .description('print your access token (--unmask)')
21
+ .option('--unmask', 'unmask access token')
22
+ .action(tokenAction)
23
+
24
+ // dotenvx-ops settings device
25
+ const deviceAction = require('./../actions/settings/device')
26
+ settings
27
+ .command('device')
28
+ .description('print your device pubkey (--unmask)')
29
+ .option('--unmask', 'unmask device pubkey')
30
+ .action(deviceAction)
31
+
32
+ // dotenvx-ops settings hostname
33
+ const hostnameAction = require('./../actions/settings/hostname')
34
+ settings
35
+ .command('hostname')
36
+ .description('print hostname')
37
+ .action(hostnameAction)
38
+
39
+ // dotenvx-ops settings path
40
+ const pathAction = require('./../actions/settings/path')
41
+ settings
42
+ .command('path')
43
+ .description('print path to settings file')
44
+ .action(pathAction)
45
+
46
+ // dotenvx-ops settings on
47
+ const onAction = require('./../actions/settings/on')
48
+ settings
49
+ .command('on')
50
+ .description('turn ops on')
51
+ .action(onAction)
52
+
53
+ // dotenvx-ops settings off
54
+ const offAction = require('./../actions/settings/off')
55
+ settings
56
+ .command('off')
57
+ .description('turn ops off')
58
+ .action(offAction)
59
+
60
+ module.exports = settings
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env node
2
+
3
+ /* c8 ignore start */
4
+ const { Command } = require('commander')
5
+ const program = new Command()
6
+
7
+ const { setLogLevel } = require('@dotenvx/dotenvx')
8
+
9
+ const packageJson = require('./../lib/helpers/packageJson')
10
+ const Session = require('./../db/session')
11
+ const argv = process.argv.slice(2)
12
+ const firstArg = argv[0]
13
+
14
+ // global log levels
15
+ program
16
+ .usage('login')
17
+ .option('-l, --log-level <level>', 'set log level', 'info')
18
+ .option('-q, --quiet', 'sets log level to error')
19
+ .option('-v, --verbose', 'sets log level to verbose')
20
+ .option('-d, --debug', 'sets log level to debug')
21
+ .hook('preAction', async (thisCommand, actionCommand) => {
22
+ const options = thisCommand.opts()
23
+
24
+ setLogLevel(options)
25
+ })
26
+
27
+ // cli
28
+ program
29
+ .name('dotenvx-ops')
30
+ .description(packageJson.description)
31
+ .version(packageJson.version)
32
+ .allowUnknownOption()
33
+
34
+ // dotenvx-ops backup
35
+ const backupAction = require('./actions/backup')
36
+ program
37
+ .command('backup')
38
+ .description('[INTERNAL] back up .env.keys')
39
+ .option('--org <organizationSlug>')
40
+ .option('-h, --hostname <url>', 'set hostname')
41
+ .action(backupAction)
42
+
43
+ // dotenvx-ops open
44
+ const openAction = require('./actions/open')
45
+ program
46
+ .command('open')
47
+ .description('[INTERNAL] open project')
48
+ .option('-h, --hostname <url>', 'set hostname')
49
+ .action(openAction)
50
+
51
+ // dotenvx-ops observe base64String
52
+ const observeAction = require('./actions/observe')
53
+ program.command('observe')
54
+ .usage('<BASE64> [options]')
55
+ .description('[INTERNAL] observe')
56
+ .allowUnknownOption()
57
+ .argument('BASE64', 'BASE64')
58
+ .option('--hostname <url>', 'set hostname')
59
+ .option('--token <token>', 'set token')
60
+ .option('--dotenvxProjectId <identifier>', 'set DOTENVX_PROJECT_ID')
61
+ .action(function (...args) {
62
+ observeAction.apply(this, args)
63
+ })
64
+
65
+ // dotenvx-ops sync
66
+ const syncAction = require('./actions/sync')
67
+ program
68
+ .command('sync')
69
+ .description('[INTERNAL] sync .env*')
70
+ .option('-h, --hostname <url>', 'set hostname')
71
+ .option('--force', 'force changes')
72
+ .action(syncAction)
73
+
74
+ // dotenvx-ops get
75
+ const getAction = require('./actions/get')
76
+ program
77
+ .command('get')
78
+ .description('[INTERNAL] fetch secret')
79
+ .argument('URI', 'URI')
80
+ .option('--hostname <url>', 'set hostname')
81
+ .option('--token <token>', 'set token')
82
+ .action(getAction)
83
+
84
+ // dotenvx-ops set
85
+ const setAction = require('./actions/set')
86
+ program
87
+ .command('set')
88
+ .description('[INTERNAL] set secret')
89
+ .argument('URI', 'URI')
90
+ .argument('value', 'value')
91
+ .option('--hostname <url>', 'set hostname')
92
+ .option('--token <token>', 'set token')
93
+ .action(setAction)
94
+
95
+ // dotenvx-ops rotate
96
+ const shouldLoadRotateCommand = firstArg === 'rotate' || firstArg === 'help' || firstArg === '--help' || firstArg === '-h'
97
+ if (shouldLoadRotateCommand) {
98
+ program.addCommand(require('./commands/rotate'))
99
+ }
100
+
101
+ // dotenvx-ops armor
102
+ program.addCommand(require('./commands/armor'))
103
+
104
+ // dotenvx-ops login
105
+ const loginAction = require('./actions/login')
106
+ program
107
+ .command('login')
108
+ .description('log in')
109
+ .option('--hostname <url>', 'set hostname')
110
+ .action(loginAction)
111
+
112
+ // dotenvx-ops logout
113
+ const logoutAction = require('./actions/logout')
114
+ program
115
+ .command('logout')
116
+ .description('log out')
117
+ .option('--hostname <url>', 'set hostname')
118
+ .action(logoutAction)
119
+
120
+ // dotenvx-ops status
121
+ const statusAction = require('./actions/status')
122
+ program
123
+ .command('status')
124
+ .description('[INTERNAL] status')
125
+ .action(statusAction)
126
+
127
+ // dotenvx-ops keypair
128
+ const keypairAction = require('./actions/keypair')
129
+ program
130
+ .command('keypair')
131
+ .description('generate armored keypair ⛨')
132
+ .argument('[publicKey]', 'existing public key')
133
+ .option('-h, --hostname <url>', 'set hostname')
134
+ .option('--token <token>', 'set token')
135
+ .option('--team <team>', 'team to generate keypair for')
136
+ .option('-f, --env-file <path>', 'path to your env file', '.env')
137
+ .option('--no-spinner', 'disable spinner output')
138
+ .option('--pp, --pretty-print', 'pretty print output')
139
+ .action(keypairAction)
140
+
141
+ program.addCommand(require('./commands/gateway'))
142
+ program.addCommand(require('./commands/settings'))
143
+
144
+ // monkey-patch help output
145
+ program.helpInformation = function () {
146
+ const originalHelp = Command.prototype.helpInformation.call(this)
147
+ const lines = originalHelp.split('\n')
148
+
149
+ const filteredLines = lines.filter(line =>
150
+ !line.includes('INTERNAL') // hide observe command
151
+ )
152
+
153
+ return filteredLines.join('\n')
154
+ }
155
+
156
+ /* c8 ignore stop */
157
+ program.action(async function () {
158
+ const sesh = new Session()
159
+ await sesh.notifyUpdate()
160
+ this.help()
161
+ })
162
+
163
+ program.parseAsync(process.argv)
@@ -0,0 +1,16 @@
1
+ const packageJson = require('./../lib/helpers/packageJson')
2
+ const path = require('path')
3
+
4
+ const commandName = 'dotenvx-ops'
5
+ const isGlobalInstall = process.env.npm_config_global === 'true' || process.env.npm_config_location === 'global'
6
+
7
+ let installPath = commandName
8
+ if (isGlobalInstall && process.env.npm_config_prefix) {
9
+ const binaryName = process.platform === 'win32' ? `${commandName}.cmd` : commandName
10
+ installPath = process.platform === 'win32'
11
+ ? path.join(process.env.npm_config_prefix, binaryName)
12
+ : path.join(process.env.npm_config_prefix, 'bin', binaryName)
13
+ }
14
+
15
+ console.log(`⛨ installed (${packageJson.version}:${installPath})`)
16
+ console.log('⮕ next run [dotenvx-ops login] and then [dotenvx encrypt]')
@@ -0,0 +1,73 @@
1
+ const Conf = require('conf')
2
+ const { PrivateKey } = require('eciesjs')
3
+
4
+ const encryptValue = require('./../lib/helpers/encryptValue')
5
+ const decryptValue = require('./../lib/helpers/decryptValue')
6
+
7
+ class Device {
8
+ constructor () {
9
+ this.store = new Conf({
10
+ cwd: process.env.DOTENVX_CONFIG || undefined,
11
+ projectName: 'dotenvx',
12
+ configName: '.device-key',
13
+ projectSuffix: '',
14
+ fileExtension: '',
15
+ encryptionKey: 'dotenvxpro dotenvxpro dotenvxpro' // backwards compatible
16
+ })
17
+ }
18
+
19
+ touch () {
20
+ const _privateKey = this.privateKey()
21
+ const _publicKey = this.publicKey()
22
+
23
+ return {
24
+ privateKey: _privateKey,
25
+ publicKey: _publicKey
26
+ }
27
+ }
28
+
29
+ configPath () {
30
+ return this.store.path
31
+ }
32
+
33
+ privateKey () {
34
+ const currentPrivateKey = this.store.get('private_key/1')
35
+ if (currentPrivateKey && currentPrivateKey.length > 0) {
36
+ this.store.set('private_key/1', currentPrivateKey)
37
+
38
+ return currentPrivateKey
39
+ }
40
+
41
+ // generate privateKey for the first time
42
+ const kp = new PrivateKey()
43
+ const _privateKey = kp.secret.toString('hex')
44
+
45
+ this.store.set('private_key/1', _privateKey)
46
+
47
+ return _privateKey
48
+ }
49
+
50
+ publicKey () {
51
+ // must have private key to try and get public key
52
+ const privateKeyHex = this.privateKey()
53
+ if (!privateKeyHex || privateKeyHex.length < 1) {
54
+ return ''
55
+ }
56
+
57
+ // create keyPair object from hex string
58
+ const _privateKey = new PrivateKey(Buffer.from(privateKeyHex, 'hex'))
59
+
60
+ // compute publicKey from privateKey
61
+ return _privateKey.publicKey.toHex()
62
+ }
63
+
64
+ encrypt (value) {
65
+ return encryptValue(value, this.publicKey())
66
+ }
67
+
68
+ decrypt (value) {
69
+ return decryptValue(value, this.privateKey())
70
+ }
71
+ }
72
+
73
+ module.exports = Device