Kaynağa Gözat

Add ability to edit an existing code

vishnukvmd 2 yıl önce
ebeveyn
işleme
c9f37b4f5a

+ 22 - 3
lib/onboarding/view/setup_enter_secret_key_page.dart

@@ -1,11 +1,14 @@
 import "package:ente_auth/l10n/l10n.dart";
 import 'package:ente_auth/models/code.dart';
+// ignore: import_of_legacy_library_into_null_safe
 import 'package:ente_auth/utils/dialog_util.dart';
 import 'package:ente_auth/utils/totp_util.dart';
 import "package:flutter/material.dart";
 
 class SetupEnterSecretKeyPage extends StatefulWidget {
-  SetupEnterSecretKeyPage({Key? key}) : super(key: key);
+  final Code? code;
+
+  SetupEnterSecretKeyPage({this.code, Key? key}) : super(key: key);
 
   @override
   State<SetupEnterSecretKeyPage> createState() =>
@@ -13,8 +16,21 @@ class SetupEnterSecretKeyPage extends StatefulWidget {
 }
 
 class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
-  final _accountController = TextEditingController();
-  final _secretController = TextEditingController(text: "");
+  late TextEditingController _accountController;
+  late TextEditingController _secretController;
+
+  @override
+  void initState() {
+    _accountController = TextEditingController(
+      text: widget.code != null
+          ? Uri.decodeFull(widget.code!.account).toString()
+          : null,
+    );
+    _secretController = TextEditingController(
+      text: widget.code != null ? widget.code!.secret : null,
+    );
+    super.initState();
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -78,6 +94,9 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
                         );
                         // Verify the validity of the code
                         getTotp(code);
+                        if (widget.code != null) {
+                          code.id = widget.code!.id;
+                        }
                         Navigator.of(context).pop(code);
                       } catch (e) {
                         _showIncorrectDetailsDialog(context);

+ 8 - 2
lib/services/authenticator_service.dart

@@ -88,7 +88,11 @@ class AuthenticatorService {
     return insertedID;
   }
 
-  Future<void> updateEntry(int generatedID, String plainText) async {
+  Future<void> updateEntry(
+    int generatedID,
+    String plainText,
+    bool shouldSync,
+  ) async {
     var key = await getOrCreateAuthDataKey();
     final encryptedKeyData = await CryptoUtil.encryptChaCha(
       utf8.encode(plainText) as Uint8List,
@@ -102,7 +106,9 @@ class AuthenticatorService {
       affectedRows == 1,
       "updateEntry should have updated exactly one row",
     );
-    unawaited(sync());
+    if (shouldSync) {
+      unawaited(sync());
+    }
   }
 
   Future<void> deleteEntry(int genID) async {

+ 16 - 4
lib/store/code_store.dart

@@ -41,16 +41,28 @@ class CodeStore {
     bool shouldSync = true,
   }) async {
     final codes = await getAllCodes();
+    bool isExistingCode = false;
     for (final existingCode in codes) {
       if (existingCode == code) {
         _logger.info("Found duplicate code, skipping add");
         return;
+      } else if (existingCode.id == code.id) {
+        isExistingCode = true;
+        break;
       }
     }
-    code.id = await _authenticatorService.addEntry(
-      jsonEncode(code.rawData),
-      shouldSync,
-    );
+    if (isExistingCode) {
+      await _authenticatorService.updateEntry(
+        code.id!,
+        jsonEncode(code.rawData),
+        shouldSync,
+      );
+    } else {
+      code.id = await _authenticatorService.addEntry(
+        jsonEncode(code.rawData),
+        shouldSync,
+      );
+    }
     Bus.instance.fire(CodesUpdatedEvent());
   }
 

+ 29 - 0
lib/ui/code_widget.dart

@@ -3,6 +3,7 @@ import 'dart:async';
 import 'package:clipboard/clipboard.dart';
 import 'package:ente_auth/ente_theme_data.dart';
 import 'package:ente_auth/models/code.dart';
+import 'package:ente_auth/onboarding/view/setup_enter_secret_key_page.dart';
 import 'package:ente_auth/store/code_store.dart';
 import 'package:ente_auth/utils/toast_util.dart';
 import 'package:ente_auth/utils/totp_util.dart';
@@ -55,6 +56,20 @@ class _CodeWidgetState extends State<CodeWidget> {
         endActionPane: ActionPane(
           motion: const ScrollMotion(),
           children: [
+            SlidableAction(
+              onPressed: _onEditPressed,
+              backgroundColor: Colors.grey.withOpacity(0.1),
+              borderRadius: const BorderRadius.all(Radius.circular(12.0)),
+              foregroundColor:
+                  Theme.of(context).colorScheme.inverseBackgroundColor,
+              icon: Icons.edit_outlined,
+              label: 'Edit',
+              padding: const EdgeInsets.only(left: 4, right: 0),
+              spacing: 8,
+            ),
+            const SizedBox(
+              width: 4,
+            ),
             SlidableAction(
               onPressed: _onDeletePressed,
               backgroundColor: Colors.grey.withOpacity(0.1),
@@ -63,6 +78,7 @@ class _CodeWidgetState extends State<CodeWidget> {
               icon: Icons.delete,
               label: 'Delete',
               padding: const EdgeInsets.only(left: 0, right: 0),
+              spacing: 8,
             ),
           ],
         ),
@@ -194,6 +210,19 @@ class _CodeWidgetState extends State<CodeWidget> {
     );
   }
 
+  Future<void> _onEditPressed(_) async {
+    final Code? code = await Navigator.of(context).push(
+      MaterialPageRoute(
+        builder: (BuildContext context) {
+          return SetupEnterSecretKeyPage(code: widget.code);
+        },
+      ),
+    );
+    if (code != null) {
+      CodeStore.instance.addCode(code);
+    }
+  }
+
   void _onDeletePressed(_) {
     final AlertDialog alert = AlertDialog(
       shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),