Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Bitwarden integration #1809

Merged
merged 3 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions js/passwordManager/bitwarden.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const ProcessSpawner = require('util/process.js')
const path = require('path')
const fs = require('fs')
var { ipcRenderer } = require('electron')

// Bitwarden password manager. Requires session key to unlock the vault.
class Bitwarden {
Expand Down Expand Up @@ -139,24 +140,52 @@ class Bitwarden {
return true
} catch (ex) {
const { error, data } = ex

if (error.includes('not logged in')) {
await this.signInAndSave()
return await this.unlockStore(password)
}

console.error('Error accessing Bitwarden CLI. STDOUT: ' + data + '. STDERR: ' + error)
throw ex
}
}

getSignInRequirements () {
return ['email', 'password']
}

async signInAndSave (credentials, path = this.path) {
async signInAndSave (path = this.path) {
// It's possible to be already logged in
const logoutProcess = new ProcessSpawner(path, ['logout'])
try {
await logoutProcess.execute()
} catch (e) {
console.warn(e)
}
const process = new ProcessSpawner(path, ['login', '--raw', credentials.email, credentials.password])

// show credentials dialog

var signInFields = [
{ placeholder: 'Client ID', id: 'clientID', type: 'password' },
{ placeholder: 'Client Secret', id: 'clientSecret', type: 'password' }
]

const credentials = ipcRenderer.sendSync('prompt', {
text: l('passwordManagerBitwardenSignIn'),
values: signInFields,
ok: l('dialogConfirmButton'),
cancel: l('dialogSkipButton'),
width: 500,
height: 240
})

for (const key in credentials) {
if (credentials[key] === '') {
throw new Error('no credentials entered')
}
}

const process = new ProcessSpawner(path, ['login', '--apikey'], {
BW_CLIENTID: credentials.clientID.trim(),
BW_CLIENTSECRET: credentials.clientSecret.trim()
})

await process.execute()

Expand Down
4 changes: 0 additions & 4 deletions js/passwordManager/keychain.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ class Keychain {
})
}

getSignInRequirements () {
return []
}

