Add security service implementation and device safety checks

ipd-changes-for-vida-plus
taha 1 day ago
parent a767f082c5
commit af8df09bf7

Binary file not shown.

@ -4,3 +4,7 @@ android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
org.gradle.jvmargs=-Xmx4608m org.gradle.jvmargs=-Xmx4608m
kotlin.jvm.target.validation.mode = IGNORE kotlin.jvm.target.validation.mode = IGNORE
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false

@ -14,8 +14,9 @@
30F70E6C266F56FD005D8F8E /* MainAppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */; }; 30F70E6C266F56FD005D8F8E /* MainAppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */; };
30F70E6F266F6509005D8F8E /* VideoCallRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */; }; 30F70E6F266F6509005D8F8E /* VideoCallRequestParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
41B879757CC2D190BA52BEC5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D9222C8F78B892C013C44A6 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
7645621A848A5D0B29B97C46 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4E9718EA62661304F55A32D /* Pods_Runner.framework */; }; 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@ -46,8 +47,13 @@
30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainAppViewController.swift; sourceTree = "<group>"; }; 30F70E6B266F56FD005D8F8E /* MainAppViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainAppViewController.swift; sourceTree = "<group>"; };
30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallRequestParameters.swift; sourceTree = "<group>"; }; 30F70E6E266F6509005D8F8E /* VideoCallRequestParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallRequestParameters.swift; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
5CEDB0C437E96DCB175D44FA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
624621692EF4C03F0724C4A9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
6946B309E20CA63FE3258287 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
6D9222C8F78B892C013C44A6 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
@ -58,10 +64,6 @@
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9CE61EBC24AB366E008D68DD /* VideoCallViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallViewController.swift; sourceTree = "<group>"; }; 9CE61EBC24AB366E008D68DD /* VideoCallViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallViewController.swift; sourceTree = "<group>"; };
9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICallProtocoll.swift; sourceTree = "<group>"; }; 9CE61ECC24ADBB4C008D68DD /* ICallProtocoll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICallProtocoll.swift; sourceTree = "<group>"; };
C55D4AE245B71956447BA22F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
C8801C5E6B82B6CB497CA5C7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
E333B59AA5538E0304102FD2 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
E4E9718EA62661304F55A32D /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -69,7 +71,8 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
7645621A848A5D0B29B97C46 /* Pods_Runner.framework in Frameworks */, 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
41B879757CC2D190BA52BEC5 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -104,9 +107,9 @@
7D66D387293CE5376A07EC5F /* Pods */ = { 7D66D387293CE5376A07EC5F /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C55D4AE245B71956447BA22F /* Pods-Runner.debug.xcconfig */, 5CEDB0C437E96DCB175D44FA /* Pods-Runner.debug.xcconfig */,
C8801C5E6B82B6CB497CA5C7 /* Pods-Runner.release.xcconfig */, 624621692EF4C03F0724C4A9 /* Pods-Runner.release.xcconfig */,
E333B59AA5538E0304102FD2 /* Pods-Runner.profile.xcconfig */, 6946B309E20CA63FE3258287 /* Pods-Runner.profile.xcconfig */,
); );
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
@ -114,6 +117,7 @@
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */, 9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
@ -129,7 +133,7 @@
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
7D66D387293CE5376A07EC5F /* Pods */, 7D66D387293CE5376A07EC5F /* Pods */,
A9562A4C43D78E443FA8BFD1 /* Frameworks */, CE522434458EBA14DCAE751B /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -171,10 +175,10 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
A9562A4C43D78E443FA8BFD1 /* Frameworks */ = { CE522434458EBA14DCAE751B /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
E4E9718EA62661304F55A32D /* Pods_Runner.framework */, 6D9222C8F78B892C013C44A6 /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -186,21 +190,24 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
4CBD0CB2C106C3E696B88FDB /* [CP] Check Pods Manifest.lock */, 3F8132D0B1477379229A46EF /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
C21500C474806845DCE7C12A /* [CP] Embed Pods Frameworks */, CD1E4AEFF4CC6FD150483363 /* [CP] Embed Pods Frameworks */,
24EE7472FCD545118644D8C4 /* [CP] Copy Pods Resources */, 6BD71B7017878A134266DEFC /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
); );
name = Runner; name = Runner;
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
productName = Runner; productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
@ -217,7 +224,6 @@
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = 3A359E86ZF;
LastSwiftMigration = 1100; LastSwiftMigration = 1100;
}; };
}; };
@ -231,6 +237,9 @@
Base, Base,
); );
mainGroup = 97C146E51CF9000F007C117D; mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
);
productRefGroup = 97C146EF1CF9000F007C117D /* Products */; productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
@ -256,24 +265,6 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
24EE7472FCD545118644D8C4 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1; alwaysOutOfDate = 1;
@ -290,7 +281,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
}; };
4CBD0CB2C106C3E696B88FDB /* [CP] Check Pods Manifest.lock */ = { 3F8132D0B1477379229A46EF /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -312,6 +303,24 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
6BD71B7017878A134266DEFC /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1; alwaysOutOfDate = 1;
@ -327,7 +336,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
C21500C474806845DCE7C12A /* [CP] Embed Pods Frameworks */ = { CD1E4AEFF4CC6FD150483363 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -352,7 +361,6 @@
"${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework", "${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework",
"${BUILT_PRODUCTS_DIR}/Try/Try.framework", "${BUILT_PRODUCTS_DIR}/Try/Try.framework",
"${BUILT_PRODUCTS_DIR}/barcode_scan2/barcode_scan2.framework", "${BUILT_PRODUCTS_DIR}/barcode_scan2/barcode_scan2.framework",
"${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework",
"${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework", "${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework",
"${BUILT_PRODUCTS_DIR}/flutter_inappwebview_ios/flutter_inappwebview_ios.framework", "${BUILT_PRODUCTS_DIR}/flutter_inappwebview_ios/flutter_inappwebview_ios.framework",
"${BUILT_PRODUCTS_DIR}/flutter_keyboard_visibility/flutter_keyboard_visibility.framework", "${BUILT_PRODUCTS_DIR}/flutter_keyboard_visibility/flutter_keyboard_visibility.framework",
@ -361,11 +369,7 @@
"${BUILT_PRODUCTS_DIR}/maps_launcher/maps_launcher.framework", "${BUILT_PRODUCTS_DIR}/maps_launcher/maps_launcher.framework",
"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
"${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework",
"${BUILT_PRODUCTS_DIR}/pointer_interceptor_ios/pointer_interceptor_ios.framework",
"${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
"${BUILT_PRODUCTS_DIR}/speech_to_text/speech_to_text.framework", "${BUILT_PRODUCTS_DIR}/speech_to_text/speech_to_text.framework",
"${BUILT_PRODUCTS_DIR}/sqflite_darwin/sqflite_darwin.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ZoomVideoSDK/CptShare/CptShare.framework/CptShare", "${PODS_XCFRAMEWORKS_BUILD_DIR}/ZoomVideoSDK/CptShare/CptShare.framework/CptShare",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ZoomVideoSDK/ZoomVideoSDK/ZoomVideoSDK.framework/ZoomVideoSDK", "${PODS_XCFRAMEWORKS_BUILD_DIR}/ZoomVideoSDK/ZoomVideoSDK/ZoomVideoSDK.framework/ZoomVideoSDK",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ZoomVideoSDK/zm_annoter_dynamic/zm_annoter_dynamic.framework/zm_annoter_dynamic", "${PODS_XCFRAMEWORKS_BUILD_DIR}/ZoomVideoSDK/zm_annoter_dynamic/zm_annoter_dynamic.framework/zm_annoter_dynamic",
@ -391,7 +395,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Try.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Try.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan2.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan2.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_keyboard_visibility.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_keyboard_visibility.framework",
@ -400,11 +403,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/maps_launcher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/maps_launcher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pointer_interceptor_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/speech_to_text.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/speech_to_text.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite_darwin.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CptShare.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CptShare.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZoomVideoSDK.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZoomVideoSDK.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/zm_annoter_dynamic.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/zm_annoter_dynamic.framework",
@ -748,6 +747,20 @@
defaultConfigurationName = Debug; defaultConfigurationName = Debug;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
isa = XCSwiftPackageProductDependency;
productName = FlutterGeneratedPluginSwiftPackage;
};
/* End XCSwiftPackageProductDependency section */
}; };
rootObject = 97C146E61CF9000F007C117D /* Project object */; rootObject = 97C146E61CF9000F007C117D /* Project object */;
} }

