feat: Update navigation logic for MPIN and OTP authentication to redirect to home page; add failed attempts tracking in MPIN controller

This commit is contained in:
Vaibhav Surve 2025-06-10 15:32:15 +05:30
parent c253c14481
commit 2ccd237329
4 changed files with 71 additions and 37 deletions

View File

@ -82,7 +82,7 @@ class LoginController extends MyController {
final bool isMpinEnabled = LocalStorage.getIsMpin();
if (isMpinEnabled) {
Get.toNamed('/auth/mpin-auth');
Get.offAllNamed('/home');
} else {
Get.offAllNamed('/home');
}
@ -90,8 +90,10 @@ class LoginController extends MyController {
Future<void> _handleRememberMe() async {
if (isChecked.value) {
await LocalStorage.setToken('username', basicValidator.getController('username')!.text);
await LocalStorage.setToken('password', basicValidator.getController('password')!.text);
await LocalStorage.setToken(
'username', basicValidator.getController('username')!.text);
await LocalStorage.setToken(
'password', basicValidator.getController('password')!.text);
await LocalStorage.setBool('remember_me', true);
} else {
await LocalStorage.removeToken('username');

View File

@ -20,7 +20,7 @@ class MPINController extends GetxController {
final retypeControllers = List.generate(6, (_) => TextEditingController());
final retypeFocusNodes = List.generate(6, (_) => FocusNode());
final RxInt failedAttempts = 0.obs;
@override
void onInit() {
super.onInit();
@ -77,7 +77,12 @@ class MPINController extends GetxController {
if (success) {
logger.i("[MPINController] MPIN generation successful.");
_navigateToDashboard(message: "MPIN Set Successfully");
showAppSnackbar(
title: "Success",
message: "MPIN generated successfully. Please login again.",
type: SnackbarType.success,
);
await LocalStorage.logout();
} else {
logger.w("[MPINController] MPIN generation failed.");
clearFields();
@ -186,9 +191,15 @@ class MPINController extends GetxController {
isLoading.value = false;
if (response == null) {
logger.i(
"[MPINController] MPIN generated successfully (null response treated as success)");
Get.toNamed('/auth/mpin-auth');
logger.i("[MPINController] MPIN generated successfully");
showAppSnackbar(
title: "Success",
message: "MPIN generated successfully. Please login again.",
type: SnackbarType.success,
);
await LocalStorage.logout();
return true;
} else {
@ -261,6 +272,7 @@ class MPINController extends GetxController {
type: SnackbarType.error,
);
clearFields();
onInvalidMPIN();
}
} catch (e) {
isLoading.value = false;
@ -273,4 +285,15 @@ class MPINController extends GetxController {
);
}
}
void onInvalidMPIN() {
failedAttempts.value++;
if (failedAttempts.value >= 3) {
showAppSnackbar(
title: "Error",
message: "Too many failed attempts. Consider logging in again.",
type: SnackbarType.error,
);
}
}
}

View File

@ -125,7 +125,7 @@ class OTPController extends GetxController {
print('MPIN Enabled? $isMpinEnabled');
if (isMpinEnabled) {
Get.toNamed('/auth/mpin-auth');
Get.offAllNamed('/home');
} else {
Get.offAllNamed('/home');
}

View File

@ -277,35 +277,44 @@ class _MPINAuthScreenState extends State<MPINAuthScreen> with UIMixin {
}
Widget _buildFooterOptions(MPINController controller, bool isNewUser) {
return Column(
children: [
if (isNewUser)
TextButton.icon(
onPressed: controller.switchToEnterMPIN,
icon: const Icon(Icons.arrow_back, size: 18, color: Colors.black87),
label: MyText.bodyMedium(
'Back to Enter MPIN',
color: Colors.black87,
fontWeight: 600,
fontSize: 14,
return Obx(() {
final showBackToLogin =
controller.failedAttempts.value >= 3 && !isNewUser;
return Column(
children: [
if (isNewUser)
TextButton.icon(
onPressed: () async {
Get.delete<MPINController>();
Get.toNamed('/dashboard');
},
icon: const Icon(Icons.arrow_back,
size: 18, color: Colors.redAccent),
label: MyText.bodyMedium(
'Back to Home Page',
color: contentTheme.brandRed,
fontWeight: 600,
fontSize: 14,
),
),
),
if (isNewUser)
TextButton.icon(
onPressed: () async {
Get.delete<MPINController>();
Get.toNamed('/dashboard');
},
icon:
const Icon(Icons.arrow_back, size: 18, color: Colors.redAccent),
label: MyText.bodyMedium(
'Back to Home Page',
color: contentTheme.brandRed,
fontWeight: 600,
fontSize: 14,
if (showBackToLogin)
TextButton.icon(
onPressed: () async {
Get.delete<MPINController>();
await LocalStorage.logout();
},
icon: const Icon(Icons.arrow_back,
size: 18, color: Colors.redAccent),
label: MyText.bodyMedium(
'Go back to Login Screen',
color: contentTheme.brandRed,
fontWeight: 600,
fontSize: 14,
),
),
),
],
);
],
);
});
}
}