Show notification with OTP after providing password through extension (#509)
* Allow to do something with a password after providing it in the extension * Make fields non-nil * Show OTP in notification after providing a password through extension
This commit is contained in:
parent
5057528ad9
commit
763cddf540
9 changed files with 67 additions and 69 deletions
|
|
@ -19,7 +19,7 @@ class CredentialProviderViewController: ASCredentialProviderViewController {
|
|||
}()
|
||||
|
||||
private lazy var credentialProvider: CredentialProvider = { [unowned self] in
|
||||
CredentialProvider(viewController: self, extensionContext: extensionContext)
|
||||
CredentialProvider(viewController: self, extensionContext: extensionContext, afterDecryption: Utils.showNotificationWithOTP)
|
||||
}()
|
||||
|
||||
private lazy var passwordsTableEntries = PasswordStore.shared.fetchPasswordEntityCoreData(withDir: false)
|
||||
|
|
|
|||
|
|
@ -10,13 +10,16 @@ import AuthenticationServices
|
|||
import passKit
|
||||
|
||||
class CredentialProvider {
|
||||
var identifier: ASCredentialServiceIdentifier?
|
||||
weak var extensionContext: ASCredentialProviderExtensionContext?
|
||||
weak var viewController: UIViewController?
|
||||
private let viewController: UIViewController
|
||||
private let extensionContext: ASCredentialProviderExtensionContext
|
||||
private let afterDecryption: (Password) -> Void
|
||||
|
||||
init(viewController: UIViewController, extensionContext: ASCredentialProviderExtensionContext) {
|
||||
var identifier: ASCredentialServiceIdentifier?
|
||||
|
||||
init(viewController: UIViewController, extensionContext: ASCredentialProviderExtensionContext, afterDecryption: @escaping (Password) -> Void) {
|
||||
self.viewController = viewController
|
||||
self.extensionContext = extensionContext
|
||||
self.afterDecryption = afterDecryption
|
||||
}
|
||||
|
||||
func credentials(for identity: ASPasswordCredentialIdentity) {
|
||||
|
|
@ -24,50 +27,35 @@ class CredentialProvider {
|
|||
return
|
||||
}
|
||||
|
||||
provideCredentials(in: viewController, with: recordIdentifier) { credential in
|
||||
guard let credential = credential else {
|
||||
return
|
||||
}
|
||||
self.extensionContext?.completeRequest(withSelectedCredential: credential)
|
||||
decryptPassword(in: viewController, with: recordIdentifier) { password in
|
||||
self.extensionContext.completeRequest(withSelectedCredential: .from(password))
|
||||
self.afterDecryption(password)
|
||||
}
|
||||
}
|
||||
|
||||
func persistAndProvideCredentials(with passwordPath: String) {
|
||||
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 {
|
||||
self.extensionContext?.completeRequest(withSelectedCredential: credential)
|
||||
return
|
||||
}
|
||||
|
||||
let store = ASCredentialIdentityStore.shared
|
||||
store.getState { state in
|
||||
if state.isEnabled {
|
||||
decryptPassword(in: viewController, with: passwordPath) { password in
|
||||
if let identifier = self.identifier {
|
||||
ASCredentialIdentityStore.shared.getState { state in
|
||||
guard state.isEnabled else {
|
||||
return
|
||||
}
|
||||
let credentialIdentity = ASPasswordCredentialIdentity(
|
||||
serviceIdentifier: identifier,
|
||||
user: password.getUsernameForCompletion(),
|
||||
recordIdentifier: passwordPath
|
||||
)
|
||||
ASCredentialIdentityStore.shared.saveCredentialIdentities([credentialIdentity])
|
||||
}
|
||||
}
|
||||
self.extensionContext?.completeRequest(withSelectedCredential: credential)
|
||||
self.extensionContext.completeRequest(withSelectedCredential: .from(password))
|
||||
self.afterDecryption(password)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func provideCredentialIdentity(for identifier: ASCredentialServiceIdentifier?, user: String, recordIdentifier: String?) -> ASPasswordCredentialIdentity? {
|
||||
guard let serviceIdentifier = identifier else {
|
||||
return nil
|
||||
}
|
||||
return ASPasswordCredentialIdentity(serviceIdentifier: serviceIdentifier, user: user, recordIdentifier: recordIdentifier)
|
||||
}
|
||||
|
||||
private func provideCredentials(in viewController: UIViewController?, with path: String, completion: @escaping ((ASPasswordCredential?) -> Void)) {
|
||||
guard let viewController = viewController else {
|
||||
return
|
||||
}
|
||||
decryptPassword(in: viewController, with: path) { password in
|
||||
let username = password.getUsernameForCompletion()
|
||||
let password = password.password
|
||||
let credential = ASPasswordCredential(user: username, password: password)
|
||||
completion(credential)
|
||||
extension ASPasswordCredential {
|
||||
static func from(_ password: Password) -> ASPasswordCredential {
|
||||
ASPasswordCredential(user: password.getUsernameForCompletion(), password: password.password)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue