Force Safari activation on agent to extension response

This commit is contained in:
Ivan Grachyov 2021-11-29 20:40:07 +03:00
parent 4c9df850b4
commit 5331af667f
6 changed files with 52 additions and 34 deletions

View File

@ -20,6 +20,7 @@
2C09CBAD273979C1009AD39B /* content.js in Resources */ = {isa = PBXBuildFile; fileRef = 2C09CBAC273979C1009AD39B /* content.js */; };
2C09CBB9273979C1009AD39B /* Safari.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2C09CB9F273979C1009AD39B /* Safari.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
2C0EE4022753874D00AC2AFA /* PeerMeta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0EE4012753874D00AC2AFA /* PeerMeta.swift */; };
2C134BA627553EC500DAFBDB /* Browser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C134BA527553EC500DAFBDB /* Browser.swift */; };
2C1995402674C4B900A8E370 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C19953F2674C4B900A8E370 /* AppDelegate.swift */; };
2C1995422674C4B900A8E370 /* ImportViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C1995412674C4B900A8E370 /* ImportViewController.swift */; };
2C1995442674C4BA00A8E370 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2C1995432674C4BA00A8E370 /* Assets.xcassets */; };
@ -115,6 +116,7 @@
2C09CBB4273979C1009AD39B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2C09CBB5273979C1009AD39B /* Safari.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Safari.entitlements; sourceTree = "<group>"; };
2C0EE4012753874D00AC2AFA /* PeerMeta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerMeta.swift; sourceTree = "<group>"; };
2C134BA527553EC500DAFBDB /* Browser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Browser.swift; sourceTree = "<group>"; };
2C19953C2674C4B900A8E370 /* Encrypted Ink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Encrypted Ink.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2C19953F2674C4B900A8E370 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
2C1995412674C4B900A8E370 /* ImportViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportViewController.swift; sourceTree = "<group>"; };
@ -222,6 +224,7 @@
children = (
0DC850E626B73A5900809E82 /* AuthenticationReason.swift */,
0D059AD126C2796200EE3023 /* ApprovalSubject.swift */,
2C134BA527553EC500DAFBDB /* Browser.swift */,
2C0EE4012753874D00AC2AFA /* PeerMeta.swift */,
2C773F5B2742D483007B04E7 /* SafariRequest.swift */,
);
@ -729,6 +732,7 @@
2C6B964C26B9D92500D2C819 /* NSColor.swift in Sources */,
2C603D0226B6E13F00956955 /* String.swift in Sources */,
2C773F5C2742D483007B04E7 /* SafariRequest.swift in Sources */,
2C134BA627553EC500DAFBDB /* Browser.swift in Sources */,
2CC89471269A334A00879245 /* UserDefaults.swift in Sources */,
2C78F8282683BDCC00C10670 /* Alert.swift in Sources */,
2C8A09EE2675965F00993638 /* WaitingViewController.swift in Sources */,

View File

