use completer to fix bug on 2FA status change

This commit is contained in:
ashilkn 2022-11-15 19:12:26 +05:30
parent 5fec54736e
commit 4555f5d79f
4 changed files with 24 additions and 11 deletions

View file

@ -609,7 +609,7 @@ class UserService {
} }
} }
Future<void> setupTwoFactor(BuildContext context) async { Future<void> setupTwoFactor(BuildContext context, Completer completer) async {
final dialog = createProgressDialog(context, "Please wait..."); final dialog = createProgressDialog(context, "Please wait...");
await dialog.show(); await dialog.show();
try { try {
@ -621,12 +621,14 @@ class UserService {
TwoFactorSetupPage( TwoFactorSetupPage(
response.data["secretCode"], response.data["secretCode"],
response.data["qrCode"], response.data["qrCode"],
completer,
), ),
), ),
); );
} catch (e) { } catch (e) {
await dialog.hide(); await dialog.hide();
_logger.severe("Failed to setup tfa", e); _logger.severe("Failed to setup tfa", e);
completer.complete();
rethrow; rethrow;
} }
} }

View file

@ -1,5 +1,6 @@
// @dart=2.9 // @dart=2.9
import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -17,9 +18,14 @@ import 'package:pinput/pin_put/pin_put.dart';
class TwoFactorSetupPage extends StatefulWidget { class TwoFactorSetupPage extends StatefulWidget {
final String secretCode; final String secretCode;
final String qrCode; final String qrCode;
final Completer completer;
const TwoFactorSetupPage(this.secretCode, this.qrCode, {Key key}) const TwoFactorSetupPage(
: super(key: key); this.secretCode,
this.qrCode,
this.completer, {
Key key,
}) : super(key: key);
@override @override
State<TwoFactorSetupPage> createState() => _TwoFactorSetupPageState(); State<TwoFactorSetupPage> createState() => _TwoFactorSetupPageState();
@ -260,6 +266,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
.enableTwoFactor(context, widget.secretCode, code); .enableTwoFactor(context, widget.secretCode, code);
if (success) { if (success) {
_showSuccessPage(); _showSuccessPage();
widget.completer.complete();
} }
} }

View file

@ -14,6 +14,8 @@ typedef FutureValueCallBack = Future<bool> Function();
class ToggleSwitchWidget extends StatefulWidget { class ToggleSwitchWidget extends StatefulWidget {
final FutureValueCallBack value; final FutureValueCallBack value;
///Make sure to use completer if onChanged callback has other async functions inside
final OnChangedCallBack onChanged; final OnChangedCallBack onChanged;
final bool initialValue; final bool initialValue;
const ToggleSwitchWidget({ const ToggleSwitchWidget({
@ -32,6 +34,7 @@ class _ToggleSwitchWidgetState extends State<ToggleSwitchWidget> {
late bool toggleValue; late bool toggleValue;
ExecutionState executionState = ExecutionState.idle; ExecutionState executionState = ExecutionState.idle;
final _debouncer = Debouncer(const Duration(milliseconds: 300)); final _debouncer = Debouncer(const Duration(milliseconds: 300));
@override @override
void initState() { void initState() {
futureToggleValue = widget.value.call(); futureToggleValue = widget.value.call();
@ -90,10 +93,6 @@ class _ToggleSwitchWidgetState extends State<ToggleSwitchWidget> {
widget.value.call().then((newValue) { widget.value.call().then((newValue) {
setState(() { setState(() {
//if onchanged on toggle is successful
// print('here');
// print(toggleValue);
// print("newValue : $newValue");
if (toggleValue == newValue) { if (toggleValue == newValue) {
if (executionState == ExecutionState.inProgress) { if (executionState == ExecutionState.inProgress) {
executionState = ExecutionState.successful; executionState = ExecutionState.successful;

View file

@ -58,6 +58,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
} }
Widget _getSectionOptions(BuildContext context) { Widget _getSectionOptions(BuildContext context) {
final Completer completer = Completer();
final List<Widget> children = []; final List<Widget> children = [];
if (_config.hasConfiguredAccount()) { if (_config.hasConfiguredAccount()) {
children.addAll( children.addAll(
@ -69,7 +70,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
), ),
trailingSwitch: ToggleSwitchWidget( trailingSwitch: ToggleSwitchWidget(
value: () => UserService.instance.fetchTwoFactorStatus(), value: () => UserService.instance.fetchTwoFactorStatus(),
initialValue: false, initialValue: _config.hasEnabledTwoFactor(),
onChanged: () async { onChanged: () async {
final hasAuthenticated = await LocalAuthenticationService final hasAuthenticated = await LocalAuthenticationService
.instance .instance
@ -81,10 +82,12 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
await UserService.instance.fetchTwoFactorStatus(); await UserService.instance.fetchTwoFactorStatus();
if (hasAuthenticated) { if (hasAuthenticated) {
if (isTwoFactorEnabled) { if (isTwoFactorEnabled) {
_disableTwoFactor(); _disableTwoFactor(completer);
} else { } else {
await UserService.instance.setupTwoFactor(context); await UserService.instance
.setupTwoFactor(context, completer);
} }
return completer.future;
} }
}, },
), ),
@ -165,7 +168,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
); );
} }
void _disableTwoFactor() { void _disableTwoFactor(Completer completer) {
final AlertDialog alert = AlertDialog( final AlertDialog alert = AlertDialog(
title: const Text("Disable two-factor"), title: const Text("Disable two-factor"),
content: const Text( content: const Text(
@ -181,6 +184,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
), ),
onPressed: () { onPressed: () {
Navigator.of(context, rootNavigator: true).pop('dialog'); Navigator.of(context, rootNavigator: true).pop('dialog');
completer.complete();
}, },
), ),
TextButton( TextButton(
@ -193,6 +197,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
onPressed: () async { onPressed: () async {
await UserService.instance.disableTwoFactor(context); await UserService.instance.disableTwoFactor(context);
Navigator.of(context, rootNavigator: true).pop('dialog'); Navigator.of(context, rootNavigator: true).pop('dialog');
completer.complete();
}, },
), ),
], ],