Update Saqel Platform: 2026-09-08 13:43:36
This commit is contained in:
@@ -19,10 +19,7 @@ class ApiClient {
|
||||
'Accept': 'application/json',
|
||||
};
|
||||
|
||||
final deviceId = await _storage.getDeviceId();
|
||||
if (deviceId != null) {
|
||||
headers['X-Device-Fingerprint'] = deviceId;
|
||||
}
|
||||
headers['X-Device-Fingerprint'] = 'saqel_student_flutter';
|
||||
|
||||
if (requiresAuth) {
|
||||
final token = await _storage.getToken();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../data/models/user_model.dart';
|
||||
import '../utils/app_logger.dart';
|
||||
|
||||
@@ -26,41 +25,7 @@ class StorageService {
|
||||
static const String _keyIdentityToken = 'saqel_identity_token';
|
||||
static const String _keyDeviceId = 'saqel_device_id';
|
||||
|
||||
// Obfuscation mask to prevent plain-text discovery in storage files
|
||||
static const String _storageSalt = 'saqel_v1_defense_salt_2026';
|
||||
|
||||
String _encrypt(String input) {
|
||||
if (input.isEmpty) return input;
|
||||
final bytes = utf8.encode(input);
|
||||
final saltBytes = utf8.encode(_storageSalt);
|
||||
final encrypted = List<int>.generate(bytes.length, (i) => bytes[i] ^ saltBytes[i % saltBytes.length]);
|
||||
return base64Encode(encrypted);
|
||||
}
|
||||
|
||||
String _decrypt(String input) {
|
||||
if (input.isEmpty) return input;
|
||||
try {
|
||||
final bytes = base64Decode(input);
|
||||
final saltBytes = utf8.encode(_storageSalt);
|
||||
final decrypted = List<int>.generate(bytes.length, (i) => bytes[i] ^ saltBytes[i % saltBytes.length]);
|
||||
return utf8.decode(decrypted);
|
||||
} catch (_) {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _writeSafe(String key, String value) async {
|
||||
final encVal = _encrypt(value);
|
||||
|
||||
// 1. Persistent disk storage
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(key, encVal);
|
||||
} catch (e) {
|
||||
AppLogger.log('Prefs write notice ($key): $e', tag: 'STORAGE');
|
||||
}
|
||||
|
||||
// 2. Hardware Secure Storage (if available)
|
||||
try {
|
||||
await _secureStorage.write(key: key, value: value);
|
||||
} on PlatformException catch (e) {
|
||||
@@ -69,31 +34,14 @@ class StorageService {
|
||||
}
|
||||
|
||||
Future<String?> _readSafe(String key) async {
|
||||
// 1. Try Keychain first
|
||||
try {
|
||||
final val = await _secureStorage.read(key: key);
|
||||
if (val != null && val.isNotEmpty) return val;
|
||||
} catch (_) {}
|
||||
|
||||
// 2. Fall back to encrypted persistent storage
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final raw = prefs.getString(key);
|
||||
if (raw != null && raw.isNotEmpty) {
|
||||
return _decrypt(raw);
|
||||
}
|
||||
} catch (e) {
|
||||
AppLogger.log('Prefs read notice ($key): $e', tag: 'STORAGE');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> _deleteSafe(String key) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(key);
|
||||
} catch (_) {}
|
||||
|
||||
try {
|
||||
await _secureStorage.delete(key: key);
|
||||
} catch (_) {}
|
||||
|
||||
Reference in New Issue
Block a user