Implemented CloudFlare TurnStile

pull/343/head
haroon amjad 2 weeks ago
parent 1a6975fd8a
commit b793426dd6

@ -84,6 +84,7 @@ import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/services/notification_service.dart'; import 'package:hmg_patient_app_new/services/notification_service.dart';
import 'package:hmg_patient_app_new/services/permission_service.dart'; import 'package:hmg_patient_app_new/services/permission_service.dart';
import 'package:hmg_patient_app_new/core/services/turnstile_service.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_calendar_model.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_calendar_model.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart';
import 'package:local_auth/local_auth.dart'; import 'package:local_auth/local_auth.dart';
@ -155,6 +156,7 @@ class AppDependencies {
); );
getIt.registerLazySingleton<PermissionService>(() => PermissionService()); getIt.registerLazySingleton<PermissionService>(() => PermissionService());
getIt.registerLazySingleton<TurnstileService>(() => TurnstileService(getIt<LoggerService>()));
// Repositories // Repositories
getIt.registerLazySingleton<CommonRepo>(() => CommonRepoImp(loggerService: getIt())); getIt.registerLazySingleton<CommonRepo>(() => CommonRepoImp(loggerService: getIt()));
@ -255,7 +257,8 @@ class AppDependencies {
dialogService: getIt(), dialogService: getIt(),
appState: getIt(), appState: getIt(),
errorHandlerService: getIt(), errorHandlerService: getIt(),
localAuthService: getIt()), localAuthService: getIt(),
turnstileService: getIt()),
); );
getIt.registerLazySingleton<ProfileSettingsViewModel>(() => ProfileSettingsViewModel( getIt.registerLazySingleton<ProfileSettingsViewModel>(() => ProfileSettingsViewModel(

@ -0,0 +1,56 @@
import 'dart:async';
import 'package:cloudflare_turnstile/cloudflare_turnstile.dart';
import 'package:flutter/foundation.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
/// Service to handle Cloudflare Turnstile captcha verification
class TurnstileService {
final LoggerService _loggerService;
// Replace with your Cloudflare Turnstile site key
static const String _siteKey = '0x4AAAAAAAkmbvEy63pcxBBt';
TurnstileService(this._loggerService);
/// Get Turnstile token using invisible mode
/// Returns the token on success, null on failure
Future<String?> getTurnstileToken() async {
// Initialize an instance of invisible Cloudflare Turnstile with your site key
final turnstile = CloudflareTurnstile.invisible(
siteKey: _siteKey,
);
try {
// Get the Turnstile token
final token = await turnstile.getToken();
_loggerService.logInfo('Turnstile token retrieved successfully');
return token; // Return the token upon success
} on TurnstileException catch (e) {
// Handle Turnstile failure
_loggerService.logError('Turnstile challenge failed: ${e.message}');
if (kDebugMode) {
print('Challenge failed: ${e.message}');
}
} catch (e) {
// Handle any other exceptions
_loggerService.logError('Unexpected error during Turnstile challenge: $e');
if (kDebugMode) {
print('Unexpected error: $e');
}
} finally {
// Ensure the Turnstile instance is properly disposed of
turnstile.dispose();
}
// Return null if the token couldn't be generated
return null;
}
/// Get the site key for Turnstile widget
String getSiteKey() => _siteKey;
/// Validate if Turnstile is properly configured
bool isConfigured() {
return _siteKey.isNotEmpty && _siteKey != '0x4AAAAAAAkmbvEy63pcxBBt';
}
}

@ -147,6 +147,9 @@ class AuthenticationRepoImp implements AuthenticationRepo {
bool isRegister = false, bool isRegister = false,
bool isFormFamilyFile = false, bool isFormFamilyFile = false,
}) async { }) async {
int isOutKsa = (sendActivationCodeReq.zipCode == '966' || sendActivationCodeReq.zipCode == '+966') ? 0 : 1; int isOutKsa = (sendActivationCodeReq.zipCode == '966' || sendActivationCodeReq.zipCode == '+966') ? 0 : 1;
sendActivationCodeReq.patientOutSA = isOutKsa; sendActivationCodeReq.patientOutSA = isOutKsa;
sendActivationCodeReq.isDentalAllowedBackend = false; sendActivationCodeReq.isDentalAllowedBackend = false;

@ -42,6 +42,7 @@ import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/localauth_service.dart'; import 'package:hmg_patient_app_new/services/localauth_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/core/services/turnstile_service.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_calendar_model.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_calendar_model.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
@ -60,6 +61,7 @@ class AuthenticationViewModel extends ChangeNotifier {
final DialogService _dialogService; final DialogService _dialogService;
final NavigationService _navigationService; final NavigationService _navigationService;
final LocalAuthService _localAuthService; final LocalAuthService _localAuthService;
final TurnstileService _turnstileService;
AuthenticationViewModel({ AuthenticationViewModel({
required AppState appState, required AppState appState,
@ -69,12 +71,14 @@ class AuthenticationViewModel extends ChangeNotifier {
required NavigationService navigationService, required NavigationService navigationService,
required CacheService cacheService, required CacheService cacheService,
required LocalAuthService localAuthService, required LocalAuthService localAuthService,
required TurnstileService turnstileService,
}) : _navigationService = navigationService, }) : _navigationService = navigationService,
_dialogService = dialogService, _dialogService = dialogService,
_errorHandlerService = errorHandlerService, _errorHandlerService = errorHandlerService,
_appState = appState, _appState = appState,
_authenticationRepo = authenticationRepo, _authenticationRepo = authenticationRepo,
_localAuthService = localAuthService {} _localAuthService = localAuthService,
_turnstileService = turnstileService {}
final TextEditingController nationalIdController = TextEditingController(), final TextEditingController nationalIdController = TextEditingController(),
phoneNumberController = TextEditingController(), phoneNumberController = TextEditingController(),
dobController = TextEditingController(), dobController = TextEditingController(),
@ -974,6 +978,15 @@ class AuthenticationViewModel extends ChangeNotifier {
// TODO: GET APP SMS SIGNATURE HERE // TODO: GET APP SMS SIGNATURE HERE
request.sMSSignature = await getSignature(); request.sMSSignature = await getSignature();
// Get Turnstile token if configured
final turnstileToken = await _turnstileService.getTurnstileToken();
if (turnstileToken != null) {
request.turnstileToken = turnstileToken;
} else {
request.turnstileToken = "";
}
if (isNeedLoading) { if (isNeedLoading) {
LoaderBottomSheet.showLoader(); LoaderBottomSheet.showLoader();
} }

@ -30,6 +30,7 @@ class SendActivationRequest {
int? status; int? status;
int? familyRegionID; int? familyRegionID;
bool? isPatientExcluded; bool? isPatientExcluded;
String? turnstileToken;
SendActivationRequest( SendActivationRequest(
{this.patientMobileNumber, {this.patientMobileNumber,
@ -62,7 +63,8 @@ class SendActivationRequest {
this.responseID, this.responseID,
this.status, this.status,
this.familyRegionID, this.familyRegionID,
this.isPatientExcluded}); this.isPatientExcluded,
this.turnstileToken});
SendActivationRequest.fromJson(Map<String, dynamic> json) { SendActivationRequest.fromJson(Map<String, dynamic> json) {
patientMobileNumber = json['PatientMobileNumber']; patientMobileNumber = json['PatientMobileNumber'];
@ -96,6 +98,7 @@ class SendActivationRequest {
status = json['Status']; status = json['Status'];
familyRegionID = json['FamilyRegionID']; familyRegionID = json['FamilyRegionID'];
isPatientExcluded = json['IsPatientExcluded']; isPatientExcluded = json['IsPatientExcluded'];
turnstileToken = json['TurnstileToken'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -135,6 +138,9 @@ class SendActivationRequest {
data['Status'] = status; data['Status'] = status;
data['FamilyRegionID'] = familyRegionID; data['FamilyRegionID'] = familyRegionID;
data['IsPatientExcluded'] = isPatientExcluded; data['IsPatientExcluded'] = isPatientExcluded;
if (turnstileToken != null) {
data['TurnstileToken'] = turnstileToken;
}
return data; return data;
} }
} }

@ -109,6 +109,7 @@ dependencies:
flutter_amazonpaymentservices: ^0.0.13 flutter_amazonpaymentservices: ^0.0.13
screen_brightness: ^1.0.1 screen_brightness: ^1.0.1
flutter_screenshot_blocker: ^1.0.4 flutter_screenshot_blocker: ^1.0.4
cloudflare_turnstile: ^3.7.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

Loading…
Cancel
Save