70 lines
2.5 KiB
Swift
70 lines
2.5 KiB
Swift
//
|
|
// CredentialProvider.swift
|
|
// passAutoFillExtension
|
|
//
|
|
// Created by Sun, Mingshen on 1/2/21.
|
|
// Copyright © 2021 Bob Sun. All rights reserved.
|
|
//
|
|
|
|
import AuthenticationServices
|
|
import passKit
|
|
|
|
class CredentialProvider {
|
|
var identifier: ASCredentialServiceIdentifier?
|
|
weak var extensionContext: ASCredentialProviderExtensionContext?
|
|
weak var viewController: UIViewController?
|
|
|
|
init(viewController: UIViewController, extensionContext: ASCredentialProviderExtensionContext) {
|
|
self.viewController = viewController
|
|
self.extensionContext = extensionContext
|
|
}
|
|
|
|
func credentials(for identity: ASPasswordCredentialIdentity) {
|
|
guard let recordIdentifier = identity.recordIdentifier else {
|
|
return
|
|
}
|
|
guard let pwCredentials = provideCredentials(in: viewController, with: recordIdentifier) else {
|
|
return
|
|
}
|
|
|
|
extensionContext?.completeRequest(withSelectedCredential: pwCredentials)
|
|
}
|
|
|
|
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])
|
|
}
|
|
}
|
|
extensionContext?.completeRequest(withSelectedCredential: pwCredentials)
|
|
}
|
|
}
|
|
|
|
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) -> ASPasswordCredential? {
|
|
print(path)
|
|
guard let viewController = viewController else {
|
|
return nil
|
|
}
|
|
var credential: ASPasswordCredential?
|
|
decryptPassword(in: viewController, with: path) { password in
|
|
let username = password.getUsernameForCompletion()
|
|
let password = password.password
|
|
credential = ASPasswordCredential(user: username, password: password)
|
|
}
|
|
return credential
|
|
}
|