@ -5,6 +5,24 @@
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"> buildImplicitDependencies = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Prepare Flutter Framework Script"
scriptText = "/bin/sh &quot;$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh&quot; prepare&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries> <BuildActionEntries>
<BuildActionEntry <BuildActionEntry
buildForTesting = "YES" buildForTesting = "YES"

@ -1,5 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
///top manage the applicagtion safe to proceed or not
///if it is not true then the application will not proceed and will show a message to the user
bool isSafeDevice = true;
const MAX_SMALL_SCREEN = 660; const MAX_SMALL_SCREEN = 660;
const ONLY_NUMBERS = "[0-9]"; const ONLY_NUMBERS = "[0-9]";
const ONLY_LETTERS = "[a-zA-Z &'\"]"; const ONLY_LETTERS = "[a-zA-Z &'\"]";

@ -0,0 +1,150 @@
import 'package:doctor_app_flutter/core/service/talsec_config.dart';
import 'package:flutter/foundation.dart';
import 'package:freerasp/freerasp.dart';
import 'package:logger/logger.dart';
import 'package:doctor_app_flutter/config/config.dart' as config;
/// Enum to categorize threat severity levels
enum ThreatSeverity {
critical, // Block app usage
warning, // Log only, don't block
}
/// Model to track threat details
class ThreatEvent {
final String threatType;
final ThreatSeverity severity;
final DateTime timestamp;
final String? additionalInfo;
ThreatEvent({
required this.threatType,
required this.severity,
this.additionalInfo,
}) : timestamp = DateTime.now();
}
/// Callback type for critical threat detection
typedef OnCriticalThreatDetected = void Function();
/// Abstract class defining the security service interface
abstract class SecurityService {
/// Initialize and start the security monitoring
Future<void> initialize();
/// Check if device is currently safe
bool get isSafeDevice;
/// Get list of detected threats
List<ThreatEvent> get detectedThreats;
/// Set callback for when critical threat is detected
void setOnCriticalThreatCallback(OnCriticalThreatDetected callback);
}
/// Implementation of SecurityService using Talsec (freeRASP)
class SecurityServiceImpl implements SecurityService {
Logger logger = Logger(
printer: PrettyPrinter(
methodCount: 2,
errorMethodCount: 5,
lineLength: 1000,
colors: true,
printEmojis: true,
),
);
final List<ThreatEvent> _detectedThreats = [];
bool _isInitialized = false;
OnCriticalThreatDetected? _onCriticalThreatCallback;
SecurityServiceImpl();
@override
bool get isSafeDevice => config.isSafeDevice;
@override
List<ThreatEvent> get detectedThreats => [..._detectedThreats];
@override
Future<void> initialize() async {
if (_isInitialized) {
logger.d('SecurityService already initialized');
return;
}
try {
logger.d('Initializing SecurityService with Talsec');
// Start the RASP engine
await Talsec.instance.start(talsecConfig);
// Setup threat callbacks
final callback = ThreatCallback(
onAppIntegrity: () => _handleThreat('App Integrity', ThreatSeverity.critical),
onObfuscationIssues: () => _handleThreat('Obfuscation Issues', ThreatSeverity.warning),
onDebug: () => _handleThreat('Debug Mode', ThreatSeverity.critical),
onDeviceBinding: () => _handleThreat('Device Binding', ThreatSeverity.critical),
onDeviceID: () => _handleThreat('Device ID Mismatch', ThreatSeverity.critical),
onHooks: () => _handleThreat('Hooks Detected', ThreatSeverity.critical),
onPasscode: () => _handleThreat('Passcode Not Set', ThreatSeverity.warning),
onPrivilegedAccess: () => _handleThreat('Privileged Access (Root/Jailbreak)', ThreatSeverity.critical),
onSecureHardwareNotAvailable: () => _handleThreat('Secure Hardware Not Available', ThreatSeverity.warning),
onSimulator: () => _handleThreat('Simulator/Emulator Detected', ThreatSeverity.critical),
onSystemVPN: () => _handleThreat('System VPN Active', ThreatSeverity.warning),
onDevMode: () => _handleThreat('Developer Mode', ThreatSeverity.warning),
onADBEnabled: () => _handleThreat('USB Debugging Enabled', ThreatSeverity.warning),
onUnofficialStore: () => _handleThreat('Unofficial Store Installation', ThreatSeverity.critical),
onScreenshot: () => _handleThreat('Screenshot Detected', ThreatSeverity.warning),
onScreenRecording: () => _handleThreat('Screen Recording Active', ThreatSeverity.warning),
onMultiInstance: () => _handleThreat('Multiple Instances', ThreatSeverity.warning),
onLocationSpoofing: () => _handleThreat('Location Spoofing', ThreatSeverity.warning),
onTimeSpoofing: () => _handleThreat('Time Spoofing', ThreatSeverity.warning),
onAutomation: () => _handleThreat('Automation Detected', ThreatSeverity.warning),
onBootloader: () => _handleThreat('Unlocked Bootloader', ThreatSeverity.critical),
onMalware: (suspiciousApps) => _handleThreat('Malware/Suspicious Apps', ThreatSeverity.critical, additionalInfo: suspiciousApps.toString()),
);
Talsec.instance.attachListener(callback);
_isInitialized = true;
logger.d('SecurityService initialized successfully');
} catch (e) {
logger.e('Failed to initialize SecurityService: $e');
rethrow;
}
}
@override
void setOnCriticalThreatCallback(OnCriticalThreatDetected callback) {
_onCriticalThreatCallback = callback;
logger.d('Critical threat callback registered');
}
/// Handle detected threats with appropriate severity
void _handleThreat(String threatType, ThreatSeverity severity, {String? additionalInfo}) {
final threat = ThreatEvent(
threatType: threatType,
severity: severity,
additionalInfo: additionalInfo,
);
_detectedThreats.add(threat);
// Log to console
if (severity == ThreatSeverity.critical) {
logger.e('🔴 CRITICAL THREAT: $threatType ${additionalInfo != null ? "- $additionalInfo" : ""}');
} else {
logger.d('⚠️ WARNING: $threatType ${additionalInfo != null ? "- $additionalInfo" : ""}');
}
// Block app if critical threat
if (severity == ThreatSeverity.critical) {
config.isSafeDevice = false;
logger.e('Device marked as UNSAFE due to: $threatType');
_onCriticalThreatCallback?.call();
}
}
}

