Move dependency from KeychainSwift, and SamKaychain to main app, update with protocol definition #5255
parent
3d228a4dbd
commit
af6688b0e4
@ -0,0 +1,87 @@ |
||||
// |
||||
// KeychainStorage.swift |
||||
// AlphaWallet |
||||
// |
||||
// Created by Vladyslav Shepitko on 02.09.2022. |
||||
// |
||||
|
||||
import Foundation |
||||
import KeychainSwift |
||||
import SAMKeychain |
||||
import AlphaWalletFoundation |
||||
import LocalAuthentication |
||||
|
||||
final class KeychainStorage: SecuredStorage, SecuredPasswordStorage { |
||||
private let keychain: KeychainSwift |
||||
|
||||
init(keyPrefix: String = Constants.keychainKeyPrefix) throws { |
||||
let keychain = KeychainSwift(keyPrefix: Constants.keychainKeyPrefix) |
||||
keychain.synchronizable = false |
||||
|
||||
self.keychain = keychain |
||||
if !UIApplication.shared.isProtectedDataAvailable { |
||||
throw EtherKeystoreError.protectionDisabled |
||||
} |
||||
} |
||||
|
||||
var hasUserCancelledLastAccess: Bool { |
||||
return keychain.lastResultCode == errSecUserCanceled |
||||
} |
||||
|
||||
var isDataNotFoundForLastAccess: Bool { |
||||
return keychain.lastResultCode == errSecItemNotFound |
||||
} |
||||
|
||||
func set(_ value: String, forKey key: String, withAccess access: AccessOptions?) -> Bool { |
||||
return keychain.set(value, forKey: key, withAccess: access?.asKeychainOptions) |
||||
} |
||||
|
||||
func set(_ value: Data, forKey key: String, withAccess access: AccessOptions?) -> Bool { |
||||
return keychain.set(value, forKey: key, withAccess: access?.asKeychainOptions) |
||||
} |
||||
|
||||
func get(_ key: String, prompt: String?, withContext context: LAContext?) -> String? { |
||||
return keychain.get(key, prompt: prompt, withContext: context) |
||||
} |
||||
|
||||
func getData(_ key: String, prompt: String?, withContext context: LAContext?) -> Data? { |
||||
return keychain.getData(key, prompt: prompt, withContext: context) |
||||
} |
||||
|
||||
func delete(_ key: String) -> Bool { |
||||
return keychain.delete(key) |
||||
} |
||||
|
||||
func password(forService service: String, account: String) -> String? { |
||||
return SAMKeychain.password(forService: service, account: account) |
||||
} |
||||
|
||||
func setPasword(_ pasword: String, forService service: String, account: String) { |
||||
SAMKeychain.setPassword(pasword, forService: service, account: account) |
||||
} |
||||
|
||||
func deletePasword(forService service: String, account: String) { |
||||
SAMKeychain.deletePassword(forService: service, account: account) |
||||
} |
||||
} |
||||
|
||||
fileprivate extension AccessOptions { |
||||
var asKeychainOptions: KeychainSwiftAccessOptions { |
||||
switch self { |
||||
case .accessibleWhenUnlocked: |
||||
return .accessibleWhenUnlocked |
||||
case .accessibleWhenUnlockedThisDeviceOnly(let userPresenceRequired): |
||||
return .accessibleWhenUnlockedThisDeviceOnly(userPresenceRequired: userPresenceRequired) |
||||
case .accessibleAfterFirstUnlock: |
||||
return .accessibleAfterFirstUnlock |
||||
case .accessibleAfterFirstUnlockThisDeviceOnly: |
||||
return .accessibleAfterFirstUnlockThisDeviceOnly |
||||
case .accessibleAlways: |
||||
return .accessibleAlways |
||||
case .accessibleWhenPasscodeSetThisDeviceOnly: |
||||
return .accessibleWhenPasscodeSetThisDeviceOnly |
||||
case .accessibleAlwaysThisDeviceOnly: |
||||
return .accessibleAlwaysThisDeviceOnly |
||||
} |
||||
} |
||||
} |
@ -1,9 +1,27 @@ |
||||
// Copyright SIX DAY LLC. All rights reserved. |
||||
|
||||
import Foundation |
||||
import LocalAuthentication |
||||
|
||||
class LockEnterPasscodeViewModel: LockViewModel { |
||||
let initialLabelText = R.string.localizable.lockEnterPasscodeViewModelInitial() |
||||
let tryAfterOneMinute = R.string.localizable.lockEnterPasscodeViewModelTryAfterOneMinute() |
||||
let loginReason = R.string.localizable.lockEnterPasscodeViewModelTouchId() |
||||
|
||||
private var context: LAContext! |
||||
var canEvaluatePolicy: Bool { |
||||
return context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) |
||||
} |
||||
|
||||
func invalidateContext() { |
||||
context = LAContext() |
||||
} |
||||
|
||||
func evaluatePolicy(completion: @escaping (Bool) -> Void) { |
||||
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: loginReason) { success, _ in |
||||
DispatchQueue.main.async { |
||||
completion(success) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue