Browse Source

rely on spawnSync to escape characters

master
Andrew Kaiser 6 years ago
parent
commit
cc8cfaa126
5 changed files with 19 additions and 20 deletions
  1. +1
    -1
      package.json
  2. +4
    -4
      src/exec-bitwarden-cli.js
  3. +2
    -2
      src/exec-dmenu.js
  4. +10
    -11
      src/index.js
  5. +2
    -2
      src/util/obfuscate/bitwarden-cli.js

+ 1
- 1
package.json View File

@ -1,6 +1,6 @@
{ {
"name": "bitwarden-dmenu", "name": "bitwarden-dmenu",
"version": "1.2.2",
"version": "1.2.3",
"description": "dmenu for bitwarden password manager.", "description": "dmenu for bitwarden password manager.",
"keywords": [ "keywords": [
"bitwarden", "bitwarden",


+ 4
- 4
src/exec-bitwarden-cli.js View File

@ -1,13 +1,13 @@
const path = require('path') const path = require('path')
const { execSync } = require('child_process')
const { spawnSync } = require('child_process')
const obfuscate = require('./util/obfuscate/bitwarden-cli') const obfuscate = require('./util/obfuscate/bitwarden-cli')
const bwExecutable = path.resolve(__dirname, '../node_modules/.bin/bw') const bwExecutable = path.resolve(__dirname, '../node_modules/.bin/bw')
module.exports = args => {
const execCommand = `${bwExecutable} ${args}`
module.exports = (...args) => {
const execCommand = `${bwExecutable} ${args.join(' ')}`
console.debug('$', obfuscate(execCommand)) console.debug('$', obfuscate(execCommand))
try { try {
const stdout = execSync(execCommand)
const { stdout } = spawnSync(bwExecutable, args)
return stdout.toString().replace(/\n$/, '') return stdout.toString().replace(/\n$/, '')
} catch (e) { } catch (e) {
throw new Error(e.stdout.toString().trim()) throw new Error(e.stdout.toString().trim())


+ 2
- 2
src/exec-dmenu.js View File

@ -1,6 +1,6 @@
const { exec, execSync, spawn } = require('child_process')
const { exec } = require('child_process')
module.exports = (choices = '\n', args = '') =>
module.exports = (...args) => choices =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
let choice = '' let choice = ''
const error = [] const error = []


+ 10
- 11
src/index.js View File

@ -19,19 +19,17 @@ const getSessionVar = async ({ saveSession, sessionFile }) => {
} else { } else {
console.debug('no session file found.') console.debug('no session file found.')
// prompt for password in dmenu // prompt for password in dmenu
const password = await dmenuRun('\n', '-p Password: -nf black -nb black')
const password = await dmenuRun('-p Password: -nf black -nb black')('\n')
if (!password) throw new Error('no password given!') if (!password) throw new Error('no password given!')
const escapedPw = password.replace(/'/g, String.raw`'\''`)
const session = bwRun(`unlock '${escapedPw}' --raw`)
const session = bwRun('unlock', password, '--raw')
writeFileSync(sessionFile, session) writeFileSync(sessionFile, session)
console.debug('saved new session file.') console.debug('saved new session file.')
return session return session
} }
} else { } else {
const password = await dmenuRun('\n', '-p Password: -nf black -nb black')
const password = await dmenuRun('-p Password: -nf black -nb black')('\n')
if (!password) throw new Error('no password given!') if (!password) throw new Error('no password given!')
const escapedPw = password.replace(/'/g, String.raw`'\''`)
const session = bwRun(`unlock '${escapedPw}' --raw`)
const session = bwRun('unlock', password, '--raw')
return session return session
} }
} }
@ -39,18 +37,18 @@ const getSessionVar = async ({ saveSession, sessionFile }) => {
// sync the password accounts with the remote server // sync the password accounts with the remote server
// if --sync-vault-after < time since the last sync // if --sync-vault-after < time since the last sync
const syncIfNecessary = ({ session, oldestAllowedVaultSync }) => { const syncIfNecessary = ({ session, oldestAllowedVaultSync }) => {
const last = bwRun(`sync --last --session=${session}`)
const last = bwRun('sync', '--last', `--session=${session}`)
const timeSinceSync = (new Date().getTime() - new Date(last).getTime()) / 1000 const timeSinceSync = (new Date().getTime() - new Date(last).getTime()) / 1000
if (timeSinceSync > oldestAllowedVaultSync) { if (timeSinceSync > oldestAllowedVaultSync) {
console.debug('syncing vault...') console.debug('syncing vault...')
bwRun(`sync --session=${session}`)
bwRun('sync', `--session=${session}`)
console.debug(`sync complete, last sync was ${last}`) console.debug(`sync complete, last sync was ${last}`)
} }
} }
// get the list all password accounts in the vault // get the list all password accounts in the vault
const getAccounts = ({ session }) => { const getAccounts = ({ session }) => {
const listStr = bwRun(`list items --session=${session}`)
const listStr = bwRun('list', 'items', `--session=${session}`)
const list = JSON.parse(listStr) const list = JSON.parse(listStr)
return list return list
} }
@ -62,7 +60,7 @@ const chooseAccount = async ({ list }) => {
.filter(a => a.type === LOGIN_TYPE) .filter(a => a.type === LOGIN_TYPE)
.map(a => `${a.name}: ${a.login.username}`) .map(a => `${a.name}: ${a.login.username}`)
// -i allows case insensitive matching // -i allows case insensitive matching
const selected = await dmenuRun(accountNames.join('\n'), '-i')
const selected = await dmenuRun('-i')(accountNames.join('\n'))
const index = accountNames.indexOf(selected) const index = accountNames.indexOf(selected)
const selectedAccount = list[index] const selectedAccount = list[index]
console.debug('selected account:\n', obfuscate(selectedAccount)) console.debug('selected account:\n', obfuscate(selectedAccount))
@ -71,6 +69,7 @@ const chooseAccount = async ({ list }) => {
// choose one field with dmenu // choose one field with dmenu
const chooseField = async ({ selectedAccount }) => { const chooseField = async ({ selectedAccount }) => {
if (!selectedAccount) throw new Error('no account selected!')
const copyable = { const copyable = {
password: selectedAccount.login.password, password: selectedAccount.login.password,
username: selectedAccount.login.username, username: selectedAccount.login.username,
@ -83,7 +82,7 @@ const chooseField = async ({ selectedAccount }) => {
{} {}
) )
} }
const field = await dmenuRun(Object.keys(copyable).join('\n'))
const field = await dmenuRun()(Object.keys(copyable).join('\n'))
console.debug(`selected field '${field}'`) console.debug(`selected field '${field}'`)
const valueToCopy = copyable[field] const valueToCopy = copyable[field]
return valueToCopy return valueToCopy


+ 2
- 2
src/util/obfuscate/bitwarden-cli.js View File

@ -1,4 +1,4 @@
module.exports = command => module.exports = command =>
command command
.replace(/unlock\s'.*'/, `unlock '******'`)
.replace(/session=.*/, 'session=****** ')
.replace(/unlock\s.*--raw$/, `unlock ****** --raw`)
.replace(/session=.*/, 'session=******')

Loading…
Cancel
Save