75 lines
2.3 KiB
Dart
75 lines
2.3 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jinzhi_flutter_app/common/network/auth_interceptor.dart';
|
|
import 'package:jinzhi_flutter_app/common/storage/preferences_storage.dart';
|
|
import 'package:jinzhi_flutter_app/common/storage/secure_identity_storage.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
test('external absolute URLs lose all backend identity headers', () async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
final preferences = await SharedPreferences.getInstance();
|
|
final session = AuthSessionStorage(
|
|
SecureIdentityStorage(
|
|
PreferencesStorage(preferences),
|
|
secureStorage: _MemorySecureStorage(),
|
|
),
|
|
);
|
|
final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'))
|
|
..interceptors.add(
|
|
AuthInterceptor(
|
|
session,
|
|
backendOrigin: Uri.parse('https://api.example.com'),
|
|
),
|
|
)
|
|
..httpClientAdapter = _CaptureAdapter();
|
|
|
|
final response = await dio.get<void>(
|
|
'https://cdn.example.net/ad.png',
|
|
options: Options(
|
|
headers: {
|
|
'Authorization': 'Bearer leaked',
|
|
'X-Device-Id': 'device',
|
|
'User-iOS-IDFA': 'idfa',
|
|
'User-DeviceToken': 'push',
|
|
},
|
|
),
|
|
);
|
|
|
|
final headers = response.requestOptions.headers.keys
|
|
.map((key) => key.toLowerCase())
|
|
.toSet();
|
|
expect(headers, isNot(contains('authorization')));
|
|
expect(headers, isNot(contains('x-device-id')));
|
|
expect(headers, isNot(contains('user-ios-idfa')));
|
|
expect(headers, isNot(contains('user-devicetoken')));
|
|
});
|
|
}
|
|
|
|
class _MemorySecureStorage implements SecureKeyValueStorage {
|
|
final Map<String, String> values = {};
|
|
|
|
@override
|
|
Future<void> delete(String key) async => values.remove(key);
|
|
@override
|
|
Future<String?> read(String key) async => values[key];
|
|
@override
|
|
Future<void> write(String key, String value) async => values[key] = value;
|
|
}
|
|
|
|
class _CaptureAdapter implements HttpClientAdapter {
|
|
@override
|
|
Future<ResponseBody> fetch(
|
|
RequestOptions options,
|
|
Stream<Uint8List>? requestStream,
|
|
Future<void>? cancelFuture,
|
|
) async => ResponseBody.fromString('', 204);
|
|
|
|
@override
|
|
void close({bool force = false}) {}
|
|
}
|