dmenu for bitwarden-cli
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.0 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. #!/usr/bin/env node
  2. const os = require('os')
  3. const path = require('path')
  4. const { exec } = require('child_process')
  5. const minimist = require('minimist')
  6. const menu = require('../src')
  7. const scheduleCleanup = require('../src/schedule-cleanup')
  8. const cachePasswordDefault = 15
  9. const lengthDefault = 0
  10. const sessionTimeoutDefault = 0
  11. const syncVaultAfterDefault = 0
  12. const stdoutDefault = false
  13. const urlFilterDefault = null
  14. const args = minimist(process.argv.slice(2))
  15. if (args.help) {
  16. console.log(
  17. `Usage: bitwarden-dmenu [options]
  18. The DMENU_PATH environment variable can be used to point to an alternative dmenu implementation. Defaults to 'dmenu'.
  19. Options:
  20. --clear-clipboard Number of seconds to keep selected field in the clipboard.
  21. Defaults to ${cachePasswordDefault}s.
  22. -l Sets the -l parameter value passed to dmenu.
  23. Defaults to ${lengthDefault}
  24. --session-timeout Number of seconds after an unlock that the menu can be accessed
  25. without providing a password again. Defaults to ${sessionTimeoutDefault}s.
  26. --stdout Prints the password and username to stdout
  27. --sync-vault-after Number of seconds allowable between last bitwarden sync and
  28. current time. Defaults to ${syncVaultAfterDefault}s.
  29. --on-error Arbitrary command to run if the program fails. The thrown error
  30. is piped to the given command. Defaults to none.
  31. --url Url to filter by.
  32. --verbose Show extra logs useful for debugging.
  33. `
  34. )
  35. process.exit()
  36. }
  37. const clearClipboardAfter = args['clear-clipboard'] || cachePasswordDefault
  38. const length = args['l'] || lengthDefault
  39. const sessionTimeout = args['session-timeout'] || sessionTimeoutDefault
  40. const syncVaultAfter = args['sync-vault-after'] || syncVaultAfterDefault
  41. const onErrorCommand = args['on-error']
  42. const stdout = args['stdout'] || stdoutDefault
  43. const urlFilter = args['url'] || urlFilterDefault
  44. console.debug = args['verbose']
  45. ? (...msgs) => console.log(...msgs, '\n')
  46. : () => {}
  47. const oldestAllowedVaultSync = syncVaultAfter
  48. const saveSession = Boolean(sessionTimeout)
  49. const sessionFile = path.resolve(os.tmpdir(), 'bitwarden-session.txt')
  50. menu({ length, saveSession, sessionFile, stdout, oldestAllowedVaultSync, urlFilter })
  51. .then(() =>
  52. scheduleCleanup({
  53. lockBitwardenAfter: sessionTimeout,
  54. clearClipboardAfter,
  55. sessionFile,
  56. stdout
  57. })
  58. )
  59. .catch(e => {
  60. console.error(e)
  61. // if something goes wrong, immediately clear the clipboard & lock bitwarden,
  62. // then run error command
  63. scheduleCleanup({
  64. lockBitwardenAfter: 0,
  65. clearClipboardAfter: 0,
  66. sessionFile,
  67. stdout
  68. })
  69. .catch(e => {
  70. // simply log an error with cleanup
  71. console.error(e)
  72. })
  73. .then(() => {
  74. if (onErrorCommand) {
  75. const errorCommand = exec(onErrorCommand)
  76. errorCommand.stdin.write(`'${e.toString()}'`)
  77. errorCommand.stdin.end()
  78. }
  79. })
  80. })