first commit

This commit is contained in:
Hamza-Ayed
2026-06-09 08:40:31 +03:00
commit d8901e1a87
3161 changed files with 536187 additions and 0 deletions

View File

@@ -0,0 +1,386 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:siro_service/constant/box_name.dart';
import 'package:siro_service/constant/links.dart';
import 'package:siro_service/controller/functions/encrypt_decrypt.dart';
import 'package:siro_service/env/env.dart';
import 'package:siro_service/controller/functions/security_helper.dart';
import 'package:siro_service/main.dart';
import 'package:siro_service/print.dart';
import '../../constant/api_key.dart';
class CRUD {
static bool _isRefreshingJWT = false;
static String? _appSignature;
static String _lastErrorSignature = '';
static DateTime _lastErrorTimestamp = DateTime(2000);
static const Duration _errorLogDebounceDuration = Duration(minutes: 1);
// ── JWT Validity Check (No external libs) ──────────────────────
static bool _isJwtValid(String? token) {
if (token == null || token.isEmpty) return false;
try {
final parts = token.split('.');
if (parts.length != 3) return false;
String payload = parts[1];
switch (payload.length % 4) {
case 2:
payload += '==';
break;
case 3:
payload += '=';
break;
}
final decoded = jsonDecode(utf8.decode(base64Url.decode(payload)));
final exp = decoded['exp'];
if (exp == null) return false;
// 30 seconds buffer
return DateTime.now().millisecondsSinceEpoch < (exp * 1000 - 30000);
} catch (_) {
return false;
}
}
static Future<void> addError(
String error, String details, String where) async {
try {
final currentErrorSignature = '$where-$error';
final now = DateTime.now();
if (currentErrorSignature == _lastErrorSignature &&
now.difference(_lastErrorTimestamp) < _errorLogDebounceDuration) {
return;
}
_lastErrorSignature = currentErrorSignature;
_lastErrorTimestamp = now;
final userId =
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID);
final userType = 'Service';
final phone = box.read(BoxName.phone) ?? box.read(BoxName.phoneDriver);
CRUD().post(
link: AppLink.addError,
payload: {
'error': error.toString(),
'userId': userId.toString(),
'userType': userType,
'phone': phone.toString(),
'device': where,
'details': details,
},
);
} catch (e) {}
}
String _getFpHeader() {
return box.read(BoxName.fingerPrint)?.toString() ?? '';
}
String _generateHmac(String body, String timestamp, String nonce) {
// نستخدم المفتاح الخاص بالمستخدم (المخزن في البوكس) كـ HMAC Secret
final hmacSecret = box.read(BoxName.hmac) ?? '';
final payload = body + timestamp + nonce;
final key = utf8.encode(hmacSecret);
final bytes = utf8.encode(payload);
final hmacSha256 = Hmac(sha256, key);
final result = hmacSha256.convert(bytes).toString();
Log.print('🔐 [HMAC-DEBUG] Secret: $hmacSecret');
Log.print('🔐 [HMAC-DEBUG] Body(${body.length}): "$body"');
Log.print('🔐 [HMAC-DEBUG] TS: $timestamp | Nonce: $nonce');
Log.print('🔐 [HMAC-DEBUG] Result: $result');
return result;
}
// ═══════════════════════════════════════════════════════════════
// _makeRequest — Central Request Handler
// ───────────────────────────────────────────────────────────────
Future<dynamic> _makeRequest({
required String link,
Map<String, dynamic>? payload,
required Map<String, String> headers,
}) async {
const totalTimeout = Duration(seconds: 60);
// توليد بيانات الـ HMAC للطلب الحالي
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
final nonce =
DateTime.now().microsecondsSinceEpoch.toString(); // Nonce فريد
// تحويل الـ payload إلى string لمحاكة ما سيصل للسيرفر (php://input)
String bodyString = '';
if (payload != null && payload.isNotEmpty) {
// الـ http.post يرسل البيانات كـ x-www-form-urlencoded
bodyString = payload.keys
.map((key) =>
"$key=${Uri.encodeQueryComponent(payload[key].toString())}")
.join("&");
}
final hmacSignature = _generateHmac(bodyString, timestamp, nonce);
// إضافة هيدرات الـ HMAC
headers['X-HMAC-Auth'] = hmacSignature;
headers['X-Timestamp'] = timestamp;
headers['X-Nonce'] = nonce;
Future<http.Response> doPost() {
final url = Uri.parse(link);
return http
.post(url, body: payload, headers: headers)
.timeout(totalTimeout);
}
http.Response? response;
int attempts = 0;
final requestId =
DateTime.now().millisecondsSinceEpoch.toString().substring(7);
Log.print('🚀 [REQ-$requestId] $link');
Log.print('🔑 [FP-$requestId] ${headers['X-Device-FP']}');
Log.print('🔏 [SIGN-$requestId] ${headers['X-App-Signature']}');
if (payload != null) Log.print('📦 [PAYLOAD-$requestId] $payload');
while (attempts < 3) {
try {
attempts++;
response = await doPost();
break;
} on SocketException catch (_) {
Log.print('⚠️ SocketException attempt $attempts$link');
if (attempts >= 3) return 'no_internet';
await Future.delayed(const Duration(seconds: 1));
} on TimeoutException catch (_) {
Log.print('⚠️ TimeoutException attempt $attempts$link');
if (attempts >= 3) return 'failure';
} catch (e) {
if (e.toString().contains('errno = 9') && attempts < 3) {
await Future.delayed(const Duration(milliseconds: 500));
continue;
}
addError(
'HTTP Exception: $e', 'Try: $attempts', 'CRUD._makeRequest $link');
return 'failure';
}
}
if (response == null) return 'failure';
final sc = response.statusCode;
final body = response.body;
Log.print('📥 [RES-$requestId] [$sc] $link');
Log.print('📄 [BODY-$requestId] $body');
if (sc >= 200 && sc < 300) {
try {
return jsonDecode(body);
} catch (e, st) {
addError(
'JSON Decode Error', 'Body: $body\n$st', 'CRUD._makeRequest $link');
return 'failure';
}
}
if (sc == 401) {
if (!_isRefreshingJWT && !link.contains('errorApp.php')) {
_isRefreshingJWT = true;
try {
await getJWT();
} finally {
_isRefreshingJWT = false;
}
}
return 'token_expired';
}
if (sc >= 500) {
addError('Server 5xx', 'SC: $sc\nBody: $body', 'CRUD._makeRequest $link');
return 'failure';
}
return 'failure';
}
// ═══════════════════════════════════════════════════════════════
// post — standard POST
// ═══════════════════════════════════════════════════════════════
Future<dynamic> post({
required String link,
Map<String, dynamic>? payload,
}) async {
String token = r(box.read(BoxName.jwt) ?? '').toString().split(Env.addd)[0];
if (!_isJwtValid(token) &&
!_isRefreshingJWT &&
!link.contains('login.php')) {
_isRefreshingJWT = true;
try {
await getJWT();
token = r(box.read(BoxName.jwt) ?? '').toString().split(Env.addd)[0];
} finally {
_isRefreshingJWT = false;
}
}
// Initialize app signature if null
_appSignature ??= await SecurityHelper.getAppSignature();
final headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer $token',
'X-Device-FP': _getFpHeader(),
'X-App-Signature': _appSignature ?? '',
};
return await _makeRequest(link: link, payload: payload, headers: headers);
}
// ═══════════════════════════════════════════════════════════════
// get — standard GET (uses POST method in this architecture)
// ═══════════════════════════════════════════════════════════════
Future<dynamic> get({
required String link,
Map<String, dynamic>? payload,
}) async {
return await post(link: link, payload: payload);
}
// ═══════════════════════════════════════════════════════════════
// getJWT — V1 Login Flow
// ═══════════════════════════════════════════════════════════════
Future<void> getJWT() async {
var payload = {
'fingerprint': _getFpHeader(),
'password': box.read(BoxName.password) ?? '',
'aud': 'service',
};
// Initialize app signature if null
_appSignature ??= await SecurityHelper.getAppSignature();
final headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'X-App-Signature': _appSignature ?? '',
};
final response = await _makeRequest(
link: AppLink.login, payload: payload, headers: headers);
if (response != 'failure' &&
response is Map &&
response['status'] == 'success') {
final jwt = response['message']['jwt'];
final hmac = response['message']['hmac'];
Log.print('jwt: $jwt');
Log.print('hmac_key: $hmac');
await box.write(BoxName.jwt, c(jwt));
if (hmac != null) {
await box.write(BoxName.hmac, hmac);
final verify = box.read(BoxName.hmac);
Log.print('✅ Verified stored HMAC: $verify');
}
}
}
// ─────────────────────────────────────────────────────────────
// Service Specific Methods (Preserved)
// ─────────────────────────────────────────────────────────────
Future<dynamic> arabicTextExtractByVisionAndAI({
required String imagePath,
required String driverID,
}) async {
var headers = {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': AK.ocpApimSubscriptionKey
};
String imagePathFull =
'${AppLink.server}/card_image/$imagePath-$driverID.jpg';
var request = http.Request(
'POST',
Uri.parse(
'https://eastus.api.cognitive.microsoft.com/computervision/imageanalysis:analyze?features=caption,read&model-version=latest&language=en&api-version=2024-02-01'));
request.body = json.encode({"url": imagePathFull});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
return await response.stream.bytesToString();
}
return 'failure';
}
Future<dynamic> getAgoraToken({
required String channelName,
required String uid,
}) async {
var res = await http.get(
Uri.parse(
'https://orca-app-b2i85.ondigitalocean.app/token?channelName=$channelName'),
headers: {'Authorization': 'Bearer '});
if (res.statusCode == 200) {
var response = jsonDecode(res.body);
return response['token'];
}
return 'failure';
}
Future<dynamic> getLlama({
required String link,
required String payload,
required String prompt,
}) async {
var url = Uri.parse(link);
var headers = {
'Content-Type': 'application/json',
'Authorization':
'Bearer LL-X5lJ0Px9CzKK0HTuVZ3u2u4v3tGWkImLTG7okGRk4t25zrsLqJ0qNoUzZ2x4ciPy'
};
var data = json.encode({
"model": "Llama-3-70b-Inst-FW",
"messages": [
{
"role": "user",
"content":
"Extract the desired information from the following passage as json decoded like $prompt just in this:\n\n$payload"
}
],
"temperature": 0.9
});
var response = await http.post(url, body: data, headers: headers);
if (response.statusCode == 200) {
return response.body;
}
return response.statusCode;
}
sendEmail(String link, Map<String, String>? payload) async {
var headers = {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
};
var request = http.Request('POST', Uri.parse(link));
request.bodyFields = payload!;
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {}
}
}

