Skip to content

Commit

Permalink
NEVISACCESSAPP-5744: InitializationError handling improvement (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
laszlo-domonkos authored May 29, 2024
1 parent dfc0e8b commit 83159d9
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 13 deletions.
26 changes: 25 additions & 1 deletion lib/domain/client_provider/client_provider.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright © 2022 Nevis Security AG. All rights reserved.

import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
Expand Down Expand Up @@ -47,8 +48,31 @@ class ClientProviderImpl implements ClientProvider {
onSuccess.call();
_operationTypeRepository.reset();
}).onError((error) {
debugPrint('Client initialization failed: ${error.runtimeType}.');
debugPrint('Client initialization failed: ${error.description}.');

// The SDK removes all the data when a rooted device or tampering
// is detected
if (Platform.isAndroid && _isGenericDeviceProtectionError(error)) {
// On Android the application must be closed when a generic device
// protection error is received (i.e. it is a checksum, debugger,
// emulator or instrumentation guard error)
exit(-1);
}

_errorHandler.handle(error);
}).execute();
}

bool _isGenericDeviceProtectionError(
InitializationError initializationError,
) {
// Return true if this is a generic tampering error different than
// rooted device error occurred (i.e. this is a checksum, debugger,
// emulator or instrumentation guard error).
return initializationError is InitializationDeviceProtectionError &&
initializationError is! InitializationRootedError &&
initializationError is! InitializationHardwareError &&
initializationError is! InitializationNoDeviceLockError &&
initializationError is! InitializationLockScreenHasChangedError;
}
}
2 changes: 1 addition & 1 deletion lib/domain/error/error_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class ErrorHandlerImpl extends ErrorHandler {
MobileAuthenticationClientError error,
) {
if (error is InitializationError) {
return ResultParameter.failure(description: error.description);
return ResultParameter.fatal(description: error.description);
} else if (error is OperationFidoError) {
return ResultParameter.failure(description: error.errorCode.description);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/app_state/operation_result_type.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Copyright © 2022 Nevis Security AG. All rights reserved.

enum OperationResultType { success, failure }
enum OperationResultType { success, failure, fatal }
5 changes: 5 additions & 0 deletions lib/ui/screens/result/navigation/result_parameter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ class ResultParameter {
this.errorType,
this.description,
}) : type = OperationResultType.failure;

ResultParameter.fatal({
this.errorType,
this.description,
}) : type = OperationResultType.fatal;
}
36 changes: 26 additions & 10 deletions lib/ui/screens/result/result_screen.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright © 2022 Nevis Security AG. All rights reserved.

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
Expand Down Expand Up @@ -66,16 +68,29 @@ class ResultContent extends StatelessWidget {
AppText.body(state.description!),
]),
),
Button.outlined(
text: localization.confirmButtonTitle,
onPressed: () {
final event = NavigateToHomeEvent(
resultType: state.type,
operationType: state.operationType,
);
context.read<ResultBloc>().add(event);
},
),
// On Android platform the confirm button is always shown,
// on iOS platform it is hidden in case of fatal result type.
if (Platform.isAndroid ||
state.type != OperationResultType.fatal)
Button.outlined(
text: localization.confirmButtonTitle,
onPressed: () {
// In case of fatal result type we can be sure the application
// is running on Android platform as this button is hidden on iOS.
// On Android the application must be closed when a fatal result
// type is received. At this moment only initialization errors are
// treated as fatal results.
if (state.type == OperationResultType.fatal) {
exit(-1);
} else {
final event = NavigateToHomeEvent(
resultType: state.type,
operationType: state.operationType,
);
context.read<ResultBloc>().add(event);
}
},
),
const SizedBox(height: 16.0),
],
))
Expand All @@ -92,6 +107,7 @@ class ResultContent extends StatelessWidget {
case OperationResultType.success:
return localizations.operationSucceededResultTitle(
state.operationType.resolve(localizations));
case OperationResultType.fatal:
case OperationResultType.failure:
return localizations.operationFailedResultTitle(
state.operationType.resolve(localizations));
Expand Down

0 comments on commit 83159d9

Please sign in to comment.