mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05:00 
			
		
		
		
	refactor(mobile): use startOAuth and server features flags (#6155)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									13ba83dce6
								
							
						
					
					
						commit
						2aaf941dda
					
				@ -11,15 +11,16 @@ class OAuthService {
 | 
				
			|||||||
  final log = Logger('OAuthService');
 | 
					  final log = Logger('OAuthService');
 | 
				
			||||||
  OAuthService(this._apiService);
 | 
					  OAuthService(this._apiService);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<OAuthConfigResponseDto?> getOAuthServerConfig(
 | 
					  Future<String?> getOAuthServerUrl(
 | 
				
			||||||
    String serverUrl,
 | 
					    String serverUrl,
 | 
				
			||||||
  ) async {
 | 
					  ) async {
 | 
				
			||||||
    // Resolve API server endpoint from user provided serverUrl
 | 
					    // Resolve API server endpoint from user provided serverUrl
 | 
				
			||||||
    await _apiService.resolveAndSetEndpoint(serverUrl);
 | 
					    await _apiService.resolveAndSetEndpoint(serverUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return await _apiService.oAuthApi.generateOAuthConfig(
 | 
					    final dto = await _apiService.oAuthApi.startOAuth(
 | 
				
			||||||
      OAuthConfigDto(redirectUri: '$callbackUrlScheme:/'),
 | 
					      OAuthConfigDto(redirectUri: '$callbackUrlScheme:/'),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    return dto?.url;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<LoginResponseDto?> oAuthLogin(String oauthUrl) async {
 | 
					  Future<LoginResponseDto?> oAuthLogin(String oauthUrl) async {
 | 
				
			||||||
 | 
				
			|||||||
@ -12,6 +12,7 @@ import 'package:immich_mobile/shared/providers/api.provider.dart';
 | 
				
			|||||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
 | 
					import 'package:immich_mobile/shared/providers/asset.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
 | 
					import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
 | 
					import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/shared/providers/server_info.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/shared/ui/immich_logo.dart';
 | 
					import 'package:immich_mobile/shared/ui/immich_logo.dart';
 | 
				
			||||||
import 'package:immich_mobile/shared/ui/immich_title_text.dart';
 | 
					import 'package:immich_mobile/shared/ui/immich_title_text.dart';
 | 
				
			||||||
import 'package:immich_mobile/shared/ui/immich_toast.dart';
 | 
					import 'package:immich_mobile/shared/ui/immich_toast.dart';
 | 
				
			||||||
@ -65,18 +66,18 @@ class LoginForm extends HookConsumerWidget {
 | 
				
			|||||||
        isLoadingServer.value = true;
 | 
					        isLoadingServer.value = true;
 | 
				
			||||||
        final endpoint = await apiService.resolveAndSetEndpoint(serverUrl);
 | 
					        final endpoint = await apiService.resolveAndSetEndpoint(serverUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final loginConfig = await apiService.oAuthApi.generateOAuthConfig(
 | 
					        // Fetch and load server config and features
 | 
				
			||||||
          OAuthConfigDto(redirectUri: serverUrl),
 | 
					        await ref.read(serverInfoProvider.notifier).getServerInfo();
 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (loginConfig != null) {
 | 
					        final serverInfo = ref.read(serverInfoProvider);
 | 
				
			||||||
          isOauthEnable.value = loginConfig.enabled;
 | 
					        final features = serverInfo.serverFeatures;
 | 
				
			||||||
          isPasswordLoginEnable.value = loginConfig.passwordLoginEnabled;
 | 
					        final config = serverInfo.serverConfig;
 | 
				
			||||||
          oAuthButtonLabel.value = loginConfig.buttonText ?? 'OAuth';
 | 
					
 | 
				
			||||||
        } else {
 | 
					        isOauthEnable.value = features.oauthEnabled;
 | 
				
			||||||
          isOauthEnable.value = false;
 | 
					        isPasswordLoginEnable.value = features.passwordLogin;
 | 
				
			||||||
          isPasswordLoginEnable.value = true;
 | 
					        oAuthButtonLabel.value = config.oauthButtonText.isNotEmpty
 | 
				
			||||||
        }
 | 
					            ? config.oauthButtonText
 | 
				
			||||||
 | 
					            : 'OAuth';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        serverEndpoint.value = endpoint;
 | 
					        serverEndpoint.value = endpoint;
 | 
				
			||||||
      } on ApiException catch (e) {
 | 
					      } on ApiException catch (e) {
 | 
				
			||||||
@ -183,11 +184,11 @@ class LoginForm extends HookConsumerWidget {
 | 
				
			|||||||
    oAuthLogin() async {
 | 
					    oAuthLogin() async {
 | 
				
			||||||
      var oAuthService = ref.watch(oAuthServiceProvider);
 | 
					      var oAuthService = ref.watch(oAuthServiceProvider);
 | 
				
			||||||
      ref.watch(assetProvider.notifier).clearAllAsset();
 | 
					      ref.watch(assetProvider.notifier).clearAllAsset();
 | 
				
			||||||
      OAuthConfigResponseDto? oAuthServerConfig;
 | 
					      String? oAuthServerUrl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        oAuthServerConfig = await oAuthService
 | 
					        oAuthServerUrl = await oAuthService
 | 
				
			||||||
            .getOAuthServerConfig(sanitizeUrl(serverEndpointController.text));
 | 
					            .getOAuthServerUrl(sanitizeUrl(serverEndpointController.text));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        isLoading.value = true;
 | 
					        isLoading.value = true;
 | 
				
			||||||
      } catch (e) {
 | 
					      } catch (e) {
 | 
				
			||||||
@ -200,9 +201,8 @@ class LoginForm extends HookConsumerWidget {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (oAuthServerConfig != null && oAuthServerConfig.enabled) {
 | 
					      if (oAuthServerUrl != null) {
 | 
				
			||||||
        var loginResponseDto =
 | 
					        var loginResponseDto = await oAuthService.oAuthLogin(oAuthServerUrl);
 | 
				
			||||||
            await oAuthService.oAuthLogin(oAuthServerConfig.url!);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (loginResponseDto != null) {
 | 
					        if (loginResponseDto != null) {
 | 
				
			||||||
          var isSuccess = await ref
 | 
					          var isSuccess = await ref
 | 
				
			||||||
 | 
				
			|||||||
@ -2,40 +2,46 @@ import 'package:openapi/api.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class ServerConfig {
 | 
					class ServerConfig {
 | 
				
			||||||
  final int trashDays;
 | 
					  final int trashDays;
 | 
				
			||||||
 | 
					  final String oauthButtonText;
 | 
				
			||||||
  final String externalDomain;
 | 
					  final String externalDomain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const ServerConfig({
 | 
					  const ServerConfig({
 | 
				
			||||||
    required this.trashDays,
 | 
					    required this.trashDays,
 | 
				
			||||||
 | 
					    required this.oauthButtonText,
 | 
				
			||||||
    required this.externalDomain,
 | 
					    required this.externalDomain,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ServerConfig copyWith({
 | 
					  ServerConfig copyWith({
 | 
				
			||||||
    int? trashDays,
 | 
					    int? trashDays,
 | 
				
			||||||
 | 
					    String? oauthButtonText,
 | 
				
			||||||
    String? externalDomain,
 | 
					    String? externalDomain,
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
    return ServerConfig(
 | 
					    return ServerConfig(
 | 
				
			||||||
      trashDays: trashDays ?? this.trashDays,
 | 
					      trashDays: trashDays ?? this.trashDays,
 | 
				
			||||||
 | 
					      oauthButtonText: oauthButtonText ?? this.oauthButtonText,
 | 
				
			||||||
      externalDomain: externalDomain ?? this.externalDomain,
 | 
					      externalDomain: externalDomain ?? this.externalDomain,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  String toString() =>
 | 
					  String toString() =>
 | 
				
			||||||
      'ServerConfig(trashDays: $trashDays, externalDomain: $externalDomain)';
 | 
					      'ServerConfig(trashDays: $trashDays, oauthButtonText: $oauthButtonText, externalDomain: $externalDomain)';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ServerConfig.fromDto(ServerConfigDto dto)
 | 
					  ServerConfig.fromDto(ServerConfigDto dto)
 | 
				
			||||||
      : trashDays = dto.trashDays,
 | 
					      : trashDays = dto.trashDays,
 | 
				
			||||||
 | 
					        oauthButtonText = dto.oauthButtonText,
 | 
				
			||||||
        externalDomain = dto.externalDomain;
 | 
					        externalDomain = dto.externalDomain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  bool operator ==(Object other) {
 | 
					  bool operator ==(covariant ServerConfig other) {
 | 
				
			||||||
    if (identical(this, other)) return true;
 | 
					    if (identical(this, other)) return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return other is ServerConfig &&
 | 
					    return other.trashDays == trashDays &&
 | 
				
			||||||
        other.trashDays == trashDays &&
 | 
					        other.oauthButtonText == oauthButtonText &&
 | 
				
			||||||
        other.externalDomain == externalDomain;
 | 
					        other.externalDomain == externalDomain;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  int get hashCode => trashDays.hashCode ^ externalDomain.hashCode;
 | 
					  int get hashCode =>
 | 
				
			||||||
 | 
					      trashDays.hashCode ^ oauthButtonText.hashCode ^ externalDomain.hashCode;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,40 +3,56 @@ import 'package:openapi/api.dart';
 | 
				
			|||||||
class ServerFeatures {
 | 
					class ServerFeatures {
 | 
				
			||||||
  final bool trash;
 | 
					  final bool trash;
 | 
				
			||||||
  final bool map;
 | 
					  final bool map;
 | 
				
			||||||
 | 
					  final bool oauthEnabled;
 | 
				
			||||||
 | 
					  final bool passwordLogin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const ServerFeatures({
 | 
					  const ServerFeatures({
 | 
				
			||||||
    required this.trash,
 | 
					    required this.trash,
 | 
				
			||||||
    required this.map,
 | 
					    required this.map,
 | 
				
			||||||
 | 
					    required this.oauthEnabled,
 | 
				
			||||||
 | 
					    required this.passwordLogin,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ServerFeatures copyWith({
 | 
					  ServerFeatures copyWith({
 | 
				
			||||||
    bool? trash,
 | 
					    bool? trash,
 | 
				
			||||||
    bool? map,
 | 
					    bool? map,
 | 
				
			||||||
 | 
					    bool? oauthEnabled,
 | 
				
			||||||
 | 
					    bool? passwordLogin,
 | 
				
			||||||
  }) {
 | 
					  }) {
 | 
				
			||||||
    return ServerFeatures(
 | 
					    return ServerFeatures(
 | 
				
			||||||
      trash: trash ?? this.trash,
 | 
					      trash: trash ?? this.trash,
 | 
				
			||||||
      map: map ?? this.map,
 | 
					      map: map ?? this.map,
 | 
				
			||||||
 | 
					      oauthEnabled: oauthEnabled ?? this.oauthEnabled,
 | 
				
			||||||
 | 
					      passwordLogin: passwordLogin ?? this.passwordLogin,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  String toString() {
 | 
					  String toString() {
 | 
				
			||||||
    return 'ServerFeatures(trash: $trash, map: $map)';
 | 
					    return 'ServerFeatures(trash: $trash, map: $map, oauthEnabled: $oauthEnabled, passwordLogin: $passwordLogin)';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ServerFeatures.fromDto(ServerFeaturesDto dto)
 | 
					  ServerFeatures.fromDto(ServerFeaturesDto dto)
 | 
				
			||||||
      : trash = dto.trash,
 | 
					      : trash = dto.trash,
 | 
				
			||||||
        map = dto.map;
 | 
					        map = dto.map,
 | 
				
			||||||
 | 
					        oauthEnabled = dto.oauth,
 | 
				
			||||||
 | 
					        passwordLogin = dto.passwordLogin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  bool operator ==(Object other) {
 | 
					  bool operator ==(covariant ServerFeatures other) {
 | 
				
			||||||
    if (identical(this, other)) return true;
 | 
					    if (identical(this, other)) return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return other is ServerFeatures && other.trash == trash && other.map == map;
 | 
					    return other.trash == trash &&
 | 
				
			||||||
 | 
					        other.map == map &&
 | 
				
			||||||
 | 
					        other.oauthEnabled == oauthEnabled &&
 | 
				
			||||||
 | 
					        other.passwordLogin == passwordLogin;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  int get hashCode {
 | 
					  int get hashCode {
 | 
				
			||||||
    return trash.hashCode ^ map.hashCode;
 | 
					    return trash.hashCode ^
 | 
				
			||||||
 | 
					        map.hashCode ^
 | 
				
			||||||
 | 
					        oauthEnabled.hashCode ^
 | 
				
			||||||
 | 
					        passwordLogin.hashCode;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,9 +26,12 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
 | 
				
			|||||||
            serverFeatures: const ServerFeatures(
 | 
					            serverFeatures: const ServerFeatures(
 | 
				
			||||||
              map: true,
 | 
					              map: true,
 | 
				
			||||||
              trash: true,
 | 
					              trash: true,
 | 
				
			||||||
 | 
					              oauthEnabled: false,
 | 
				
			||||||
 | 
					              passwordLogin: true,
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            serverConfig: const ServerConfig(
 | 
					            serverConfig: const ServerConfig(
 | 
				
			||||||
              trashDays: 30,
 | 
					              trashDays: 30,
 | 
				
			||||||
 | 
					              oauthButtonText: '',
 | 
				
			||||||
              externalDomain: '',
 | 
					              externalDomain: '',
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            serverDiskInfo: const ServerDiskInfo(
 | 
					            serverDiskInfo: const ServerDiskInfo(
 | 
				
			||||||
@ -45,10 +48,10 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  final ServerInfoService _serverInfoService;
 | 
					  final ServerInfoService _serverInfoService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getServerInfo() {
 | 
					  Future<void> getServerInfo() async {
 | 
				
			||||||
    getServerVersion();
 | 
					    await getServerVersion();
 | 
				
			||||||
    getServerFeatures();
 | 
					    await getServerFeatures();
 | 
				
			||||||
    getServerConfig();
 | 
					    await getServerConfig();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getServerVersion() async {
 | 
					  getServerVersion() async {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user