Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Fix #948: Re-add 1Password extension and show it in the share sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
kylehickinson committed Apr 9, 2019
1 parent 934e22d commit 97e13c8
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cartfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github "SnapKit/SnapKit" "4.0.0"
github "rs/SDWebImage" "4.4.2"
github "swisspol/GCDWebServer" "3.4.2"
github "kif-framework/KIF" "v3.7.4"
github "AgileBits/onepassword-app-extension" "add-framework-support"
github "mozilla-mobile/SwiftKeychainWrapper" "3.0.1"
github "DaveWoodCom/XCGLogger" "6.0.4"
github "cezheng/Fuzi" "2.1.0"
Expand Down
1 change: 1 addition & 0 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
github "AgileBits/onepassword-app-extension" "bcc4cc97fed9a6e73fa204f2e61138e353cb3ef7"
github "Alamofire/Alamofire" "4.7.3"
github "DaveWoodCom/XCGLogger" "6.0.4"
github "SnapKit/SnapKit" "4.0.0"
Expand Down
5 changes: 5 additions & 0 deletions Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
0BF8F8DA1AEFF1C900E90BC2 /* noTitle.html in Resources */ = {isa = PBXBuildFile; fileRef = 0BF8F8D91AEFF1C900E90BC2 /* noTitle.html */; };
27187808216526090006036E /* AlertPopupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27187807216526090006036E /* AlertPopupView.swift */; };
2718780A216526240006036E /* PopupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27187809216526240006036E /* PopupView.swift */; };
272FCAA0225CF8F00091E645 /* OnePasswordExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 272FCA98225CF8F00091E645 /* OnePasswordExtension.framework */; };
2760D2BF215ACCE20068E131 /* BundleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2760D2BE215ACCE20068E131 /* BundleExtensions.swift */; };
2765825D2171263A00754B2F /* UserReferralProgram.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2765825C2171263A00754B2F /* UserReferralProgram.swift */; };
276582692171266900754B2F /* ReferralData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 276582652171266900754B2F /* ReferralData.swift */; };
Expand Down Expand Up @@ -1232,6 +1233,7 @@
0BF8F8D91AEFF1C900E90BC2 /* noTitle.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = noTitle.html; sourceTree = "<group>"; };
27187807216526090006036E /* AlertPopupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertPopupView.swift; sourceTree = "<group>"; };
27187809216526240006036E /* PopupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupView.swift; sourceTree = "<group>"; };
272FCA98225CF8F00091E645 /* OnePasswordExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OnePasswordExtension.framework; path = Carthage/Build/iOS/OnePasswordExtension.framework; sourceTree = "<group>"; };
2760D2BE215ACCE20068E131 /* BundleExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleExtensions.swift; sourceTree = "<group>"; };
2765825C2171263A00754B2F /* UserReferralProgram.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserReferralProgram.swift; sourceTree = "<group>"; };
276582652171266900754B2F /* ReferralData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReferralData.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2215,6 +2217,7 @@
E4B334881BBF23F3004E2BFF /* iAd.framework in Frameworks */,
0B8E0FF41A932BD500161DC3 /* ImageIO.framework in Frameworks */,
A1AD4BD720BF4772007A6EA1 /* FastImageCache.framework in Frameworks */,
272FCAA0225CF8F00091E645 /* OnePasswordExtension.framework in Frameworks */,
7B8A47F61D01D3B400C07734 /* PassKit.framework in Frameworks */,
7B604F9B1C4950F2006EEEC3 /* SDWebImage.framework in Frameworks */,
7B604FA21C495268006EEEC3 /* SnapKit.framework in Frameworks */,
Expand Down Expand Up @@ -3343,6 +3346,7 @@
7B604FC11C496005006EEEC3 /* Frameworks */ = {
isa = PBXGroup;
children = (
272FCA98225CF8F00091E645 /* OnePasswordExtension.framework */,
A1F66A7F20DD87CA00303328 /* Static.framework */,
A1AD4BD520BF476E007A6EA1 /* FastImageCache.framework */,
A1AD4BD020BF3F4D007A6EA1 /* Eureka.framework */,
Expand Down Expand Up @@ -5124,6 +5128,7 @@
"$(SRCROOT)/Carthage/Build/iOS/Eureka.framework",
"$(SRCROOT)/Carthage/Build/iOS/FastImageCache.framework",
"$(SRCROOT)/Carthage/Build/iOS/Static.framework",
"$(SRCROOT)/Carthage/Build/iOS/OnePasswordExtension.framework",
);
name = "Copy Carthage Dependencies";
outputPaths = (
Expand Down
66 changes: 64 additions & 2 deletions Client/Frontend/Share/ShareExtensionHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import Foundation
import Shared
import MobileCoreServices
import OnePasswordExtension

private let log = Logger.browserLogger

Expand Down Expand Up @@ -47,6 +47,11 @@ class ShareExtensionHelper: NSObject {
activityViewController.excludedActivityTypes = [
UIActivityType.addToReadingList,
]

// This needs to be ready by the time the share menu has been displayed and
// activityViewController(activityViewController:, activityType:) is called,
// which is after the user taps the button. So a million cycles away.
findLoginExtensionItem()

activityViewController.completionWithItemsHandler = { activityType, completed, returnedItems, activityError in
if !completed {
Expand All @@ -58,6 +63,12 @@ class ShareExtensionHelper: NSObject {
if UIPasteboard.general.hasURLs, let url = UIPasteboard.general.urls?.first {
UIPasteboard.general.urls = [url]
}

if self.isPasswordManagerActivityType(activityType.map { $0.rawValue }) {
if let logins = returnedItems {
self.fillPasswords(logins as [AnyObject])
}
}

completionHandler(completed, activityType.map { $0.rawValue })
}
Expand All @@ -71,12 +82,63 @@ extension ShareExtensionHelper: UIActivityItemSource {
}

func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType?) -> Any? {
if let type = activityType, isPasswordManagerActivityType(type.rawValue) {
return onePasswordExtensionItem
}
// Return the URL for the selected tab. If we are in reader view then decode
// it so that we copy the original and not the internal localhost one.
return selectedURL.isReaderModeURL ? selectedURL.decodeReaderModeURL : selectedURL
}

func activityViewController(_ activityViewController: UIActivityViewController, dataTypeIdentifierForActivityType activityType: UIActivityType?) -> String {
return kUTTypeURL as String
if let type = activityType, isPasswordManagerActivityType(type.rawValue) {
return browserFillIdentifier
}
return activityType == nil ? browserFillIdentifier : kUTTypeURL as String
}
}

private extension ShareExtensionHelper {

func isPasswordManagerActivityType(_ activityType: String?) -> Bool {
// A 'password' substring covers the most cases, such as pwsafe and 1Password.
// com.agilebits.onepassword-ios.extension
// com.app77.ios.pwsafe2.find-login-action-password-actionExtension
// If your extension's bundle identifier does not contain "password", simply submit a pull request by adding your bundle identifier.
return (activityType?.range(of: "password") != nil)
|| (activityType == "com.lastpass.ilastpass.LastPassExt")
|| (activityType == "in.sinew.Walletx.WalletxExt")
|| (activityType == "com.8bit.bitwarden.find-login-action-extension")
|| (activityType == "me.mssun.passforios.find-login-action-extension")

}

func findLoginExtensionItem() {
guard let selectedWebView = selectedTab?.webView else {
return
}

// Add 1Password to share sheet
OnePasswordExtension.shared().createExtensionItem(forWebView: selectedWebView, completion: {(extensionItem, error) -> Void in
if extensionItem == nil {
log.error("Failed to create the password manager extension item: \(error.debugDescription).")
return
}

// Set the 1Password extension item property
self.onePasswordExtensionItem = extensionItem
})
}

func fillPasswords(_ returnedItems: [AnyObject]) {
guard let selectedWebView = selectedTab?.webView else {
return
}

OnePasswordExtension.shared().fillReturnedItems(returnedItems, intoWebView: selectedWebView, completion: { (success, returnedItemsError) -> Void in
if !success {
log.error("Failed to fill item into webview: \(returnedItemsError ??? "nil").")
}
})
}
}

0 comments on commit 97e13c8

Please sign in to comment.