fix(mobile): mtls on native clients (#25802)

* handle mtls on ios

* update android impl

* ui improvements

* dead code

* no need to store data separately

* improve concurrency

* dead code

* add migration

* remove unused dependency

* trust user-installed certs

* removed print statement

* fix ios

* improve android styling

* outdated comments

* update lock file

* handle translation

* fix prompt cancellation

* fix video playback

* Apply suggestion from @shenlong-tanwen

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>

* Apply suggestion from @shenlong-tanwen

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>

* formatting

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
This commit is contained in:
Mert
2026-02-05 12:42:53 -05:00
committed by GitHub
parent 0a8a65a45e
commit 27a2808470
32 changed files with 1560 additions and 579 deletions
+4 -19
View File
@@ -1,26 +1,20 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/http_ssl_cert_override.dart';
import 'package:logging/logging.dart';
class HttpSSLOptions {
static const MethodChannel _channel = MethodChannel('immich/httpSSLOptions');
static void apply({bool applyNative = true}) {
static void apply() {
AppSettingsEnum setting = AppSettingsEnum.allowSelfSignedSSLCert;
bool allowSelfSignedSSLCert = Store.get(setting.storeKey as StoreKey<bool>, setting.defaultValue);
_apply(allowSelfSignedSSLCert, applyNative: applyNative);
return _apply(allowSelfSignedSSLCert);
}
static void applyFromSettings(bool newValue) {
_apply(newValue);
}
static void applyFromSettings(bool newValue) => _apply(newValue);
static void _apply(bool allowSelfSignedSSLCert, {bool applyNative = true}) {
static void _apply(bool allowSelfSignedSSLCert) {
String? serverHost;
if (allowSelfSignedSSLCert && Store.tryGet(StoreKey.currentUser) != null) {
serverHost = Uri.parse(Store.tryGet(StoreKey.serverEndpoint) ?? "").host;
@@ -29,14 +23,5 @@ class HttpSSLOptions {
SSLClientCertStoreVal? clientCert = SSLClientCertStoreVal.load();
HttpOverrides.global = HttpSSLCertOverride(allowSelfSignedSSLCert, serverHost, clientCert);
if (applyNative && Platform.isAndroid) {
_channel
.invokeMethod("apply", [allowSelfSignedSSLCert, serverHost, clientCert?.data, clientCert?.password])
.onError<PlatformException>((e, _) {
final log = Logger("HttpSSLOptions");
log.severe('Failed to set SSL options', e.message);
});
}
}
}
+1 -1
View File
@@ -54,7 +54,7 @@ Cancelable<T?> runInIsolateGentle<T>({
Logger log = Logger("IsolateLogger");
try {
HttpSSLOptions.apply(applyNative: false);
HttpSSLOptions.apply();
result = await computation(ref);
} on CanceledError {
log.warning("Computation cancelled ${debugLabel == null ? '' : ' for $debugLabel'}");
+10 -1
View File
@@ -23,6 +23,8 @@ import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
import 'package:immich_mobile/platform/native_sync_api.g.dart';
import 'package:immich_mobile/platform/network_api.g.dart';
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/datetime_helpers.dart';
import 'package:immich_mobile/utils/debug_print.dart';
@@ -32,7 +34,7 @@ import 'package:isar/isar.dart';
// ignore: import_rule_photo_manager
import 'package:photo_manager/photo_manager.dart';
const int targetVersion = 20;
const int targetVersion = 21;
Future<void> migrateDatabaseIfNeeded(Isar db, Drift drift) async {
final hasVersion = Store.tryGet(StoreKey.version) != null;
@@ -91,6 +93,13 @@ Future<void> migrateDatabaseIfNeeded(Isar db, Drift drift) async {
await _syncLocalAlbumIsIosSharedAlbum(drift);
}
if (version < 21) {
final certData = SSLClientCertStoreVal.load();
if (certData != null) {
await networkApi.addCertificate(ClientCertData(data: certData.data, password: certData.password ?? ""));
}
}
if (targetVersion >= 12) {
await Store.put(StoreKey.version, targetVersion);
return;