Browse Source

Added options for console output & url filters

master
AGitBoy 6 years ago
parent
commit
9ee413ce71
6 changed files with 137 additions and 79 deletions
  1. +3
    -1
      README.md
  2. +14
    -4
      bin/cli.js
  3. +87
    -61
      package-lock.json
  4. +1
    -1
      package.json
  5. +24
    -9
      src/index.js
  6. +8
    -3
      src/schedule-cleanup.js

+ 3
- 1
README.md View File

@ -10,7 +10,7 @@ clipboard.
## Usage
```
$ bitwarden-dmenu --help
$ bitwarden-demu --help
Usage: bitwarden-dmenu [options]
The DMENU_PATH environment variable can be used to point to an alternative dmenu implementation. Defaults to 'dmenu'.
@ -20,10 +20,12 @@ Options:
Defaults to 15s.
--session-timeout Number of seconds after an unlock that the menu can be accessed
without providing a password again. Defaults to 0s.
--stdout Prints the password & username to stdout
--sync-vault-after Number of seconds allowable between last bitwarden sync and
current time. Defaults to 0s.
--on-error Arbitrary command to run if the program fails. The thrown error
is piped to the given command. Defaults to none.
--url Url to filter by.
--verbose Show extra logs useful for debugging.
```


+ 14
- 4
bin/cli.js View File

