Implemented storing a default password (but not making use of it yet)
This commit is contained in:
parent
0f83b2aced
commit
b40eb25b70
|
@ -1,9 +1,12 @@
|
|||
import SwiftUI
|
||||
import LocalAuthentication
|
||||
|
||||
|
||||
class AuthenticationService {
|
||||
|
||||
static private let AuthenticationTypeUserDefaultsKey = "AuthenticationType"
|
||||
|
||||
static private let DefaultPasswordKeychainAccountName = "DefaultPassword"
|
||||
|
||||
static private let UserLoginPasswordKeychainAccountName = "UserLoginPassword"
|
||||
|
||||
|
@ -55,14 +58,19 @@ class AuthenticationService {
|
|||
setAuthenticationType(.password)
|
||||
|
||||
setLoginPassword(newPassword)
|
||||
setDefaultPassword(false)
|
||||
}
|
||||
|
||||
func setAuthenticationMethodToBiometric() {
|
||||
setAuthenticationType(.biometric)
|
||||
|
||||
setDefaultPassword(true)
|
||||
}
|
||||
|
||||
func removeAppProtection() {
|
||||
setAuthenticationType(.none)
|
||||
|
||||
setDefaultPassword(false)
|
||||
}
|
||||
|
||||
private func setAuthenticationType(_ type: AuthenticationType) {
|
||||
|
@ -73,12 +81,62 @@ class AuthenticationService {
|
|||
UserDefaults.standard.set(type.rawValue, forKey: Self.AuthenticationTypeUserDefaultsKey)
|
||||
}
|
||||
|
||||
func setAuthenticationTypeToPassword(_ newPassword: String) {
|
||||
setAuthenticationType(.password)
|
||||
|
||||
@discardableResult
|
||||
private func setDefaultPassword(_ useBiometricAuthentication: Bool) -> Bool {
|
||||
do {
|
||||
let passwordItem = createDefaultPasswordKeychainItem(useBiometricAuthentication)
|
||||
|
||||
let currentPassword = try? passwordItem.readPassword()
|
||||
|
||||
try? passwordItem.deleteItem()
|
||||
|
||||
if let currentPassword = currentPassword {
|
||||
try passwordItem.savePassword(currentPassword)
|
||||
}
|
||||
else {
|
||||
createNewDefaultPassword(useBiometricAuthentication)
|
||||
}
|
||||
|
||||
return true
|
||||
} catch {
|
||||
NSLog("Could not save default password: \(error)")
|
||||
}
|
||||
|
||||
setLoginPassword(newPassword)
|
||||
return false
|
||||
}
|
||||
|
||||
private func createNewDefaultPassword(_ useBiometricAuthentication: Bool) {
|
||||
do {
|
||||
let newDefaultPassword = generateRandomPassword(30)
|
||||
|
||||
let passwordItem = createDefaultPasswordKeychainItem(useBiometricAuthentication)
|
||||
|
||||
try passwordItem.savePassword(newDefaultPassword)
|
||||
} catch {
|
||||
NSLog("Could not create new default password: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func createDefaultPasswordKeychainItem(_ useBiometricAuthentication: Bool) -> KeychainPasswordItem {
|
||||
var accessControl: SecAccessControl? = nil
|
||||
var context: LAContext? = nil
|
||||
|
||||
if useBiometricAuthentication {
|
||||
accessControl = SecAccessControlCreateWithFlags(nil, // Use the default allocator.
|
||||
kSecAttrAccessibleWhenUnlocked,
|
||||
.userPresence,
|
||||
nil) // Ignore any error.
|
||||
|
||||
// TODO: this does not work yet, setting LAContext results in a "unexpectedPasswordData" error
|
||||
// context = LAContext()
|
||||
// context?.touchIDAuthenticationAllowableReuseDuration = 45
|
||||
}
|
||||
|
||||
return KeychainPasswordItem(service: Self.DefaultPasswordKeychainAccountName, account: nil, accessGroup: nil, secAccessControl: accessControl, authenticationContext: context)
|
||||
}
|
||||
|
||||
|
||||
@discardableResult
|
||||
private func setLoginPassword(_ newPassword: String) -> Bool {
|
||||
do {
|
||||
|
@ -139,4 +197,11 @@ class AuthenticationService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private func generateRandomPassword(_ passwordLength: Int) -> String {
|
||||
let dictionary = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789§±!@#$%^&*-_=+;:|/?.>,<"
|
||||
|
||||
return String((0 ..< passwordLength).map{ _ in dictionary.randomElement()! })
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue