From 80314e766f449b61caa3d7f1f2993528856c642e Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 20 Aug 2019 13:06:38 -0400 Subject: [PATCH] process safari tab on app messages --- src/2fa/2fa.ts | 2 +- src/browser/safariApp.ts | 5 +- src/content/autofiller.ts | 2 +- src/content/notificationBar.ts | 2 +- src/downloader/downloader.ts | 2 +- src/notification/bar.js | 2 +- .../safari/SafariExtensionHandler.swift | 52 +++++++++++++++++-- .../SafariExtensionViewController.swift | 16 +----- 8 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/2fa/2fa.ts b/src/2fa/2fa.ts index 5dd35153d6..6ff7062c93 100644 --- a/src/2fa/2fa.ts +++ b/src/2fa/2fa.ts @@ -9,7 +9,7 @@ document.addEventListener('DOMContentLoaded', () => { } safari.self.addEventListener('message', (msgEvent: any) => { - init2fa(msgEvent.message); + init2fa(JSON.parse(msgEvent.message.msg)); }, false); function init2fa(msg: any) { diff --git a/src/browser/safariApp.ts b/src/browser/safariApp.ts index 6d3b3cdc21..ca4cb44496 100644 --- a/src/browser/safariApp.ts +++ b/src/browser/safariApp.ts @@ -59,7 +59,10 @@ export class SafariApp { if ((message.id == null || message.id === '') && message.command === 'app_message') { try { const msg = JSON.parse(message.data); - SafariApp.sendMessageToListeners(msg, 'app_message', null); + SafariApp.sendMessageToListeners(msg, { + id: 'app_message', + tab: message.senderTab, + }, null); } catch { } } else if (message.id != null && (window as any).bitwardenSafariAppRequests.has(message.id)) { const p = (window as any).bitwardenSafariAppRequests.get(message.id); diff --git a/src/content/autofiller.ts b/src/content/autofiller.ts index 85a72f56ad..253c82603c 100644 --- a/src/content/autofiller.ts +++ b/src/content/autofiller.ts @@ -17,7 +17,7 @@ document.addEventListener('DOMContentLoaded', (event) => { bitwardenFrameId: (window as any).__bitwardenFrameId, }); safari.self.addEventListener('message', (msgEvent: any) => { - const msg = msgEvent.message; + const msg = JSON.parse(msgEvent.message.msg); if (msg.bitwardenFrameId != null && (window as any).__bitwardenFrameId !== msg.bitwardenFrameId) { return; } diff --git a/src/content/notificationBar.ts b/src/content/notificationBar.ts index bc346d991a..f28f2675c6 100644 --- a/src/content/notificationBar.ts +++ b/src/content/notificationBar.ts @@ -38,7 +38,7 @@ document.addEventListener('DOMContentLoaded', (event) => { bitwardenFrameId: (window as any).__bitwardenFrameId, }); safari.self.addEventListener('message', (msgEvent: any) => { - const msg = msgEvent.message; + const msg = JSON.parse(msgEvent.message.msg); if (msg.bitwardenFrameId != null && (window as any).__bitwardenFrameId !== msg.bitwardenFrameId) { return; } diff --git a/src/downloader/downloader.ts b/src/downloader/downloader.ts index ac49192900..a840309f12 100644 --- a/src/downloader/downloader.ts +++ b/src/downloader/downloader.ts @@ -7,7 +7,7 @@ document.addEventListener('DOMContentLoaded', () => { } safari.self.addEventListener('message', (msgEvent: any) => { - doDownload(msgEvent.message); + doDownload(JSON.parse(msgEvent.message.msg)); }, false); function doDownload(msg: any) { diff --git a/src/notification/bar.js b/src/notification/bar.js index 24ca081f98..fe9379c970 100644 --- a/src/notification/bar.js +++ b/src/notification/bar.js @@ -9,7 +9,7 @@ document.addEventListener('DOMContentLoaded', () => { responseCommand: responseCommand }); safari.self.addEventListener('message', (msgEvent) => { - const msg = msgEvent.message; + const msg = JSON.parse(msgEvent.message.msg); if (msg.command === responseCommand && msg.data) { i18n = msg.data.i18n; load(); diff --git a/src/safari/app/desktop/safari/SafariExtensionHandler.swift b/src/safari/app/desktop/safari/SafariExtensionHandler.swift index 142166c47c..d578da4a25 100644 --- a/src/safari/app/desktop/safari/SafariExtensionHandler.swift +++ b/src/safari/app/desktop/safari/SafariExtensionHandler.swift @@ -17,10 +17,12 @@ class SafariExtensionHandler: SFSafariExtensionHandler { override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String: Any]?) { // This method will be called when a content script provided by your extension calls safari.extension.dispatchMessage("message"). if messageName == "bitwarden" { - page.getPropertiesWithCompletionHandler { _ in + page.getPropertiesWithCompletionHandler { properties in // NSLog("The extension received a message (\(messageName)) from a script injected into (\(String(describing: properties?.url))) with userInfo (\(userInfo ?? [:]))") DispatchQueue.main.async { - SafariExtensionViewController.shared.sendMessage(msg: userInfo) + makeSenderTabObject(page: page, props: properties, complete: { senderTab in + self.sendMessage(msg: userInfo, sender: senderTab) + }) } } } @@ -42,7 +44,51 @@ class SafariExtensionHandler: SFSafariExtensionHandler { override func popoverWillShow(in _: SFSafariWindow) { DispatchQueue.main.async { - SafariExtensionViewController.shared.sendMessage(msg: ["command": "reloadPopup"]) + self.sendMessage(msg: ["command": "reloadPopup"], sender: nil) } } + + func sendMessage(msg: [String: Any]?, sender: Tab? = nil) { + if SafariExtensionViewController.shared.webView == nil { + return + } + let newMsg = AppMessage() + newMsg.command = "app_message" + newMsg.senderTab = sender + do { + let jsonData = try JSONSerialization.data(withJSONObject: msg as Any, options: []) + newMsg.data = String(data: jsonData, encoding: .utf8) + } catch let error { + print("error converting to json: \(error)") + } + SafariExtensionViewController.shared.replyMessage(message: newMsg) + } +} + +func makeSenderTabObject(page: SFSafariPage, props: SFSafariPageProperties?, complete: @escaping (Tab) -> Void) { + let t = Tab() + t.title = props?.title + t.url = props?.url?.absoluteString + page.getContainingTab { tab in + tab.getContainingWindow(completionHandler: { win in + win?.getActiveTab(completionHandler: { activeTab in + t.active = activeTab != nil && tab == activeTab + SFSafariApplication.getAllWindows(completionHandler: { allWins in + t.windowId = allWins.firstIndex(of: win!) ?? -100 + let winGroup = DispatchGroup() + for allWin in allWins { + winGroup.enter() + allWin.getAllTabs { allWinTabs in + t.index = allWinTabs.firstIndex(of: tab) ?? -1 + winGroup.leave() + } + } + winGroup.notify(queue: .main) { + t.id = "\(t.windowId)_\(t.index)" + complete(t) + } + }) + }) + }) + } } diff --git a/src/safari/app/desktop/safari/SafariExtensionViewController.swift b/src/safari/app/desktop/safari/SafariExtensionViewController.swift index cfe2295798..2b41726cbb 100644 --- a/src/safari/app/desktop/safari/SafariExtensionViewController.swift +++ b/src/safari/app/desktop/safari/SafariExtensionViewController.swift @@ -169,21 +169,6 @@ class SafariExtensionViewController: SFSafariExtensionViewController, WKScriptMe let json = (jsonSerialize(obj: message) ?? "null") webView.evaluateJavaScript("window.bitwardenSafariAppMessageReceiver(\(json));", completionHandler: nil) } - - func sendMessage(msg: [String: Any]?) { - if webView == nil { - return - } - let newMsg = AppMessage() - newMsg.command = "app_message" - do { - let jsonData = try JSONSerialization.data(withJSONObject: msg as Any, options: []) - newMsg.data = String(data: jsonData, encoding: .utf8) - } catch let error { - print("error converting to json: \(error)") - } - replyMessage(message: newMsg) - } } func processWindowsForTabs(wins: [SFSafariWindow], options: TabQueryOptions?, complete: @escaping ([Tab]) -> Void) { @@ -289,6 +274,7 @@ class AppMessage: Decodable, Encodable { var data: String? var responseData: String? var responseError: Bool? + var senderTab: Tab? } class StorageData: Decodable, Encodable {