mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 16:32:01 +03:00
Refactor AppFailurePage.
This commit is contained in:
parent
f33087fd0f
commit
9cce216e9f
83
lib/app/views/app_failure_page.dart
Executable file
83
lib/app/views/app_failure_page.dart
Executable file
@ -0,0 +1,83 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../desktop/models.dart';
|
||||
import '../../desktop/state.dart';
|
||||
import '../../theme.dart';
|
||||
import '../message.dart';
|
||||
import 'graphics.dart';
|
||||
import 'message_page.dart';
|
||||
|
||||
class AppFailurePage extends ConsumerWidget {
|
||||
final Widget? title;
|
||||
final Object cause;
|
||||
const AppFailurePage({this.title, required this.cause, super.key}) : super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final reason = cause;
|
||||
|
||||
Widget? graphic = const Icon(Icons.error);
|
||||
String? header = 'An error has occured';
|
||||
String? message = reason.toString();
|
||||
List<Widget> actions = [];
|
||||
|
||||
if (reason is RpcError) {
|
||||
if (reason.status == 'connection-error') {
|
||||
switch (reason.body['connection']) {
|
||||
case 'ccid':
|
||||
header = 'Failed to open smart card connection';
|
||||
if (Platform.isMacOS) {
|
||||
message = 'Try to remove and re-insert your YubiKey.';
|
||||
} else if (Platform.isLinux) {
|
||||
message = 'Make sure pcscd is running.';
|
||||
} else {
|
||||
message = 'Make sure your smart card service is functioning.';
|
||||
}
|
||||
break;
|
||||
case 'fido':
|
||||
if (Platform.isWindows &&
|
||||
!ref.watch(rpcStateProvider.select((state) => state.isAdmin))) {
|
||||
graphic = noPermission;
|
||||
header = null;
|
||||
message = 'WebAuthn management requires elevated privileges.';
|
||||
actions = [
|
||||
OutlinedButton.icon(
|
||||
label: const Text('Unlock'),
|
||||
icon: const Icon(Icons.lock_open),
|
||||
style: AppTheme.primaryOutlinedButtonStyle(context),
|
||||
onPressed: () async {
|
||||
final controller = showMessage(
|
||||
context, 'Elevating permissions...',
|
||||
duration: const Duration(seconds: 30));
|
||||
try {
|
||||
if (await ref.read(rpcProvider).elevate()) {
|
||||
ref.refresh(rpcProvider);
|
||||
} else {
|
||||
showMessage(context, 'Permission denied');
|
||||
}
|
||||
} finally {
|
||||
controller.close();
|
||||
}
|
||||
}),
|
||||
];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
header = 'Failed to open connection';
|
||||
message = 'Try to remove and re-insert your YubiKey.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MessagePage(
|
||||
title: title,
|
||||
graphic: graphic,
|
||||
header: header,
|
||||
message: message,
|
||||
actions: actions,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:yubico_authenticator/desktop/models.dart';
|
||||
|
||||
class AppFailureScreen extends StatelessWidget {
|
||||
final Object reason;
|
||||
const AppFailureScreen(this.reason, {super.key}) : super();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cause = reason;
|
||||
if (cause is RpcError) {
|
||||
if (cause.status == 'connection-error' &&
|
||||
cause.body['connection'] == 'ccid') {
|
||||
var msg = 'Failed to open smart card connection';
|
||||
if (Platform.isMacOS) {
|
||||
msg += '\nTry to remove and re-insert your YubiKey to regain access.';
|
||||
} else if (Platform.isLinux) {
|
||||
msg += '\nMake sure pcscd is running.';
|
||||
}
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
msg,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
cause.toString(),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,19 +1,12 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../app/message.dart';
|
||||
import '../../app/models.dart';
|
||||
import '../../app/views/app_failure_screen.dart';
|
||||
import '../../app/views/app_failure_page.dart';
|
||||
import '../../app/views/app_loading_screen.dart';
|
||||
import '../../app/views/app_page.dart';
|
||||
import '../../app/views/graphics.dart';
|
||||
import '../../app/views/message_page.dart';
|
||||
import '../../desktop/models.dart';
|
||||
import '../../desktop/state.dart';
|
||||
import '../../management/models.dart';
|
||||
import '../../theme.dart';
|
||||
import '../state.dart';
|
||||
import 'locked_page.dart';
|
||||
import 'unlocked_page.dart';
|
||||
@ -53,41 +46,10 @@ class FidoScreen extends ConsumerWidget {
|
||||
'WebAuthn requires the FIDO2 application to be enabled on your YubiKey',
|
||||
);
|
||||
}
|
||||
if (Platform.isWindows && error is RpcError) {
|
||||
if (error.status == 'connection-error' &&
|
||||
!ref.watch(
|
||||
rpcStateProvider.select((state) => state.isAdmin))) {
|
||||
return MessagePage(
|
||||
title: const Text('WebAuthn'),
|
||||
graphic: noPermission,
|
||||
message: 'WebAuthn management requires elevated privileges.',
|
||||
actions: [
|
||||
OutlinedButton.icon(
|
||||
label: const Text('Unlock'),
|
||||
icon: const Icon(Icons.lock_open),
|
||||
style: AppTheme.primaryOutlinedButtonStyle(context),
|
||||
onPressed: () async {
|
||||
final controller = showMessage(
|
||||
context, 'Elevating permissions...',
|
||||
duration: const Duration(seconds: 30));
|
||||
try {
|
||||
if (await ref.read(rpcProvider).elevate()) {
|
||||
ref.refresh(rpcProvider);
|
||||
} else {
|
||||
showMessage(context, 'Permission denied');
|
||||
}
|
||||
} finally {
|
||||
controller.close();
|
||||
}
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
return AppPage(
|
||||
|
||||
return AppFailurePage(
|
||||
title: const Text('WebAuthn'),
|
||||
centered: true,
|
||||
child: AppFailureScreen(error),
|
||||
cause: error,
|
||||
);
|
||||
},
|
||||
data: (fidoState) {
|
||||
|
@ -5,7 +5,6 @@ import 'package:collection/collection.dart';
|
||||
import '../../app/message.dart';
|
||||
import '../../app/models.dart';
|
||||
import '../../app/state.dart';
|
||||
import '../../app/views/app_failure_screen.dart';
|
||||
import '../../app/views/app_loading_screen.dart';
|
||||
import '../../core/models.dart';
|
||||
import '../../widgets/responsive_dialog.dart';
|
||||
@ -241,7 +240,18 @@ class _ManagementScreenState extends ConsumerState<ManagementScreen> {
|
||||
final child =
|
||||
ref.watch(managementStateProvider(widget.deviceData.node.path)).when(
|
||||
loading: () => const AppLoadingScreen(),
|
||||
error: (error, _) => AppFailureScreen(error),
|
||||
error: (error, _) => Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
error.toString(),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
data: (info) {
|
||||
bool hasConfig = info.version.major > 4;
|
||||
if (hasConfig) {
|
||||
|
@ -6,7 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../app/message.dart';
|
||||
import '../../app/models.dart';
|
||||
import '../../app/views/app_failure_screen.dart';
|
||||
import '../../app/views/app_failure_page.dart';
|
||||
import '../../app/views/app_loading_screen.dart';
|
||||
import '../../app/views/app_page.dart';
|
||||
import '../../app/views/graphics.dart';
|
||||
@ -31,10 +31,9 @@ class OathScreen extends ConsumerWidget {
|
||||
centered: true,
|
||||
child: const AppLoadingScreen(),
|
||||
),
|
||||
error: (error, _) => AppPage(
|
||||
error: (error, _) => AppFailurePage(
|
||||
title: const Text('Authenticator'),
|
||||
centered: true,
|
||||
child: AppFailureScreen(error),
|
||||
cause: error,
|
||||
),
|
||||
data: (oathState) => oathState.locked
|
||||
? _LockedView(devicePath, oathState)
|
||||
|
Loading…
Reference in New Issue
Block a user