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.

103 lines
3.6 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
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 bwListArgsDefault = ""
  9. const cachePasswordDefault = 15
  10. const dmenuArgsDefault = ""
  11. const dmenuPswdArgsDefault = ""
  12. const lengthDefault = 0
  13. const sessionTimeoutDefault = 0
  14. const syncVaultAfterDefault = 0
  15. const stdoutDefault = false
  16. const args = minimist(process.argv.slice(2))
  17. if (args.help) {
  18. console.log(
  19. `Usage: bitwarden-dmenu [options]
  20. The DMENU_PATH environment variable can be used to point to an alternative dmenu implementation. Defaults to 'dmenu'.
  21. Options:
  22. --bw-list-args Arbitrary arguments to pass to bitwarden's 'list' command
  23. Defaults to nothing.
  24. --clear-clipboard Number of seconds to keep selected field in the clipboard.
  25. Defaults to ${cachePasswordDefault}s.
  26. --dmenu-args Sets arbitrary arguments to pass to dmenu
  27. Defaults to nothing.
  28. --dmenu-pswd-args Sets arbitrary arguments to pass to the dmenu password prompt
  29. Defaults to nothing.
  30. --session-timeout Number of seconds after an unlock that the menu can be accessed
  31. without providing a password again. Defaults to ${sessionTimeoutDefault}s.
  32. --stdout Prints the password and username to stdout
  33. --sync-vault-after Number of seconds allowable between last bitwarden sync and
  34. current time. Defaults to ${syncVaultAfterDefault}s.
  35. --on-error Arbitrary command to run if the program fails. The thrown error
  36. is piped to the given command. Defaults to none.
  37. --verbose Show extra logs useful for debugging.
  38. `
  39. )
  40. process.exit()
  41. }
  42. const bwListArgs = args['bw-list-args'] || bwListArgsDefault
  43. const dmenuArgs = args['dmenu-args'] || dmenuArgsDefault
  44. const dmenuPswdArgs = args['dmenu-pswd-args'] || dmenuPswdArgsDefault
  45. const length = args['l'] || lengthDefault
  46. const sessionTimeout = args['session-timeout'] || sessionTimeoutDefault
  47. const syncVaultAfter = args['sync-vault-after'] || syncVaultAfterDefault
  48. const onErrorCommand = args['on-error']
  49. const stdout = args['stdout'] || stdoutDefault
  50. // prevent clipboard clearing from locking up process when printing to stdout
  51. const clearClipboardAfter = stdout ? 0 : args['clear-clipboard'] || cachePasswordDefault
  52. console.debug = args['verbose']
  53. ? (...msgs) => console.log(...msgs, '\n')
  54. : () => {}
  55. console.info = args['stdout']
  56. ? () => {}
  57. : console.info
  58. const oldestAllowedVaultSync = syncVaultAfter
  59. const saveSession = Boolean(sessionTimeout)
  60. const sessionFile = path.resolve(os.tmpdir(), 'bitwarden-session.txt')
  61. menu({ bwListArgs, dmenuArgs, dmenuPswdArgs, saveSession, sessionFile, stdout, oldestAllowedVaultSync })
  62. .then(() =>
  63. scheduleCleanup({
  64. lockBitwardenAfter: sessionTimeout,
  65. clearClipboardAfter,
  66. sessionFile,
  67. stdout
  68. })
  69. )
  70. .catch(e => {
  71. console.error(e)
  72. // if something goes wrong, immediately clear the clipboard & lock bitwarden,
  73. // then run error command
  74. scheduleCleanup({
  75. lockBitwardenAfter: 0,
  76. clearClipboardAfter: 0,
  77. sessionFile,
  78. stdout
  79. })
  80. .catch(e => {
  81. // simply log an error with cleanup
  82. console.error(e)
  83. })
  84. .then(() => {
  85. if (onErrorCommand) {
  86. const errorCommand = exec(onErrorCommand)
  87. errorCommand.stdin.write(`'${e.toString()}'`)
  88. errorCommand.stdin.end()
  89. }
  90. })
  91. })