diff --git a/passAutoFillExtension/Controllers/CredentialProviderViewController.swift b/passAutoFillExtension/Controllers/CredentialProviderViewController.swift index 2b87537..da3bbc1 100644 --- a/passAutoFillExtension/Controllers/CredentialProviderViewController.swift +++ b/passAutoFillExtension/Controllers/CredentialProviderViewController.swift @@ -43,7 +43,21 @@ class CredentialProviderViewController: ASCredentialProviderViewController { } override func provideCredentialWithoutUserInteraction(for credentialIdentity: ASPasswordCredentialIdentity) { - credentialProvider.credentials(for: credentialIdentity) + credentialProvider.identifier = credentialIdentity.serviceIdentifier + if !PasscodeLock.shared.hasPasscode, Defaults.isRememberPGPPassphraseOn { + credentialProvider.credentials(for: credentialIdentity) + } else { + extensionContext.cancelRequest(withError: NSError(domain: ASExtensionErrorDomain, code: ASExtensionError.userInteractionRequired.rawValue)) + } + } + + override func prepareInterfaceToProvideCredential(for credentialIdentity: ASPasswordCredentialIdentity) { + guard let identifier = credentialIdentity.recordIdentifier else { + return + } + credentialProvider.identifier = credentialIdentity.serviceIdentifier + passwordsViewController.navigationItem.prompt = identifier + passwordsViewController.showPasswordsWithSuggstion([identifier]) } } diff --git a/passAutoFillExtension/Controllers/PasswordsViewController.swift b/passAutoFillExtension/Controllers/PasswordsViewController.swift index 9667943..d7a7c0f 100644 --- a/passAutoFillExtension/Controllers/PasswordsViewController.swift +++ b/passAutoFillExtension/Controllers/PasswordsViewController.swift @@ -79,7 +79,7 @@ extension PasswordsViewController: UITableViewDelegate { if indexPath.section == 0 { entry = dataSource.suggestedPasswordsTableEntries[indexPath.row] } else { - entry = dataSource.filteredPasswordsTableEntries[indexPath.row] + entry = dataSource.otherPasswordsTableEntries[indexPath.row] } } else { entry = dataSource.filteredPasswordsTableEntries[indexPath.row] diff --git a/passAutoFillExtension/Services/CredentialProvider.swift b/passAutoFillExtension/Services/CredentialProvider.swift index 95397bf..e9c172c 100644 --- a/passAutoFillExtension/Services/CredentialProvider.swift +++ b/passAutoFillExtension/Services/CredentialProvider.swift @@ -23,28 +23,32 @@ class CredentialProvider { guard let recordIdentifier = identity.recordIdentifier else { return } - guard let pwCredentials = provideCredentials(in: viewController, with: recordIdentifier) else { - return - } - extensionContext?.completeRequest(withSelectedCredential: pwCredentials) + provideCredentials(in: viewController, with: recordIdentifier) { credential in + guard let credential = credential else { + return + } + self.extensionContext?.completeRequest(withSelectedCredential: credential) + } } func persistAndProvideCredentials(with passwordPath: String) { - guard let pwCredentials = provideCredentials(in: viewController, with: passwordPath) else { - return - } - guard let credentialIdentity = provideCredentialIdentity(for: identifier, user: pwCredentials.user, recordIdentifier: passwordPath) else { - return - } - - let store = ASCredentialIdentityStore.shared - store.getState { state in - if state.isEnabled { - ASCredentialIdentityStore.shared.saveCredentialIdentities([credentialIdentity]) + provideCredentials(in: viewController, with: passwordPath) { credential in + guard let credential = credential else { + return } + guard let credentialIdentity = provideCredentialIdentity(for: self.identifier, user: credential.user, recordIdentifier: passwordPath) else { + return + } + + let store = ASCredentialIdentityStore.shared + store.getState { state in + if state.isEnabled { + ASCredentialIdentityStore.shared.saveCredentialIdentities([credentialIdentity]) + } + } + self.extensionContext?.completeRequest(withSelectedCredential: credential) } - extensionContext?.completeRequest(withSelectedCredential: pwCredentials) } } @@ -55,16 +59,14 @@ private func provideCredentialIdentity(for identifier: ASCredentialServiceIdenti return ASPasswordCredentialIdentity(serviceIdentifier: serviceIdentifier, user: user, recordIdentifier: recordIdentifier) } -private func provideCredentials(in viewController: UIViewController?, with path: String) -> ASPasswordCredential? { - print(path) +private func provideCredentials(in viewController: UIViewController?, with path: String, completion: @escaping ((ASPasswordCredential?) -> Void)) { guard let viewController = viewController else { - return nil + return } - var credential: ASPasswordCredential? decryptPassword(in: viewController, with: path) { password in let username = password.getUsernameForCompletion() let password = password.password - credential = ASPasswordCredential(user: username, password: password) + let credential = ASPasswordCredential(user: username, password: password) + completion(credential) } - return credential } diff --git a/passAutoFillExtension/Services/PasswordDecryptor.swift b/passAutoFillExtension/Services/PasswordDecryptor.swift index b70a505..30ccae1 100644 --- a/passAutoFillExtension/Services/PasswordDecryptor.swift +++ b/passAutoFillExtension/Services/PasswordDecryptor.swift @@ -10,21 +10,29 @@ import UIKit import passKit func decryptPassword(in controller: UIViewController, with passwordPath: String, using keyID: String? = nil, completion: @escaping ((Password) -> Void)) { - do { - let requestPGPKeyPassphrase = Utils.createRequestPGPKeyPassphraseHandler(controller: controller) - let decryptedPassword = try PasswordStore.shared.decrypt(path: passwordPath, keyID: keyID, requestPGPKeyPassphrase: requestPGPKeyPassphrase) + DispatchQueue.global(qos: .userInteractive).async { + do { + let requestPGPKeyPassphrase = Utils.createRequestPGPKeyPassphraseHandler(controller: controller) + let decryptedPassword = try PasswordStore.shared.decrypt(path: passwordPath, keyID: keyID, requestPGPKeyPassphrase: requestPGPKeyPassphrase) - completion(decryptedPassword) - } catch let AppError.pgpPrivateKeyNotFound(keyID: key) { - let alert = UIAlertController(title: "CannotShowPassword".localize(), message: AppError.pgpPrivateKeyNotFound(keyID: key).localizedDescription, preferredStyle: .alert) - alert.addAction(UIAlertAction.cancelAndPopView(controller: controller)) - let selectKey = UIAlertAction.selectKey(controller: controller) { action in - decryptPassword(in: controller, with: passwordPath, using: action.title, completion: completion) + DispatchQueue.main.async { + completion(decryptedPassword) + } + } catch let AppError.pgpPrivateKeyNotFound(keyID: key) { + DispatchQueue.main.async { + let alert = UIAlertController(title: "CannotShowPassword".localize(), message: AppError.pgpPrivateKeyNotFound(keyID: key).localizedDescription, preferredStyle: .alert) + alert.addAction(UIAlertAction.cancelAndPopView(controller: controller)) + let selectKey = UIAlertAction.selectKey(controller: controller) { action in + decryptPassword(in: controller, with: passwordPath, using: action.title, completion: completion) + } + alert.addAction(selectKey) + + controller.present(alert, animated: true) + } + } catch { + DispatchQueue.main.async { + Utils.alert(title: "CannotCopyPassword".localize(), message: error.localizedDescription, controller: controller) + } } - alert.addAction(selectKey) - - controller.present(alert, animated: true) - } catch { - Utils.alert(title: "CannotCopyPassword".localize(), message: error.localizedDescription, controller: controller) } }