View File

@@ -0,0 +1,49 @@
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:siro_service/constant/box_name.dart';
import 'package:siro_service/controller/functions/encrypt_decrypt.dart';
import '../../main.dart';
import '../../print.dart';
class DeviceHelper {
static Future<String> getDeviceFingerprint() async {
await EncryptionHelper.initialize();
final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
var deviceData;
try {
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo;
deviceData = androidInfo.toMap();
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo;
deviceData = iosInfo.toMap();
} else {
throw UnsupportedError('Unsupported platform');
}
final String deviceId = Platform.isAndroid
? deviceData['id'] ??
deviceData['androidId'] ??
deviceData['fingerprint'] ??
'unknown'
: deviceData['identifierForVendor'] ?? 'unknown';
final String deviceModel = deviceData['model'] ?? 'unknown';
Log.print('DeviceId: $deviceId');
Log.print('DeviceModel: $deviceModel');
final String fingerprint =
EncryptionHelper.instance.encryptData('${deviceId}_$deviceModel');
Log.print('Generated Fingerprint: $fingerprint');
box.write(BoxName.fingerPrint, fingerprint);
return (fingerprint);
} catch (e) {
Log.print('Error generating device fingerprint: $e');
return '';
}
}
}

View File

@@ -0,0 +1,87 @@
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:flutter/foundation.dart';
import 'package:siro_service/env/env.dart';
import 'package:secure_string_operations/secure_string_operations.dart';
import 'package:siro_service/constant/char_map.dart';
import 'package:siro_service/print.dart';
class EncryptionHelper {
static EncryptionHelper? _instance;
late final encrypt.Key key;
late final encrypt.IV iv;
EncryptionHelper._(this.key, this.iv);
static EncryptionHelper get instance {
if (_instance == null) {
throw Exception(
"EncryptionHelper is not initialized. Call `await EncryptionHelper.initialize()` in main.");
}
return _instance!;
}
/// Initializes and stores the instance globally
static Future<void> initialize() async {
if (_instance != null) {
debugPrint("EncryptionHelper is already initialized.");
return; // Prevent re-initialization
}
debugPrint("Initializing EncryptionHelper...");
// Read stored keys
String keyOfApp = r(Env.keyOfApp).toString().split(Env.addd)[0];
String initializationVector = r(Env.initializationVector).toString().split(Env.addd)[0];
Log.print('Key Length: ${keyOfApp.length}');
Log.print('IV Length: ${initializationVector.length}');
// Set the global instance
_instance = EncryptionHelper._(
encrypt.Key.fromUtf8(keyOfApp),
encrypt.IV.fromUtf8(initializationVector),
);
debugPrint("EncryptionHelper initialized successfully.");
}
/// Encrypts a string
String encryptData(String plainText) {
Log.print('Encrypting: $plainText');
try {
final encrypter =
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
final encrypted = encrypter.encrypt(plainText, iv: iv);
return encrypted.base64;
} catch (e) {
Log.print('Encryption Error: $e');
return '';
}
}
/// Decrypts a string
String decryptData(String encryptedText) {
try {
final encrypter =
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
final encrypted = encrypt.Encrypted.fromBase64(encryptedText);
return encrypter.decrypt(encrypted, iv: iv);
} catch (e) {
debugPrint('Decryption Error: $e');
return '';
}
}
}
r(String string) {
var res = X.r(X.r(X.r(string, cn), cC), cs).toString();
// Log.print('r($string) => $res');
return res;
}
c(String string) {
return X.c(X.c(X.c(string, cn), cC), cs).toString();
}

