From a0a032957e344e95ee2ecf1ebe1c2d8e8aec6ea1 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 29 Dec 2020 09:18:14 -0600 Subject: [PATCH] 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