2021-01-03 15:08:15 -08:00
|
|
|
//
|
|
|
|
|
// CredentialProvider.swift
|
|
|
|
|
// passAutoFillExtension
|
|
|
|
|
//
|
|
|
|
|
// Created by Sun, Mingshen on 1/2/21.
|
|
|
|
|
// Copyright © 2021 Bob Sun. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import AuthenticationServices
|
|
|
|
|
import passKit
|
|
|
|
|
|
|
|
|
|
class CredentialProvider {
|
2021-09-20 09:50:05 +02:00
|
|
|
private let viewController: UIViewController
|
|
|
|
|
private let extensionContext: ASCredentialProviderExtensionContext
|
|
|
|
|
private let afterDecryption: (Password) -> Void
|
|
|
|
|
|
2021-01-03 15:08:15 -08:00
|
|
|
var identifier: ASCredentialServiceIdentifier?
|
|
|
|
|
|
2021-09-20 09:50:05 +02:00
|
|
|
init(viewController: UIViewController, extensionContext: ASCredentialProviderExtensionContext, afterDecryption: @escaping (Password) -> Void) {
|
2021-01-03 15:08:15 -08:00
|
|
|
self.viewController = viewController
|
|
|
|
|
self.extensionContext = extensionContext
|
2021-09-20 09:50:05 +02:00
|
|
|
self.afterDecryption = afterDecryption
|
2021-01-03 15:08:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func credentials(for identity: ASPasswordCredentialIdentity) {
|
|
|
|
|
guard let recordIdentifier = identity.recordIdentifier else {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-20 09:50:05 +02:00
|
|
|
decryptPassword(in: viewController, with: recordIdentifier) { password in
|
|
|
|
|
self.extensionContext.completeRequest(withSelectedCredential: .from(password))
|
|
|
|
|
self.afterDecryption(password)
|
2021-01-03 17:38:02 -08:00
|
|
|
}
|
2021-01-03 15:08:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func persistAndProvideCredentials(with passwordPath: String) {
|
2021-09-20 09:50:05 +02:00
|
|
|
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
|
|
|
|
|
)
|
2021-01-03 17:38:02 -08:00
|
|
|
ASCredentialIdentityStore.shared.saveCredentialIdentities([credentialIdentity])
|
|
|
|
|
}
|
2021-01-03 15:08:15 -08:00
|
|
|
}
|
2021-09-20 09:50:05 +02:00
|
|
|
self.extensionContext.completeRequest(withSelectedCredential: .from(password))
|
|
|
|
|
self.afterDecryption(password)
|
2021-01-03 15:08:15 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-20 09:50:05 +02:00
|
|
|
extension ASPasswordCredential {
|
|
|
|
|
static func from(_ password: Password) -> ASPasswordCredential {
|
|
|
|
|
ASPasswordCredential(user: password.getUsernameForCompletion(), password: password.password)
|
2021-01-03 15:08:15 -08:00
|
|
|
}
|
|
|
|
|
}
|