From 54d355c711795d6f403afd611ee327d13398cf3f Mon Sep 17 00:00:00 2001 From: Lulin Yang Date: Sat, 23 Nov 2024 09:42:33 +1300 Subject: [PATCH] third party signin optimize --- .../repositories/auth_repository_impl.dart | 29 +++++++++++++ .../auth_repository.dart | 1 + domain/lib/usecases/auth_usecase.dart | 11 +++-- .../settings/viewModels/login_view_model.dart | 41 +++++-------------- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/data/lib/repositories/auth_repository_impl.dart b/data/lib/repositories/auth_repository_impl.dart index 516be91..39f3927 100644 --- a/data/lib/repositories/auth_repository_impl.dart +++ b/data/lib/repositories/auth_repository_impl.dart @@ -198,4 +198,33 @@ class AuthRepositoryImpl implements AuthRepository { throw mapServerErrorToDomainException(response); } } + + @override + Future validateAppleToken(String identityToken) async { + final baseURL = await apiEnvironmentRepository.getBaseUrl(); + final url = + Uri.parse('http://localhost:8080/api/auth/sign_in_with_apple'); + final response = await client.post( + url, + headers: { + 'Content-Type': 'application/json', + }, + body: jsonEncode({ + 'identityToken': identityToken, + }), + ); + if (response.statusCode != 200) { + print('Token validation failed: ${response.body}'); + throw Exception('Failed to validate token with backend'); + } + final responseJson = jsonDecode(response.body); + + // Extract email from the payload + final String? email = responseJson["payload"]?["email"]; // Safely access payload + + if (email == null || email.isEmpty) { + throw Exception('Validation failed: email not retrieved from token'); + } + return email; + } } diff --git a/domain/lib/repositories_abstract/auth_repository.dart b/domain/lib/repositories_abstract/auth_repository.dart index 78bfce2..6359556 100644 --- a/domain/lib/repositories_abstract/auth_repository.dart +++ b/domain/lib/repositories_abstract/auth_repository.dart @@ -11,4 +11,5 @@ abstract class AuthRepository { Future sendSignupVerificationCode(String email); Future updatePassword(String newPassword); Future syncUser(String? displayName, String email, String? photoUrl); + Future validateAppleToken(String identityToken); } diff --git a/domain/lib/usecases/auth_usecase.dart b/domain/lib/usecases/auth_usecase.dart index 7b68f24..4aeea5b 100644 --- a/domain/lib/usecases/auth_usecase.dart +++ b/domain/lib/usecases/auth_usecase.dart @@ -11,7 +11,8 @@ class AuthUseCase { AuthUseCase({required this.repository, required this.tokenProvider}); - Future signup(String email, String password,String verificationCode,{String? name}) async { + Future signup(String email, String password, String verificationCode, + {String? name}) async { return await repository.signup(email, password, verificationCode, name: name); } @@ -64,6 +65,10 @@ class AuthUseCase { return accessToken; } -} + Future validateAppleToken(String identityToken) async { + String email = await repository.validateAppleToken(identityToken); + return email; + } + - +} \ No newline at end of file diff --git a/lib/presentation/settings/viewModels/login_view_model.dart b/lib/presentation/settings/viewModels/login_view_model.dart index ae1fbe1..1e46989 100644 --- a/lib/presentation/settings/viewModels/login_view_model.dart +++ b/lib/presentation/settings/viewModels/login_view_model.dart @@ -29,6 +29,8 @@ class LoginViewModel extends ChangeNotifier { bool get isButtonEnabled => _isButtonEnabled; bool obscureText = true; + String? email; + void togglePasswordVisibility() { obscureText = !obscureText; notifyListeners(); @@ -122,6 +124,7 @@ class LoginViewModel extends ChangeNotifier { } Future signInWithApple() async { + String? email; try { _isSigningIn = false; // Request credentials from Apple @@ -141,42 +144,16 @@ class LoginViewModel extends ChangeNotifier { ), ); + print('Apple credential: $credential'); + // Get the identity token final identityToken = credential.identityToken; if (identityToken == null) { throw Exception('Identity token not available in Apple credentials'); } - // Send token to backend for validation - // This is where app sends token to backend to check if the the "identityToken" is real and safe to use. - final validateTokenEndpoint = - Uri.parse('http://localhost:8080/api/auth/sign_in_with_apple'); - final response = await http.Client().post( - validateTokenEndpoint, - headers: { - 'Content-Type': 'application/json', - }, - body: jsonEncode({ - 'identityToken': identityToken, - }), - ); - - if (response.statusCode != 200) { - print('Token validation failed: ${response.body}'); - throw Exception('Failed to validate token with backend'); - } - print('Token validated successfully: ${response.body}'); - - // Extract user information - final responseJson = jsonDecode(response.body); - final String? email = responseJson["payload"]["email"]; - - if (email == null) { - throw Exception('Email not available in Apple credentials'); - } else { - print(email); - } + // Validate the token with backend and retrieve email if valid + email = await validateAppleToken(identityToken); - // Sync user with backend (you may modify syncUser based on backend response if needed) await syncUser(null, email, null); _isSigningIn = true; @@ -187,4 +164,8 @@ class LoginViewModel extends ChangeNotifier { rethrow; // Optionally rethrow for higher-level error handling } } + + Future validateAppleToken(String identityToken) async { + return await authUseCase.validateAppleToken(identityToken); + } }