1- const ProcessSpawner = require ( 'util/process.js' )
2- const path = require ( 'path' )
1+
2+ const { join } = require ( 'path' )
33const fs = require ( 'fs' )
4- var { ipcRenderer } = require ( 'electron' )
4+ const { ipcRenderer } = require ( 'electron' )
5+
6+ const ProcessSpawner = require ( 'util/process.js' )
57
68// Bitwarden password manager. Requires session key to unlock the vault.
79class Bitwarden {
@@ -12,18 +14,17 @@ class Bitwarden {
1214 }
1315
1416 getDownloadLink ( ) {
15- switch ( window . platformType ) {
16- case 'mac' :
17- return 'https://vault.bitwarden.com/download/?app=cli&platform=macos'
18- case 'windows' :
19- return 'https://vault.bitwarden.com/download/?app=cli&platform=windows'
20- case 'linux' :
21- return 'https://vault.bitwarden.com/download/?app=cli&platform=linux'
17+ if ( window . platformType === 'mac' ) {
18+ return 'https://vault.bitwarden.com/download/?app=cli&platform=macos'
2219 }
20+ if ( window . platformType === 'windows' ) {
21+ return 'https://vault.bitwarden.com/download/?app=cli&platform=windows'
22+ }
23+ return 'https://vault.bitwarden.com/download/?app=cli&platform=linux'
2324 }
2425
2526 getLocalPath ( ) {
26- return path . join ( window . globalArgs [ 'user-data-path' ] , 'tools' , ( platformType === 'windows' ? 'bw.exe' : 'bw' ) )
27+ return join ( window . globalArgs [ 'user-data-path' ] , 'tools' , ( platformType === 'windows' ? 'bw.exe' : 'bw' ) )
2728 }
2829
2930 getSetupMode ( ) {
@@ -41,7 +42,7 @@ class Bitwarden {
4142 try {
4243 await fs . promises . access ( localPath , fs . constants . X_OK )
4344 local = true
44- } catch ( e ) { }
45+ } catch { }
4546 if ( local ) {
4647 return localPath
4748 }
@@ -71,7 +72,7 @@ class Bitwarden {
7172
7273 // Tries to get a list of credential suggestions for a given domain name.
7374 async getSuggestions ( domain ) {
74- if ( this . lastCallList [ domain ] != null ) {
75+ if ( this . lastCallList [ domain ] ) {
7576 return this . lastCallList [ domain ]
7677 }
7778
@@ -84,32 +85,34 @@ class Bitwarden {
8485 throw new Error ( )
8586 }
8687
87- this . lastCallList [ domain ] = this . loadSuggestions ( command , domain ) . then ( suggestions => {
88- this . lastCallList [ domain ] = null
88+ try {
89+ const suggestions = await this . loadSuggestions ( command , domain )
90+ this . lastCallList [ domain ] = suggestions
91+ console . log ( 'getSuggestions' , suggestions )
8992 return suggestions
90- } ) . catch ( ex => {
93+ } catch ( e ) {
9194 this . lastCallList [ domain ] = null
92- } )
95+ }
9396
9497 return this . lastCallList [ domain ]
9598 }
9699
97100 // Loads credential suggestions for given domain name.
98101 async loadSuggestions ( command , domain ) {
102+ console . log ( domain . replace ( / [ ^ a - z A - Z 0 - 9 . - ] / g, '' ) )
99103 try {
100- const process = new ProcessSpawner ( command , [ 'list' , 'items' , '--url' , this . sanitize ( domain ) , '--session' , this . sessionKey ] )
101- const data = await process . execute ( )
102-
103- const matches = JSON . parse ( data )
104- const credentials = matches . map ( match => {
105- const { login : { username, password } } = match
106- return { username, password, manager : 'Bitwarden' }
107- } )
108-
109- return credentials
110- } catch ( ex ) {
111- const { error, data } = ex
112- console . error ( 'Error accessing Bitwarden CLI. STDOUT: ' + data + '. STDERR: ' + error )
104+ const process = new ProcessSpawner (
105+ command ,
106+ [ 'list' , 'items' , '--url' , domain . replace ( / [ ^ a - z A - Z 0 - 9 . - ] / g, '' ) , '--session' , this . sessionKey ]
107+ )
108+ const matches = JSON . parse ( await process . execute ( ) )
109+ console . log ( matches )
110+ return matches . map (
111+ ( { login : { username, password } } ) =>
112+ ( { username, password, manager : 'Bitwarden' } )
113+ )
114+ } catch ( { error, data } ) {
115+ console . error ( `Error accessing Bitwarden CLI. STDOUT: ${ data } . STDERR: ${ error } ` )
113116 return [ ]
114117 }
115118 }
@@ -118,9 +121,8 @@ class Bitwarden {
118121 try {
119122 const process = new ProcessSpawner ( command , [ 'sync' , '--session' , this . sessionKey ] )
120123 await process . execute ( )
121- } catch ( ex ) {
122- const { error, data } = ex
123- console . error ( 'Error accessing Bitwarden CLI. STDOUT: ' + data + '. STDERR: ' + error )
124+ } catch ( { error, data } ) {
125+ console . error ( `Error accessing Bitwarden CLI. STDOUT: ${ data } . STDERR: ${ error } ` )
124126 }
125127 }
126128
@@ -138,17 +140,17 @@ class Bitwarden {
138140 await this . forceSync ( this . path )
139141
140142 return true
141- } catch ( ex ) {
142- const { error, data } = ex
143+ } catch ( err ) {
144+ const { error, data } = err
143145
144- console . error ( ' Error accessing Bitwarden CLI. STDOUT: ' + data + ' . STDERR: ' + error )
146+ console . error ( ` Error accessing Bitwarden CLI. STDOUT: ${ data } . STDERR: ${ error } ` )
145147
146148 if ( error . includes ( 'not logged in' ) ) {
147149 await this . signInAndSave ( )
148150 return await this . unlockStore ( password )
149151 }
150152
151- throw ex
153+ throw err
152154 }
153155 }
154156
@@ -161,41 +163,43 @@ class Bitwarden {
161163 console . warn ( e )
162164 }
163165
164- // show credentials dialog
165-
166- var signInFields = [
166+ // show ask-for-credential dialog
167+ const signInFields = [
168+ { placeholder : 'Server URL (Leave blank for the default Bitwarden server)' , id : 'url' , type : 'text' } ,
167169 { placeholder : 'Client ID' , id : 'clientID' , type : 'password' } ,
168170 { placeholder : 'Client Secret' , id : 'clientSecret' , type : 'password' }
169171 ]
170172
171- const credentials = ipcRenderer . sendSync ( 'prompt' , {
172- text : l ( 'passwordManagerBitwardenSignIn' ) ,
173- values : signInFields ,
174- ok : l ( 'dialogConfirmButton' ) ,
175- cancel : l ( 'dialogSkipButton' ) ,
176- width : 500 ,
177- height : 260
178- } )
179-
180- for ( const key in credentials ) {
181- if ( credentials [ key ] === '' ) {
182- throw new Error ( 'no credentials entered' )
173+ const credentials = ipcRenderer . sendSync (
174+ 'prompt' ,
175+ {
176+ text : l ( 'passwordManagerBitwardenSignIn' ) ,
177+ values : signInFields ,
178+ ok : l ( 'dialogConfirmButton' ) ,
179+ cancel : l ( 'dialogSkipButton' ) ,
180+ width : 500 ,
181+ height : 260
183182 }
184- }
183+ )
185184
186- const process = new ProcessSpawner ( path , [ 'login' , '--apikey' ] , {
187- BW_CLIENTID : credentials . clientID . trim ( ) ,
188- BW_CLIENTSECRET : credentials . clientSecret . trim ( )
189- } )
185+ if ( credentials . clientID === '' || credentials . clientSecret === '' ) {
186+ throw new Error ( 'no credentials entered' )
187+ }
190188
191- await process . execute ( )
189+ credentials . url = credentials . url || 'bitwarden.com'
192190
193- return true
194- }
191+ const process1 = new ProcessSpawner ( path , [ 'config' , 'server' , credentials . url . trim ( ) ] )
192+ await process1 . execute ( )
195193
196- // Basic domain name cleanup. Removes any non-ASCII symbols.
197- sanitize ( domain ) {
198- return domain . replace ( / [ ^ a - z A - Z 0 - 9 . - ] / g, '' )
194+ const process2 = new ProcessSpawner (
195+ path ,
196+ [ 'login' , '--apikey' ] ,
197+ {
198+ BW_CLIENTID : credentials . clientID . trim ( ) ,
199+ BW_CLIENTSECRET : credentials . clientSecret . trim ( )
200+ }
201+ )
202+ await process2 . execute ( )
199203 }
200204}
201205
0 commit comments