diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt index 9e98ffdd78..f76aa13cf2 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt @@ -5,6 +5,7 @@ import app.alextran.immich.BuildConfig import okhttp3.Cache import okhttp3.ConnectionPool import okhttp3.Dispatcher +import okhttp3.Headers import okhttp3.OkHttpClient import java.io.ByteArrayInputStream import java.io.File @@ -38,6 +39,7 @@ object HttpClientManager { private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) } + var headers: Headers = Headers.headersOf("User-Agent", USER_AGENT) val isMtls: Boolean get() = keyStore.containsAlias(CERT_ALIAS) fun initialize(context: Context) { @@ -92,6 +94,12 @@ object HttpClientManager { synchronized(this) { clientChangedListeners.add(listener) } } + fun setRequestHeaders(headerMap: Map) { + val builder = Headers.Builder() + headerMap.forEach { (key, value) -> builder.add(key, value) } + headers = builder.build() + } + private fun build(cacheDir: File): OkHttpClient { val connectionPool = ConnectionPool( maxIdleConnections = KEEP_ALIVE_CONNECTIONS, @@ -107,8 +115,10 @@ object HttpClientManager { .apply { init(arrayOf(DynamicKeyManager()), arrayOf(trustManager), null) } return OkHttpClient.Builder() - .addInterceptor { chain -> - chain.proceed(chain.request().newBuilder().header("User-Agent", USER_AGENT).build()) + .addInterceptor { + val builder = it.request().newBuilder() + headers.forEach { (key, value) -> builder.addHeader(key, value) } + it.proceed(builder.build()) } .connectionPool(connectionPool) .dispatcher(Dispatcher().apply { maxRequestsPerHost = MAX_REQUESTS_PER_HOST }) diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt index 3e34ffa7ac..19f53120ca 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt @@ -228,6 +228,7 @@ interface NetworkApi { * iOS only - Android should use OkHttpWebSocket.connectWithClient directly. */ fun createWebSocketTask(url: String, protocols: List?, callback: (Result) -> Unit) + fun setRequestHeaders(headers: Map) companion object { /** The codec used by NetworkApi. */ @@ -330,6 +331,24 @@ interface NetworkApi { channel.setMessageHandler(null) } } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NetworkApi.setRequestHeaders$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val headersArg = args[0] as Map + val wrapped: List = try { + api.setRequestHeaders(headersArg) + listOf(null) + } catch (exception: Throwable) { + NetworkPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } } } } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt index c552def3ed..c63f227201 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt @@ -104,6 +104,17 @@ private class NetworkApiImpl(private val context: Context) : NetworkApi { return NativeBuffer.createGlobalRef(client) } + // only used on iOS + override fun createWebSocketTask( + url: String, + protocols: List?, + callback: (Result) -> Unit + ) {} + + override fun setRequestHeaders(headers: Map) { + HttpClientManager.setRequestHeaders(headers) + } + private fun handlePickedFile(uri: Uri) { val callback = pendingCallback ?: return pendingCallback = null diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImages.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImages.g.kt index 0e3cf19657..6d6864c8ba 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImages.g.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImages.g.kt @@ -47,7 +47,7 @@ private open class RemoteImagesPigeonCodec : StandardMessageCodec() { /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ interface RemoteImageApi { - fun requestImage(url: String, headers: Map, requestId: Long, callback: (Result?>) -> Unit) + fun requestImage(url: String, requestId: Long, callback: (Result?>) -> Unit) fun cancelRequest(requestId: Long) fun clearCache(callback: (Result) -> Unit) @@ -66,9 +66,8 @@ interface RemoteImageApi { channel.setMessageHandler { message, reply -> val args = message as List val urlArg = args[0] as String - val headersArg = args[1] as Map - val requestIdArg = args[2] as Long - api.requestImage(urlArg, headersArg, requestIdArg) { result: Result?> -> + val requestIdArg = args[1] as Long + api.requestImage(urlArg, requestIdArg) { result: Result?> -> val error = result.exceptionOrNull() if (error != null) { reply.reply(RemoteImagesPigeonUtils.wrapError(error)) diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt index 04a181cd6e..3dfdaaf6cc 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt @@ -49,7 +49,6 @@ class RemoteImagesImpl(context: Context) : RemoteImageApi { override fun requestImage( url: String, - headers: Map, requestId: Long, callback: (Result?>) -> Unit ) { @@ -58,7 +57,6 @@ class RemoteImagesImpl(context: Context) : RemoteImageApi { ImageFetcherManager.fetch( url, - headers, signal, onSuccess = { buffer -> requestMap.remove(requestId) @@ -119,12 +117,11 @@ private object ImageFetcherManager { fun fetch( url: String, - headers: Map, signal: CancellationSignal, onSuccess: (NativeByteBuffer) -> Unit, onFailure: (Exception) -> Unit, ) { - fetcher.fetch(url, headers, signal, onSuccess, onFailure) + fetcher.fetch(url, signal, onSuccess, onFailure) } fun clearCache(onCleared: (Result) -> Unit) { @@ -151,7 +148,6 @@ private object ImageFetcherManager { private sealed interface ImageFetcher { fun fetch( url: String, - headers: Map, signal: CancellationSignal, onSuccess: (NativeByteBuffer) -> Unit, onFailure: (Exception) -> Unit, @@ -178,7 +174,6 @@ private class CronetImageFetcher(context: Context, cacheDir: File) : ImageFetche override fun fetch( url: String, - headers: Map, signal: CancellationSignal, onSuccess: (NativeByteBuffer) -> Unit, onFailure: (Exception) -> Unit, @@ -193,7 +188,7 @@ private class CronetImageFetcher(context: Context, cacheDir: File) : ImageFetche val callback = FetchCallback(onSuccess, onFailure, ::onComplete) val requestBuilder = engine.newUrlRequestBuilder(url, callback, executor) - headers.forEach { (key, value) -> requestBuilder.addHeader(key, value) } + HttpClientManager.headers.forEach { (key, value) -> requestBuilder.addHeader(key, value) } val request = requestBuilder.build() signal.setOnCancelListener(request::cancel) request.start() @@ -390,7 +385,6 @@ private class OkHttpImageFetcher private constructor( override fun fetch( url: String, - headers: Map, signal: CancellationSignal, onSuccess: (NativeByteBuffer) -> Unit, onFailure: (Exception) -> Unit, @@ -403,7 +397,6 @@ private class OkHttpImageFetcher private constructor( } val requestBuilder = Request.Builder().url(url) - headers.forEach { (key, value) -> requestBuilder.addHeader(key, value) } val call = client.newCall(requestBuilder.build()) signal.setOnCancelListener(call::cancel) diff --git a/mobile/ios/Runner/Core/Network.g.swift b/mobile/ios/Runner/Core/Network.g.swift index 9018f05f49..0cc094fdc4 100644 --- a/mobile/ios/Runner/Core/Network.g.swift +++ b/mobile/ios/Runner/Core/Network.g.swift @@ -261,6 +261,7 @@ protocol NetworkApi { /// Creates a WebSocket task and waits for connection to be established. /// iOS only - Android should use OkHttpWebSocket.connectWithClient directly. func createWebSocketTask(url: String, protocols: [String]?, completion: @escaping (Result) -> Void) + func setRequestHeaders(headers: [String: String]) throws } /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. @@ -351,5 +352,20 @@ class NetworkApiSetup { } else { createWebSocketTaskChannel.setMessageHandler(nil) } + let setRequestHeadersChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NetworkApi.setRequestHeaders\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setRequestHeadersChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let headersArg = args[0] as! [String: String] + do { + try api.setRequestHeaders(headers: headersArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setRequestHeadersChannel.setMessageHandler(nil) + } } } diff --git a/mobile/ios/Runner/Core/NetworkApiImpl.swift b/mobile/ios/Runner/Core/NetworkApiImpl.swift index 51e746fa08..ac314d186a 100644 --- a/mobile/ios/Runner/Core/NetworkApiImpl.swift +++ b/mobile/ios/Runner/Core/NetworkApiImpl.swift @@ -67,6 +67,10 @@ class NetworkApiImpl: NetworkApi { } } } + + func setRequestHeaders(headers: [String : String]) throws { + URLSessionManager.shared.session.configuration.httpAdditionalHeaders = headers + } } private class CertImporter: NSObject, UIDocumentPickerDelegate { diff --git a/mobile/ios/Runner/Images/RemoteImages.g.swift b/mobile/ios/Runner/Images/RemoteImages.g.swift index fc83b09d4b..7781e6f02f 100644 --- a/mobile/ios/Runner/Images/RemoteImages.g.swift +++ b/mobile/ios/Runner/Images/RemoteImages.g.swift @@ -70,7 +70,7 @@ class RemoteImagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol RemoteImageApi { - func requestImage(url: String, headers: [String: String], requestId: Int64, completion: @escaping (Result<[String: Int64]?, Error>) -> Void) + func requestImage(url: String, requestId: Int64, completion: @escaping (Result<[String: Int64]?, Error>) -> Void) func cancelRequest(requestId: Int64) throws func clearCache(completion: @escaping (Result) -> Void) } @@ -86,9 +86,8 @@ class RemoteImageApiSetup { requestImageChannel.setMessageHandler { message, reply in let args = message as! [Any?] let urlArg = args[0] as! String - let headersArg = args[1] as! [String: String] - let requestIdArg = args[2] as! Int64 - api.requestImage(url: urlArg, headers: headersArg, requestId: requestIdArg) { result in + let requestIdArg = args[1] as! Int64 + api.requestImage(url: urlArg, requestId: requestIdArg) { result in switch result { case .success(let res): reply(wrapResult(res)) diff --git a/mobile/ios/Runner/Images/RemoteImagesImpl.swift b/mobile/ios/Runner/Images/RemoteImagesImpl.swift index 56e8938521..b886f35905 100644 --- a/mobile/ios/Runner/Images/RemoteImagesImpl.swift +++ b/mobile/ios/Runner/Images/RemoteImagesImpl.swift @@ -33,12 +33,9 @@ class RemoteImageApiImpl: NSObject, RemoteImageApi { kCGImageSourceCreateThumbnailFromImageAlways: true ] as CFDictionary - func requestImage(url: String, headers: [String : String], requestId: Int64, completion: @escaping (Result<[String : Int64]?, any Error>) -> Void) { + func requestImage(url: String, requestId: Int64, completion: @escaping (Result<[String : Int64]?, any Error>) -> Void) { var urlRequest = URLRequest(url: URL(string: url)!) urlRequest.cachePolicy = .returnCacheDataElseLoad - for (key, value) in headers { - urlRequest.setValue(value, forHTTPHeaderField: key) - } let task = URLSessionManager.shared.session.dataTask(with: urlRequest) { data, response, error in Self.handleCompletion(requestId: requestId, data: data, response: response, error: error) diff --git a/mobile/lib/infrastructure/loaders/remote_image_request.dart b/mobile/lib/infrastructure/loaders/remote_image_request.dart index 2da70c3ae1..2544aa088b 100644 --- a/mobile/lib/infrastructure/loaders/remote_image_request.dart +++ b/mobile/lib/infrastructure/loaders/remote_image_request.dart @@ -2,9 +2,8 @@ part of 'image_request.dart'; class RemoteImageRequest extends ImageRequest { final String uri; - final Map headers; - RemoteImageRequest({required this.uri, required this.headers}); + RemoteImageRequest({required this.uri}); @override Future load(ImageDecoderCallback decode, {double scale = 1.0}) async { @@ -12,7 +11,7 @@ class RemoteImageRequest extends ImageRequest { return null; } - final info = await remoteImageApi.requestImage(uri, headers: headers, requestId: requestId); + final info = await remoteImageApi.requestImage(uri, requestId: requestId); final frame = switch (info) { {'pointer': int pointer, 'length': int length} => await _fromEncodedPlatformImage(pointer, length), {'pointer': int pointer, 'width': int width, 'height': int height, 'rowBytes': int rowBytes} => diff --git a/mobile/lib/infrastructure/repositories/network.repository.dart b/mobile/lib/infrastructure/repositories/network.repository.dart index 071027d414..37710a078b 100644 --- a/mobile/lib/infrastructure/repositories/network.repository.dart +++ b/mobile/lib/infrastructure/repositories/network.repository.dart @@ -60,7 +60,7 @@ class NetworkRepository { final result = await networkApi.createWebSocketTask(uri.toString(), protocols?.toList()); final pointer = Pointer.fromAddress(result.taskPointer); final task = URLSessionWebSocketTask.fromRawPointer(pointer.cast()); - return CupertinoWebSocket.fromConnectedTask(task, protocol: result.protocol ?? ''); + return CupertinoWebSocket.fromConnectedTask(task, protocol: result.taskProtocol ?? ''); } static Future _createAndroidWebSocket(Uri uri, {Iterable? protocols}) { diff --git a/mobile/lib/infrastructure/repositories/sync_api.repository.dart b/mobile/lib/infrastructure/repositories/sync_api.repository.dart index 90ff1b1c2e..b2e9cde156 100644 --- a/mobile/lib/infrastructure/repositories/sync_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_api.repository.dart @@ -36,10 +36,6 @@ class SyncApiRepository { final headers = {'Content-Type': 'application/json', 'Accept': 'application/jsonlines+json'}; - final headerParams = {}; - await _api.applyToParams([], headerParams); - headers.addAll(headerParams); - final shouldReset = Store.get(StoreKey.shouldResetSync, false); final request = http.Request('POST', Uri.parse(endpoint)); request.headers.addAll(headers); diff --git a/mobile/lib/pages/common/headers_settings.page.dart b/mobile/lib/pages/common/headers_settings.page.dart index 1cfab355d6..adfcbff1aa 100644 --- a/mobile/lib/pages/common/headers_settings.page.dart +++ b/mobile/lib/pages/common/headers_settings.page.dart @@ -8,6 +8,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/generated/intl_keys.g.dart'; +import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; +import 'package:immich_mobile/services/api.service.dart'; class SettingsHeader { String key = ""; @@ -20,7 +22,6 @@ class HeaderSettingsPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - // final apiService = ref.watch(apiServiceProvider); final headers = useState>([]); final setInitialHeaders = useState(false); @@ -87,7 +88,7 @@ class HeaderSettingsPage extends HookConsumerWidget { ); } - saveHeaders(List headers) { + saveHeaders(List headers) async { final headersMap = {}; for (var header in headers) { final key = header.key.trim(); @@ -98,7 +99,8 @@ class HeaderSettingsPage extends HookConsumerWidget { } var encoded = jsonEncode(headersMap); - Store.put(StoreKey.customHeaders, encoded); + await Store.put(StoreKey.customHeaders, encoded); + await networkApi.setRequestHeaders(ApiService.getRequestHeaders()); } } diff --git a/mobile/lib/platform/network_api.g.dart b/mobile/lib/platform/network_api.g.dart index 6f3e860568..079b8d769c 100644 --- a/mobile/lib/platform/network_api.g.dart +++ b/mobile/lib/platform/network_api.g.dart @@ -329,4 +329,27 @@ class NetworkApi { return (pigeonVar_replyList[0] as WebSocketTaskResult?)!; } } + + Future setRequestHeaders(Map headers) async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.NetworkApi.setRequestHeaders$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([headers]); + final List? pigeonVar_replyList = await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } } diff --git a/mobile/lib/platform/remote_image_api.g.dart b/mobile/lib/platform/remote_image_api.g.dart index 410db03ece..f393a89b1c 100644 --- a/mobile/lib/platform/remote_image_api.g.dart +++ b/mobile/lib/platform/remote_image_api.g.dart @@ -49,11 +49,7 @@ class RemoteImageApi { final String pigeonVar_messageChannelSuffix; - Future?> requestImage( - String url, { - required Map headers, - required int requestId, - }) async { + Future?> requestImage(String url, {required int requestId}) async { final String pigeonVar_channelName = 'dev.flutter.pigeon.immich_mobile.RemoteImageApi.requestImage$pigeonVar_messageChannelSuffix'; final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( @@ -61,7 +57,7 @@ class RemoteImageApi { pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); - final Future pigeonVar_sendFuture = pigeonVar_channel.send([url, headers, requestId]); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([url, requestId]); final List? pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); diff --git a/mobile/lib/presentation/widgets/images/remote_image_provider.dart b/mobile/lib/presentation/widgets/images/remote_image_provider.dart index 6cb68c1442..8f4358ed68 100644 --- a/mobile/lib/presentation/widgets/images/remote_image_provider.dart +++ b/mobile/lib/presentation/widgets/images/remote_image_provider.dart @@ -6,7 +6,6 @@ import 'package:immich_mobile/domain/services/setting.service.dart'; import 'package:immich_mobile/infrastructure/loaders/image_request.dart'; import 'package:immich_mobile/presentation/widgets/images/image_provider.dart'; import 'package:immich_mobile/presentation/widgets/images/one_frame_multi_image_stream_completer.dart'; -import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/utils/image_url_builder.dart'; import 'package:openapi/api.dart'; @@ -37,7 +36,7 @@ class RemoteImageProvider extends CancellableImageProvider } Stream _codec(RemoteImageProvider key, ImageDecoderCallback decode) { - final request = this.request = RemoteImageRequest(uri: key.url, headers: ApiService.getRequestHeaders()); + final request = this.request = RemoteImageRequest(uri: key.url); return loadRequest(request, decode); } @@ -88,10 +87,8 @@ class RemoteFullImageProvider extends CancellableImageProvider { Future saveAuthInfo({required String accessToken}) async { await _apiService.setAccessToken(accessToken); + await networkApi.setRequestHeaders(ApiService.getRequestHeaders()); final serverEndpoint = Store.get(StoreKey.serverEndpoint); final customHeaders = Store.tryGet(StoreKey.customHeaders); diff --git a/mobile/lib/providers/websocket.provider.dart b/mobile/lib/providers/websocket.provider.dart index d46428c50f..c31084b0ff 100644 --- a/mobile/lib/providers/websocket.provider.dart +++ b/mobile/lib/providers/websocket.provider.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'package:collection/collection.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -13,7 +12,6 @@ import 'package:immich_mobile/providers/auth.provider.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/db.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; -import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/sync.service.dart'; import 'package:immich_mobile/utils/debounce.dart'; import 'package:immich_mobile/utils/debug_print.dart'; @@ -100,11 +98,6 @@ class WebsocketNotifier extends StateNotifier { if (authenticationState.isAuthenticated) { try { final endpoint = Uri.parse(Store.get(StoreKey.serverEndpoint)); - final headers = ApiService.getRequestHeaders(); - if (endpoint.userInfo.isNotEmpty) { - headers["Authorization"] = "Basic ${base64.encode(utf8.encode(endpoint.userInfo))}"; - } - dPrint(() => "Attempting to connect to websocket"); // Configure socket transports must be specified Socket socket = io( @@ -117,7 +110,6 @@ class WebsocketNotifier extends StateNotifier { .enableForceNew() .enableForceNewConnection() .enableAutoConnect() - .setExtraHeaders(headers) .build(), ); diff --git a/mobile/lib/services/api.service.dart b/mobile/lib/services/api.service.dart index 2c860e68c1..7b1cc0fa44 100644 --- a/mobile/lib/services/api.service.dart +++ b/mobile/lib/services/api.service.dart @@ -129,11 +129,8 @@ class ApiService implements Authentication { Future _getWellKnownEndpoint(String baseUrl) async { try { - var headers = {"Accept": "application/json"}; - headers.addAll(getRequestHeaders()); - final res = await NetworkRepository.client - .get(Uri.parse("$baseUrl/.well-known/immich"), headers: headers) + .get(Uri.parse("$baseUrl/.well-known/immich")) .timeout(const Duration(seconds: 5)); if (res.statusCode == 200) { @@ -197,10 +194,7 @@ class ApiService implements Authentication { @override Future applyToParams(List queryParams, Map headerParams) { - return Future(() { - var headers = ApiService.getRequestHeaders(); - headerParams.addAll(headers); - }); + return Future.value(); } ApiClient get apiClient => _apiClient; diff --git a/mobile/lib/services/auth.service.dart b/mobile/lib/services/auth.service.dart index 0ed9328d3e..c5f3fa6a4a 100644 --- a/mobile/lib/services/auth.service.dart +++ b/mobile/lib/services/auth.service.dart @@ -68,7 +68,7 @@ class AuthService { try { final uri = Uri.parse('$url/users/me'); - final response = await NetworkRepository.client.get(uri, headers: ApiService.getRequestHeaders()); + final response = await NetworkRepository.client.get(uri); if (response.statusCode == 200) { isValid = true; } diff --git a/mobile/pigeon/network_api.dart b/mobile/pigeon/network_api.dart index da4a0be3b2..0da29c84b5 100644 --- a/mobile/pigeon/network_api.dart +++ b/mobile/pigeon/network_api.dart @@ -52,4 +52,6 @@ abstract class NetworkApi { /// iOS only - Android should use OkHttpWebSocket.connectWithClient directly. @async WebSocketTaskResult createWebSocketTask(String url, List? protocols); + + void setRequestHeaders(Map headers); } diff --git a/mobile/pigeon/remote_image_api.dart b/mobile/pigeon/remote_image_api.dart index 749deb828e..50f30456f1 100644 --- a/mobile/pigeon/remote_image_api.dart +++ b/mobile/pigeon/remote_image_api.dart @@ -5,8 +5,7 @@ import 'package:pigeon/pigeon.dart'; dartOut: 'lib/platform/remote_image_api.g.dart', swiftOut: 'ios/Runner/Images/RemoteImages.g.swift', swiftOptions: SwiftOptions(includeErrorClass: false), - kotlinOut: - 'android/app/src/main/kotlin/app/alextran/immich/images/RemoteImages.g.kt', + kotlinOut: 'android/app/src/main/kotlin/app/alextran/immich/images/RemoteImages.g.kt', kotlinOptions: KotlinOptions(package: 'app.alextran.immich.images', includeErrorClass: false), dartOptions: DartOptions(), dartPackageName: 'immich_mobile', @@ -15,11 +14,7 @@ import 'package:pigeon/pigeon.dart'; @HostApi() abstract class RemoteImageApi { @async - Map? requestImage( - String url, { - required Map headers, - required int requestId, - }); + Map? requestImage(String url, {required int requestId}); void cancelRequest(int requestId); diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 99296a8ee3..ee168765d6 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -333,8 +333,8 @@ packages: dependency: "direct main" description: path: "pkgs/cupertino_http" - ref: "114b2807bdeee641457b5703f411318d722b67b5" - resolved-ref: "114b2807bdeee641457b5703f411318d722b67b5" + ref: "398fcc427e1a15a08ea9ddb467bb8368e1acc09d" + resolved-ref: "398fcc427e1a15a08ea9ddb467bb8368e1acc09d" url: "https://github.com/mertalev/http" source: git version: "3.0.0-wip" @@ -1267,8 +1267,8 @@ packages: dependency: "direct main" description: path: "pkgs/ok_http" - ref: "114b2807bdeee641457b5703f411318d722b67b5" - resolved-ref: "114b2807bdeee641457b5703f411318d722b67b5" + ref: "398fcc427e1a15a08ea9ddb467bb8368e1acc09d" + resolved-ref: "398fcc427e1a15a08ea9ddb467bb8368e1acc09d" url: "https://github.com/mertalev/http" source: git version: "0.1.1-wip" @@ -1727,19 +1727,20 @@ packages: socket_io_client: dependency: "direct main" description: - name: socket_io_client - sha256: ede469f3e4c55e8528b4e023bdedbc20832e8811ab9b61679d1ba3ed5f01f23b - url: "https://pub.dev" - source: hosted - version: "2.0.3+1" + path: "." + ref: "95a61e3d92b0ad0d70ba488b9cb4598a3d655c36" + resolved-ref: "95a61e3d92b0ad0d70ba488b9cb4598a3d655c36" + url: "https://github.com/mertalev/socket.io-client-dart" + source: git + version: "3.1.4" socket_io_common: dependency: transitive description: name: socket_io_common - sha256: "2ab92f8ff3ebbd4b353bf4a98bee45cc157e3255464b2f90f66e09c4472047eb" + sha256: "162fbaecbf4bf9a9372a62a341b3550b51dcef2f02f3e5830a297fd48203d45b" url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "3.1.1" source_gen: dependency: transitive description: @@ -2101,21 +2102,21 @@ packages: source: hosted version: "1.1.1" web_socket: - dependency: transitive + dependency: "direct main" description: name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" url: "https://pub.dev" source: hosted - version: "0.1.6" + version: "1.0.1" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5" + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" webdriver: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index e0af1d80d7..62d2d3e8cb 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -75,7 +75,6 @@ dependencies: share_handler: ^0.0.25 share_plus: ^10.1.4 sliver_tools: ^0.2.12 - socket_io_client: ^2.0.3+1 stream_transform: ^2.1.1 thumbhash: 0.1.0+1 timezone: ^0.9.4 @@ -83,16 +82,21 @@ dependencies: uuid: ^4.5.1 wakelock_plus: ^1.3.0 worker_manager: ^7.2.7 + web_socket: ^1.0.1 # TODO: upstream these changes + socket_io_client: + git: + url: https://github.com/mertalev/socket.io-client-dart + ref: '95a61e3d92b0ad0d70ba488b9cb4598a3d655c36' cupertino_http: git: url: https://github.com/mertalev/http - ref: '114b2807bdeee641457b5703f411318d722b67b5' + ref: '398fcc427e1a15a08ea9ddb467bb8368e1acc09d' path: pkgs/cupertino_http/ ok_http: git: url: https://github.com/mertalev/http - ref: '114b2807bdeee641457b5703f411318d722b67b5' + ref: '398fcc427e1a15a08ea9ddb467bb8368e1acc09d' path: pkgs/ok_http/ dev_dependencies: