import 'dart:io'; import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/svg.dart'; import 'package:local_auth_darwin/local_auth_darwin.dart'; import 'package:local_auth_android/local_auth_android.dart'; import 'package:local_auth/local_auth.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/dialogs/otp_dialog.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/basic_member_information_model.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; // WhatsApp 2 // SMS 1 // Face ID 3 // Finger Print 4 class VerifyLoginScreen extends StatefulWidget { VerifyLoginScreen({Key? key}) : super(key: key); @override _VerifyLoginScreenState createState() { return _VerifyLoginScreenState(); } } class _VerifyLoginScreenState extends State { final LocalAuthentication auth = LocalAuthentication(); List _availableBioMetricType = []; String? firebaseToken; //For face and finger print verification int selectedFlag = 0; bool isNeedVerifyWithFaceIDAndBiometrics = false; @override void initState() { _getAvailableBiometrics(); // setDefault(); super.initState(); } @override Widget build(BuildContext context) { firebaseToken ??= ModalRoute.of(context)!.settings.arguments as String; return Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, leading: IconButton( icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), onPressed: () => Navigator.pop(context), ), // actions: [Center(child: "Employee Digital ID".toText12(color: MyColors.textMixColor, isUnderLine: true).onPress(() {})), 21.width], ), body: ListView( padding: const EdgeInsets.all(21), physics: const BouncingScrollPhysics(), children: [ LocaleKeys.pleaseVerify.tr().toText16(), if (isNeedVerifyWithFaceIDAndBiometrics) LocaleKeys.pleaseVerifyForBio.tr().toText12(), GridView( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 13, mainAxisSpacing: 9), physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.only(top: 9), shrinkWrap: true, children: [ if (!isNeedVerifyWithFaceIDAndBiometrics) getButton(3), if (!isNeedVerifyWithFaceIDAndBiometrics) getButton(4), getButton(2), getButton(1), ], ) ], ), ); } Future _getAvailableBiometrics() async { try { _availableBioMetricType = await auth.getAvailableBiometrics(); print("the available biometric are ${_availableBioMetricType.length}"); } on PlatformException catch (e) { // AppToast.showErrorToast(message: e.message); print(e); } if (mounted) setState(() {}); } // authenticateUser(int type, {int isActive}) { // GifLoaderDialogUtils.showMyDialog(context); // if (type == 2 || type == 3) { // fingrePrintBefore = type; // } // this.selectedOption = fingrePrintBefore != null ? fingrePrintBefore : type; // // switch (type) { // case 1: // this.loginWithSMS(type); // break; // case 2: // this.loginWithFingurePrintFace(type, isActive); // break; // case 3: // this.loginWithFingurePrintFace(type, isActive); // break; // case 4: // this.loginWithSMS(type); // break; // default: // break; // } // sharedPref.setInt(LAST_LOGIN, this.selectedOption); //this.cs.sharedService.setStorage(this.selectedOption, AuthenticationService.LAST_LOGIN); // } // // loginWithSMS(type) { // //if (!el.disabled) { // if (this.user != null && this.registerd_data == null) { // this.checkUserAuthentication(type); // } else { // if (this.loginTokenID != null) { // // Future.delayed(Duration(seconds: 1), () { // this.sendActivationCode(type); // // }); // } else { // this.checkUserAuthentication(type); // } // } // } // // checkUserAuthentication(type) { // showLoader(true); // var req = getCommonRequest(type: type); // req.logInTokenID = ""; // // var request = CheckPatientAuthenticationReq.fromJson(req.toJson()); // // sharedPref.setObject(REGISTER_DATA_FOR_REGISTER, request); // authService // .checkPatientAuthentication(request) // .then((value) => { // GifLoaderDialogUtils.hideDialog(context), // if (value['isSMSSent']) // { // sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), // this.loginTokenID = value['LogInTokenID'], // sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), // // Future.delayed(Duration(seconds: 1), () { // this.sendActivationCode(type) // // }) // } // else // { // if (value['IsAuthenticated']) {this.checkActivationCode()} // } // }) // .catchError((err) { // print(err); // GifLoaderDialogUtils.hideDialog(context); // }); // } // // sendActivationCode(type) async { // var request = this.getCommonRequest(type: type); // request.sMSSignature = await SMSOTP.getSignature(); // GifLoaderDialogUtils.showMyDialog(context); // if (healthId != null) { // // final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); // // final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); // request.dob = dob; //isHijri == 1 ? dob : dateFormat2.format(dateFormat.parse(dob)); // request.healthId = healthId; // request.isHijri = isHijri; // await this.authService.sendActivationCodeRegister(request).then((result) { // GifLoaderDialogUtils.hideDialog(context); // if (result != null && result['isSMSSent'] == true) { // this.startSMSService(type); // } // }).catchError((r) { // GifLoaderDialogUtils.hideDialog(context); // }); // } else { // request.dob = ""; // request.healthId = ""; // request.isHijri = 0; // await this.authService.sendActivationCode(request).then((result) { // GifLoaderDialogUtils.hideDialog(context); // if (result != null && result['isSMSSent'] == true) { // this.startSMSService(type); // } // }).catchError((r) { // GifLoaderDialogUtils.hideDialog(context); // }); // } // } // // var tempType; // // startSMSService(type) { // tempType = type; // new SMSOTP( // context, // type, // this.mobileNumber, // (value) { // this.checkActivationCode(value: value); // }, // () => { // Navigator.pop(context), // }, // ).displayDialog(context); // } // // loginWithFingurePrintFace(type, int isActive) async { // if (isActive == 1 || isActive == 0) { // const iosStrings = // const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); // // try { // authenticated = await auth.authenticateWithBiometrics(localizedReason: 'Scan your fingerprint to authenticate', useErrorDialogs: true, stickyAuth: true, iOSAuthStrings: iosStrings); // } on PlatformException catch (e) { // GifLoaderDialogUtils.hideDialog(context); // AppToast.showErrorToast(message: 'Please enable your Touch or Face ID'); // } // // if (authenticated == true) { // // if (user != null && (user.logInType == 2 || user.logInType == 3)) { // // this.checkActivationCode(); // // } else { // // var request = this.getCommonRequest(type: type); // this.getMobileInfo(request); // //} // } // } // } // // getMobileInfo(request) { // // GifLoaderDialogUtils.showMyDialog(context); // this.authService.getLoginInfo(request).then((result) { // GifLoaderDialogUtils.hideDialog(context); // if (result['SMSLoginRequired'] == false) { // this.loginTokenID = result['LogInTokenID']; // this.patientOutSA = result['PatientOutSA']; // // sms for register the biometric // if (result['isSMSSent']) { // setState(() { // isMoreOption = true; // this.onlySMSBox = true; // // this.fingrePrintBefore = true; // }); // //this.button(); // } else { // setDefault(); // checkActivationCode(); // } // } else { // if (result['IsAuthenticated'] == true) { // setState(() { // isMoreOption = true; // this.onlySMSBox = true; // // this.fingrePrintBefore = true; // }); // } // } // }).catchError((err) { // GifLoaderDialogUtils.hideDialog(context); // print(err); // }); // } // // setDefault() async { // if (await sharedPref.getObject(IMEI_USER_DATA) != null) user = SelectDeviceIMEIRES.fromJson(await sharedPref.getObject(IMEI_USER_DATA)); // // if (await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN) != null) { // isMoreOption = true; // this.registerd_data = CheckPatientAuthenticationReq.fromJson(await sharedPref.getObject(REGISTER_DATA_FOR_LOGIIN)); // } // // this.mobileNumber = this.registerd_data != null ? this.registerd_data.patientMobileNumber : int.parse(this.user.mobile); // this.zipCode = this.registerd_data != null // ? this.registerd_data.zipCode // : this.user.outSA == true // ? "971" // : "966"; // this.patientOutSA = this.registerd_data != null // ? this.registerd_data.zipCode == "966" // ? 0 // : 1 // : this.user.outSA; // if (this.registerd_data != null) { // this.loginTokenID = await sharedPref.getString(LOGIN_TOKEN_ID); // this.loginType = this.registerd_data.searchType; // } // var nhic = await sharedPref.getObject(NHIC_DATA); // if (nhic != null) { // final DateFormat dateFormat = DateFormat('MM/dd/yyyy'); // final DateFormat dateFormat2 = DateFormat('dd/MM/yyyy'); // dob = nhic['IsHijri'] ? nhic['DateOfBirth'] : dateFormat2.format(dateFormat.parse(nhic['DateOfBirth'])); // // isHijri = nhic['IsHijri'] ? 1 : 0; // healthId = nhic['HealthId']; // } // this.deviceToken = await sharedPref.getString(PUSH_TOKEN); // this.lastLogin = await sharedPref.getInt(LAST_LOGIN) != null // ? await sharedPref.getInt(LAST_LOGIN) // : user != null // ? user.logInType // : null; // // //this.cs.sharedService.getStorage(AuthenticationService.LAST_LOGIN); // } // // getCommonRequest({type}) { // var request = SendActivationRequest(); // request.patientMobileNumber = this.mobileNumber; // request.mobileNo = '0' + this.mobileNumber.toString(); // request.deviceToken = this.deviceToken; // request.projectOutSA = this.patientOutSA == true ? true : false; // request.loginType = this.selectedOption; // request.oTPSendType = type == 1 ? type : 2; //this.selectedOption == 1 ? 1 : 2; // request.zipCode = this.zipCode; // // request.logInTokenID = this.loginTokenID ?? ""; // // if (this.registerd_data != null) { // request.searchType = this.registerd_data.searchType != null ? this.registerd_data.searchType : 1; // request.patientID = this.registerd_data.patientID != null ? this.registerd_data.patientID : 0; // request.patientIdentificationID = request.nationalID = this.registerd_data.patientIdentificationID != null ? this.registerd_data.patientIdentificationID : '0'; // // request.isRegister = this.registerd_data.isRegister; // } else { // request.searchType = request.searchType != null ? request.searchType : 2; // request.patientID = this.user.patientID != null ? this.user.patientID : 0; // request.nationalID = request.nationalID != null ? request.nationalID : '0'; // request.patientIdentificationID = request.patientIdentificationID != null ? request.patientIdentificationID : '0'; // request.isRegister = false; // } // request.deviceTypeID = request.searchType; // return request; // } // // // checkActivationCode({value}) async { // // // Navigator.pop(context); // // GifLoaderDialogUtils.showMyDialog(context); // // var request = this.getCommonRequest().toJson(); // // dynamic res; // // if (healthId != null) { // // request['DOB'] = dob; // // request['HealthId'] = healthId; // // request['IsHijri'] = isHijri; // // // // authService // // .checkActivationCodeRegister(request, value) // // .then((result) => { // // res = result, // // if (result is Map) // // { // // result = CheckActivationCode.fromJson(result), // // if (this.registerd_data != null && this.registerd_data.isRegister == true) // // { // // widget.changePageViewIndex(1), // // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), // // } // // } // // else // // { // // // Navigator.of(context).pop(), // // GifLoaderDialogUtils.hideDialog(context), // // Future.delayed(Duration(seconds: 1), () { // // AppToast.showErrorToast(message: result); // // }), // // } // // }) // // .catchError((err) { // // print(err); // // GifLoaderDialogUtils.hideDialog(context); // // Future.delayed(Duration(seconds: 1), () { // // AppToast.showErrorToast(message: err); // // startSMSService(tempType); // // }); // // }); // // } else { // // authService // // .checkActivationCode(request, value) // // .then((result) => { // // res = result, // // if (result is Map) // // { // // result = CheckActivationCode.fromJson(result), // // if (this.registerd_data != null && this.registerd_data.isRegister == true) // // { // // widget.changePageViewIndex(1), // // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)), // // } // // else // // { // // sharedPref.remove(FAMILY_FILE), // // result.list.isFamily = false, // // userData = result.list, // // sharedPref.setString(BLOOD_TYPE, result.patientBloodType), // // authenticatedUserObject.user = result.list, // // projectViewModel.setPrivilege(privilegeList: res), // // sharedPref.setObject(MAIN_USER, result.list), // // sharedPref.setObject(USER_PROFILE, result.list), // // loginTokenID = result.logInTokenID, // // sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), // // sharedPref.setString(TOKEN, result.authenticationTokenID), // // checkIfUserAgreedBefore(result), // // } // // } // // else // // { // // // // Navigator.of(context).pop(), // // // GifLoaderDialogUtils.hideDialog(context), // // // Future.delayed(Duration(seconds: 1), () { // // // AppToast.showErrorToast(message: result); // // // startSMSService(tempType); // // // }), // // } // // }) // // .catchError((err) { // // // print(err); // // // GifLoaderDialogUtils.hideDialog(context); // // // Future.delayed(Duration(seconds: 1), () { // // // AppToast.showErrorToast(message: err); // // // startSMSService(tempType); // // // }); // // }); // // } // // } // // // checkIfUserAgreedBefore(CheckActivationCode result) { // // if (result.isNeedUserAgreement == true) { // // //move to agreement page. // // } else { // // goToHome(); // // } // // } // // insertIMEI() { // authService.insertDeviceImei(selectedOption).then((value) => {}).catchError((err) { // print(err); // }); // } // // // getToDoCount() { // // toDoProvider.setState(0, true, "0"); // // ClinicListService service = new ClinicListService(); // // service.getActiveAppointmentNo(context).then((res) { // // if (res['MessageStatus'] == 1) { // // toDoProvider.setState(res['AppointmentActiveNumber'], true, "0"); // // } else {} // // }).catchError((err) { // // print(err); // // }); // // } // // // goToHome() async { // // authenticatedUserObject.isLogin = true; // // appointmentRateViewModel.isLogin = true; // // projectViewModel.isLogin = true; // // projectViewModel.user = authenticatedUserObject.user; // // await authenticatedUserObject.getUser(getUser: true); // // // // // getToDoCount(); // // // // appointmentRateViewModel // // .getIsLastAppointmentRatedList() // // .then((value) => { // // getToDoCount(), // // GifLoaderDialogUtils.hideDialog(AppGlobal.context), // // if (appointmentRateViewModel.isHaveAppointmentNotRate) // // { // // Navigator.pushAndRemoveUntil( // // context, // // FadePage( // // page: RateAppointmentDoctor(), // // ), // // (r) => false) // // } // // else // // { // // Navigator.pushAndRemoveUntil( // // context, // // FadePage( // // page: LandingPage(), // // ), // // (r) => false) // // }, // // insertIMEI() // // }) // // .catchError((err) { // // print(err); // // }); // // } // // loading(flag) { // // setState(() { // // isLoading = flag; // // }); // } // Future loginWithFaceIDAndBiometrics() async { IOSAuthMessages iosStrings = const IOSAuthMessages(cancelButton: 'cancel', goToSettingsButton: 'settings', goToSettingsDescription: 'Please set up your Touch ID.', lockOut: 'Please reenable your Touch ID'); bool authenticated = false; try { authenticated = await auth.authenticate(localizedReason: 'Scan your fingerprint to authenticate', options: const AuthenticationOptions(useErrorDialogs: true, stickyAuth: true, biometricOnly: true,), authMessages: [ iosStrings, const AndroidAuthMessages(), ],); } on PlatformException catch (e) { print(e); Utils.hideLoading(context); Utils.showToast("Please enable your Touch or Face ID"); } return authenticated; } Widget _loginOptionButton(String _title, String _icon, int _flag, int? _loginIndex) { bool isDisable = false; if(_flag >= 3 && _flag <= 4) { bool isFaceEnabled = (_flag == 3 && (checkBiometricIsAvailable(BiometricType.face) || checkBiometricIsAvailable(BiometricType.weak))); bool isThumbEnabled = (_flag == 4 && (checkBiometricIsAvailable(BiometricType.fingerprint) || checkBiometricIsAvailable(BiometricType.strong))); isDisable = !(isFaceEnabled || isThumbEnabled); } return InkWell( onTap: isDisable ? null : () async { if (_flag == 0) { setState(() { // isMoreOption = true; }); } else { if (_flag == 3 || _flag == 4) { bool authenticateWithFaceAndTouchID = await loginWithFaceIDAndBiometrics(); if (!authenticateWithFaceAndTouchID) { return; } else { isNeedVerifyWithFaceIDAndBiometrics = true; selectedFlag = _flag; setState(() { return; }); } } else { if (isNeedVerifyWithFaceIDAndBiometrics) performApiCall(_title, _icon, selectedFlag, _flag); else performApiCall(_title, _icon, _flag, _flag); } } }, child: Container( padding: const EdgeInsets.only(left: 20, right: 20, bottom: 15, top: 28), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDisable ? Colors.grey.withOpacity(0.3) : Colors.white, border: Border.all(color: MyColors.lightGreyEFColor, width: 1), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SvgPicture.asset( _icon, height: 38, width: 38, color: isDisable ? MyColors.darkTextColor.withOpacity(0.7) : null, ), _title.toText16(height: 20/16) ], ), ), ); } Widget getButton(int flag) { switch (flag) { case 1: return _loginOptionButton(LocaleKeys.verifyThroughSMS.tr(), 'assets/images/login/verify_sms.svg', flag, null); case 2: return _loginOptionButton(LocaleKeys.verifyThroughWhatsapp.tr(), 'assets/images/login/verify_whatsapp.svg', flag, null); case 3: return _loginOptionButton(LocaleKeys.verifyThroughFace.tr(), 'assets/images/login/verify_face.svg', flag, BiometricType.face.index); case 4: return _loginOptionButton(LocaleKeys.verifyThroughFingerprint.tr(), 'assets/images/login/verify_thumb.svg', flag, BiometricType.fingerprint.index); default: return const SizedBox(); } } bool checkBiometricIsAvailable(BiometricType biometricType) { bool isAvailable = false; print("the given biometric is $biometricType"); for (int i = 0; i < _availableBioMetricType.length; i++) { print("the current biometric is ${_availableBioMetricType[i]}"); if (biometricType == _availableBioMetricType[i]) { print("the data is available $biometricType"); isAvailable = true; break; } } return isAvailable; } Future performApiCall(String _title, String _icon, int _flag, int sendVerificationFlat) async { try { Utils.showLoading(context); await LoginApiClient().checkMobileAppVersion(); await LoginApiClient().memberLogin(AppState().getUserName!, AppState().password!); BasicMemberInformationModel? memberInformationModel = await LoginApiClient().mohemmSendActivationCodeByOTPNotificationType(0, AppState().memberLoginList?.pMOBILENUMBER, sendVerificationFlat, AppState().getUserName); Utils.hideLoading(context); OtpDialog( context, sendVerificationFlat, int.tryParse(AppState().memberLoginList?.pMOBILENUMBER ?? ""), (value, TextEditingController _pinPutController) async { Utils.showLoading(context); try { GenericResponseModel? genericResponseModel = await LoginApiClient().checkActivationCode(true, AppState().memberLoginList?.pMOBILENUMBER, value, AppState().getUserName); GenericResponseModel? genericResponseModel1 = await LoginApiClient().insertMobileLoginInfoNEW( AppState().memberLoginList?.pEMAILADDRESS ?? "", genericResponseModel?.pSESSIONID ?? 0, genericResponseModel?.memberInformationList![0].eMPLOYEENAME ?? "", _flag, AppState().memberLoginList?.pMOBILENUMBER ?? "", AppState().getUserName!, AppState().getIsHuawei ? AppState().getHuaweiPushToken : firebaseToken!, Platform.isAndroid ? "android" : "ios"); if (genericResponseModel?.errorMessage != null) { Utils.showToast(genericResponseModel?.errorMessage ?? ""); } else { AppState().setPrivilegeListModel = genericResponseModel!.privilegeList ?? []; AppState().setMemberInformationListModel = genericResponseModel.memberInformationList?.first; MemberInformationListModel.saveToPrefs(genericResponseModel.memberInformationList ?? []); PrivilegeListModel.saveToPrefs(genericResponseModel.privilegeList ?? []); AppState().setMohemmWifiSSID = genericResponseModel.mohemmWifiSSID; AppState().setMohemmWifiPassword = genericResponseModel.mohemmWifiPassword; AppState().setMohemmWifiPassword = genericResponseModel.mohemmWifiPassword; Utils.saveStringFromPrefs(SharedPrefsConsts.username, AppState().getUserName!); Utils.saveStringFromPrefs(SharedPrefsConsts.password, AppState().password!); Utils.saveStringFromPrefs(SharedPrefsConsts.mohemmWifiSSID, genericResponseModel.mohemmWifiSSID!); Utils.saveStringFromPrefs(SharedPrefsConsts.mohemmWifiPassword, genericResponseModel.mohemmWifiPassword!); } Utils.hideLoading(context); Navigator.pop(context); Navigator.pushNamedAndRemoveUntil(context, AppRoutes.dashboard, (Route route) => false); } catch (ex) { print(ex); _pinPutController.clear(); otpFieldClear.value = ""; Utils.hideLoading(context); Utils.handleException(ex, context, null); dynamic errorCode = ex; if(errorCode.error.errorStatusCode ==699){ Future.delayed(const Duration(seconds: 2), () { Navigator.pop(context); Navigator.pushNamedAndRemoveUntil( context, AppRoutes.login, (Route route) => false); }); } } }, () => { Navigator.pop(context), }, onResendCode: () { performApiCall(_title, _icon, _flag, sendVerificationFlat); }, ).displayDialog(context); } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, null); } } // // formatDate(date) { // return date; // return DateFormat('MMM dd, yyy, kk:mm').format(date); // } // // showLoader(bool isTrue) { // setState(() { // // isLoading = isTrue; // }); // } }