Przeglądaj źródła

Show recovery key prompt if key derivication fails on lowspec devices

Neeraj Gupta 2 lat temu
rodzic
commit
c0a7f4203a

+ 5 - 1
lib/core/configuration.dart

@@ -11,6 +11,7 @@ import 'package:logging/logging.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:photos/core/constants.dart';
 import 'package:photos/core/error-reporting/super_logging.dart';
+import 'package:photos/core/errors.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/db/collections_db.dart';
 import 'package:photos/db/files_db.dart';
@@ -257,7 +258,10 @@ class Configuration {
       Sodium.base642bin(attributes.kekSalt),
       attributes.memLimit,
       attributes.opsLimit,
-    );
+    ).onError((e, s) {
+      _logger.severe('deriveKey failed', e, s);
+      throw KeyDerivationError();
+    });
 
     _logger.info('user-key done');
     Uint8List key;

+ 2 - 0
lib/core/errors.dart

@@ -40,3 +40,5 @@ class UnauthorizedEditError extends AssertionError {}
 class InvalidStateError extends AssertionError {
   InvalidStateError(String message) : super(message);
 }
+
+class KeyDerivationError extends Error {}

+ 26 - 0
lib/ui/account/password_reentry_page.dart

@@ -3,6 +3,7 @@
 import 'package:flutter/material.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
+import 'package:photos/core/errors.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/models/key_attributes.dart';
@@ -77,6 +78,31 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
               _passwordController.text,
               Configuration.instance.getKeyAttributes(),
             );
+          } on KeyDerivationError catch (e, s) {
+            _logger.severe("Password verification failed", e, s);
+            await dialog.hide();
+            final dialogUserChoice = await showChoiceDialog(
+              context,
+              "Recreate password",
+              "The current device is not powerful enough to verify your "
+                  "password, so we need to regenerate it once in a way that "
+                  "works with all devices. \n\nPlease login using your "
+                  "recovery key and regenerate your password (you can use the same one again if you wish).",
+              firstAction: "Cancel",
+              firstActionColor: Theme.of(context).colorScheme.primary,
+              secondAction: "Use recovery key",
+              secondActionColor: Theme.of(context).colorScheme.primary,
+            );
+            if (dialogUserChoice == DialogUserChoice.secondChoice) {
+              Navigator.of(context).push(
+                MaterialPageRoute(
+                  builder: (BuildContext context) {
+                    return const RecoveryPage();
+                  },
+                ),
+              );
+            }
+            return;
           } catch (e, s) {
             _logger.severe("Password verification failed", e, s);
             await dialog.hide();