Эх сурвалжийг харах

attempts passcode improvements

Signed-off-by: Marino Faggiana <8616947+marinofaggiana@users.noreply.github.com>
Marino Faggiana 1 жил өмнө
parent
commit
d36915879d

+ 4 - 0
Brand/NCBrand.swift

@@ -87,6 +87,10 @@ let userAgent: String = {
     // Max upload concurrent
     // Max upload concurrent
     public let maxConcurrentOperationUpload: Int = 10
     public let maxConcurrentOperationUpload: Int = 10
 
 
+    // Number of failed attempts after reset app
+    @objc public let resetAppPasscodeAttempts: Int = 10
+    public let passcodeSecondsFail: Int = 30
+
     // Info Paging
     // Info Paging
     enum NCInfoPagingTab: Int, CaseIterable {
     enum NCInfoPagingTab: Int, CaseIterable {
         case activity, sharing
         case activity, sharing

+ 18 - 15
iOSClient/AppDelegate.swift

@@ -723,9 +723,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
     func presentPasscode(completion: @escaping () -> Void) {
     func presentPasscode(completion: @escaping () -> Void) {
 
 
-        let laContext = LAContext()
         var error: NSError?
         var error: NSError?
-
         defer { self.requestAccount() }
         defer { self.requestAccount() }
 
 
         let presentedViewController = window?.rootViewController?.presentedViewController
         let presentedViewController = window?.rootViewController?.presentedViewController
@@ -737,13 +735,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         let passcodeViewController = TOPasscodeViewController(passcodeType: .sixDigits, allowCancel: false)
         let passcodeViewController = TOPasscodeViewController(passcodeType: .sixDigits, allowCancel: false)
         passcodeViewController.delegate = self
         passcodeViewController.delegate = self
         passcodeViewController.keypadButtonShowLettering = false
         passcodeViewController.keypadButtonShowLettering = false
-        if NCKeychain().touchFaceID,
-           laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error),
-           NCKeychain().passcodeCounterFail < 3 {
+        if NCKeychain().touchFaceID, LAContext().canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
             if error == nil {
             if error == nil {
-                if laContext.biometryType == .faceID {
+                if LAContext().biometryType == .faceID {
                     passcodeViewController.biometryType = .faceID
                     passcodeViewController.biometryType = .faceID
-                } else if laContext.biometryType == .touchID {
+                } else if LAContext().biometryType == .touchID {
                     passcodeViewController.biometryType = .touchID
                     passcodeViewController.biometryType = .touchID
                 }
                 }
                 passcodeViewController.allowBiometricValidation = true
                 passcodeViewController.allowBiometricValidation = true
@@ -753,9 +749,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
 
         // show passcode on top of privacy window
         // show passcode on top of privacy window
         privacyProtectionWindow?.rootViewController?.present(passcodeViewController, animated: true, completion: {
         privacyProtectionWindow?.rootViewController?.present(passcodeViewController, animated: true, completion: {
-            let resetAppCounterFail = NCKeychain().resetAppCounterFail
             let passcodeCounterFail = NCKeychain().passcodeCounterFail
             let passcodeCounterFail = NCKeychain().passcodeCounterFail
-            if resetAppCounterFail > 0 && (passcodeCounterFail >= resetAppCounterFail) {
+            if NCKeychain().resetAppCounterFail && (passcodeCounterFail >= NCBrandOptions.shared.resetAppPasscodeAttempts) {
                 self.passcodeResetApp(passcodeViewController)
                 self.passcodeResetApp(passcodeViewController)
             } else if passcodeCounterFail >= 3 {
             } else if passcodeCounterFail >= 3 {
                 self.passcodeAlert(passcodeViewController)
                 self.passcodeAlert(passcodeViewController)
@@ -773,12 +768,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
               NCKeychain().touchFaceID,
               NCKeychain().touchFaceID,
               NCKeychain().passcode != nil,
               NCKeychain().passcode != nil,
               NCKeychain().requestPasscodeAtStart,
               NCKeychain().requestPasscodeAtStart,
-              NCKeychain().passcodeCounterFail < 3,
               let passcodeViewController = privacyProtectionWindow?.rootViewController?.presentedViewController as? TOPasscodeViewController
               let passcodeViewController = privacyProtectionWindow?.rootViewController?.presentedViewController as? TOPasscodeViewController
         else { return }
         else { return }
 
 
         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
-            LAContext().evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: NCBrandOptions.shared.brand) { success, _ in
+            LAContext().evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: NCBrandOptions.shared.brand) { success, evaluateError in
                 if success {
                 if success {
                     DispatchQueue.main.async {
                     DispatchQueue.main.async {
                         passcodeViewController.dismiss(animated: true) {
                         passcodeViewController.dismiss(animated: true) {
@@ -788,7 +782,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
                         }
                         }
                     }
                     }
                 } else {
                 } else {
-                    NCKeychain().passcodeCounterFail += 1
+                    if let error = evaluateError {
+                        if error._code == LAError.authenticationFailed.rawValue {
+                            // var error: NSError?
+                            // LAContext().canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
+                        } else if error._code == LAError.biometryLockout.rawValue {
+                            let reason = "TouchID has been locked out due to few fail attemp. Enter iPhone passcode to enable TouchID."
+                            LAContext().evaluatePolicy(LAPolicy.deviceOwnerAuthentication, localizedReason: reason, reply: { success, _ in
+                                if success { DispatchQueue.main.async { self.enableTouchFaceID() } }
+                            })
+                        }
+                    }
                 }
                 }
             }
             }
         }
         }
@@ -809,9 +813,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
             return true
             return true
         } else {
         } else {
             NCKeychain().passcodeCounterFail += 1
             NCKeychain().passcodeCounterFail += 1
-            let resetAppCounterFail = NCKeychain().resetAppCounterFail
             let passcodeCounterFail = NCKeychain().passcodeCounterFail
             let passcodeCounterFail = NCKeychain().passcodeCounterFail
-            if resetAppCounterFail > 0 && (passcodeCounterFail >= resetAppCounterFail) {
+            if NCKeychain().resetAppCounterFail && (passcodeCounterFail >= NCBrandOptions.shared.resetAppPasscodeAttempts) {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.passcodeResetApp(passcodeViewController) }
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.passcodeResetApp(passcodeViewController) }
             } else if passcodeCounterFail >= 3 {
             } else if passcodeCounterFail >= 3 {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.passcodeAlert(passcodeViewController) }
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.passcodeAlert(passcodeViewController) }
@@ -833,7 +836,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         let alertController = UIAlertController(title: NSLocalizedString("_passcode_counter_fail_", comment: ""), message: nil, preferredStyle: .alert)
         let alertController = UIAlertController(title: NSLocalizedString("_passcode_counter_fail_", comment: ""), message: nil, preferredStyle: .alert)
         passcodeViewController.present(alertController, animated: true, completion: { })
         passcodeViewController.present(alertController, animated: true, completion: { })
 
 
-        var seconds = NCKeychain().passcodeSecondsFail * 30
+        var seconds = NCKeychain().passcodeSecondsFail * NCBrandOptions.shared.passcodeSecondsFail
         _ = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
         _ = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
             alertController.message = "\(seconds) " + NSLocalizedString("_seconds_", comment: "")
             alertController.message = "\(seconds) " + NSLocalizedString("_seconds_", comment: "")
             seconds -= 1
             seconds -= 1

+ 3 - 3
iOSClient/Settings/NCKeychain.swift

@@ -54,12 +54,12 @@ import KeychainAccess
         }
         }
     }
     }
 
 
-    @objc var resetAppCounterFail: Int {
+    @objc var resetAppCounterFail: Bool {
         get {
         get {
-            if let value = try? keychain.get("resetAppCounterFail"), let result = Int(value) {
+            if let value = try? keychain.get("resetAppCounterFail"), let result = Bool(value) {
                 return result
                 return result
             }
             }
-            return 0
+            return false
         }
         }
         set {
         set {
             keychain["resetAppCounterFail"] = String(newValue)
             keychain["resetAppCounterFail"] = String(newValue)

+ 5 - 7
iOSClient/Settings/NCSettings.m

@@ -102,10 +102,7 @@
     [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"];
     [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"];
     [section addFormRow:row];
     [section addFormRow:row];
     // Reset app wrong attemps
     // Reset app wrong attemps
-    row = [XLFormRowDescriptor formRowDescriptorWithTag:@"resetAppAttemps" rowType:XLFormRowDescriptorTypeStepCounter title:NSLocalizedString(@"_reset_wrong_passcode_", nil)];
-    [row.cellConfigAtConfigure setObject:@5 forKey:@"stepControl.stepValue"];
-    [row.cellConfigAtConfigure setObject:@0 forKey:@"stepControl.minimumValue"];
-    [row.cellConfigAtConfigure setObject:@20 forKey:@"stepControl.maximumValue"];
+    row = [XLFormRowDescriptor formRowDescriptorWithTag:@"resetAppAttemps" rowType:XLFormRowDescriptorTypeBooleanSwitch title:NSLocalizedString(@"_reset_wrong_passcode_", nil)];
     row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor;
     row.cellConfigAtConfigure[@"backgroundColor"] = UIColor.secondarySystemGroupedBackgroundColor;
     [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"];
     [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"];
     [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"];
     [row.cellConfig setObject:UIColor.labelColor forKey:@"textLabel.textColor"];
@@ -282,9 +279,8 @@
         rowBloccoPasscode.title = NSLocalizedString(@"_lock_not_active_", nil);
         rowBloccoPasscode.title = NSLocalizedString(@"_lock_not_active_", nil);
         [rowBloccoPasscode.cellConfig setObject:[[UIImage imageNamed:@"lock_open"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"];
         [rowBloccoPasscode.cellConfig setObject:[[UIImage imageNamed:@"lock_open"] imageWithColor:UIColor.systemGrayColor size:25] forKey:@"imageView.image"];
     }
     }
-    long resetAppCounterFail = [[NCKeychain alloc] init].resetAppCounterFail;
-    [rowResetAppAttemps setValue:[NSString stringWithFormat: @"%ld", resetAppCounterFail]];
 
 
+    if ([[NCKeychain alloc] init].resetAppCounterFail) [rowResetAppAttemps setValue:@1]; else [rowResetAppAttemps setValue:@0];
     if ([[NCKeychain alloc] init].touchFaceID) [rowEnableTouchDaceID setValue:@1]; else [rowEnableTouchDaceID setValue:@0];
     if ([[NCKeychain alloc] init].touchFaceID) [rowEnableTouchDaceID setValue:@1]; else [rowEnableTouchDaceID setValue:@0];
     if ([[NCKeychain alloc] init].requestPasscodeAtStart) [rowNotPasscodeAtStart setValue:@0]; else [rowNotPasscodeAtStart setValue:@1];
     if ([[NCKeychain alloc] init].requestPasscodeAtStart) [rowNotPasscodeAtStart setValue:@0]; else [rowNotPasscodeAtStart setValue:@1];
     if ([[NCKeychain alloc] init].privacyScreenEnabled) [rowPrivacyScreen setValue:@1]; else [rowPrivacyScreen setValue:@0];
     if ([[NCKeychain alloc] init].privacyScreenEnabled) [rowPrivacyScreen setValue:@1]; else [rowPrivacyScreen setValue:@0];
@@ -476,7 +472,9 @@
     NSInteger numSections = [tableView numberOfSections] - 1;
     NSInteger numSections = [tableView numberOfSections] - 1;
 
 
     if (section == 1) {
     if (section == 1) {
-        sectionName = NSLocalizedString(@"_lock_protection_no_screen_footer_", nil);
+        NSString *reset = [NSString stringWithFormat:NSLocalizedString(@"_reset_wrong_passcode_desc_", nil), NCBrandOptions.shared.resetAppPasscodeAttempts];
+        NSString *lock = NSLocalizedString(@"_lock_protection_no_screen_footer_", nil);
+        sectionName = [NSString stringWithFormat:@"%@\n%@", reset, lock];
     } else if (section == 2 && !NCBrandOptions.shared.disable_mobileconfig) {
     } else if (section == 2 && !NCBrandOptions.shared.disable_mobileconfig) {
         sectionName = NSLocalizedString(@"_calendar_contacts_footer_", nil);
         sectionName = NSLocalizedString(@"_calendar_contacts_footer_", nil);
     } else if (section == numSections) {
     } else if (section == numSections) {

+ 3 - 3
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -297,7 +297,7 @@
 "_lock_active_"                 = "Lock: On";
 "_lock_active_"                 = "Lock: On";
 "_lock_not_active_"             = "Lock: Off";
 "_lock_not_active_"             = "Lock: Off";
 "_lock_protection_no_screen_"        = "Do not ask at startup";
 "_lock_protection_no_screen_"        = "Do not ask at startup";
-"_lock_protection_no_screen_footer_" = "Use \"Do not ask at startup\" for the encryption option";
+"_lock_protection_no_screen_footer_" = "Use \"Do not ask at startup\" for the encryption option.";
 "_enable_touch_face_id_"        = "Enable Touch/Face ID";
 "_enable_touch_face_id_"        = "Enable Touch/Face ID";
 "_url_"                         = "URL";
 "_url_"                         = "URL";
 "_username_"                    = "Username";
 "_username_"                    = "Username";
@@ -947,8 +947,8 @@
 "_chunk_move_"              = "The sent file could not be reassembled, please check the server log";
 "_chunk_move_"              = "The sent file could not be reassembled, please check the server log";
 "_download_image_"          = "Download image";
 "_download_image_"          = "Download image";
 "_download_video_"          = "Download video";
 "_download_video_"          = "Download video";
-"_reset_wrong_passcode_"    = "Resets after wrong passcode";
-"_failes_attemps_reset_"    = "Number of failed attempts. App reset";
+"_reset_wrong_passcode_"    = "Reset application";
+"_reset_wrong_passcode_desc_" = "Use \"Reset application\" for remove all accounts and local data after %d failed code entry attempts.";
 
 
 // Video
 // Video
 "_select_trace_"            = "Select the trace";
 "_select_trace_"            = "Select the trace";