View File

@@ -0,0 +1,340 @@
import 'dart:convert';
import 'dart:io';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:image/image.dart' as img;
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../main.dart';
import 'package:siro_service/controller/functions/encrypt_decrypt.dart';
import 'package:siro_service/env/env.dart';
class ImageController extends GetxController {
File? myImage;
bool isloading = false;
CroppedFile? croppedFile;
final picker = ImagePicker();
var image;
Future<img.Image> detectAndCropDocument(File imageFile) async {
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) throw Exception('Unable to decode image');
int left = image.width, top = image.height, right = 0, bottom = 0;
// Threshold for considering a pixel as part of the document (adjust as needed)
const int threshold = 240;
for (int y = 0; y < image.height; y++) {
for (int x = 0; x < image.width; x++) {
final pixel = image.getPixel(x, y);
final luminance = img.getLuminance(pixel);
if (luminance < threshold) {
left = x < left ? x : left;
top = y < top ? y : top;
right = x > right ? x : right;
bottom = y > bottom ? y : bottom;
}
}
}
// Add a small padding
left = (left - 5).clamp(0, image.width);
top = (top - 5).clamp(0, image.height);
right = (right + 5).clamp(0, image.width);
bottom = (bottom + 5).clamp(0, image.height);
return img.copyCrop(image,
x: left, y: top, width: right - left, height: bottom - top);
}
Future<File> rotateImageIfNeeded(File imageFile) async {
img.Image croppedDoc = await detectAndCropDocument(imageFile);
// Check if the document is in portrait orientation
bool isPortrait = croppedDoc.height > croppedDoc.width;
img.Image processedImage;
if (isPortrait) {
// Rotate the image by 90 degrees clockwise
processedImage = img.copyRotate(croppedDoc, angle: 90);
} else {
processedImage = croppedDoc;
}
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the processed image file
File processedFile = File('$tempPath/processed_image.jpg');
await processedFile.writeAsBytes(img.encodeJpg(processedImage));
return processedFile;
}
Future<File> rotateImage(File imageFile) async {
// Read the image file
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) return imageFile;
// Rotate the image by 90 degrees clockwise
img.Image rotatedImage = img.copyRotate(image, angle: 90);
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the rotated image file
File rotatedFile = File('$tempPath/rotated_image.jpg');
await rotatedFile.writeAsBytes(img.encodeJpg(rotatedImage));
return rotatedFile;
}
choosImage(String link, String driverId, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
);
if (pickedImage == null) return;
image = File(pickedImage.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
if (croppedFile == null) return;
myImage = File(croppedFile!.path);
isloading = true;
update();
// Rotate the compressed image
// File rotatedImage = await rotateImage(compressedImage);
File processedImage = await rotateImageIfNeeded(File(croppedFile!.path));
File compressedImage = await compressImage(processedImage);
print('link =$link');
try {
await uploadImage(
compressedImage,
{'driverID': driverId, 'imageType': imageType},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
choosFace(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.camera,
preferredCameraDevice: CameraDevice.front,
);
if (pickedImage != null) {
image = File(pickedImage.path);
isloading = true;
update();
// Compress the image
File compressedImage = await compressImage(File(pickedImage.path));
// Save the picked image directly
// File savedImage = File(pickedImage.path);
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
}
uploadImage(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link), //'https://ride.mobile-app.store/uploadImage1.php'
);
var length = await file.length();
var stream = http.ByteStream(file.openRead());
var multipartFile = http.MultipartFile(
'image',
stream,
length,
filename: basename(file.path),
);
String token = r(box.read(BoxName.jwt) ?? '').toString().split(Env.addd)[0];
request.headers.addAll({
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
'Authorization': 'Bearer $token',
'X-Device-FP': box.read(BoxName.fingerPrint)?.toString() ?? '',
});
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
choosImagePicture(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
// preferredCameraDevice: CameraDevice.rear,
// maxHeight: Get.height * .3,
// maxWidth: Get.width * .9,
// imageQuality: 100,
);
image = File(pickedImage!.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
myImage = File(pickedImage.path);
isloading = true;
update();
// Save the cropped image
// File savedCroppedImage = File(croppedFile!.path);
File compressedImage = await compressImage(File(croppedFile!.path));
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
uploadImagePicture(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link), //'https://ride.mobile-app.store/uploadImage1.php'
);
var length = await file.length();
var stream = http.ByteStream(file.openRead());
var multipartFile = http.MultipartFile(
'image',
stream,
length,
filename: basename(file.path),
);
String token = r(box.read(BoxName.jwt) ?? '').toString().split(Env.addd)[0];
request.headers.addAll({
'Authorization': 'Bearer $token',
'X-Device-FP': box.read(BoxName.fingerPrint)?.toString() ?? '',
});
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
}
Future<File> compressImage(File file) async {
final dir = await path_provider.getTemporaryDirectory();
final targetPath = "${dir.absolute.path}/temp.jpg";
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path,
targetPath,
quality: 70,
minWidth: 1024,
minHeight: 1024,
);
return File(result!.path);
}