@ -0,0 +1,15 @@
import 'package:freerasp/freerasp.dart';
final talsecConfig = TalsecConfig(
androidConfig: AndroidConfig(
packageName: 'com.hmg.hmgDr',
signingCertHashes: ['uNLWc6Ces/bVOgSs5vxQtlHdNtDW8hoBxe4FypG697Y=', 'MP0tIs2hPii94DAsiU9Jy9oZJfsEQy0a0PrG0/qVQfo='], // Must be the release cert hash
supportedStores: ['com.android.vending'], // Google Play Store
),
iosConfig: IOSConfig(
bundleIds: ['com.hmg.hmgDr'], // iOS Bundle ID
teamId: '3A359E86ZF', // Found in Apple Developer portal
),
watcherMail: '', // Required to receive security alerts
isProd: true, // Enforces strict checks for release builds
);

@ -3,6 +3,7 @@ import 'package:doctor_app_flutter/core/service/home/scan_qr_service.dart';
import 'package:doctor_app_flutter/core/service/patient/profile/discharge_summary_servive.dart'; import 'package:doctor_app_flutter/core/service/patient/profile/discharge_summary_servive.dart';
import 'package:doctor_app_flutter/core/service/patient_medical_file/ER_signin/ER_signin_service.dart'; import 'package:doctor_app_flutter/core/service/patient_medical_file/ER_signin/ER_signin_service.dart';
import 'package:doctor_app_flutter/core/service/pending_order_service.dart'; import 'package:doctor_app_flutter/core/service/pending_order_service.dart';
import 'package:doctor_app_flutter/core/service/security_service.dart';
import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/dashboard_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/hospitals_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/medical_file_view_model.dart';
@ -155,4 +156,5 @@ void setupLocator() {
locator.registerFactory(() => InterventionMedicationViewModel()); locator.registerFactory(() => InterventionMedicationViewModel());
locator.registerFactory(() => ERSignInViewModel()); locator.registerFactory(() => ERSignInViewModel());
locator.registerFactory(() => PharmacyInterventionViewModel()); locator.registerFactory(() => PharmacyInterventionViewModel());
locator.registerFactory<SecurityService>(() => SecurityServiceImpl());
} }

