Add reusable two-factor verification for login and money operations (#32)

This commit is contained in:
Stephan D committed 2026-09-12 12:44:34 +02:00
1 parent b7a58b1a87
commit fb40f860d2
41 files changed
+2439 -43

No files matched your search

+35 -1
View File
@@ -6,8 +6,12 @@ import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:sxchnge_auth/sxchnge_auth.dart';
import 'package:sxchnge_wallet/sxchnge_wallet.dart';
import '../security/challenge.dart';
import 'copy.dart';
import 'summary.dart';
@@ -64,6 +68,25 @@ class TransferPageState extends State<TransferPage> {
}
}
Future<void> _confirm() async {
final p = _provider;
final challenge = await p.challenge();
if (!mounted || p.factorError != null || p.error != null) return;
FactorGrant? grant;
if (challenge != null) {
grant = await verifyFactor(
context,
challenge: challenge,
service: p.wallet.factors!,
recorder: p.recorder,
journey: p.journey,
summary: TransferSummary(quote: p.quote!),
);
if (!mounted || grant == null) return;
}
await p.submit(approval: grant);
}
Future<bool> allowExit() async {
if (_provider.result != null) return true;
if (_provider.busy || _provider.uncertain) return false;
@@ -163,6 +186,17 @@ class TransferPageState extends State<TransferPage> {
),
),
),
if (p.factorError != null)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Semantics(
liveRegion: true,
child: Text(
factorErrorText(l, p.factorError!),
style: TextStyle(color: t.colorScheme.error),
),
),
),
if (p.noSubmission) Text(l.wNoSubmission),
if (p.uncertain) ...[
Text(l.wUncertain),
@@ -183,7 +217,7 @@ class TransferPageState extends State<TransferPage> {
else
FilledButton(
key: const ValueKey('transfer-confirm'),
onPressed: p.busy ? null : p.submit,
onPressed: p.busy ? null : _confirm,
child: Text(l.wConfirm),
),
TextButton(