-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: Keyfile sign in 2.0.0 (#10)
Previously, while signing in to an application using a keyfile, the console threw InvalidPasswordException every time the user entered a password. While fixing the bug, it was noticed that all control of the view is done directly in the widget. For this reason, the entire keyfile signing functionality was rebuilt, separating view management into cubit. List of changes: - created keyfile_dropzone_cubit.dart to manage parsing of uploaded file to Keyfile after drag & drop - created sign_in_keyfile_drawer_page_cubit.dart to combine and manage the functionality of uploading a keyfile, entering a password and signing in to the application - created new version of keyfile [2.0.0], which contains secret_data, public_key and version. In comparison with previous versions, it replaced "address" with "public_key", removed "public_address" and replaced camelCase names with snake_case. - created keyfile_entity.dart representing single keyfile structure and keyfile_secret_data_entity.dart representing its private key - replaced keyfile.dart with decrypted_keyfile_model.dart and encrypted_keyfile_model.dart to allow recognizing keyfile content before and after its decrypting
- Loading branch information
Showing
38 changed files
with
1,332 additions
and
690 deletions.
There are no files selected for viewing
61 changes: 61 additions & 0 deletions
61
lib/blocs/pages/drawer/sign_in_keyfile_drawer_page/sign_in_keyfile_drawer_page_cubit.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_bloc/flutter_bloc.dart'; | ||
import 'package:miro/blocs/pages/drawer/sign_in_keyfile_drawer_page/sign_in_keyfile_drawer_page_state.dart'; | ||
import 'package:miro/blocs/widgets/keyfile_dropzone/keyfile_dropzone_cubit.dart'; | ||
import 'package:miro/blocs/widgets/keyfile_dropzone/keyfile_dropzone_state.dart'; | ||
import 'package:miro/shared/exceptions/keyfile_exception/keyfile_exception.dart'; | ||
import 'package:miro/shared/exceptions/keyfile_exception/keyfile_exception_type.dart'; | ||
import 'package:miro/shared/models/keyfile/decrypted_keyfile_model.dart'; | ||
import 'package:miro/shared/models/keyfile/encrypted_keyfile_model.dart'; | ||
|
||
class SignInKeyfileDrawerPageCubit extends Cubit<SignInKeyfileDrawerPageState> { | ||
final KeyfileDropzoneCubit keyfileDropzoneCubit; | ||
final TextEditingController passwordTextEditingController; | ||
late final StreamSubscription<KeyfileDropzoneState> _keyfileDropzoneStateSubscription; | ||
|
||
SignInKeyfileDrawerPageCubit({ | ||
required this.keyfileDropzoneCubit, | ||
required this.passwordTextEditingController, | ||
}) : super(const SignInKeyfileDrawerPageState()) { | ||
_keyfileDropzoneStateSubscription = keyfileDropzoneCubit.stream.listen(_listenKeyfileChange); | ||
} | ||
|
||
@override | ||
Future<void> close() { | ||
keyfileDropzoneCubit.close(); | ||
_keyfileDropzoneStateSubscription.cancel(); | ||
return super.close(); | ||
} | ||
|
||
void notifyPasswordChanged() { | ||
bool keyfileUploadedBool = keyfileDropzoneCubit.state.hasKeyfile; | ||
if (keyfileUploadedBool) { | ||
_decryptKeyfile(); | ||
} | ||
} | ||
|
||
void _listenKeyfileChange(KeyfileDropzoneState keyfileDropzoneState) { | ||
bool keyfileValidBool = keyfileDropzoneState.keyfileExceptionType == null; | ||
if (keyfileValidBool) { | ||
_decryptKeyfile(); | ||
} else { | ||
emit(SignInKeyfileDrawerPageState(keyfileExceptionType: keyfileDropzoneState.keyfileExceptionType)); | ||
} | ||
} | ||
|
||
void _decryptKeyfile() { | ||
try { | ||
String password = passwordTextEditingController.text; | ||
EncryptedKeyfileModel encryptedKeyfileModel = keyfileDropzoneCubit.state.encryptedKeyfileModel!; | ||
DecryptedKeyfileModel decryptedKeyfileModel = encryptedKeyfileModel.decrypt(password); | ||
|
||
emit(SignInKeyfileDrawerPageState(decryptedKeyfileModel: decryptedKeyfileModel)); | ||
} on KeyfileException catch (e) { | ||
emit(SignInKeyfileDrawerPageState(keyfileExceptionType: e.keyfileExceptionType)); | ||
} catch (e) { | ||
emit(const SignInKeyfileDrawerPageState(keyfileExceptionType: KeyfileExceptionType.invalidKeyfile)); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
lib/blocs/pages/drawer/sign_in_keyfile_drawer_page/sign_in_keyfile_drawer_page_state.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import 'package:equatable/equatable.dart'; | ||
import 'package:miro/shared/exceptions/keyfile_exception/keyfile_exception_type.dart'; | ||
import 'package:miro/shared/models/keyfile/decrypted_keyfile_model.dart'; | ||
|
||
class SignInKeyfileDrawerPageState extends Equatable { | ||
final KeyfileExceptionType? keyfileExceptionType; | ||
final DecryptedKeyfileModel? decryptedKeyfileModel; | ||
|
||
const SignInKeyfileDrawerPageState({ | ||
this.keyfileExceptionType, | ||
this.decryptedKeyfileModel, | ||
}); | ||
|
||
@override | ||
List<Object?> get props => <Object?>[keyfileExceptionType, decryptedKeyfileModel]; | ||
} |
52 changes: 52 additions & 0 deletions
52
lib/blocs/widgets/keyfile_dropzone/keyfile_dropzone_cubit.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import 'dart:convert'; | ||
import 'dart:html' as html; | ||
|
||
import 'package:file_picker/file_picker.dart'; | ||
import 'package:flutter_bloc/flutter_bloc.dart'; | ||
import 'package:miro/blocs/widgets/keyfile_dropzone/keyfile_dropzone_state.dart'; | ||
import 'package:miro/shared/entity/keyfile/keyfile_entity.dart'; | ||
import 'package:miro/shared/exceptions/keyfile_exception/keyfile_exception.dart'; | ||
import 'package:miro/shared/exceptions/keyfile_exception/keyfile_exception_type.dart'; | ||
import 'package:miro/shared/models/generic/file_model.dart'; | ||
import 'package:miro/shared/models/keyfile/encrypted_keyfile_model.dart'; | ||
import 'package:miro/shared/utils/logger/app_logger.dart'; | ||
|
||
class KeyfileDropzoneCubit extends Cubit<KeyfileDropzoneState> { | ||
KeyfileDropzoneCubit() : super(KeyfileDropzoneState.empty()); | ||
|
||
Future<void> uploadFileViaHtml(dynamic htmlFile) async { | ||
if (htmlFile is html.File) { | ||
updateSelectedFile(await FileModel.fromHtmlFile(htmlFile)); | ||
} else { | ||
AppLogger().log(message: 'Unsupported file type ${htmlFile.runtimeType}'); | ||
} | ||
} | ||
|
||
Future<void> uploadFileManually() async { | ||
FilePickerResult? filePickerResult = await FilePicker.platform.pickFiles(allowMultiple: false); | ||
if (filePickerResult == null) { | ||
return; | ||
} | ||
PlatformFile platformFile = filePickerResult.files.single; | ||
if (platformFile.bytes == null) { | ||
return; | ||
} | ||
|
||
updateSelectedFile(FileModel.fromPlatformFile(platformFile)); | ||
} | ||
|
||
void updateSelectedFile(FileModel fileModel) { | ||
try { | ||
Map<String, dynamic> keyfileJson = jsonDecode(fileModel.content) as Map<String, dynamic>; | ||
KeyfileEntity keyfileEntity = KeyfileEntity.fromJson(keyfileJson); | ||
EncryptedKeyfileModel encryptedKeyfileModel = EncryptedKeyfileModel.fromEntity(keyfileEntity); | ||
emit(KeyfileDropzoneState(encryptedKeyfileModel: encryptedKeyfileModel, fileModel: fileModel)); | ||
} on KeyfileException catch (keyfileException) { | ||
AppLogger().log(message: keyfileException.keyfileExceptionType.toString()); | ||
emit(KeyfileDropzoneState(keyfileExceptionType: keyfileException.keyfileExceptionType, fileModel: fileModel)); | ||
} catch (e) { | ||
AppLogger().log(message: 'Invalid keyfile: $e'); | ||
emit(KeyfileDropzoneState(keyfileExceptionType: KeyfileExceptionType.invalidKeyfile, fileModel: fileModel)); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
lib/blocs/widgets/keyfile_dropzone/keyfile_dropzone_state.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import 'package:equatable/equatable.dart'; | ||
import 'package:miro/shared/exceptions/keyfile_exception/keyfile_exception_type.dart'; | ||
import 'package:miro/shared/models/generic/file_model.dart'; | ||
import 'package:miro/shared/models/keyfile/encrypted_keyfile_model.dart'; | ||
|
||
class KeyfileDropzoneState extends Equatable { | ||
final EncryptedKeyfileModel? encryptedKeyfileModel; | ||
final FileModel? fileModel; | ||
final KeyfileExceptionType? keyfileExceptionType; | ||
|
||
const KeyfileDropzoneState({ | ||
this.encryptedKeyfileModel, | ||
this.fileModel, | ||
this.keyfileExceptionType, | ||
}); | ||
|
||
factory KeyfileDropzoneState.empty() { | ||
return const KeyfileDropzoneState(); | ||
} | ||
|
||
bool get hasFile => fileModel != null; | ||
|
||
bool get hasKeyfile => encryptedKeyfileModel != null; | ||
|
||
@override | ||
List<Object?> get props => <Object?>[encryptedKeyfileModel, fileModel, keyfileExceptionType]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.