package com.tasteby.service; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.gson.GsonFactory; import com.tasteby.domain.UserInfo; import com.tasteby.security.JwtTokenProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; import java.util.Collections; import java.util.Map; @Service public class AuthService { private static final Logger log = LoggerFactory.getLogger(AuthService.class); private final UserService userService; private final JwtTokenProvider jwtProvider; private final GoogleIdTokenVerifier verifier; public AuthService(UserService userService, JwtTokenProvider jwtProvider, @Value("${app.google.client-id}") String googleClientId) { this.userService = userService; this.jwtProvider = jwtProvider; this.verifier = new GoogleIdTokenVerifier.Builder( new NetHttpTransport(), GsonFactory.getDefaultInstance()) .setAudience(Collections.singletonList(googleClientId)) .build(); } public Map loginGoogle(String idTokenString) { try { GoogleIdToken idToken = verifier.verify(idTokenString); if (idToken == null) { throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid Google token"); } GoogleIdToken.Payload payload = idToken.getPayload(); UserInfo user = userService.findOrCreate( "google", payload.getSubject(), payload.getEmail(), (String) payload.get("name"), (String) payload.get("picture")); // Convert to Map for JWT Map userMap = Map.of( "id", user.getId(), "email", user.getEmail() != null ? user.getEmail() : "", "nickname", user.getNickname() != null ? user.getNickname() : "", "is_admin", user.isAdmin() ); String accessToken = jwtProvider.createToken(userMap); return Map.of("access_token", accessToken, "user", user); } catch (ResponseStatusException e) { throw e; } catch (Exception e) { // #266 — 외부에는 고정 메시지만, 상세는 로그로 (Google verifier 내부 네트워크/공개키 // 조회 실패 메시지가 클라이언트에 노출되지 않도록) log.warn("Google token verification failed: {}", e.getMessage()); throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid Google token"); } } public UserInfo getCurrentUser(String userId) { UserInfo user = userService.findById(userId); if (user == null) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found"); } return user; } }