@ -10,6 +10,9 @@ const scheduleCleanup = require('../src/schedule-cleanup')
const cachePasswordDefault = 15
const sessionTimeoutDefault = 0
const syncVaultAfterDefault = 0
const urlFilterDefault = null
const stdoutDefault = false
const args = minimist(process.argv.slice(2))
if (args.help) {
console.log(
@ -22,11 +25,13 @@ Options:
Defaults to ${cachePasswordDefault}s.
--session-timeout Number of seconds after an unlock that the menu can be accessed
without providing a password again. Defaults to ${sessionTimeoutDefault}s.
--stdout Prints the password & username to stdout
--sync-vault-after Number of seconds allowable between last bitwarden sync and
current time. Defaults to ${syncVaultAfterDefault}s.
--on-error Arbitrary command to run if the program fails. The thrown error
is piped to the given command. Defaults to none.
--url Url to filter by.
--verbose Show extra logs useful for debugging.
`
)
@ -37,6 +42,9 @@ const clearClipboardAfter = args['clear-clipboard'] || cachePasswordDefault
const sessionTimeout = args['session-timeout'] || sessionTimeoutDefault
const syncVaultAfter = args['sync-vault-after'] || syncVaultAfterDefault
const onErrorCommand = args['on-error']
const urlFilter = args['url'] || urlFilterDefault
const stdout = args['stdout'] || stdoutDefault
console.debug = args['verbose']
? (...msgs) => console.log(...msgs, '\n')
: () => {}
@ -45,12 +53,13 @@ const oldestAllowedVaultSync = syncVaultAfter
const saveSession = Boolean(sessionTimeout)
const sessionFile = path.resolve(os.tmpdir(), 'bitwarden-session.txt')
menu({ saveSession, sessionFile, oldestAllowedVaultSync })
menu({ saveSession, sessionFile, oldestAllowedVaultSync, urlFilter, stdout })
.then(() =>
scheduleCleanup({
lockBitwardenAfter: sessionTimeout,
clearClipboardAfter,
sessionFile
sessionFile,
stdout
})
)
.catch(e => {
@ -60,7 +69,8 @@ menu({ saveSession, sessionFile, oldestAllowedVaultSync })
scheduleCleanup({
lockBitwardenAfter: 0,
clearClipboardAfter: 0,
sessionFile
sessionFile,
stdout
})
.catch(e => {
// simply log an error with cleanup


+ 87
- 61
package-lock.json View File

@ -1,23 +1,26 @@
{
"name": "bitwarden-dmenu",
"version": "1.1.4",
"version": "1.2.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@bitwarden/cli": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@bitwarden/cli/-/cli-1.3.0.tgz",
"integrity": "sha512-zXJfkSGsvk0MH+Ik150htYqmW4vEPrvuEaV4NGsHzYhoqyu4Hfk7Vf4w2soKmT3LF8Cj7eMiGnDo/G852edCBw==",
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@bitwarden/cli/-/cli-1.7.0.tgz",
"integrity": "sha512-rynqUqyfC33dMQ21OlrOu4MQVEvtjyHw1kmu85+l0j9f2CQWEffeqVwoHF5GTtQOXev4PMyqRfSSYI6dRsseag==",
"requires": {
"big-integer": "1.6.36",
"chalk": "2.4.1",
"commander": "2.15.1",
"commander": "2.18.0",
"form-data": "2.3.2",
"inquirer": "5.2.0",
"inquirer": "6.2.0",
"lowdb": "1.0.0",
"lunr": "2.3.1",
"node-fetch": "2.1.2",
"node-forge": "0.7.1",
"papaparse": "4.3.5"
"lunr": "2.3.3",
"node-fetch": "2.2.0",
"node-forge": "0.7.6",
"papaparse": "4.6.0",
"tldjs": "2.3.1",
"zxcvbn": "4.4.2"
}
},
"ansi-escapes": {
@ -48,6 +51,11 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"big-integer": {
"version": "1.6.36",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz",
"integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg=="
},
"chalk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
@ -59,9 +67,9 @@
}
},
"chardet": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"cli-cursor": {
"version": "2.1.0",
@ -107,9 +115,9 @@
}
},
"commander": {
"version": "2.15.1",
"resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz",
"integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ=="
},
"cross-spawn": {
"version": "5.1.0",
@ -146,12 +154,12 @@
}
},
"external-editor": {
"version": "2.2.0",
"resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
"integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
"requires": {
"chardet": "^0.4.0",
"iconv-lite": "^0.4.17",
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
"tmp": "^0.0.33"
}
},
@ -179,9 +187,9 @@
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
"version": "4.1.15",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
"integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
},
"has-flag": {
"version": "3.0.0",
@ -197,20 +205,20 @@
}
},
"inquirer": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz",
"integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==",
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz",
"integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==",
"requires": {
"ansi-escapes": "^3.0.0",
"chalk": "^2.0.0",
"cli-cursor": "^2.1.0",
"cli-width": "^2.0.0",
"external-editor": "^2.1.0",
"external-editor": "^3.0.0",
"figures": "^2.0.0",
"lodash": "^4.3.0",
"lodash": "^4.17.10",
"mute-stream": "0.0.7",
"run-async": "^2.2.0",
"rxjs": "^5.5.2",
"rxjs": "^6.1.0",
"string-width": "^2.1.0",
"strip-ansi": "^4.0.0",
"through": "^2.3.6"
@ -237,9 +245,9 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"lodash": {
"version": "4.17.10",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
"lowdb": {
"version": "1.0.0",
@ -263,21 +271,21 @@
}
},
"lunr": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.1.tgz",
"integrity": "sha1-ETYWorYC3cEJMqe/ik5uV+v+zfI="
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.3.tgz",
"integrity": "sha512-rlAEsgU9Bnavca2w1WJ6+6cdeHMXNyadcersyk3ZpuhgWb5HBNj8l4WwJz9PjksAhYDlpQffCVXPctOn+wCIVA=="
},
"mime-db": {
"version": "1.36.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
"integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
"version": "1.37.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
"integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
},
"mime-types": {
"version": "2.1.20",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
"integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
"version": "2.1.21",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
"integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
"requires": {
"mime-db": "~1.36.0"
"mime-db": "~1.37.0"
}
},
"mimic-fn": {
@ -296,14 +304,14 @@
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
},
"node-fetch": {
"version": "2.1.2",
"resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
"integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz",
"integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA=="
},
"node-forge": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
"integrity": "sha1-naYR6giYL0uUIGs760zJZl8gwwA="
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz",
"integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw=="
},
"npm-run-path": {
"version": "2.0.2",
@ -332,9 +340,9 @@
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
},
"papaparse": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-4.3.5.tgz",
"integrity": "sha1-ts31yub+nsYDsb5m8RSmOsZFoDY="
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-4.6.0.tgz",
"integrity": "sha512-ylm8pmgyz9rkS3Ng/ru5tHUF3JxWwKYP0aZZWZ8eCGdSxoqgYiDUXLNQei73mUJOjHw8QNu5ZNCsLoDpkMA6sg=="
},
"path-key": {
"version": "2.0.1",
@ -357,6 +365,11 @@
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"restore-cursor": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
@ -375,11 +388,11 @@
}
},
"rxjs": {
"version": "5.5.12",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
"integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==",
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz",
"integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==",
"requires": {
"symbol-observable": "1.0.1"
"tslib": "^1.9.0"
}
},
"safer-buffer": {
@ -443,16 +456,19 @@
"has-flag": "^3.0.0"
}
},
"symbol-observable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
"integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ="
},
"through": {
"version": "2.3.8",
"resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"tldjs": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tldjs/-/tldjs-2.3.1.tgz",
"integrity": "sha512-W/YVH/QczLUxVjnQhFC61Iq232NWu3TqDdO0S/MtXVz4xybejBov4ud+CIwN9aYqjOecEqIy0PscGkwpG9ZyTw==",
"requires": {
"punycode": "^1.4.1"
}
},
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@ -461,6 +477,11 @@
"os-tmpdir": "~1.0.2"
}
},
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@ -473,6 +494,11 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
},
"zxcvbn": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
"integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA="
}
}
}

+ 1
- 1
package.json View File

@ -22,7 +22,7 @@
"lint": "git ls-files '*.js' '*.json' | xargs prettier -l"
},
"dependencies": {
"@bitwarden/cli": "^1.3.0",
"@bitwarden/cli": "^1.4.0",
"clipboardy": "^1.2.3",
"minimist": "^1.2.0"
},


+ 24
- 9
src/index.js View File

@ -47,8 +47,17 @@ const syncIfNecessary = ({ session, oldestAllowedVaultSync }) => {
}
// get the list all password accounts in the vault
const getAccounts = ({ session }) => {
const listStr = bwRun('list', 'items', `--session=${session}`)
const getAccounts = ({ session, urlFilter }) => {
var listStr = ""
if(urlFilter) {
listStr = bwRun('list', 'items', `--url=${urlFilter}`, `--session=${session}`)
} else {
listStr = bwRun('list', 'items', `--session=${session}`)
}
// const listStr = urlFilter
// ? bwRun('list', 'items', `--url=${urlFilter}`, `--session=${session}`)
// : bwRun('list', 'items', `--session=${session}`)
const list = JSON.parse(listStr)
return list
}
@ -60,7 +69,7 @@ const chooseAccount = async ({ list }) => {
const accountNames = loginList.map(a => `${a.name}: ${a.login.username}`)
// -i allows case insensitive matching
const selected = await dmenuRun('-i')(accountNames.join('\n'))
const selected = await dmenuRun()(accountNames.join('\n'))
const index = accountNames.indexOf(selected)
// accountNames indexes match loginList indexes
const selectedAccount = loginList[index]
@ -92,7 +101,9 @@ const chooseField = async ({ selectedAccount }) => {
module.exports = async ({
saveSession,
sessionFile,
oldestAllowedVaultSync
oldestAllowedVaultSync,
urlFilter,
stdout
}) => {
const session = await getSessionVar({ saveSession, sessionFile })
@ -100,14 +111,18 @@ module.exports = async ({
syncIfNecessary({ session, oldestAllowedVaultSync })
// bw list
const list = getAccounts({ session })
const list = getAccounts({ session, urlFilter })
// choose account in dmenu
const selectedAccount = await chooseAccount({ list })
// choose field to copy in dmenu
const valueToCopy = await chooseField({ selectedAccount })
if(stdout) {
console.log(`${selectedAccount.login.username}\n${selectedAccount.login.password}`)
} else {
// choose field to copy in dmenu
const valueToCopy = await chooseField({ selectedAccount })
// copy to clipboard
clipboardy.writeSync(valueToCopy)
// copy to clipboard
clipboardy.writeSync(valueToCopy)
}
}

+ 8
- 3
src/schedule-cleanup.js View File

@ -9,7 +9,7 @@ const timeout = n => new Promise(resolve => setTimeout(resolve, n))
*
*/
module.exports = ({ lockBitwardenAfter, clearClipboardAfter, sessionFile }) => {
module.exports = ({ lockBitwardenAfter, clearClipboardAfter, sessionFile, stdout }) => {
console.debug('begin cleanup')
return Promise.all([
timeout(lockBitwardenAfter * 1000).then(() => {
@ -21,11 +21,16 @@ module.exports = ({ lockBitwardenAfter, clearClipboardAfter, sessionFile }) => {
console.debug(`${sessionFile} already removed.`)
}
bwRun('lock')
console.info('bitwarden is locked.')
// don't output to stdout if it is being used for reading information
if(!stdout) {
console.info('bitwarden is locked.')
}
}),
timeout(clearClipboardAfter * 1000).then(() => {
clipboardy.writeSync('')
console.info('clipboard is cleared.')
if(!stdout) {
console.info('clipboard is cleared.')
}
})
])
}

Loading…
Cancel
Save