@ -11,14 +11,19 @@ import 'package:doctor_app_flutter/core/viewModel/livecare_view_model.dart';
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart'; import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
import 'package:doctor_app_flutter/locator.dart'; import 'package:doctor_app_flutter/locator.dart';
import 'package:doctor_app_flutter/routes.dart'; import 'package:doctor_app_flutter/routes.dart';
import 'package:doctor_app_flutter/unsafe_device.dart';
import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart'; import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:timezone/data/latest_all.dart' as tz; import 'package:timezone/data/latest_all.dart' as tz;
import 'core/service/security_service.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(); await Firebase.initializeApp();
@ -26,6 +31,24 @@ void main() async {
setupLocator(); setupLocator();
await clearPrefsOnFirstLaunch(); await clearPrefsOnFirstLaunch();
tz.initializeTimeZones(); tz.initializeTimeZones();
if (!kReleaseMode) {
await locator.get<SecurityService>().initialize();
// Set up critical threat callback to navigate to unsafe device page
locator.get<SecurityService>().setOnCriticalThreatCallback(() {
final navigationService = locator.get<NavigationService>();
final context = navigationService.navigatorKey.currentContext;
if (context != null) {
// Clear entire navigation stack and show unsafe device page
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (_) => const UnsafeDevice()),
(route) => false, // Remove all previous routes
);
debugPrint('🚨 Navigated to UnsafeDevice page - Critical threat detected');
}
});
}
runApp(MyApp()); runApp(MyApp());
} }
@ -43,42 +66,36 @@ class MyApp extends StatelessWidget {
return LayoutBuilder( return LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
return OrientationBuilder(builder: (context, orientation) { return OrientationBuilder(
SizeConfig().init(constraints, orientation); builder: (context, orientation) {
return MultiProvider( SizeConfig().init(constraints, orientation);
providers: [ return MultiProvider(
ChangeNotifierProvider<AuthenticationViewModel>(create: (context) => AuthenticationViewModel()), providers: [
ChangeNotifierProvider<ProjectViewModel>( ChangeNotifierProvider<AuthenticationViewModel>(create: (context) => AuthenticationViewModel()),
create: (context) => ProjectViewModel(), ChangeNotifierProvider<ProjectViewModel>(create: (context) => ProjectViewModel()),
), ChangeNotifierProvider<LiveCareViewModel>(create: (context) => LiveCareViewModel()),
ChangeNotifierProvider<LiveCareViewModel>( StreamProvider.value(value: RobotProvider().intStream(), initialData: RobotProvider().setValue({})),
create: (context) => LiveCareViewModel(), ],
), child: Consumer<ProjectViewModel>(
StreamProvider.value( builder: (context, projectProvider, child) => SafeArea(
value: RobotProvider().intStream(), top: false,
initialData: RobotProvider().setValue({}), bottom: Platform.isAndroid ? true : false,
) child: MaterialApp(
], showSemanticsDebugger: false,
child: Consumer<ProjectViewModel>( title: 'Doctors App',
builder: (context, projectProvider, child) => SafeArea( locale: projectProvider.appLocal,
top: false, localizationsDelegates: [
bottom: Platform.isAndroid ? true : false, TranslationBaseDelegate(),
child: MaterialApp( GlobalMaterialLocalizations.delegate,
showSemanticsDebugger: false, GlobalWidgetsLocalizations.delegate,
title: 'Doctors App', GlobalCupertinoLocalizations.delegate,
locale: projectProvider.appLocal, DefaultCupertinoLocalizations.delegate,
localizationsDelegates: [ ],
TranslationBaseDelegate(), supportedLocales: [
GlobalMaterialLocalizations.delegate, const Locale('ar', ''), // Arabic
GlobalWidgetsLocalizations.delegate, const Locale('en', ''), // English
GlobalCupertinoLocalizations.delegate, ],
DefaultCupertinoLocalizations.delegate theme: ThemeData(
],
supportedLocales: [
const Locale('ar', ''), // Arabic
const Locale('en', ''), // English
],
theme: ThemeData(
primarySwatch: Colors.grey, primarySwatch: Colors.grey,
primaryColor: Colors.grey, primaryColor: Colors.grey,
//buttonColor: HexColor('#D02127'), //buttonColor: HexColor('#D02127'),
@ -86,19 +103,19 @@ class MyApp extends StatelessWidget {
dividerColor: Colors.grey[350], dividerColor: Colors.grey[350],
// backgroundColor: Color.fromRGBO(255, 255, 255, 1), // backgroundColor: Color.fromRGBO(255, 255, 255, 1),
useMaterial3: false), useMaterial3: false,
navigatorKey: locator<NavigationService>().navigatorKey, ),
navigatorObservers: [ navigatorKey: locator<NavigationService>().navigatorKey,
locator<AnalyticsService>().getAnalyticsObserver(), navigatorObservers: [locator<AnalyticsService>().getAnalyticsObserver()],
], initialRoute: INIT_ROUTE,
initialRoute: INIT_ROUTE, routes: routes,
routes: routes, debugShowCheckedModeBanner: false,
debugShowCheckedModeBanner: false, ),
), ),
), ),
), );
); },
}); );
}, },
); );
} }

