This commit is contained in:
Adam Velebil 2024-09-04 15:27:37 +02:00
commit 48e04c588c
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
11 changed files with 70 additions and 23 deletions

View File

@ -173,6 +173,7 @@ class FidoManager(
fidoChannel.setMethodCallHandler(null)
fidoViewModel.clearSessionState()
fidoViewModel.updateCredentials(null)
connectionHelper.cancelPending()
coroutineScope.cancel()
}

View File

@ -208,6 +208,7 @@ class OathManager(
oathChannel.setMethodCallHandler(null)
oathViewModel.clearSession()
oathViewModel.updateCredentials(mapOf())
pendingAction?.invoke(Result.failure(Exception()))
coroutineScope.cancel()
}

View File

@ -35,6 +35,8 @@ import '../../exception/no_data_exception.dart';
import '../../exception/platform_exception_decoder.dart';
import '../../oath/models.dart';
import '../../oath/state.dart';
import '../../widgets/toast.dart';
import '../tap_request_dialog.dart';
final _log = Logger('android.oath.state');
@ -136,27 +138,45 @@ class _AndroidOathStateNotifier extends OathStateNotifier {
}
}
// Converts Platform exception during Add Account operation
// Returns CancellationException for situations we don't want to show a Toast
Exception _decodeAddAccountException(PlatformException platformException) {
final decodedException = platformException.decode();
Exception handlePlatformException(
Ref ref, PlatformException platformException) {
final decoded = platformException.decode();
final l10n = ref.read(l10nProvider);
final withContext = ref.read(withContextProvider);
// Auth required, the app will show Unlock dialog
if (decodedException is ApduException && decodedException.sw == 0x6982) {
_log.error('Add account failed: Auth required');
return CancellationException();
toast(String message, {bool popStack = false}) =>
withContext((context) async {
ref.read(androidDialogProvider).closeDialog();
if (popStack) {
Navigator.of(context).popUntil((route) {
return route.isFirst;
});
}
showToast(context, message, duration: const Duration(seconds: 4));
});
switch (decoded) {
case ApduException apduException:
if (apduException.sw == 0x6985) {
// pop stack to show the OATH view with "Set password"
toast(l10n.l_add_account_password_required, popStack: true);
return CancellationException();
}
if (apduException.sw == 0x6982) {
toast(l10n.l_add_account_unlock_required);
return CancellationException();
}
case PlatformException pe:
if (pe.code == 'JobCancellationException') {
// pop stack to show FIDO view
toast(l10n.l_add_account_func_missing, popStack: true);
return CancellationException();
} else if (pe.code == 'IllegalArgumentException') {
toast(l10n.l_add_account_already_exists);
return CancellationException();
}
}
// Thrown in native code when the account already exists on the YubiKey
// The entry dialog will show an error message and that is why we convert
// this to CancellationException to avoid showing a Toast
if (platformException.code == 'IllegalArgumentException') {
_log.error('Add account failed: Account already exists');
return CancellationException();
}
// original exception
return decodedException;
return decoded;
}
final addCredentialToAnyProvider =
@ -171,7 +191,7 @@ final addCredentialToAnyProvider =
var result = jsonDecode(resultString);
return OathCredential.fromJson(result['credential']);
} on PlatformException catch (pe) {
throw _decodeAddAccountException(pe);
throw handlePlatformException(ref, pe);
}
});
@ -286,7 +306,7 @@ class _AndroidCredentialListNotifier extends OathCredentialListNotifier {
var result = jsonDecode(resultString);
return OathCredential.fromJson(result['credential']);
} on PlatformException catch (pe) {
throw _decodeAddAccountException(pe);
throw handlePlatformException(_ref, pe);
}
}

View File

@ -129,7 +129,7 @@ class _DialogProvider {
final args = jsonDecode(call.arguments);
switch (call.method) {
case 'close':
_closeDialog();
closeDialog();
break;
case 'show':
await _showDialog(args['title'], args['description'], args['icon']);
@ -147,7 +147,7 @@ class _DialogProvider {
});
}
void _closeDialog() {
void closeDialog() {
_controller?.close();
_controller = null;
}

View File

@ -69,6 +69,7 @@ class MainPage extends ConsumerWidget {
'oath_add_account',
'oath_icon_pack_dialog',
'android_qr_scanner_view',
'android_alert_dialog'
].contains(route.settings.name);
});
});

View File

@ -429,6 +429,10 @@
"message": {}
}
},
"l_add_account_password_required": null,
"l_add_account_unlock_required": null,
"l_add_account_already_exists": null,
"l_add_account_func_missing": null,
"l_account_name_required": "Ihr Konto muss einen Namen haben",
"l_name_already_exists": "Für diesen Aussteller existiert dieser Name bereits",
"l_account_already_exists": "Dieses Konto existiert bereits auf dem YubiKey",

View File

@ -429,6 +429,10 @@
"message": {}
}
},
"l_add_account_password_required": "Password required",
"l_add_account_unlock_required": "Unlock required",
"l_add_account_already_exists": "Account already exists",
"l_add_account_func_missing": "Functionality missing or disabled",
"l_account_name_required": "Your account must have a name",
"l_name_already_exists": "This name already exists for the issuer",
"l_account_already_exists": "This account already exists on the YubiKey",

View File

@ -429,6 +429,10 @@
"message": {}
}
},
"l_add_account_password_required": null,
"l_add_account_unlock_required": null,
"l_add_account_already_exists": null,
"l_add_account_func_missing": null,
"l_account_name_required": "Votre compte doit avoir un nom",
"l_name_already_exists": "Ce nom existe déjà pour l'émetteur",
"l_account_already_exists": "Ce compte existe déjà sur la YubiKey",

View File

@ -429,6 +429,10 @@
"message": {}
}
},
"l_add_account_password_required": null,
"l_add_account_unlock_required": null,
"l_add_account_already_exists": null,
"l_add_account_func_missing": null,
"l_account_name_required": "アカウントには名前が必要です",
"l_name_already_exists": "この名前は発行者にすでに存在します",
"l_account_already_exists": "このアカウントはYubiKeyにすでに存在します",

View File

@ -429,6 +429,10 @@
"message": {}
}
},
"l_add_account_password_required": null,
"l_add_account_unlock_required": null,
"l_add_account_already_exists": null,
"l_add_account_func_missing": null,
"l_account_name_required": "Twoje konto musi mieć nazwę",
"l_name_already_exists": "Ta nazwa już istnieje dla tego wydawcy",
"l_account_already_exists": "To konto już istnieje w YubiKey",

View File

@ -429,6 +429,10 @@
"message": {}
}
},
"l_add_account_password_required": null,
"l_add_account_unlock_required": null,
"l_add_account_already_exists": null,
"l_add_account_func_missing": null,
"l_account_name_required": "Tài khoản của bạn phải có tên",
"l_name_already_exists": "Tên này đã tồn tại cho nhà phát hành",
"l_account_already_exists": "Tài khoản này đã tồn tại trên YubiKey",