Add support to show mnemonic recovery key
This commit is contained in:
parent
630a2ee97a
commit
fbc5e7329e
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
|||
import 'dart:io' as io;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:flutter_sodium/flutter_sodium.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
@ -28,6 +29,8 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||
import 'package:super_logging/super_logging.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import 'constants.dart';
|
||||
|
||||
class Configuration {
|
||||
Configuration._privateConstructor();
|
||||
|
||||
|
@ -265,6 +268,14 @@ class Configuration {
|
|||
}
|
||||
|
||||
Future<void> recover(String recoveryKey) async {
|
||||
// check if user has entered mnemonic code
|
||||
if (recoveryKey.contains(' ')) {
|
||||
if (recoveryKey.split(' ').length != kMnemonicKeyWordCount) {
|
||||
throw AssertionError(
|
||||
'recovery code should have $kMnemonicKeyWordCount words');
|
||||
}
|
||||
recoveryKey = bip39.mnemonicToEntropy(recoveryKey);
|
||||
}
|
||||
final attributes = getKeyAttributes();
|
||||
Uint8List masterKey;
|
||||
try {
|
||||
|
|
|
@ -20,3 +20,7 @@ const String kLivePhotoToastCounterKey = "show_live_photo_toast";
|
|||
|
||||
const kThumbnailDiskLoadDeferDuration = Duration(milliseconds: 40);
|
||||
const kThumbnailServerLoadDeferDuration = Duration(milliseconds: 80);
|
||||
|
||||
// 256 bit key maps to 24 words
|
||||
// https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#Generating_the_mnemonic
|
||||
const kMnemonicKeyWordCount = 24;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import 'dart:io' as io;
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/core/constants.dart';
|
||||
import 'package:photos/utils/toast_util.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
|
@ -34,12 +36,21 @@ class RecoveryKeyDialog extends StatefulWidget {
|
|||
|
||||
class _RecoveryKeyDialogState extends State<RecoveryKeyDialog> {
|
||||
bool _hasTriedToSave = false;
|
||||
bool _showMnenomicCode = true;
|
||||
final _recoveryKeyFile = io.File(
|
||||
Configuration.instance.getTempDirectory() + "ente-recovery-key.txt");
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final recoveryKey = widget.recoveryKey;
|
||||
String recoveryKey = widget.recoveryKey;
|
||||
if (_showMnenomicCode) {
|
||||
recoveryKey = bip39.entropyToMnemonic(recoveryKey);
|
||||
if (recoveryKey.split(' ').length != kMnemonicKeyWordCount) {
|
||||
throw AssertionError(
|
||||
'recovery code should have $kMnemonicKeyWordCount words');
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> actions = [];
|
||||
if (!_hasTriedToSave) {
|
||||
actions.add(TextButton(
|
||||
|
@ -128,6 +139,17 @@ class _RecoveryKeyDialogState extends State<RecoveryKeyDialog> {
|
|||
Text(
|
||||
"please save this in a safe place",
|
||||
),
|
||||
Padding(padding: EdgeInsets.all(8)),
|
||||
CheckboxListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: Text('show human readable key'),
|
||||
value: _showMnenomicCode,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_showMnenomicCode = value;
|
||||
});
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -136,6 +158,7 @@ class _RecoveryKeyDialogState extends State<RecoveryKeyDialog> {
|
|||
);
|
||||
}
|
||||
|
||||
// author civil bicycle drop gown ship file shallow chicken hub isolate among report piece cram crumble leopard guard spike segment update fall defy achieve
|
||||
Future _shareRecoveryKey(String recoveryKey) async {
|
||||
if (_recoveryKeyFile.existsSync()) {
|
||||
await _recoveryKeyFile.delete();
|
||||
|
|
|
@ -86,8 +86,13 @@ class _RecoveryPageState extends State<RecoveryPage> {
|
|||
);
|
||||
} catch (e) {
|
||||
await dialog.hide();
|
||||
showErrorDialog(context, "incorrect recovery key",
|
||||
"the recovery key you entered is incorrect");
|
||||
String errMessage =
|
||||
'the recovery key you entered is incorrect';
|
||||
if (e is AssertionError) {
|
||||
errMessage = '$errMessage : ${e.message}';
|
||||
}
|
||||
showErrorDialog(
|
||||
context, "incorrect recovery key", errMessage);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
|
|
21
pubspec.lock
21
pubspec.lock
|
@ -50,6 +50,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.73"
|
||||
bip39:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: bip39
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -492,6 +499,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.5"
|
||||
hex:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hex
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -827,6 +841,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.4.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -21,6 +21,7 @@ dependencies:
|
|||
animate_do: ^2.0.0
|
||||
archive: ^3.1.2
|
||||
background_fetch: ^1.0.1
|
||||
bip39: ^1.0.6
|
||||
cached_network_image: ^3.0.0
|
||||
chewie:
|
||||
path: thirdparty/chewie
|
||||
|
|
Loading…
Reference in a new issue