MESSENGER-2762 Initial Merge

This commit is contained in:
Frank Rotermund
2022-03-17 15:51:23 +01:00
parent ecae8d618f
commit c2108a2178
384 changed files with 17708 additions and 1928 deletions
@@ -1,5 +1,6 @@
/*
Copyright 2018 New Vector Ltd
Copyright (c) 2021 BWI GmbH
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -19,6 +20,11 @@ import KeychainAccess
import LocalAuthentication
import MatrixSDK
extension Notification.Name {
/// Posted when fallbacking to PIN from a biometrics protection
static let biometricsDidFallbackToPin = Notification.Name("BiometricsDidFallbackToPin")
}
/// Pin code preferences.
@objcMembers
final class PinCodePreferences: NSObject {
@@ -39,20 +45,57 @@ final class PinCodePreferences: NSObject {
static let shared = PinCodePreferences()
/// Store. Defaults to `KeychainStore`
private let store: KeyValueStore
/// Store. Defaults to `SecureFileStore`
private let secureStore: SecureFileStorage
override private init() {
store = KeychainStore(withKeychain: Keychain(service: PinConstants.pinCodeKeychainService,
accessGroup: BuildSettings.keychainAccessGroup))
secureStore = SecureFileStorage.shared
super.init()
migrateOldData()
}
private func migrateOldData() {
let oldStore = KeychainVault(Keychain(service: PinConstants.pinCodeKeychainService,
accessGroup: BuildSettings.keychainAccessGroup))
if let oldPin = try? oldStore.string(forKey: StoreKeys.pin) {
do {
// migrate
pin = oldPin
// clear old pin
try oldStore.removeObject(forKey: StoreKeys.pin)
} catch let error {
MXLog.error("[PinCodePreferences] Error when migrating old user pin: \(error)")
}
}
if let oldBiometricsEnabled = try? oldStore.bool(forKey: StoreKeys.biometricsEnabled) {
biometricsEnabled = oldBiometricsEnabled
try? oldStore.removeObject(forKey: StoreKeys.biometricsEnabled)
}
if let oldCanUseBiometricsToUnlock = try? oldStore.bool(forKey: StoreKeys.canUseBiometricsToUnlock) {
canUseBiometricsToUnlock = oldCanUseBiometricsToUnlock
try? oldStore.removeObject(forKey: StoreKeys.canUseBiometricsToUnlock)
}
if let oldNumberOfPinFailures = try? oldStore.integer(forKey: StoreKeys.numberOfPinFailures) {
numberOfPinFailures = oldNumberOfPinFailures
try? oldStore.removeObject(forKey: StoreKeys.numberOfPinFailures)
}
if let oldNumberOfBiometricsFailures = try? oldStore.integer(forKey: StoreKeys.numberOfBiometricsFailures) {
numberOfBiometricsFailures = oldNumberOfBiometricsFailures
try? oldStore.removeObject(forKey: StoreKeys.numberOfBiometricsFailures)
}
}
// MARK: - Public
/// Setting to force protection by pin code
var forcePinProtection: Bool {
return BuildSettings.forcePinProtection
return BwiBuildSettings.forcedPinProtection
}
/// Not allowed pin codes. User won't be able to select one of the pin in the list.
@@ -71,7 +114,11 @@ final class PinCodePreferences: NSObject {
}
var isBiometricsAvailable: Bool {
return LAContext().canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
let context = LAContext()
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
return context.biometryType == .touchID || context.biometryType == .faceID
}
return false
}
/// Allowed number of PIN trials before showing forgot help alert
@@ -87,99 +134,81 @@ final class PinCodePreferences: NSObject {
/// Is user has set a pin
var isPinSet: Bool {
return pin != nil
return secureStore.objectExists(withKey: StoreKeys.pin)
}
/// Saved user PIN
var pin: String? {
get {
do {
return try store.string(forKey: StoreKeys.pin)
return try secureStore.string(forKey: StoreKeys.pin)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when reading user pin from store: \(error)")
return nil
}
} set {
do {
try store.set(newValue, forKey: StoreKeys.pin)
if let newPin = newValue {
if !secureStore.locked {
try secureStore.update(passphrase: newPin)
} else {
try secureStore.unlock(passphrase: newPin)
}
}
try secureStore.set(newValue, forKey: StoreKeys.pin)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when storing user pin to the store: \(error)")
}
}
}
var biometricsEnabled: Bool? {
get {
do {
return try store.bool(forKey: StoreKeys.biometricsEnabled)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when reading biometrics enabled from store: \(error)")
return nil
}
} set {
do {
try store.set(newValue, forKey: StoreKeys.biometricsEnabled)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when storing biometrics enabled to the store: \(error)")
}
func pinsMatch(_ pinCode: String) -> Bool {
do {
try secureStore.unlock(passphrase: pinCode)
let pin = try secureStore.string(forKey: StoreKeys.pin)
return pinCode == pin
} catch let error {
MXLog.error("[PinCodePreferences] Error when checking user pin: \(error)")
return false
}
}
var canUseBiometricsToUnlock: Bool? {
var biometricsEnabled: Bool {
get {
do {
return try store.bool(forKey: StoreKeys.canUseBiometricsToUnlock)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when reading canUseBiometricsToUnlock from store: \(error)")
return nil
}
return RiotSettings.shared.biometricsEnabled
} set {
do {
try store.set(newValue, forKey: StoreKeys.canUseBiometricsToUnlock)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when storing canUseBiometricsToUnlock to the store: \(error)")
}
RiotSettings.shared.biometricsEnabled = newValue
}
}
var canUseBiometricsToUnlock: Bool {
get {
return RiotSettings.shared.canUseBiometricsToUnlock
} set {
RiotSettings.shared.canUseBiometricsToUnlock = newValue
}
}
var numberOfPinFailures: Int {
get {
do {
return try store.integer(forKey: StoreKeys.numberOfPinFailures) ?? 0
} catch let error {
MXLog.debug("[PinCodePreferences] Error when reading numberOfPinFailures from store: \(error)")
return 0
}
return RiotSettings.shared.numberOfPinFailures
} set {
do {
try store.set(newValue, forKey: StoreKeys.numberOfPinFailures)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when storing numberOfPinFailures to the store: \(error)")
}
RiotSettings.shared.numberOfPinFailures = newValue
}
}
var numberOfBiometricsFailures: Int {
get {
do {
return try store.integer(forKey: StoreKeys.numberOfBiometricsFailures) ?? 0
} catch let error {
MXLog.debug("[PinCodePreferences] Error when reading numberOfBiometricsFailures from store: \(error)")
return 0
}
return RiotSettings.shared.numberOfBiometricsFailures
} set {
do {
try store.set(newValue, forKey: StoreKeys.numberOfBiometricsFailures)
} catch let error {
MXLog.debug("[PinCodePreferences] Error when storing numberOfBiometricsFailures to the store: \(error)")
}
RiotSettings.shared.numberOfBiometricsFailures = newValue
}
}
var isBiometricsSet: Bool {
return biometricsEnabled == true && (canUseBiometricsToUnlock ?? true)
return biometricsEnabled && canUseBiometricsToUnlock && isBiometricsAvailable
}
func localizedBiometricsName() -> String? {
if isBiometricsAvailable {
let context = LAContext()
@@ -217,8 +246,8 @@ final class PinCodePreferences: NSObject {
/// Resets user PIN
func reset() {
pin = nil
biometricsEnabled = nil
canUseBiometricsToUnlock = nil
biometricsEnabled = false
canUseBiometricsToUnlock = true
resetCounters()
}