@ -100,7 +100,7 @@ class _DoctorReplayChatState extends State<DoctorReplayChat> {
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
}, },
child: Icon(FontAwesomeIcons.times, child: Icon(FontAwesomeIcons.times.data,
size: 30, size: 30,
color: Color(0xFF2B353E))) color: Color(0xFF2B353E)))
], ],
@ -522,7 +522,7 @@ class _DoctorReplayChatState extends State<DoctorReplayChat> {
.typeHereToReply, .typeHereToReply,
fontSize: 13.5, fontSize: 13.5,
suffixIcon: suffixIcon:
FontAwesomeIcons.arrowRight, FontAwesomeIcons.arrowRight.data,
suffixIconColor: suffixIconColor:
AppGlobal.appGreenColor, AppGlobal.appGreenColor,
onSuffixTap: () async { onSuffixTap: () async {

@ -109,7 +109,7 @@ class _InPatientListPageState extends State<InPatientListPage> {
widget.selectedClinicName ?? TranslationBase.of(context).clinicSelect, widget.selectedClinicName ?? TranslationBase.of(context).clinicSelect,
fontSize: 15, fontSize: 15,
), ),
Container(margin: EdgeInsets.only(bottom: 10), child: Icon(FontAwesomeIcons.sortDown)) Container(margin: EdgeInsets.only(bottom: 10), child: Icon(FontAwesomeIcons.sortDown.data))
], ],
)), )),
], ],
@ -126,9 +126,9 @@ class _InPatientListPageState extends State<InPatientListPage> {
marginTop: widget.isMyInPatient ? 15 : 5, marginTop: widget.isMyInPatient ? 15 : 5,
positionedChild: IconButton( positionedChild: IconButton(
icon: Icon( icon: Icon(
isSortDes ? FontAwesomeIcons.sortAmountDown : FontAwesomeIcons.sortAmountUp, isSortDes ? FontAwesomeIcons.sortAmountDown.data : FontAwesomeIcons.sortAmountUp.data,
color: Colors.black, color: Colors.black,
), ),
iconSize: 20, iconSize: 20,
// padding: EdgeInsets.only(bottom: 30), // padding: EdgeInsets.only(bottom: 30),
onPressed: () { onPressed: () {

@ -107,8 +107,8 @@ class _ReferralDischargedPatientPageState
clinicDescription: model clinicDescription: model
.myDischargeReferralPatient[index] .myDischargeReferralPatient[index]
.referringClinicDescription!, .referringClinicDescription!,
infoIcon: Icon(FontAwesomeIcons.arrowRight, infoIcon: Icon(FontAwesomeIcons.arrowRight.data,
size: 25, color: Colors.black), size: 25, color: Colors.black),
), ),
)), )),
), ),

