Feature_MPIN_OTP #46

Merged
vaibhav.surve merged 8 commits from Feature_MPIN_OTP into main 2025-06-11 09:38:35 +00:00
4 changed files with 71 additions and 37 deletions
Showing only changes of commit 2ccd237329 - Show all commits

View File

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

View File

@ -20,7 +20,7 @@ class MPINController extends GetxController {
final retypeControllers = List.generate(6, (_) => TextEditingController()); final retypeControllers = List.generate(6, (_) => TextEditingController());
final retypeFocusNodes = List.generate(6, (_) => FocusNode()); final retypeFocusNodes = List.generate(6, (_) => FocusNode());
final RxInt failedAttempts = 0.obs;
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@ -77,7 +77,12 @@ class MPINController extends GetxController {
if (success) { if (success) {
logger.i("[MPINController] MPIN generation successful."); 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 { } else {
logger.w("[MPINController] MPIN generation failed."); logger.w("[MPINController] MPIN generation failed.");
clearFields(); clearFields();
@ -186,9 +191,15 @@ class MPINController extends GetxController {
isLoading.value = false; isLoading.value = false;
if (response == null) { if (response == null) {
logger.i( logger.i("[MPINController] MPIN generated successfully");
"[MPINController] MPIN generated successfully (null response treated as success)");
Get.toNamed('/auth/mpin-auth'); showAppSnackbar(
title: "Success",
message: "MPIN generated successfully. Please login again.",
type: SnackbarType.success,
);
await LocalStorage.logout();
return true; return true;
} else { } else {
@ -261,6 +272,7 @@ class MPINController extends GetxController {
type: SnackbarType.error, type: SnackbarType.error,
); );
clearFields(); clearFields();
onInvalidMPIN();
} }
} catch (e) { } catch (e) {
isLoading.value = false; 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'); print('MPIN Enabled? $isMpinEnabled');
if (isMpinEnabled) { if (isMpinEnabled) {
Get.toNamed('/auth/mpin-auth'); Get.offAllNamed('/home');
} else { } else {
Get.offAllNamed('/home'); Get.offAllNamed('/home');
} }

View File

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