From 0e9c2e005586b54b2efa78743e74732fc3decb5d Mon Sep 17 00:00:00 2001 From: Manish Date: Wed, 26 Nov 2025 10:10:54 +0530 Subject: [PATCH] implementation of security service --- lib/helpers/services/api_service.dart | 25 +++++++++++-- lib/helpers/services/security_service.dart | 41 ++++++++++++++++++++++ pubspec.yaml | 2 ++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 lib/helpers/services/security_service.dart diff --git a/lib/helpers/services/api_service.dart b/lib/helpers/services/api_service.dart index 2c22e46..56a94a2 100644 --- a/lib/helpers/services/api_service.dart +++ b/lib/helpers/services/api_service.dart @@ -40,6 +40,7 @@ import 'package:on_field_work/model/service_project/service_project_job_detail_m import 'package:on_field_work/model/service_project/job_attendance_logs_model.dart'; import 'package:on_field_work/model/service_project/job_allocation_model.dart'; import 'package:on_field_work/model/service_project/service_project_branches_model.dart'; +import 'package:on_field_work/helpers/services/security_service.dart'; class ApiService { static const bool enableLogs = true; @@ -165,7 +166,7 @@ class ApiService { .timeout(extendedTimeout); logSafe("Response Status: ${response.statusCode}", level: LogLevel.debug); - logSafe("Response Body: ${response.body}", level: LogLevel.debug); + logSafe("Encrypted Response: ${response.body}", level: LogLevel.debug); if (response.statusCode == 401 && !hasRetried) { logSafe("Unauthorized (401). Attempting token refresh...", @@ -186,6 +187,14 @@ class ApiService { await LocalStorage.logout(); } + // *********** DECRYPT HERE ************* + final decrypted = await SecurityService.decryptResponse(response.body); + + if (decrypted != null) { + return http.Response(jsonEncode(decrypted), response.statusCode); + } + // ************************************* + return response; } catch (e) { logSafe("HTTP GET Exception: $e", level: LogLevel.error); @@ -219,6 +228,17 @@ class ApiService { customTimeout: customTimeout, hasRetried: true); } } + + logSafe("Encrypted Response: ${response.body}", level: LogLevel.debug); + + // *********** DECRYPT HERE ************* + final decrypted = await SecurityService.decryptResponse(response.body); + + if (decrypted != null) { + return http.Response(jsonEncode(decrypted), response.statusCode); + } + // ************************************* + return response; } catch (e) { logSafe("HTTP POST Exception: $e", level: LogLevel.error); @@ -671,8 +691,7 @@ class ApiService { 'pageNumber': pageNumber.toString(), 'pageSize': pageSize.toString(), 'isActive': isActive.toString(), - if (isArchive) - 'isArchive': 'true', + if (isArchive) 'isArchive': 'true', }; final response = await _getRequest(endpoint, queryParams: queryParams); diff --git a/lib/helpers/services/security_service.dart b/lib/helpers/services/security_service.dart new file mode 100644 index 0000000..d3c3290 --- /dev/null +++ b/lib/helpers/services/security_service.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; +import 'package:cryptography/cryptography.dart'; + +class SecurityService { + // Same 32-byte key + static const _keyBase64 = "Your32ByteBase64KeyGoesHere/1234567890+XY="; + + static Future decryptResponse(String encryptedBase64) async { + final algorithm = AesGcm.with256bits(); + + // 1. Decode Key and Data + final secretKey = await algorithm.newSecretKeyFromBytes(base64.decode(_keyBase64)); + final encryptedBytes = base64.decode(encryptedBase64); + + // 2. Extract Parts: [Nonce 12] + [Ciphertext] + [Tag 16] + // The "SecretBox" class helps us organize these parts + final nonce = encryptedBytes.sublist(0, 12); + final ciphertext = encryptedBytes.sublist(12, encryptedBytes.length - 16); + final mac = encryptedBytes.sublist(encryptedBytes.length - 16); + + final secretBox = SecretBox( + ciphertext, + nonce: nonce, + mac: Mac(mac), + ); + + // 3. Decrypt + try { + final decryptedBytes = await algorithm.decrypt( + secretBox, + secretKey: secretKey, + ); + + final decryptedString = utf8.decode(decryptedBytes); + return json.decode(decryptedString); + } catch (e) { + print("Decryption failed: $e"); + return null; + } + } +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 44f705c..caf93bd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -83,6 +83,8 @@ dependencies: timeago: ^3.7.1 cached_network_image: ^3.4.1 + cryptography: ^2.7.0 + gallery_saver_plus: ^3.2.9 share_plus: ^12.0.1 timeline_tile: ^2.0.0