From 5941a4387dabbeddf8abfc37d91ddee9613a32f0 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 22 Dec 2020 16:38:53 -0500 Subject: [PATCH 01/10] warning dialog is now handled in base component (#1506) --- jslib | 2 +- src/_locales/en/messages.json | 3 +++ src/popup/settings/export.component.html | 7 ------- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/jslib b/jslib index f9042408f4..aa1499f70a 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit f9042408f44b299a7cdd1286490b70f5fd2db999 +Subproject commit aa1499f70a4ccb0556460942c7c5be1fd517d598 diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 94e5f5ad63..c21743085f 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -606,6 +606,9 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "confirmVaultExport": { + "message": "Confirm Vault Export" + }, "exportWarningDesc": { "message": "This export contains your vault data in an unencrypted format. You should not store or send the exported file over unsecure channels (such as email). Delete it immediately after you are done using it." }, diff --git a/src/popup/settings/export.component.html b/src/popup/settings/export.component.html index f4a90062c9..759fbec53c 100644 --- a/src/popup/settings/export.component.html +++ b/src/popup/settings/export.component.html @@ -41,13 +41,6 @@ From a0a032957e344e95ee2ecf1ebe1c2d8e8aec6ea1 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 29 Dec 2020 09:18:14 -0600 Subject: [PATCH 02/10] Fix safari sso (#1508) * Fix extension tab creation TODO: still getting errors thrown by safariApp at `(window as any).webkit.messageHandlers` upon loading the extension window * Support message sending from app extension context * Load sso login in popover * Handle nil urlComponents and nil queryItems --- src/browser/safariApp.ts | 20 +++++++++---- src/content/sso.ts | 9 ++++++ src/popup/accounts/sso.component.ts | 4 +-- .../SafariExtensionViewController.swift | 28 +++++++++++++++---- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/browser/safariApp.ts b/src/browser/safariApp.ts index 5593b069b8..894ae2c6d4 100644 --- a/src/browser/safariApp.ts +++ b/src/browser/safariApp.ts @@ -25,12 +25,20 @@ export class SafariApp { return new Promise((resolve) => { const now = new Date(); const messageId = now.getTime().toString() + '_' + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); - (window as any).webkit.messageHandlers.bitwardenApp.postMessage(JSON.stringify({ - id: messageId, - command: command, - data: data, - responseData: null, - })); + if (typeof safari === typeof undefined) { + (window as any).webkit.messageHandlers.bitwardenApp.postMessage(JSON.stringify({ + id: messageId, + command: command, + data: data, + responseData: null, + })); + } else { + safari.extension.dispatchMessage('bitwarden', { + command: command, + data: data, + responseData: null, + }); + } if (resolveNow) { resolve(); } else { diff --git a/src/content/sso.ts b/src/content/sso.ts index 508bc2aea3..a127a39d55 100644 --- a/src/content/sso.ts +++ b/src/content/sso.ts @@ -3,6 +3,15 @@ window.addEventListener('message', (event) => { return; if (event.data.command && (event.data.command === 'authResult')) { + if (typeof chrome === typeof undefined) { + safari.extension.dispatchMessage('bitwarden', { + command: event.data.command, + code: event.data.code, + state: event.data.state, + referrer: event.source.location.hostname, + }); + return; + } chrome.runtime.sendMessage({ command: event.data.command, code: event.data.code, diff --git a/src/popup/accounts/sso.component.ts b/src/popup/accounts/sso.component.ts index c88f3d1e60..0867b781a7 100644 --- a/src/popup/accounts/sso.component.ts +++ b/src/popup/accounts/sso.component.ts @@ -41,11 +41,11 @@ export class SsoComponent extends BaseSsoComponent { this.redirectUri = url + '/sso-connector.html'; this.clientId = 'browser'; - super.onSuccessfulLogin = () => { + super.onSuccessfulLogin = async () => { + await syncService.fullSync(true); BrowserApi.reloadOpenWindows(); const thisWindow = window.open('', '_self'); thisWindow.close(); - return syncService.fullSync(true); }; } } diff --git a/src/safari/safari/SafariExtensionViewController.swift b/src/safari/safari/SafariExtensionViewController.swift index 0f2ac13eaa..0241df00ce 100644 --- a/src/safari/safari/SafariExtensionViewController.swift +++ b/src/safari/safari/SafariExtensionViewController.swift @@ -16,14 +16,10 @@ class SafariExtensionViewController: SFSafariExtensionViewController, WKScriptMe if initedWebView { return } - let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String initedWebView = true let parentHeight = SafariExtensionViewController.shared.preferredContentSize.height let parentWidth = SafariExtensionViewController.shared.preferredContentSize.width let webViewConfig = WKWebViewConfiguration() - let bundleURL = Bundle.main.resourceURL!.absoluteURL - let html = bundleURL.appendingPathComponent("app/popup/index.html") - let url = URL(string: "\(html.absoluteString)?appVersion=\(version!)") webViewConfig.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") webViewConfig.preferences.setValue(true, forKey: "developerExtrasEnabled") webViewConfig.userContentController.add(self, name: "bitwardenApp") @@ -31,12 +27,26 @@ class SafariExtensionViewController: SFSafariExtensionViewController, WKScriptMe configuration: webViewConfig) webView.navigationDelegate = self webView.allowsLinkPreview = false - webView.loadFileURL(url!, allowingReadAccessTo: bundleURL) + navigateWebView("app/popup/index.html") webView.alphaValue = 0.0 webView.uiDelegate = self view.addSubview(webView) } + func navigateWebView(_ relativeUrl: String){ + let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String + let bundleUrl = Bundle.main.resourceURL!.absoluteURL + + if var urlComponents = URLComponents(string: bundleUrl.absoluteString + relativeUrl) { + if (urlComponents.queryItems?.first(where: { $0.name == "appVersion" })?.value == nil) { + urlComponents.queryItems = urlComponents.queryItems ?? [] + urlComponents.queryItems!.append(URLQueryItem(name: "appVersion", value: version)) + } + + webView.loadFileURL(urlComponents.url!, allowingReadAccessTo: bundleUrl) + } + } + func webView(_ webView: WKWebView, didFinish _: WKNavigation!) { if #available(OSXApplicationExtension 10.12, *) { NSAnimationContext.runAnimationGroup({ _ in @@ -179,6 +189,14 @@ class SafariExtensionViewController: SFSafariExtensionViewController, WKScriptMe replyMessage(message: m) } else if command == "createNewTab" { if let data = m.data, let url = URL(string: data) { + if !data.starts(with: "https://") && !data.starts(with: "http://") { + SFSafariApplication.getActiveWindow { win in + win?.getToolbarItem(completionHandler: { item in + item?.showPopover() + self.navigateWebView("app/" + url.absoluteString) + }) + } + } SFSafariApplication.getActiveWindow { win in win?.openTab(with: url, makeActiveIfPossible: true, completionHandler: { _ in // Tab opened From 74a9ff799227759628de01669208fc1e1ea14829 Mon Sep 17 00:00:00 2001 From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Date: Wed, 30 Dec 2020 20:35:06 -0600 Subject: [PATCH 03/10] update jslib (48144a7) (#1510) --- jslib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jslib b/jslib index aa1499f70a..48144a7eae 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit aa1499f70a4ccb0556460942c7c5be1fd517d598 +Subproject commit 48144a7eaea34984d98b5f22e14a73a24348dcd2 From 8d2b84cbb35d129e123a37029cb6f35ed4bb5a34 Mon Sep 17 00:00:00 2001 From: wusatosi <26424577+wusatosi@users.noreply.github.com> Date: Sun, 3 Jan 2021 00:32:22 +0800 Subject: [PATCH 04/10] [ref] Improved readability for #1441 --- src/services/autofill.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/autofill.service.ts b/src/services/autofill.service.ts index 7498248bbe..82d5224a6e 100644 --- a/src/services/autofill.service.ts +++ b/src/services/autofill.service.ts @@ -254,7 +254,7 @@ export default class AutofillService implements AutofillServiceInterface { } } - const autoFillResponse = await this.doAutoFill({ + const totpCode = await this.doAutoFill({ cipher: cipher, pageDetails: pageDetails, skipTotp: !fromCommand, @@ -265,12 +265,12 @@ export default class AutofillService implements AutofillServiceInterface { fillNewPassword: fromCommand, }); - // Only update last used index if doAutoFill didn't throw an exception + // Update last used index as autofill has succeed if (fromCommand) { this.cipherService.updateLastUsedIndexForUrl(tab.url); } - return autoFillResponse; + return totpCode; } // Helpers From 3541f458e5d62c4e856f141c42b8428275852d63 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Mon, 4 Jan 2021 11:38:21 -0600 Subject: [PATCH 05/10] Update jslib (#1520) --- jslib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jslib b/jslib index 48144a7eae..afa01f67f4 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 48144a7eaea34984d98b5f22e14a73a24348dcd2 +Subproject commit afa01f67f4f5f45506bb14ccb194bb22e11d803e From e922ff0bc291ff6fa493c9eb910545e2f41b2b14 Mon Sep 17 00:00:00 2001 From: Hinton Date: Mon, 4 Jan 2021 20:53:49 +0100 Subject: [PATCH 06/10] Make error handler more generic --- src/background/nativeMessaging.background.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/background/nativeMessaging.background.ts b/src/background/nativeMessaging.background.ts index a8db0cbf04..902ddee06a 100644 --- a/src/background/nativeMessaging.background.ts +++ b/src/background/nativeMessaging.background.ts @@ -115,9 +115,7 @@ export class NativeMessagingBackground { error = chrome.runtime.lastError.message; } - if (error === 'Specified native messaging host not found.' || - error === 'Access to the specified native messaging host is forbidden.' || - error === 'An unexpected error occurred') { + if (error != null) { this.messagingService.send('showDialog', { text: this.i18nService.t('desktopIntegrationDisabledDesc'), title: this.i18nService.t('desktopIntegrationDisabledTitle'), From 98cc69c6faccc1d943406c8ca3ae758c240ddc1f Mon Sep 17 00:00:00 2001 From: Hinton Date: Tue, 5 Jan 2021 15:12:48 +0100 Subject: [PATCH 07/10] Solve native messaging silently disconnecting when restarting the desktop app --- src/background/nativeMessaging.background.ts | 25 ++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/background/nativeMessaging.background.ts b/src/background/nativeMessaging.background.ts index 902ddee06a..ddd9317da8 100644 --- a/src/background/nativeMessaging.background.ts +++ b/src/background/nativeMessaging.background.ts @@ -143,7 +143,7 @@ export class NativeMessagingBackground { message.timestamp = Date.now(); const encrypted = await this.cryptoService.encrypt(JSON.stringify(message), this.sharedSecret); - this.port.postMessage({appId: this.appId, message: encrypted}); + this.postMessage({appId: this.appId, message: encrypted}); } getResponse(): Promise { @@ -152,6 +152,27 @@ export class NativeMessagingBackground { }); } + private postMessage(message: any) { + // Wrap in try-catch to when the port disconnected without triggering `onDisconnect`. + try { + this.port.postMessage(message); + } catch (e) { + // tslint:disable-next-line + console.error("NativeMessaging port disconnected, disconnecting."); + + this.sharedSecret = null; + this.privateKey = null; + this.connected = false; + + this.messagingService.send('showDialog', { + text: this.i18nService.t('nativeMessagingInvalidEncryptionDesc'), + title: this.i18nService.t('nativeMessagingInvalidEncryptionTitle'), + confirmText: this.i18nService.t('ok'), + type: 'error', + }); + } + } + private async onMessage(rawMessage: any) { const message = JSON.parse(await this.cryptoService.decryptToUtf8(rawMessage, this.sharedSecret)); @@ -229,7 +250,7 @@ export class NativeMessagingBackground { message.timestamp = Date.now(); - this.port.postMessage({appId: this.appId, message: message}); + this.postMessage({appId: this.appId, message: message}); } private async showFingerprintDialog() { From 8af54375f3e36ae78d3308b4f71aab30f3b73549 Mon Sep 17 00:00:00 2001 From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Date: Tue, 5 Jan 2021 17:34:00 -0600 Subject: [PATCH 08/10] [Policy] Personal Ownership banner (#1523) * Initial commit of ownership banner * updated capitlization --- src/_locales/en/messages.json | 3 +++ src/popup/vault/add-edit.component.html | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index c21743085f..cdcbd64736 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1434,5 +1434,8 @@ }, "personalOwnershipSubmitError": { "message": "Due to an Enterprise Policy, you are restricted from saving items to your personal vault. Change the Ownership option to an organization and choose from available Collections." + }, + "personalOwnershipPolicyInEffect": { + "message": "An organization policy is affecting your ownership options." } } diff --git a/src/popup/vault/add-edit.component.html b/src/popup/vault/add-edit.component.html index c2961321b2..a94e8217da 100644 --- a/src/popup/vault/add-edit.component.html +++ b/src/popup/vault/add-edit.component.html @@ -14,6 +14,9 @@ + + {{'personalOwnershipPolicyInEffect' | i18n}} +
{{'itemInformation' | i18n}} From b1e376ce669b149ebad3afe9f50de48ae27116cf Mon Sep 17 00:00:00 2001 From: Hinton Date: Fri, 8 Jan 2021 15:48:48 +0100 Subject: [PATCH 09/10] Fix action buttons not working when TOTP is not available --- src/popup/components/action-buttons.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/popup/components/action-buttons.component.ts b/src/popup/components/action-buttons.component.ts index ab22d38678..909d20b8e2 100644 --- a/src/popup/components/action-buttons.component.ts +++ b/src/popup/components/action-buttons.component.ts @@ -57,7 +57,7 @@ export class ActionButtonsComponent { } async copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) { - if (value == null || !this.displayTotpCopyButton(cipher)) { + if (value == null || aType === 'TOTP' && !this.displayTotpCopyButton(cipher)) { return; } else if (value === cipher.login.totp) { value = await this.totpService.getCode(value); From ad1c1cb5687c47e5a348e1f48fca697e94b3135b Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Fri, 8 Jan 2021 12:13:15 -0600 Subject: [PATCH 10/10] Update jslib (#1526) --- jslib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jslib b/jslib index afa01f67f4..cea09a22e5 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit afa01f67f4f5f45506bb14ccb194bb22e11d803e +Subproject commit cea09a22e533ef3598bb497ba0503c2fcd5b2dc1