namespace Application.Abstractions.Authentication; /// 소셜 provider 토큰 교환 결과 (authorization code → access token) public sealed record SocialTokens( string AccessToken, string? RefreshToken, DateTime ExpiresAt, string[] Scopes ); /// /// 소셜 provider 프로필 조회 결과. /// Email 은 카카오 선택동의 미동의 시 null. EmailVerified 는 provider 가 검증을 보장하는 경우만 true /// (네이버는 연락처 이메일이라 항상 false — d5 §③ 계정 매칭 정책). /// public sealed record SocialUserInfo( string ProviderUserKey, string? Email, bool EmailVerified, string? Nickname, string? ProfileImageUrl ); /// /// Naver/Kakao authorization code 로그인 provider (d5 §③). /// Google 로그인은 GIS id_token 방식(IGoogleTokenValidator) 현행 유지 — 비목표. /// public interface ISocialAuthProvider { /// "Naver" | "Kakao" string Provider { get; } /// 동의 화면 authorize URL 생성 (state 는 호출자가 생성/보관 후 콜백에서 대조) string GetAuthorizationUrl(string clientId, string redirectUri, string state); /// 승인 코드 → 토큰 교환. 실패 시 null (사유는 provider 가 로깅) Task ExchangeCodeAsync(string code, string redirectUri, string? state, string clientId, string? clientSecret, CancellationToken ct); /// 액세스 토큰으로 프로필 조회. 실패 시 null Task GetUserInfoAsync(string accessToken, CancellationToken ct); }