@ -88,32 +88,32 @@ class Agent: NSObject {
}
}
func showApprove(transaction: Transaction, chain: EthereumChain, peerMeta: PeerMeta?, completion: @escaping (Transaction?) -> Void) {
func showApprove(transaction: Transaction, chain: EthereumChain, peerMeta: PeerMeta?, browser: Browser?, completion: @escaping (Transaction?) -> Void) {
let windowController = Window.showNew()
let approveViewController = ApproveTransactionViewController.with(transaction: transaction, chain: chain, peerMeta: peerMeta) { [weak self] transaction in
if transaction != nil {
self?.askAuthentication(on: windowController.window, onStart: false, reason: .sendTransaction) { success in
completion(success ? transaction : nil)
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: browser)
}
} else {
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: browser)
completion(nil)
}
}
windowController.contentViewController = approveViewController
}
func showApprove(subject: ApprovalSubject, meta: String, peerMeta: PeerMeta?, completion: @escaping (Bool) -> Void) {
func showApprove(subject: ApprovalSubject, meta: String, peerMeta: PeerMeta?, browser: Browser?, completion: @escaping (Bool) -> Void) {
let windowController = Window.showNew()
let approveViewController = ApproveViewController.with(subject: subject, meta: meta, peerMeta: peerMeta) { [weak self] result in
if result {
self?.askAuthentication(on: windowController.window, onStart: false, reason: subject.asAuthenticationReason) { success in
completion(success)
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: browser)
}
} else {
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: browser)
completion(result)
}
}
@ -301,7 +301,7 @@ class Agent: NSObject {
walletConnect.connect(session: session, chainId: chainId, walletId: wallet.id) { [weak window] _ in
if window?.isVisible == true {
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: nil)
}
}
}
@ -318,12 +318,12 @@ class Agent: NSObject {
} else {
// TODO: respond with error
}
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: .safari)
case .signPersonalMessage:
guard let data = safariRequest.message else { return }// TODO: respond with error
let text = String(data: data, encoding: .utf8) ?? data.hexString
// TODO: display meta and peerMeta
showApprove(subject: .signPersonalMessage, meta: text, peerMeta: peerMeta) { [weak self] approved in
showApprove(subject: .signPersonalMessage, meta: text, peerMeta: peerMeta, browser: .safari) { [weak self] approved in
if approved {
self?.signPersonalMessage(address: safariRequest.address, data: data, request: safariRequest)
// TODO: sign and respond
@ -345,7 +345,7 @@ class Agent: NSObject {
} else {
ExtensionBridge.respond(id: safariRequest.id, response: ResponseToExtension(name: safariRequest.name, error: "Canceled"))
}
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: .safari)
}
// TODO: pass cancel as well
@ -356,7 +356,7 @@ class Agent: NSObject {
}
// TODO: display meta and peerMeta
showApprove(subject: .signMessage, meta: data.hexString, peerMeta: peerMeta) { [weak self] approved in
showApprove(subject: .signMessage, meta: data.hexString, peerMeta: peerMeta, browser: .safari) { [weak self] approved in
if approved {
self?.signMessage(address: safariRequest.address, data: data, request: safariRequest)
// TODO: sign and respond
@ -368,7 +368,7 @@ class Agent: NSObject {
guard let raw = safariRequest.raw else { return } // TODO: respond with error
// TODO: display meta and peerMeta
showApprove(subject: .signTypedData, meta: raw, peerMeta: peerMeta) { [weak self] approved in
showApprove(subject: .signTypedData, meta: raw, peerMeta: peerMeta, browser: .safari) { [weak self] approved in
if approved {
self?.signTypedData(address: safariRequest.address, raw: raw, request: safariRequest)
// TODO: sign and respond
@ -380,7 +380,7 @@ class Agent: NSObject {
guard let transaction = safariRequest.transaction, let chain = safariRequest.chain else {
return // TODO: respond with error
}
showApprove(transaction: transaction, chain: chain, peerMeta: peerMeta) { [weak self] transaction in
showApprove(transaction: transaction, chain: chain, peerMeta: peerMeta, browser: .safari) { [weak self] transaction in
if let transaction = transaction {
self?.sendTransaction(transaction, address: safariRequest.address, chain: chain, request: safariRequest)
// TODO: show some kind of spinner
@ -397,10 +397,10 @@ class Agent: NSObject {
} else {
ExtensionBridge.respond(id: safariRequest.id, response: ResponseToExtension(name: safariRequest.name, error: "Failed to verify"))
}
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: .safari)
default:
// TODO: implement all cases
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: .safari)
}
}

View File

@ -0,0 +1,17 @@
// Copyright © 2021 Encrypted Ink. All rights reserved.
import Foundation
enum Browser: String, CaseIterable {
case safari = "com.apple.Safari"
case chrome = "com.google.Chrome"
case tor = "org.torproject.torbrowser"
case opera = "com.operasoftware.Opera"
case edge = "com.microsoft.edgemac"
case brave = "com.brave.Browser"
case firefox = "org.mozilla.firefox"
case vivaldi = "com.vivaldi.Vivaldi"
case yandex = "ru.yandex.desktop.yandex-browser"
static let allBundleIds = Set(Browser.allCases.map { $0.rawValue })
}

View File

@ -21,7 +21,7 @@ class ErrorViewController: NSViewController {
}
@IBAction func actionButtonTapped(_ sender: Any) {
Window.closeAllAndActivateBrowser()
Window.closeAllAndActivateBrowser(force: nil)
}
}

View File

@ -132,7 +132,7 @@ class WalletConnect {
let peer = PeerMeta(wcPeerMeta: getPeerOfInteractor(interactor))
let transaction = Transaction(from: wct.from, to: to, nonce: wct.nonce, gasPrice: wct.gasPrice, gas: wct.gas, value: wct.value, data: wct.data)
Agent.shared.showApprove(transaction: transaction, chain: chain, peerMeta: peer) { [weak self, weak interactor] transaction in
Agent.shared.showApprove(transaction: transaction, chain: chain, peerMeta: peer, browser: nil) { [weak self, weak interactor] transaction in
if let transaction = transaction {
self?.sendTransaction(transaction, walletId: walletId, chainId: chainId, requestId: id, interactor: interactor)
} else {
@ -159,7 +159,7 @@ class WalletConnect {
}
let peer = PeerMeta(wcPeerMeta: getPeerOfInteractor(interactor))
Agent.shared.showApprove(subject: approvalSubject, meta: message ?? "", peerMeta: peer) { [weak self, weak interactor] approved in
Agent.shared.showApprove(subject: approvalSubject, meta: message ?? "", peerMeta: peer, browser: nil) { [weak self, weak interactor] approved in
if approved {
self?.sign(id: id, payload: payload, walletId: walletId, interactor: interactor)
} else {

View File

@ -4,18 +4,6 @@ import Cocoa
struct Window {
private static let browsersBundleIds = Set([
"com.apple.Safari",
"com.google.Chrome",
"org.torproject.torbrowser",
"com.operasoftware.Opera",
"com.microsoft.edgemac",
"com.brave.Browser",
"org.mozilla.firefox",
"com.vivaldi.Vivaldi",
"ru.yandex.desktop.yandex-browser"
])
static func showNew() -> NSWindowController {
closeAll()
let windowController = new
@ -33,9 +21,9 @@ struct Window {
window?.makeKeyAndOrderFront(nil)
}
static func closeAllAndActivateBrowser() {
static func closeAllAndActivateBrowser(force browser: Browser?) {
closeAll()
activateBrowser()
activateBrowser(force: browser)
}
static func closeAll(updateStatusBarItem: Bool = true) {
@ -45,10 +33,15 @@ struct Window {
}
}
static func activateBrowser() {
static func activateBrowser(force browser: Browser?) {
if let browser = browser {
activateBrowser(browser)
return
}
let browsers = NSWorkspace.shared.runningApplications.filter { app in
if let bundleId = app.bundleIdentifier {
return browsersBundleIds.contains(bundleId)
return Browser.allBundleIds.contains(bundleId)
} else {
return false
}
@ -67,6 +60,10 @@ struct Window {
}
}
private static func activateBrowser(_ browser: Browser) {
NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == browser.rawValue })?.activate(options: .activateIgnoringOtherApps)
}
static var current: NSWindowController? {
return NSApplication.shared.windows.first?.windowController
}