mirror of
https://github.com/we-promise/sure.git
synced 2026-05-25 21:44:56 +00:00
* Add mobile custom proxy headers * Clear login placeholders on focus Email/password fields ship with example values pre-filled. Tapping the field now clears the placeholder so users don't have to delete it manually. Skips clearing if the user has already edited the value. * Push Configuration as a route from Sign in Opening Configuration from the Sign in screen now uses Navigator.push instead of toggling a state flag, so Android back returns to Sign in instead of quitting the app. Saving the URL auto-pops the route. * Address PR review on custom proxy headers - Test Connection no longer leaves global ApiConfig headers mutated; unsaved edits are restored in a finally block after the probe. - _loadSavedUrl / _loadCustomHeaders wrap storage reads in try/catch and always finish initialization with sensible defaults. - Sanitization is now a single CustomProxyHeader.sanitize() reused by ApiConfig.setCustomProxyHeaders and CustomProxyHeadersService. - Brief comment on redactedValue explaining the length-obscuring design. * Harden custom proxy header validation and load path - validateValue now rejects ASCII control characters (CR/LF/tab/etc.) to prevent header-injection via crafted values. - loadHeaders moves the secure-storage read inside the try block so platform exceptions are caught the same way JSON parse errors are.
48 lines
1.5 KiB
Dart
48 lines
1.5 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:sure_mobile/models/custom_proxy_header.dart';
|
|
import 'package:sure_mobile/services/custom_proxy_headers_service.dart';
|
|
|
|
void main() {
|
|
setUp(() {
|
|
FlutterSecureStorage.setMockInitialValues({});
|
|
});
|
|
|
|
test('saves and loads custom proxy headers', () async {
|
|
final service = CustomProxyHeadersService.instance;
|
|
final headers = [
|
|
CustomProxyHeader(name: 'X-Auth-Id', value: 'id'),
|
|
CustomProxyHeader(name: 'X-Auth-Secret', value: 'secret'),
|
|
];
|
|
|
|
await service.saveHeaders(headers);
|
|
|
|
expect(await service.loadHeaders(), headers);
|
|
});
|
|
|
|
test('drops incomplete and duplicate headers, keeping the last value', () async {
|
|
final service = CustomProxyHeadersService.instance;
|
|
|
|
await service.saveHeaders([
|
|
CustomProxyHeader(name: 'X-Auth-Id', value: 'old'),
|
|
CustomProxyHeader(name: '', value: 'ignored'),
|
|
CustomProxyHeader(name: 'X-Auth-Id', value: 'new'),
|
|
CustomProxyHeader(name: 'X-Empty', value: ''),
|
|
]);
|
|
|
|
expect(await service.loadHeaders(), [
|
|
CustomProxyHeader(name: 'X-Auth-Id', value: 'new'),
|
|
]);
|
|
});
|
|
|
|
test('returns an empty list for invalid stored json', () async {
|
|
const storage = FlutterSecureStorage();
|
|
await storage.write(
|
|
key: CustomProxyHeadersService.storageKey,
|
|
value: 'not json',
|
|
);
|
|
|
|
expect(await CustomProxyHeadersService.instance.loadHeaders(), isEmpty);
|
|
});
|
|
}
|