View File

@@ -0,0 +1,43 @@
import 'dart:convert';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:secure_string_operations/secure_string_operations.dart';
import 'package:siro_service/controller/functions/crud.dart';
import '../../constant/box_name.dart';
import '../../constant/char_map.dart';
import '../../constant/info.dart';
import '../../constant/links.dart';
import '../../env/env.dart';
import '../../main.dart';
import '../../print.dart';
class AppInitializer {
List<Map<String, dynamic>> links = [];
// Future<void> initializeApp() async {
// if (box.read(BoxName.jwt) == null) {
// await CRUD().getJWT();
// } else {
// bool isTokenExpired = JwtDecoder.isExpired(X
// .r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs)
// .toString()
// .split(AppInformation.addd)[0]);
// if (isTokenExpired) {
// await CRUD().getJWT();
// }
// }
// }
getAIKey(String key1) async {
if (box.read(BoxName.firstTimeLoadKey) == null) {
var res =
await CRUD().get(link: Env.getapiKey, payload: {"keyName": key1});
if (res != 'failure') {
var d = res['message'];
await storage.write(key: key1, value: d[key1].toString());
await Future.delayed(Duration.zero);
} else {}
}
}
}

View File

@@ -0,0 +1,76 @@
import 'package:url_launcher/url_launcher.dart';
import 'dart:io';
void showInBrowser(String url) async {
if (await canLaunchUrl(Uri.parse(url))) {
launchUrl(Uri.parse(url));
} else {}
}
Future<void> makePhoneCall(String phoneNumber) async {
final Uri launchUri = Uri(
scheme: 'tel',
path: phoneNumber,
);
await launchUrl(launchUri);
}
void launchCommunication(
String method, String contactInfo, String message) async {
String url;
if (Platform.isIOS) {
switch (method) {
case 'phone':
url = 'tel:$contactInfo';
break;
case 'sms':
url = 'sms:$contactInfo?body=${Uri.encodeComponent(message)}';
break;
case 'whatsapp':
url =
'https://api.whatsapp.com/send?phone=$contactInfo&text=${Uri.encodeComponent(message)}';
break;
case 'email':
url =
'mailto:$contactInfo?subject=Subject&body=${Uri.encodeComponent(message)}';
break;
default:
return;
}
} else if (Platform.isAndroid) {
switch (method) {
case 'phone':
url = 'tel:$contactInfo';
break;
case 'sms':
url = 'sms:$contactInfo?body=${Uri.encodeComponent(message)}';
break;
case 'whatsapp':
// Check if WhatsApp is installed
final bool whatsappInstalled =
await canLaunchUrl(Uri.parse('whatsapp://'));
if (whatsappInstalled) {
url =
'whatsapp://send?phone=$contactInfo&text=${Uri.encodeComponent(message)}';
} else {
// Provide an alternative action, such as opening the WhatsApp Web API
url =
'https://api.whatsapp.com/send?phone=$contactInfo&text=${Uri.encodeComponent(message)}';
}
break;
case 'email':
url =
'mailto:$contactInfo?subject=Subject&body=${Uri.encodeComponent(message)}';
break;
default:
return;
}
} else {
return;
}
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {}
}

View File

@@ -0,0 +1,32 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:siro_service/print.dart';
class SecurityHelper {
static const platform = MethodChannel('com.service_intaleq/security');
static Future<String?> getAppSignature() async {
try {
final String? signature = await platform.invokeMethod('getAppSignature');
final mode = kDebugMode ? 'DEBUG' : 'RELEASE';
Log.print('----------------------------------------------------');
Log.print('🚀 APP SIGNATURE HASH ($mode): $signature');
Log.print('----------------------------------------------------');
return signature;
} on PlatformException catch (e) {
Log.print('❌ Failed to get app signature: ${e.message}');
return null;
}
}
static Future<bool> isDeviceRooted() async {
try {
final bool isRooted = await platform.invokeMethod('isNativeRooted');
return isRooted;
} on PlatformException catch (e) {
Log.print('❌ Failed to check root: ${e.message}');
return false;
}
}
}