From 90642983098b5e50d3957e93fb7f9a59541b12fd Mon Sep 17 00:00:00 2001 From: Hinton Date: Wed, 21 Oct 2020 15:56:10 +0200 Subject: [PATCH] Display error message when browser integration is disabled, or desktop not running --- src/_locales/en/messages.json | 12 +++++ src/background/nativeMessaging.background.ts | 51 ++++++++++++++++---- src/browser/browserApi.ts | 8 +++ 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index be4275d8bb..ec562879df 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1371,5 +1371,17 @@ }, "desktopIntegrationVerificationText": { "message": "Please verify that the desktop application shows this fingerprint: " + }, + "desktopIntegrationDisabledTitle": { + "message": "Browser integration is not enabled" + }, + "desktopIntegrationDisabledDesc": { + "message": "Browser integration is not enabled in the Bitwarden Desktop Application. Please enable it in the settings within the desktop application." + }, + "startDesktopTitle": { + "message": "Start the Bitwarden Desktop Application" + }, + "startDesktopDesc": { + "message": "The bitwarden desktop application needs to be started before this function can be used." } } diff --git a/src/background/nativeMessaging.background.ts b/src/background/nativeMessaging.background.ts index caebdc8e27..6938935870 100644 --- a/src/background/nativeMessaging.background.ts +++ b/src/background/nativeMessaging.background.ts @@ -16,6 +16,7 @@ const EncryptionAlgorithm = 'sha1'; export class NativeMessagingBackground { private connected = false; + private connecting: boolean; private port: browser.runtime.Port | chrome.runtime.Port; private resolver: any = null; @@ -29,22 +30,54 @@ export class NativeMessagingBackground { private runtimeBackground: RuntimeBackground, private i18nService: I18nService, private userService: UserService, private messagingService: MessagingService) {} - connect() { - this.port = BrowserApi.connectNative('com.8bit.bitwarden'); + async connect() { + return new Promise((resolve, reject) => { + this.port = BrowserApi.connectNative('com.8bit.bitwarden'); - this.connected = true; + this.connecting = true; - this.port.onMessage.addListener((msg) => this.onMessage(msg)); + this.port.onMessage.addListener((message: any) => { + if (message.command === 'connected') { + this.connected = true; + this.connecting = false; + resolve(); + } else if (message.command === 'disconnected') { + if (this.connecting) { + this.messagingService.send('showDialog', { + text: this.i18nService.t('startDesktopDesc'), + title: this.i18nService.t('startDesktopTitle'), + confirmText: this.i18nService.t('ok'), + type: 'error', + }); + reject(); + } + this.connected = false; + this.port.disconnect(); + return; + } - this.port.onDisconnect.addListener(() => { - this.connected = false; + this.onMessage(message); + }); + + this.port.onDisconnect.addListener(() => { + if (BrowserApi.runtimeLastError().message === 'Specified native messaging host not found.') { + this.messagingService.send('showDialog', { + text: this.i18nService.t('desktopIntegrationDisabledDesc'), + title: this.i18nService.t('desktopIntegrationDisabledTitle'), + confirmText: this.i18nService.t('ok'), + type: 'error', + }); + } + this.connected = false; + reject(); + }); }); } async send(message: any) { // If not connected, try to connect if (!this.connected) { - this.connect(); + await this.connect(); } if (this.sharedSecret == null) { @@ -118,7 +151,7 @@ export class NativeMessagingBackground { const fingerprint = (await this.cryptoService.getFingerprint(await this.userService.getUserId(), this.publicKey)).join(' '); this.messagingService.send('showDialog', { - html: `${this.i18nService.t('desktopIntegrationVerificationText')}

${fingerprint}.`, + html: `${this.i18nService.t('desktopIntegrationVerificationText')}

${fingerprint}`, title: this.i18nService.t('desktopSyncVerificationTitle'), confirmText: this.i18nService.t('ok'), type: 'warning', @@ -129,7 +162,7 @@ export class NativeMessagingBackground { private async sendUnencrypted(message: any) { if (!this.connected) { - this.connect(); + await this.connect(); } message.timestamp = Date.now(); diff --git a/src/browser/browserApi.ts b/src/browser/browserApi.ts index 1ee54a45b1..660defcca3 100644 --- a/src/browser/browserApi.ts +++ b/src/browser/browserApi.ts @@ -229,4 +229,12 @@ export class BrowserApi { return chrome.runtime.connectNative(application); } } + + static runtimeLastError(): browser.runtime._LastError | chrome.runtime.LastError { + if (BrowserApi.isWebExtensionsApi) { + return browser.runtime.lastError; + } else if (BrowserApi.isChromeApi) { + return chrome.runtime.lastError; + } + } }