@ -167,7 +167,7 @@ class _OutPatientsScreenState extends State<OutPatientsScreen> {
marginTop: 5, marginTop: 5,
suffixIcon: IconButton( suffixIcon: IconButton(
icon: Icon( icon: Icon(
_activeLocation != 0 ? DoctorApp.filter_1 : FontAwesomeIcons.slidersH, _activeLocation != 0 ? DoctorApp.filter_1 : FontAwesomeIcons.slidersH.data,
color: Colors.black, color: Colors.black,
), ),
iconSize: 20, iconSize: 20,
@ -187,7 +187,7 @@ class _OutPatientsScreenState extends State<OutPatientsScreen> {
), ),
positionedChild: IconButton( positionedChild: IconButton(
icon: Icon( icon: Icon(
isSortDes ? FontAwesomeIcons.sortAmountDown : FontAwesomeIcons.sortAmountUp, isSortDes ? FontAwesomeIcons.sortAmountDown.data : FontAwesomeIcons.sortAmountUp.data,
color: Colors.black, color: Colors.black,
), ),
iconSize: 20, iconSize: 20,

@ -237,7 +237,7 @@ class _ProgressNoteState extends State<ProgressNoteScreen> {
child: Row( child: Row(
children: [ children: [
Icon( Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 12, size: 12,
color: Colors.white, color: Colors.white,
), ),
@ -289,13 +289,13 @@ class _ProgressNoteState extends State<ProgressNoteScreen> {
), ),
// color:Colors.red[600], // color:Colors.red[600],
child: Row( child: Row(
children: [ children: [
Icon( Icon(
FontAwesomeIcons.trash, FontAwesomeIcons.trash.data,
size: 12, size: 12,
color: Colors.white, color: Colors.white,
), ),
SizedBox( SizedBox(
width: 2, width: 2,
), ),

@ -113,7 +113,7 @@ class _ReferredPatientScreenState extends State<ReferredPatientScreen> {
doctorAvatar: model.getReferredPatientItem(index).doctorImageURL!, doctorAvatar: model.getReferredPatientItem(index).doctorImageURL!,
referralDoctorName: "${TranslationBase.of(context).dr} ${model.getReferredPatientItem(index).referralDoctorName}", referralDoctorName: "${TranslationBase.of(context).dr} ${model.getReferredPatientItem(index).referralDoctorName}",
clinicDescription: model.getReferredPatientItem(index).referralClinicDescription!, clinicDescription: model.getReferredPatientItem(index).referralClinicDescription!,
infoIcon: Icon(FontAwesomeIcons.arrowRight, size: 25, color: Colors.black), infoIcon: Icon(FontAwesomeIcons.arrowRight.data, size: 25, color: Colors.black),
), ),
); );
}, },

@ -105,7 +105,7 @@ class _MyReferralInPatientScreenState extends State<MyReferralInPatientScreen> {
doctorAvatar: model.myReferralPatients[index].doctorImageURL!, doctorAvatar: model.myReferralPatients[index].doctorImageURL!,
referralDoctorName: model.myReferralPatients[index].referringDoctorName!, referralDoctorName: model.myReferralPatients[index].referringDoctorName!,
clinicDescription: model.myReferralPatients[index].referringClinicDescription!, clinicDescription: model.myReferralPatients[index].referringClinicDescription!,
infoIcon: Icon(FontAwesomeIcons.arrowRight, size: 25, color: Colors.black), infoIcon: Icon(FontAwesomeIcons.arrowRight.data, size: 25, color: Colors.black),
), ),
); );
}) })

@ -51,7 +51,7 @@ class ExpandableSOAPWidget extends StatelessWidget {
), ),
if (isRequired) if (isRequired)
Icon( Icon(
FontAwesomeIcons.asterisk, FontAwesomeIcons.asterisk.data,
size: SizeConfig.getTextMultiplierBasedOnWidth() * 2.5, size: SizeConfig.getTextMultiplierBasedOnWidth() * 2.5,
) )
], ],

@ -25,11 +25,11 @@ class RemoveButton extends StatelessWidget {
letterSpacing: -0.48, letterSpacing: -0.48,
), ),
), ),
Icon( Icon(
FontAwesomeIcons.times, FontAwesomeIcons.times.data,
color: HexColor("#D02127"), color: HexColor("#D02127"),
size: SizeConfig.getTextMultiplierBasedOnWidth() * 4, size: SizeConfig.getTextMultiplierBasedOnWidth() * 4,
), ),
], ],
), ),
onTap: onTap, onTap: onTap,

