chore: أرشفة تطبيقات ولوحات تريبز التي سيحلّ محلها كود سيرو
استكمال قرار 2026-07-27 (كوميت fff76c9 أرشف الباك إند):
apps/rider → apps/rider-archive-cubit
apps/driver → apps/driver-archive-cubit
dashboards/admin-web → dashboards/admin-web-archive
dashboards/service-web → dashboards/service-web-archive
إعادة تسمية بلا تعديل محتوى. rider/driver كانا إعادة بناء Cubit مبنية على
عقد NestJS المؤرشف. admin-web و service-web نموذجان بملف HTML واحد (164 و
128 سطراً) — يحلّ محلهما siro_admin و siro_service المكتملان.
يُحمل من المؤرشف ولا يُعاد اكتشافه: عقد map-saas المثبَّت بالتجربة في
apps/rider-archive-cubit/lib/core/api/ (x-api-key ترويسة، reverse مصفوفة،
route في points) ودرس مسار FCM.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@@ -1,139 +0,0 @@
|
||||
|
||||
import UIKit
|
||||
import Flutter
|
||||
import FirebaseCore
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
|
||||
FirebaseApp.configure()
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
|
||||
// Perform security checks *before* showing the main UI
|
||||
if SecurityChecks.isDeviceCompromised() { // Call Objective-C method
|
||||
showSecurityAlert()
|
||||
return false // Prevent app from launching further
|
||||
}
|
||||
//setup method channel
|
||||
setupMethodChannel()
|
||||
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
func setupMethodChannel(){
|
||||
guard let controller = window?.rootViewController as? FlutterViewController else {
|
||||
return
|
||||
}
|
||||
|
||||
let channel = FlutterMethodChannel(name: "com.mobileapp.store.ride/security",
|
||||
binaryMessenger: controller.binaryMessenger)
|
||||
channel.setMethodCallHandler { call, result in
|
||||
switch call.method {
|
||||
case "isNativeRooted":
|
||||
// We already check this in isDeviceCompromised,
|
||||
// so we can just return the result directly.
|
||||
result(SecurityChecks.isDeviceCompromised())
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func showSecurityAlert() {
|
||||
guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else {
|
||||
// Handle the case where rootVC is nil (extremely unlikely, but good practice)
|
||||
exit(0)
|
||||
// return
|
||||
}
|
||||
|
||||
let alert = UIAlertController(
|
||||
title: "Security Warning".localized, // Use localized strings!
|
||||
message: "Compromised device detected. Exiting.".localized,
|
||||
preferredStyle: .alert
|
||||
)
|
||||
|
||||
// Add an "OK" button with an obfuscated action
|
||||
alert.addAction(UIAlertAction(title: "OK".localized, style: .destructive) { _ in
|
||||
// More robust exit (see explanation below)
|
||||
self.obfuscatedExit()
|
||||
})
|
||||
|
||||
// Use a presentationDetents to prevent dismissing
|
||||
if #available(iOS 15.0, *) {
|
||||
alert.popoverPresentationController?.sourceView = rootVC.view
|
||||
alert.popoverPresentationController?.sourceRect = CGRect(x: rootVC.view.bounds.midX, y: rootVC.view.bounds.midY, width: 0, height: 0)
|
||||
alert.popoverPresentationController?.permittedArrowDirections = []
|
||||
alert.presentationController?.delegate = self
|
||||
if let presentationController = alert.presentationController as? UISheetPresentationController {
|
||||
presentationController.detents = [.medium()] // Set a fixed height if desired
|
||||
presentationController.preferredCornerRadius = 20;
|
||||
presentationController.prefersEdgeAttachedInCompactHeight = true;// Set corner radius
|
||||
presentationController.prefersGrabberVisible = false // Optional: show a grabber
|
||||
}
|
||||
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
rootVC.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
// Obfuscated Exit (Example - you'll need a more robust solution)
|
||||
func obfuscatedExit() {
|
||||
// This is a *very* basic example. A real obfuscation would be MUCH more complex.
|
||||
let selector = NSSelectorFromString(String(format: "%@%@", "ex", "it:"))
|
||||
if responds(to: selector) {
|
||||
perform(selector, with: 0) // Call exit(0) indirectly
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Secure API Key Storage (Example)
|
||||
func getAPIKey() -> String {
|
||||
// DO NOT store API keys directly in your code!
|
||||
// Load it from a more secure location, such as:
|
||||
// 1. A configuration file that is *not* checked into source control.
|
||||
// 2. Keychain Services (recommended for iOS).
|
||||
// 3. A backend server (best option).
|
||||
|
||||
// This is just a placeholder. Replace with your actual key loading.
|
||||
// In a real app, you'd fetch this from a secure source.
|
||||
guard let filePath = Bundle.main.path(forResource: "keys", ofType: "plist"),
|
||||
let plist = NSDictionary(contentsOfFile: filePath),
|
||||
let apiKey = plist["google_maps_api_key"] as? String else {
|
||||
fatalError("Couldn't find keys or API Key") // Ensure a crash if not found
|
||||
}
|
||||
|
||||
return apiKey
|
||||
}
|
||||
func loadConfig() -> [String: Any]? {
|
||||
guard let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
|
||||
let config = NSDictionary(contentsOfFile: path) as? [String: Any] else {
|
||||
return nil // Or handle the error appropriately
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// Add for prevent dismissing
|
||||
extension AppDelegate: UIAdaptivePresentationControllerDelegate {
|
||||
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Add String extension
|
||||
extension String {
|
||||
var localized: String {
|
||||
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
{
|
||||
"images": [
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-20x20@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-20x20@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-29x29@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-29x29@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-29x29@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-40x40@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-40x40@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"size": "57x57",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-57x57@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "57x57",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-57x57@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "60x60",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-60x60@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "60x60",
|
||||
"idiom": "iphone",
|
||||
"filename": "Icon-App-60x60@3x.png",
|
||||
"scale": "3x"
|
||||
},
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-20x20@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-20x20@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-29x29@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-29x29@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-40x40@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-40x40@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "50x50",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-50x50@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "50x50",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-50x50@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "72x72",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-72x72@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "72x72",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-72x72@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "76x76",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-76x76@1x.png",
|
||||
"scale": "1x"
|
||||
},
|
||||
{
|
||||
"size": "76x76",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-76x76@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "83.5x83.5",
|
||||
"idiom": "ipad",
|
||||
"filename": "Icon-App-83.5x83.5@2x.png",
|
||||
"scale": "2x"
|
||||
},
|
||||
{
|
||||
"size": "1024x1024",
|
||||
"idiom": "ios-marketing",
|
||||
"filename": "Icon-App-1024x1024@1x.png",
|
||||
"scale": "1x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 376 KiB |
|
Before Width: | Height: | Size: 679 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 26 KiB |
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "background.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 69 B |
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "LaunchImage.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 78 KiB |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon_share.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon_support.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon_user.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon_wallet.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 5.0 KiB |
@@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" image="LaunchBackground" translatesAutoresizingMaskIntoConstraints="NO" id="tWc-Dq-wcI"/>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"></imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="3T2-ad-Qdv"/>
|
||||
<constraint firstItem="tWc-Dq-wcI" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="RPx-PI-7Xg"/>
|
||||
<constraint firstItem="tWc-Dq-wcI" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="SdS-ul-q2q"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tWc-Dq-wcI" secondAttribute="trailing" id="Swv-Gf-Rwn"/>
|
||||
<constraint firstAttribute="trailing" secondItem="YRO-k0-Ey4" secondAttribute="trailing" id="TQA-XW-tRk"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="duK-uY-Gun"/>
|
||||
<constraint firstItem="tWc-Dq-wcI" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="kV7-tw-vXt"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="xPn-NY-SIU"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="512" height="279"/>
|
||||
<image name="LaunchBackground" width="1" height="1"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>APIKey</key>
|
||||
<string>AIzaSyCf2mW2h0HD8ZYjwh4VOa2ladw6MJkCDTM</string>
|
||||
<key>Environment</key>
|
||||
<string>development</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,12 +0,0 @@
|
||||
//
|
||||
// Constants1.swift
|
||||
// Runner
|
||||
//
|
||||
// Created by Hamza Aleghwairyeen on 20/02/2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct Constants {
|
||||
static let googleMapsAPIKey = "AIzaSyD0a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q"
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>googlechromes</string>
|
||||
<string>comgooglemaps</string>
|
||||
</array>
|
||||
<key>NSContactsUsageDescription</key>
|
||||
<string>This app requires contacts access to function properly.</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>12.0</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>com.googleusercontent.apps.594687661098-8e26699cris2k3nj5msj1osi59it9kpf</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Tripz</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Tripz</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>106</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>5.0.996</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>FirebaseAppDelegateProxyEnabled</key>
|
||||
<string>NO</string>
|
||||
<key>GMSApiKey</key>
|
||||
<string>YOUR_API_KEY</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string></string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Sovo app requires access to your camera in order to scan QR codes and capture images for uploading and access to connect to a call.</string>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>Use Face ID to securely authenticate payment accounts.</string>
|
||||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
<string>This app needs access to your location to provide you with the best ride experience. Your location data will be used to find the nearest available cars and connect you with the closest captain for efficient and convenient rides.</string>
|
||||
<key>NSLocationAlwaysUsageDescription</key>
|
||||
<string>This app needs access to location.</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>This app needs access to your location to provide you with the best ride experience. Your location data will be used to find the nearest available cars and connect you with the closest captain for efficient and convenient rides.</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>This app requires access to your microphone to record audio, allowing you to add voice recordings to your photos and videos and access to connect to a call.</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>Explanation of why your app needs access to the photo library.</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>fetch</string>
|
||||
<string>location</string>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// JailbreakDetection.swift
|
||||
// Runner
|
||||
//
|
||||
// Created by Hamza Aleghwairyeen on 15/02/2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class JailbreakDetection {
|
||||
static func isJailbroken() -> Bool {
|
||||
let paths = [
|
||||
"/Applications/Cydia.app",
|
||||
"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
||||
"/usr/sbin/sshd",
|
||||
"/etc/apt"
|
||||
]
|
||||
for path in paths {
|
||||
if FileManager.default.fileExists(atPath: path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
//
|
||||
// KeychainHelper.swift
|
||||
// Runner
|
||||
//
|
||||
// Created by Hamza Aleghwairyeen on 12/03/2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Security
|
||||
|
||||
class KeychainHelper {
|
||||
static let shared = KeychainHelper()
|
||||
|
||||
private init() {}
|
||||
|
||||
// حفظ البيانات في Keychain
|
||||
func save(key: String, value: String) {
|
||||
let data = value.data(using: .utf8)!
|
||||
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrAccount as String: key,
|
||||
kSecValueData as String: data,
|
||||
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
|
||||
]
|
||||
|
||||
SecItemDelete(query as CFDictionary) // حذف أي قيمة قديمة بنفس المفتاح
|
||||
SecItemAdd(query as CFDictionary, nil) // إضافة القيمة الجديدة
|
||||
}
|
||||
|
||||
// استرجاع البيانات من Keychain
|
||||
func get(key: String) -> String? {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrAccount as String: key,
|
||||
kSecReturnData as String: kCFBooleanTrue!,
|
||||
kSecMatchLimit as String: kSecMatchLimitOne
|
||||
]
|
||||
|
||||
var dataTypeRef: AnyObject?
|
||||
let status = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
|
||||
|
||||
guard status == errSecSuccess, let data = dataTypeRef as? Data else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return String(data: data, encoding: .utf8)
|
||||
}
|
||||
|
||||
// حذف البيانات من Keychain
|
||||
func delete(key: String) {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrAccount as String: key
|
||||
]
|
||||
|
||||
SecItemDelete(query as CFDictionary)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
//
|
||||
// Localizable.strings
|
||||
// Runner
|
||||
//
|
||||
// Created by Hamza Aleghwairyeen on 12/03/2025.
|
||||
//
|
||||
|
||||
"Security Warning" = "تحذير أمني";
|
||||
"Compromised device detected. Exiting." = "تم اكتشاف جهاز مُخترق. جارٍ الخروج.";
|
||||
"OK" = "موافق";
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>destination</key>
|
||||
<string>export</string>
|
||||
<key>method</key>
|
||||
<string>release-testing</string>
|
||||
<key>signingStyle</key>
|
||||
<string>automatic</string>
|
||||
<key>stripSwiftSymbols</key>
|
||||
<true/>
|
||||
<key>teamID</key>
|
||||
<string>63CVT8G5P8</string>
|
||||
<key>thinning</key>
|
||||
<string><none></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,2 +0,0 @@
|
||||
#import "GeneratedPluginRegistrant.h"
|
||||
#import "SecurityChecks.h"
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.applesignin</key>
|
||||
<array>
|
||||
<string>Default</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// SecurityChecks.h
|
||||
// Runner
|
||||
//
|
||||
// Created by Hamza Aleghwairyeen on 12/03/2025.
|
||||
//
|
||||
|
||||
//#ifndef SecurityChecks_h
|
||||
//#define SecurityChecks_h
|
||||
//
|
||||
//
|
||||
//#endif /* SecurityChecks_h */
|
||||
|
||||
|
||||
|
||||
// SecurityChecks.h
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h> // Import UIKit
|
||||
|
||||
@interface SecurityChecks : NSObject
|
||||
|
||||
+ (BOOL)isDeviceCompromised; // Combined check
|
||||
|
||||
@end
|
||||
@@ -1,197 +0,0 @@
|
||||
//
|
||||
// SecurityChecks.m
|
||||
// Runner
|
||||
//
|
||||
// Created by Hamza Aleghwairyeen on 12/03/2025.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
|
||||
#import "SecurityChecks.h"
|
||||
#import <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#import <sys/sysctl.h>
|
||||
#include <mach-o/dyld.h> // For _dyld_image_count and _dyld_get_image_name
|
||||
#include <unistd.h> // for fork()
|
||||
#include <sys/socket.h> //for socket, connect
|
||||
#include <netinet/in.h> // for sockaddr_in
|
||||
#include <arpa/inet.h> // for inet_pton
|
||||
|
||||
@implementation SecurityChecks
|
||||
|
||||
+ (BOOL)isDeviceJailbroken {
|
||||
// (Same jailbreak checks as before - from previous responses)
|
||||
// 1. Check for common jailbreak files
|
||||
NSArray *jailbreakPaths = @[
|
||||
@"/Applications/Cydia.app",
|
||||
// #if !TARGET_IPHONE_SIMULATOR
|
||||
// @"/bin/bash",
|
||||
// #endif
|
||||
@"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
||||
@"/bin/bash",
|
||||
@"/usr/sbin/sshd",
|
||||
@"/etc/apt",
|
||||
@"/private/var/lib/apt/",
|
||||
@"/private/var/tmp/cydia.log",
|
||||
];
|
||||
|
||||
for (NSString *path in jailbreakPaths) {
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
|
||||
NSLog(@"Jailbreak file detected: %@", path);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Check if we can write outside the sandbox (a strong indicator)
|
||||
NSError *error = nil;
|
||||
NSString *testPath = @"/private/jailbreaktest.txt";
|
||||
[@"test" writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
|
||||
|
||||
if (!error) {
|
||||
// If we can write, it's jailbroken. Remove the file immediately.
|
||||
[[NSFileManager defaultManager] removeItemAtPath:testPath error:nil];
|
||||
NSLog(@"Sandbox write test indicates jailbreak.");
|
||||
return YES;
|
||||
}
|
||||
//3: Check for existence of the symbolic link /Applications.
|
||||
struct stat s;
|
||||
if (lstat("/Applications", &s) == 0) {
|
||||
if (S_ISLNK(s.st_mode)) {
|
||||
NSLog(@"Symbolic link /Applications exists, jailbroken");
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
//4:Check for dyld Libraries
|
||||
uint32_t count = _dyld_image_count();
|
||||
for (uint32_t i = 0 ; i < count ; ++i) {
|
||||
const char *dyld = _dyld_get_image_name(i);
|
||||
if (strstr(dyld, "MobileSubstrate") != NULL || strstr(dyld, "libcycript") != NULL) {
|
||||
NSLog(@"Suspicious dyld library found: %s", dyld);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
//5 Check if fork() is available. Sandboxed apps should not be able to call fork().
|
||||
#if !TARGET_IPHONE_SIMULATOR // Don't run this on the simulator
|
||||
int pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
//in child, exit immediately to avoid crashing.
|
||||
exit(0);
|
||||
} else if (pid > 0)
|
||||
{
|
||||
NSLog(@"Fork available. Likely jailbroken.");
|
||||
return YES; // Fork succeeded; likely jailbroken
|
||||
}
|
||||
#endif
|
||||
|
||||
return NO; // No jailbreak indicators found
|
||||
}
|
||||
+ (BOOL)isDebuggerAttached {
|
||||
int mib[4];
|
||||
struct kinfo_proc info;
|
||||
size_t size = sizeof(info);
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = getpid();
|
||||
|
||||
sysctl(mib, 4, &info, &size, NULL, 0);
|
||||
|
||||
return (info.kp_proc.p_flag & P_TRACED) != 0;
|
||||
}
|
||||
|
||||
// Check for Frida's default port
|
||||
+ (BOOL)isFridaListeningOnDefaultPort {
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == -1) {
|
||||
return NO; // Couldn't create socket
|
||||
}
|
||||
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(27042); // Default Frida port
|
||||
inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr);
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) != -1) {
|
||||
NSLog(@"Frida default port (27042) is open.");
|
||||
close(sock);
|
||||
return YES;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL)isFridaDetected {
|
||||
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
|
||||
size_t length;
|
||||
struct kinfo_proc *procs, *proc;
|
||||
|
||||
sysctl(name, 3, NULL, &length, NULL, 0);
|
||||
procs = malloc(length);
|
||||
sysctl(name, 3, procs, &length, NULL, 0);
|
||||
|
||||
for (proc = procs; (char *)proc < (char *)procs + length; proc++) {
|
||||
if (strstr(proc->kp_proc.p_comm, "frida") != NULL) {
|
||||
free(procs);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
free(procs);
|
||||
return NO;
|
||||
}
|
||||
// Check for loaded dylibs that indicate Frida
|
||||
+(BOOL) checkForFridaDylib{
|
||||
uint32_t count = _dyld_image_count();
|
||||
for (uint32_t i = 0 ; i < count ; ++i) {
|
||||
const char *dyld = _dyld_get_image_name(i);
|
||||
if (strstr(dyld, "FridaGadget") != NULL) { // Look for FridaGadget
|
||||
NSLog(@"FridaGadget dylib found: %s", dyld);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Check process name
|
||||
+ (BOOL)checkProcessName {
|
||||
NSString* processName = [[NSProcessInfo processInfo] processName];
|
||||
if ([processName containsString:@"Frida"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
// A combined check for jailbreak and Frida
|
||||
+ (BOOL)isDeviceCompromised {
|
||||
if ([SecurityChecks isDeviceJailbroken]) {
|
||||
return YES;
|
||||
}
|
||||
if ([SecurityChecks isFridaListeningOnDefaultPort]) {
|
||||
return YES;
|
||||
}
|
||||
if ([SecurityChecks checkForFridaDylib]) {
|
||||
return YES;
|
||||
}
|
||||
if([SecurityChecks checkProcessName]){
|
||||
return YES;
|
||||
}
|
||||
// if ([SecurityChecks isDebuggerAttached]) {
|
||||
// return YES;
|
||||
// }
|
||||
// if ([SecurityChecks isFridaDetected]) {
|
||||
// return YES;
|
||||
// }
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||