diff --git a/app/lib/features/auth/social_providers.dart b/app/lib/features/auth/social_providers.dart index 08f0bd6..7ab2b18 100644 --- a/app/lib/features/auth/social_providers.dart +++ b/app/lib/features/auth/social_providers.dart @@ -396,6 +396,13 @@ final class KakaoSignInProvider implements SocialAuthProvider { if (error.error == kakao.AuthErrorCause.accessDenied) { return const AuthCancelled(); } + // 카카오톡 왕복 뒤 인가 코드 · 토큰 단계 실패(KOE · misconfigured 등). 원인을 로그로만 남긴다. + debugPrint( + '[KakaoSignInProvider] auth failed: ${error.error} ${error.errorDescription}', + ); + return const AuthFailed('E-AUTH-03', '소셜 로그인에 실패했습니다.'); + } on kakao.KakaoException catch (error) { + debugPrint('[KakaoSignInProvider] sdk error: $error'); return const AuthFailed('E-AUTH-03', '소셜 로그인에 실패했습니다.'); } on FirebaseFunctionsException catch (error) { final details = error.details; @@ -407,10 +414,7 @@ final class KakaoSignInProvider implements SocialAuthProvider { '가입하신 이메일과 다른 계정입니다.', 'E-AUTH-08' => '다른 FANUZU 계정에 이미 연결된 소셜 계정입니다.', 'E-AUTH-09' => '이미 연결된 계정입니다.', - _ => - flow == AuthFlow.link - ? '계정 연결에 실패했습니다.' - : '소셜 로그인에 실패했습니다.', + _ => flow == AuthFlow.link ? '계정 연결에 실패했습니다.' : '소셜 로그인에 실패했습니다.', }); } on fb.FirebaseAuthException catch (error) { return AuthFailed(authCatalogCode(error), authMessage(error, flow: flow)); diff --git a/app/test/auth_kakao_test.dart b/app/test/auth_kakao_test.dart index 6af6143..2e89df0 100644 --- a/app/test/auth_kakao_test.dart +++ b/app/test/auth_kakao_test.dart @@ -6,6 +6,8 @@ import 'package:fancake/features/auth/social_providers.dart'; import 'package:firebase_auth_mocks/firebase_auth_mocks.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart' + as kakao_sdk; /// 카카오 — SDK 로그인(주입) → 서버 교환(주입) → signInWithCustomToken 계약. /// 토큰 검증·기존 oidc.kakao 사용자 매핑은 서버 테스트(functions/test/auth_kakao.test.ts)가 본다. @@ -61,6 +63,23 @@ void main() { expect(sent, isEmpty); }); + test('카카오 인가 · 토큰 단계 실패는 로그인 실패(E-AUTH-03) · 서버를 부르지 않는다', () async { + for (final error in [ + kakao_sdk.KakaoAuthException( + kakao_sdk.AuthErrorCause.misconfigured, + 'KOE', + ), + kakao_sdk.KakaoClientException(kakao_sdk.ClientErrorCause.unknown, 'sdk'), + ]) { + final outcome = await kakao( + MockFirebaseAuth(), + token: () async => throw error, + ).signIn(); + expect((outcome as AuthFailed).code, 'E-AUTH-03', reason: '$error'); + } + expect(sent, isEmpty); + }); + test('서버 오류는 카탈로그 코드로 · 로그인하지 않는다', () async { final auth = MockFirebaseAuth(); final outcome = await kakao(