@ -80,7 +80,7 @@ class StepsWidget extends StatelessWidget {
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),
@ -128,7 +128,7 @@ class StepsWidget extends StatelessWidget {
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),
@ -179,22 +179,22 @@ class StepsWidget extends StatelessWidget {
? AppGlobal.appGreenColor ? AppGlobal.appGreenColor
: Color(0xFFCCCCCC), : Color(0xFFCCCCCC),
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),
), ),
SizedBox( SizedBox(
height: 5, height: 5,
), ),
Column( Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
StepDetailsWidget( StepDetailsWidget(
stepLabel: "Assessment", stepLabel: "Assessment",
), ),
StatusLabel( StatusLabel(
selectedStepId: index, selectedStepId: index,
stepId: 2, stepId: 2,
@ -230,7 +230,7 @@ class StepsWidget extends StatelessWidget {
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),
@ -302,7 +302,7 @@ class StepsWidget extends StatelessWidget {
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),
@ -349,7 +349,7 @@ class StepsWidget extends StatelessWidget {
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),
@ -395,23 +395,23 @@ class StepsWidget extends StatelessWidget {
? Color(0xFFCC9B14) ? Color(0xFFCC9B14)
: Color(0xFFCCCCCC), : Color(0xFFCCCCCC),
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),
), ),
SizedBox( SizedBox(
height: 5, height: 5,
), ),
Padding( Padding(
padding: const EdgeInsets.only(right: 2), padding: const EdgeInsets.only(right: 2),
child: Column( child: Column(
children: [ children: [
StepDetailsWidget( StepDetailsWidget(
stepLabel: "تقدير", stepLabel: "تقدير",
), ),
StatusLabel( StatusLabel(
selectedStepId: index, selectedStepId: index,
stepId: 2, stepId: 2,
@ -450,7 +450,7 @@ class StepsWidget extends StatelessWidget {
), ),
child: Center( child: Center(
child: Icon( child: Icon(
FontAwesomeIcons.check, FontAwesomeIcons.check.data,
size: 20, size: 20,
color: Colors.white, color: Colors.white,
)), )),

@ -8,8 +8,13 @@ import 'package:doctor_app_flutter/screens/auth/login_screen.dart';
import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart'; import 'package:doctor_app_flutter/screens/auth/verification_methods_screen.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:safe_device/safe_device.dart';
import '../../core/service/NavigationService.dart';
import '../../unsafe_device.dart' show UnsafeDevice;
class SplashScreen extends StatefulWidget { class SplashScreen extends StatefulWidget {
@override @override
_SplashScreenState createState() => _SplashScreenState(); _SplashScreenState createState() => _SplashScreenState();
@ -18,17 +23,44 @@ class SplashScreen extends StatefulWidget {
class _SplashScreenState extends State<SplashScreen> { class _SplashScreenState extends State<SplashScreen> {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
late AuthenticationViewModel _authViewModel; late AuthenticationViewModel _authViewModel;
bool isJailBroken = false;
bool isRealDevice = true;
bool isDevelopmentModeEnable = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
AppGlobal.CONTEX = context; AppGlobal.CONTEX = context;
if (!kReleaseMode) {
checkDeviceSafety();
}
Timer(Duration(seconds: 2, milliseconds: 500), () async {
if (isJailBroken || !isRealDevice || !isSafeDevice) {
// Critical threat detected - navigate to unsafe device page
Navigator.of(locator.get<NavigationService>().navigatorKey.currentContext!).pushAndRemoveUntil(
MaterialPageRoute(builder: (_) => const UnsafeDevice()),
(route) => false, // Remove all previous routes
);
}else {
_initializeApp();
}
});
}
_initializeApp(); void checkDeviceSafety() {
try {
SafeDevice.isJailBroken.then((bool value) {
isJailBroken = value;
});
SafeDevice.isJailBrokenCustom.then((bool value) {
isJailBroken = value;
});
SafeDevice.isRealDevice.then((value) {
isRealDevice = value;
});
} catch (error) {
print(error);
}
} }
Future<void> _initializeApp() async { Future<void> _initializeApp() async {

@ -0,0 +1,117 @@
import 'package:doctor_app_flutter/core/service/security_service.dart';
import 'package:flutter/material.dart';
import 'package:freerasp/freerasp.dart';
import 'package:http/http.dart' as getIt;
import 'locator.dart';
class UnsafeDevice extends StatefulWidget {
const UnsafeDevice({super.key});
@override
State<UnsafeDevice> createState() => _UnsafeDeviceState();
}
class _UnsafeDeviceState extends State<UnsafeDevice> {
@override
void initState() {
Talsec.instance.detachListener();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Logo
Center(
child: Image.asset('assets/images/dr_app_logo.png'),
),
SizedBox(height: 32),
// Warning Icon
Icon(
Icons.security,
size: 80,
color: Color(0xFFED1C2B),
),
SizedBox(height: 24),
// Title
Text(
'Unsafe Device Detected',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Color(0xFFED1C2B),
),
textAlign: TextAlign.center,
),
SizedBox(height: 16),
// Description
Text(
'For your security, this app cannot run on devices with security vulnerabilities. is ssss',
style: TextStyle(
fontSize: 16,
color: Colors.black87,
),
textAlign: TextAlign.center,
),
SizedBox(height: 24),
if (locator.get<SecurityService>().detectedThreats.isNotEmpty) ...[
Text(
'Detected Issues:',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
SizedBox(height: 8),
Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.red.withOpacity(0.3)),
),
child: Column(
children: locator
.get<SecurityService>()
.detectedThreats
.where((t) => t.severity == ThreatSeverity.critical)
.take(5) // Show max 5 threats
.map((threat) => Padding(
padding: EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Icon(Icons.error_outline, size: 16, color: Colors.red),
SizedBox(width: 8),
Expanded(
child: Text(
threat.threatType,
style: TextStyle(fontSize: 12),
),
),
],
),
))
.toList(),
),
),
SizedBox(height: 24),
],
],
),
),
),
);
}
}

@ -121,14 +121,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.1" version: "4.0.1"
build_modules:
dependency: transitive
description:
name: build_modules
sha256: "0126ba5111c4b8f5b1f557beb23eb0bd9266f9114199ff42d9270c29c997b1be"
url: "https://pub.dev"
source: hosted
version: "5.0.18"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
@ -157,10 +149,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_web_compilers name: build_web_compilers
sha256: e93b5d5af529269f52b691f7542d859fba82982cadec23b19680c15c70f65378 sha256: c8be4b48f09289d145c7eaa3240f1e7776c529ea1cecddf483218edd3129de3f
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.3.0" version: "4.8.0"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
@ -205,10 +197,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.1"
charts_common: charts_common:
dependency: transitive dependency: transitive
description: description:
@ -373,10 +365,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: eva_icons_flutter name: eva_icons_flutter
sha256: "6d48a10b93590ab83eb092bee5adacdeb14f3d83f527a4b9e4092c363d56e2a8" sha256: d87ed92f8ec1cd4b6a3100c34a644e201758900a3bc64f4bf3e0f39ec297093c
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.0" version: "4.0.0"
events_emitter: events_emitter:
dependency: transitive dependency: transitive
description: description:
@ -413,10 +405,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: file name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.0" version: "7.0.1"
file_picker: file_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -769,10 +761,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: font_awesome_flutter name: font_awesome_flutter
sha256: "275ff26905134bcb59417cf60ad979136f1f8257f2f449914b2c3e05bbb4cd6f" sha256: "09dcde8ab90ffae1a7d65ff2ef96fc62a17ad9d0ce7c127b317ded676b0d5935"
url: "https://pub.dev"
source: hosted
version: "11.0.0"
freerasp:
dependency: "direct main"
description:
name: freerasp
sha256: afba9e2ec1b578450701345230e87fda54e95c2f448154fbca55cf993f1ab2b3
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.7.0" version: "8.2.1"
frontend_server_client: frontend_server_client:
dependency: transitive dependency: transitive
description: description:
@ -1057,26 +1057,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.17" version: "0.12.19"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.11.1" version: "0.13.0"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.0" version: "1.18.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -1373,14 +1373,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.27.7" version: "0.27.7"
safe_device:
dependency: "direct main"
description:
name: safe_device
sha256: ad1b32a564484c710f6d52b5a526838c8a7d999c8ab2e14890ff55c06a018248
url: "https://pub.dev"
source: hosted
version: "1.4.1"
scratch_space: scratch_space:
dependency: transitive dependency: transitive
description: description:
name: scratch_space name: scratch_space
sha256: "8510fbff458d733a58fc427057d1ac86303b376d609d6e1bc43f240aad9aa445" sha256: "55f141cf286eca871f739518b689af61cb994d671f3fd8efabd63aba7578c309"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.2.2"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1598,10 +1606,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.7" version: "0.7.11"
timezone: timezone:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1819,5 +1827,5 @@ packages:
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
sdks: sdks:
dart: ">=3.8.0-0 <3.11.0-z" dart: ">=3.10.0-0 <3.13.0-z"
flutter: ">=3.29.0" flutter: ">=3.29.0"

@ -52,8 +52,8 @@ dependencies:
#flutter_swiper: ^1.1.6 #flutter_swiper: ^1.1.6
flutter_swiper_view: ^1.1.8 flutter_swiper_view: ^1.1.8
#Icons #Icons
eva_icons_flutter: ^3.1.0 eva_icons_flutter: ^4.0.0
font_awesome_flutter: ^10.6.0 font_awesome_flutter: ^11.0.0
dropdown_search: ^5.0.6 dropdown_search: ^5.0.6
flutter_staggered_grid_view: ^0.7.0 flutter_staggered_grid_view: ^0.7.0
@ -141,6 +141,8 @@ dependencies:
two_dimensional_scrollables: ^0.3.3 two_dimensional_scrollables: ^0.3.3
timezone: ^0.10.1 timezone: ^0.10.1
logger: ^2.6.1 logger: ^2.6.1
freerasp: ^8.2.1
safe_device: ^1.4.1
dependency_overrides: dependency_overrides:
flutter_localizations: flutter_localizations:

Loading…
Cancel
Save