saveCredential (domain, username, password) {
ipcRenderer.invoke('credentialStoreSetPassword', { domain, username, password })
}
Expand Down
26 changes: 3 additions & 23 deletions js/passwordManager/managerSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const setupDialog = {
document.getElementById('password-manager-setup-link').textContent = l('passwordManagerSetupLink').replace('%p', manager.name)
document.getElementById('password-manager-setup-link-installer').textContent = l('passwordManagerSetupLinkInstaller').replace('%p', manager.name)

dragBox.textContent = l('passwordManagerSetupDragBox')

if (setupDialog.setupMode === 'installer') {
primaryInstructions.hidden = true
secondaryInstructions.hidden = false
Expand Down Expand Up @@ -162,29 +164,7 @@ function launchInstaller (filePath, platform) {
}

function afterInstall (toolPath) {
var signInFields = [
{ placeholder: l('email'), id: 'email', type: 'text' },
{ placeholder: l('password'), id: 'password', type: 'password' },
{ placeholder: l('secretKey'), id: 'secretKey', type: 'password' }
].filter(f => setupDialog.manager.getSignInRequirements().includes(f.id))

// Verify the tool by trying to use it to unlock the password store.
const data = ipcRenderer.sendSync('prompt', {
text: l('passwordManagerSetupSignIn'),
values: signInFields,
ok: l('dialogConfirmButton'),
cancel: l('dialogSkipButton'),
width: 500,
height: 220
})

for (const key in data) {
if (data[key] === '') {
throw new Error('no credentials entered')
}
}

setupDialog.manager.signInAndSave(data, toolPath)
setupDialog.manager.signInAndSave(toolPath)
.then(() => {
setupDialog.hide()
})
Expand Down
31 changes: 26 additions & 5 deletions js/passwordManager/onePassword.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const ProcessSpawner = require('util/process.js')
const path = require('path')
const fs = require('fs')
var { ipcRenderer } = require('electron')

// 1Password password manager. Requires session key to unlock the vault.
class OnePassword {
Expand Down Expand Up @@ -165,18 +166,38 @@ class OnePassword {
}
}

getSignInRequirements () {
return ['email', 'password', 'secretKey']
}

async signInAndSave (credentials, path = this.path) {
async signInAndSave (path = this.path) {
// It's possible to be already logged in
const logoutProcess = new ProcessSpawner(path, ['signout'])
try {
await logoutProcess.executeSyncInAsyncContext()
} catch (e) {
console.warn(e)
}

// show credentials dialog
var signInFields = [
{ placeholder: l('email'), id: 'email', type: 'text' },
{ placeholder: l('password'), id: 'password', type: 'password' },
{ placeholder: l('secretKey'), id: 'secretKey', type: 'password' }
]

// Verify the tool by trying to use it to unlock the password store.
const credentials = ipcRenderer.sendSync('prompt', {
text: l('passwordManagerSetupSignIn'),
values: signInFields,
ok: l('dialogConfirmButton'),
cancel: l('dialogSkipButton'),
width: 500,
height: 220
})

for (const key in credentials) {
if (credentials[key] === '') {
throw new Error('no credentials entered')
}
}

const process = new ProcessSpawner(path, ['signin', '--raw', 'my.1password.com', credentials.email, credentials.secretKey])

const key = await process.executeSyncInAsyncContext(credentials.password)
Expand Down
11 changes: 6 additions & 5 deletions js/util/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ const customEnv = Object.assign({}, process.env, { PATH: processPath })
const maxBufferSize = 25 * 1024 * 1024

class ProcessSpawner {
constructor (command, args) {
constructor (command, args, env = {}) {
this.command = command
this.args = args
this.data = ''
this.error = ''
this.env = Object.assign({}, customEnv, env)
}

async execute () {
return new Promise((resolve, reject) => {
const process = spawn(this.command, this.args, { env: customEnv, maxBuffer: maxBufferSize })
const process = spawn(this.command, this.args, { env: this.env, maxBuffer: maxBufferSize })

process.stdout.on('data', (data) => {
this.data += data
Expand All @@ -56,7 +57,7 @@ class ProcessSpawner {
}

executeSync (input) {
const process = spawnSync(this.command, this.args, { input: input, encoding: 'utf8', env: customEnv, maxBuffer: maxBufferSize })
const process = spawnSync(this.command, this.args, { input: input, encoding: 'utf8', env: this.env, maxBuffer: maxBufferSize })
return process.output[1].slice(0, -1)
}

Expand All @@ -76,7 +77,7 @@ class ProcessSpawner {
command: this.command,
args: this.args,
input: input,
customEnv: customEnv,
customEnv: this.env,
maxBuffer: maxBufferSize,
taskId: taskId
})
Expand All @@ -86,7 +87,7 @@ class ProcessSpawner {
checkCommandExists () {
return new Promise((resolve, reject) => {
const checkCommand = (platformType === 'windows') ? 'where' : 'which'
const process = spawn(checkCommand, [this.command], { env: customEnv })
const process = spawn(checkCommand, [this.command], { env: this.env })

process.stdout.on('data', (data) => {
if (data.length > 0) {
Expand Down
1 change: 1 addition & 0 deletions localization/languages/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@
"passwordManagerSetupStep2": null, //missing translation
"passwordManagerSetupDragBox": null, //missing translation
"passwordManagerSetupInstalling": null, //missing translation
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": null, //missing translation
"disableAutofill": null, //missing translation
"passwordManagerSetupUnlockError": null, //missing translation
Expand Down
1 change: 1 addition & 0 deletions localization/languages/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@
"passwordManagerSetupStep2": "След това плъзнете уреда в полето отдолу:",
"passwordManagerSetupDragBox": "Плъзнете уреда тук",
"passwordManagerSetupInstalling": "Инсталиране...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Впишете се във Вашия мениджър на пароли, за да започнете употребата на автоматично попълване. Вашите пълномощия няма да се съхраняват никъде в Min.",
"disableAutofill": "Деактивиране на автоматично попълване на пароли",
"passwordManagerSetupUnlockError": "Неуспешно отключване на хранилището за пароли: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/bn.json
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
"passwordManagerSetupStep2": null, //missing translation
"passwordManagerSetupDragBox": null, //missing translation
"passwordManagerSetupInstalling": null, //missing translation
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": null, //missing translation
"disableAutofill": null, //missing translation
"passwordManagerSetupUnlockError": null, //missing translation
Expand Down
1 change: 1 addition & 0 deletions localization/languages/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
"passwordManagerSetupStep2": "Pak přetáhněte nástroj do pole níže:",
"passwordManagerSetupDragBox": "Přetáhněte nástroj sem",
"passwordManagerSetupInstalling": "Probíhá instalace...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Přihlaste se do vašeho správce hesel, abyste mohli začít používat automatické vkládání. Vaše přihlašovací údaje nebudou v prohlížeči Min nikde uchovány.",
"disableAutofill": "Vypnout automatické vkládání",
"passwordManagerSetupUnlockError": "Selhalo odemčení úložiště hesel: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Ziehe danach das Programm in die untere Box:",
"passwordManagerSetupDragBox": "Ziehe das Programm hierher",
"passwordManagerSetupInstalling": "Installiere...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Melde dich in deinem Passwortmanager an, um die automatische Ausfüll Funktion zu nutzen. Deine Zugangsdaten werden nirgendwo in Min gespeichert.",
"disableAutofill": "Automatische Ausfüll Funktion deaktivieren",
"passwordManagerSetupUnlockError": "Beim Entsperren des Passwortmanagers ist ein Fehler aufgetreten:",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Then drag the tool into the box below:",
"passwordManagerSetupDragBox": "Drag the tool here",
"passwordManagerSetupInstalling": "Installing...",
"passwordManagerBitwardenSignIn": "To connect your Bitwarden account, go to vault.bitwarden.com/#/settings/account, scroll to the bottom, and choose \"View API Key\". Then paste the values into the fields below.",
"passwordManagerSetupSignIn": "Sign in to your password manager to start using autofill. Your credentials won't be stored anywhere inside Min.",
"disableAutofill": "Disable Autofill",
"passwordManagerSetupUnlockError": "Failed to unlock the password store: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@
"passwordManagerSetupStep2": "Luego arrastra la herramienta hasta el cuadro de abajo:",
"passwordManagerSetupDragBox": "Arrastra la herramienta hasta aquí",
"passwordManagerSetupInstalling": "Instalando...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Inicia sesión en tu gestor de contraseñas para empezar a usar el Auto-llenado. Tus credenciales no serán almacenadas en ningún lugar dentro de Min.",
"disableAutofill": "Desactivar Auto-llenado",
"passwordManagerSetupUnlockError": "No se pudo desbloquear el almacén de contraseñas:",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/fa.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@
"passwordManagerSetupStep2": null, //missing translation
"passwordManagerSetupDragBox": null, //missing translation
"passwordManagerSetupInstalling": null, //missing translation
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": null, //missing translation
"disableAutofill": null, //missing translation
"passwordManagerSetupUnlockError": null, //missing translation
Expand Down
1 change: 1 addition & 0 deletions localization/languages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Puis cliquer-glisser l'outil dans le cadre ci-dessous :",
"passwordManagerSetupDragBox": "Déposer l'outil ici",
"passwordManagerSetupInstalling": "En cours d'installation...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Connectez-vous à votre gestionnaire de mots de pass pour commencer à utiliser le remplissage automatique. Vos informations de connexion ne seront jamais stockées par Min.",
"disableAutofill": "Désactiver le remplissage automatique",
"passwordManagerSetupUnlockError": "Échec d'ouverture de la bibliothèque de mots passe : ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/hr.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Zatim povucite alat u donji okvir:",
"passwordManagerSetupDragBox": "Povucite alat ovdje",
"passwordManagerSetupInstalling": "Instaliranje...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Prijavite se na upravitelj lozinki da biste počeli koristiti automatsko popunjavanje. Vjerodajnice se neće pohraniti nigdje u Min.",
"disableAutofill": "Onemogući automatsko popunjavanje",
"passwordManagerSetupUnlockError": "Otključavanje spremišta lozinki nije uspjelo: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/hu.json
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
"passwordManagerSetupStep2": null, //missing translation
"passwordManagerSetupDragBox": null, //missing translation
"passwordManagerSetupInstalling": null, //missing translation
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": null, //missing translation
"disableAutofill": null, //missing translation
"passwordManagerSetupUnlockError": null, //missing translation
Expand Down
1 change: 1 addition & 0 deletions localization/languages/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Quindi trascina il tool nel box qui sotto:",
"passwordManagerSetupDragBox": "Trascina il tool qui",
"passwordManagerSetupInstalling": "Installazione...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Entra nel tuo gestore di password per iniziare ad usare l'autocompletamento. Le tue credenziali non saranno salvate da nessuna parte in Min.",
"disableAutofill": "Disabilita autocompletamento",
"passwordManagerSetupUnlockError": "Impossibile sbloccare le password: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "次に、ツールを下のボックスにドラッグします。",
"passwordManagerSetupDragBox": "ここにツールをドラッグ",
"passwordManagerSetupInstalling": "インストールしています...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "パスワードマネージャーにログインして、自動入力の使用を開始します。 資格情報はMin内のどこにも保存されません。",
"disableAutofill": "自動入力を無効にする",
"passwordManagerSetupUnlockError": "パスワードストアのロック解除に失敗しました: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "그 다음 도구를 아래 박스 안에 끌어다 놓습니다:",
"passwordManagerSetupDragBox": "도구를 여기에 끌어다 놓으세요.",
"passwordManagerSetupInstalling": "설치하는 중...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "자동완성을 사용하려면 비밀번호 관리자에 로그인하세요. 귀하의 자격증명은 민(Min)의 그 어디에도 저장되지 않습니다.",
"disableAutofill": "자동완성 비활성화",
"passwordManagerSetupUnlockError": "비밀번호 저장소를 여는데 실패했습니다: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/lt.json
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
"passwordManagerSetupStep2": null, //missing translation
"passwordManagerSetupDragBox": null, //missing translation
"passwordManagerSetupInstalling": null, //missing translation
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": null, //missing translation
"disableAutofill": null, //missing translation
"passwordManagerSetupUnlockError": null, //missing translation
Expand Down
1 change: 1 addition & 0 deletions localization/languages/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Następnie przeciągnij narzędzie do pola poniżej:",
"passwordManagerSetupDragBox": "Przeciągnij narzędzie tutaj",
"passwordManagerSetupInstalling": "Instalowanie...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Zaloguj się do menedżera haseł, aby rozpocząć korzystanie z autouzupełniania. Twoje dane uwierzytelniające nie będą przechowywane nigdzie w Min.",
"disableAutofill": "Wyłącz autouzupełnianie",
"passwordManagerSetupUnlockError": "nie udało się odblokować przechowalni haseł: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Em seguida, arraste a ferramenta para a caixa abaixo:",
"passwordManagerSetupDragBox": "Arraste a ferramenta aqui",
"passwordManagerSetupInstalling": "Instalando ...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Entre no seu gerenciador de senhas para começar a usar o preenchimento automático. Suas credenciais não serão armazenadas em nenhum lugar do Min.",
"disableAutofill": "Desativar preenchimento automático",
"passwordManagerSetupUnlockError": "Falha ao desbloquear o armazenamento de senhas:",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/pt-PT.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Depois, arraste a ferramenta para a caixa abaixo:",
"passwordManagerSetupDragBox": "Arraste a ferramenta para aqui",
"passwordManagerSetupInstalling": "A instalar...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Inicie sessão no gestor de palavras-passe para utilizar o preenchimento automático. As suas credenciais não serão guardadas no Min.",
"disableAutofill": "Desativar preenchimento automático",
"passwordManagerSetupUnlockError": "Falha ao desbloquear: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Затем перетащите инструмент в поле ниже:",
"passwordManagerSetupDragBox": "Перетащите инструмент сюда",
"passwordManagerSetupInstalling": "Установка...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Войдите в свой менеджер паролей, чтобы начать использовать автозаполнение. Ваши учетные данные не будут храниться где-либо внутри Min.",
"disableAutofill": "Отключить автозаполнение",
"passwordManagerSetupUnlockError": "Не удалось разблокировать хранилище паролей: ",
Expand Down
1 change: 1 addition & 0 deletions localization/languages/tr.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@
"passwordManagerSetupStep2": "Ardından aracı aşağıdaki kutucuğa sürükleyip bırakın:",
"passwordManagerSetupDragBox": "Aracı buraya sürükleyin",
"passwordManagerSetupInstalling": "Yükleniyor...",
"passwordManagerBitwardenSignIn": null, //missing translation
"passwordManagerSetupSignIn": "Otomatik dolduru kullanabilmek için parola yöneticinize giriş yapın. Kimlik bilgileriniz Min içerisinde bir yere kaydedilmeyecektir.",
"disableAutofill": "Otomatik Dolduru Devre Dışı Bırak",
"passwordManagerSetupUnlockError": "Parola kayıtlarının kilidi açılamadı: ",
Expand Down
Loading