Minor imprvements & fixes (#198)

This commit is contained in:
Neeraj Gupta 2023-08-13 11:08:37 +05:30 committed by GitHub
commit 16b2602423
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 27 deletions

View file

@ -216,14 +216,17 @@ class Configuration {
Future<Uint8List> decryptSecretsAndGetKeyEncKey(
String password,
KeyAttributes attributes,
{
Uint8List? keyEncryptionKey,
}
) async {
_logger.info('Start decryptAndSaveSecrets');
final keyEncryptionKey = await CryptoUtil.deriveKey(
utf8.encode(password) as Uint8List,
Sodium.base642bin(attributes.kekSalt),
attributes.memLimit,
attributes.opsLimit,
);
keyEncryptionKey ??= await CryptoUtil.deriveKey(
utf8.encode(password) as Uint8List,
Sodium.base642bin(attributes.kekSalt),
attributes.memLimit,
attributes.opsLimit,
);
_logger.info('user-key done');
Uint8List key;

View file

@ -309,5 +309,11 @@
"twofactorAuthenticationSuccessfullyReset": "Two-factor authentication successfully reset",
"incorrectRecoveryKey": "Incorrect recovery key",
"theRecoveryKeyYouEnteredIsIncorrect": "The recovery key you entered is incorrect",
"enterPassword": "Enter password"
"enterPassword": "Enter password",
"selectExportFormat": "Select export format",
"exportDialogDesc": "Encrypted exports will be protected by a password of your choice.",
"encrypted": "Encrypted",
"plainText": "Plain text",
"passwordToEncryptExport": "Password to encrypt export",
"export": "Export"
}

View file

@ -30,6 +30,7 @@ class ViewQrPage extends StatelessWidget {
children: [
QrImage(
data: code!.rawData,
foregroundColor: Theme.of(context).colorScheme.onBackground,
version: QrVersions.auto,
size: qrSize,
),

View file

@ -25,6 +25,7 @@ import 'package:ente_auth/ui/account/password_entry_page.dart';
import 'package:ente_auth/ui/account/password_reentry_page.dart';
import 'package:ente_auth/ui/account/recovery_page.dart';
import 'package:ente_auth/ui/components/buttons/button_widget.dart';
import 'package:ente_auth/ui/home_page.dart';
import 'package:ente_auth/ui/two_factor_authentication_page.dart';
import 'package:ente_auth/ui/two_factor_recovery_page.dart';
import 'package:ente_auth/utils/crypto_util.dart';
@ -521,14 +522,15 @@ class UserService {
isDismissible: true,
);
await dialog.show();
late Uint8List keyEncryptionKey;
try {
final kek = await CryptoUtil.deriveKey(
keyEncryptionKey = await CryptoUtil.deriveKey(
utf8.encode(userPassword) as Uint8List,
CryptoUtil.base642bin(srpAttributes.kekSalt),
srpAttributes.memLimit,
srpAttributes.opsLimit,
);
final loginKey = await CryptoUtil.deriveLoginKey(kek);
final loginKey = await CryptoUtil.deriveLoginKey(keyEncryptionKey);
final Uint8List identity = Uint8List.fromList(
utf8.encode(srpAttributes.srpUserID),
);
@ -566,21 +568,25 @@ class UserService {
},
);
if (response.statusCode == 200) {
await dialog.hide();
Widget page;
final String twoFASessionID = response.data["twoFactorSessionID"];
Configuration.instance.setVolatilePassword(userPassword);
if (twoFASessionID.isNotEmpty) {
page = TwoFactorAuthenticationPage(twoFASessionID);
} else {
await _saveConfiguration(response);
if (Configuration.instance.getEncryptedToken() != null) {
page = const PasswordReentryPage();
await Configuration.instance.decryptSecretsAndGetKeyEncKey(
userPassword,
Configuration.instance.getKeyAttributes()!,
keyEncryptionKey: keyEncryptionKey,
);
page = const HomePage();
} else {
throw Exception("unexpected response during email verification");
}
}
await dialog.hide();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext context) {

View file

@ -42,6 +42,7 @@ Future<void> autoLogoutAlert(BuildContext context) async {
);
await showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return alert;
},

View file

@ -22,19 +22,19 @@ import 'package:share_plus/share_plus.dart';
Future<void> handleExportClick(BuildContext context) async {
final result = await showDialogWidget(
context: context,
title: "Select export format",
body: "Encrypted exports will be protected by a password of your choice.",
title: context.l10n.selectExportFormat,
body: context.l10n.exportDialogDesc,
buttons: [
const ButtonWidget(
ButtonWidget(
buttonType: ButtonType.primary,
labelText: "Encrypted",
labelText: context.l10n.encrypted,
isInAlert: true,
buttonSize: ButtonSize.large,
buttonAction: ButtonAction.first,
),
const ButtonWidget(
ButtonWidget(
buttonType: ButtonType.secondary,
labelText: "Plain text",
labelText: context.l10n.plainText,
buttonSize: ButtonSize.large,
isInAlert: true,
buttonAction: ButtonAction.second,
@ -50,13 +50,16 @@ Future<void> handleExportClick(BuildContext context) async {
}
}
Future<void> _requestForEncryptionPassword(BuildContext context,
{String? password,}) async {
Future<void> _requestForEncryptionPassword(
BuildContext context, {
String? password,
}) async {
final l10n = context.l10n;
await showTextInputDialog(
context,
title: "Password to encrypt export",
submitButtonLabel: "Export",
hintText: "Enter password",
title: l10n.passwordToEncryptExport,
submitButtonLabel: l10n.export,
hintText: l10n.enterPassword,
isPasswordInput: true,
alwaysShowSuccessState: false,
onSubmit: (String password) async {
@ -77,7 +80,9 @@ Future<void> _requestForEncryptionPassword(BuildContext context,
String exportPlainText = await _getAuthDataForExport();
// Encrypt the key with this derived key
final encResult = await CryptoUtil.encryptChaCha(
utf8.encode(exportPlainText) as Uint8List, derivedKeyResult.key,);
utf8.encode(exportPlainText) as Uint8List,
derivedKeyResult.key,
);
final encContent = Sodium.bin2base64(encResult.encryptedData!);
final encNonce = Sodium.bin2base64(encResult.header!);
final EnteAuthExport data = EnteAuthExport(
@ -87,11 +92,12 @@ Future<void> _requestForEncryptionPassword(BuildContext context,
kdfParams: KDFParams(
memLimit: derivedKeyResult.memLimit,
opsLimit: derivedKeyResult.opsLimit,
salt: Sodium.bin2base64(kekSalt),),
salt: Sodium.bin2base64(kekSalt),
),
);
// get json value of data
_exportCodes(context, jsonEncode(data.toJson()));
} catch(e,s) {
} catch (e, s) {
Logger("ExportWidget").severe(e, s);
showToast(context, "Error while exporting codes.");
}
@ -128,7 +134,8 @@ Future<void> _exportCodes(BuildContext context, String fileContent) async {
await _codeFile.delete();
}
_codeFile.writeAsStringSync(fileContent);
await Share.shareFiles([_codeFile.path]);
final Size size = MediaQuery.of(context).size;
await Share.shareFiles([_codeFile.path], sharePositionOrigin: Rect.fromLTWH(0, 0, size.width, size.height / 2),);
Future.delayed(const Duration(seconds: 15), () async {
if (_codeFile.existsSync()) {
_codeFile.deleteSync();