From d5b7fdf8533014327aca8b3db61076382ee0a730 Mon Sep 17 00:00:00 2001 From: nguyennt1 Date: Sat, 15 Nov 2025 22:59:46 +0700 Subject: [PATCH] =?UTF-8?q?th=C3=AAm=20l=C6=B0u=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/vega/hrm/dto/CustomTokenResponse.java | 14 ++++ .../com/vega/hrm/service/GoogleService.java | 29 +++++++- .../hrm/core/entities/UserGoogleToken.java | 73 +++++++++++++++++++ .../UserGoogleTokenRepository.java | 11 +++ .../src/main/resources/application.properties | 4 + .../src/main/resources/youtube.properties | 3 + 6 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 vega-hrm-auth/src/main/java/com/vega/hrm/dto/CustomTokenResponse.java create mode 100644 vega-hrm-core/src/main/java/com/vega/hrm/core/entities/UserGoogleToken.java create mode 100644 vega-hrm-core/src/main/java/com/vega/hrm/core/repositories/UserGoogleTokenRepository.java create mode 100644 vega-hrm-core/src/main/resources/application.properties create mode 100644 vega-hrm-core/src/main/resources/youtube.properties diff --git a/vega-hrm-auth/src/main/java/com/vega/hrm/dto/CustomTokenResponse.java b/vega-hrm-auth/src/main/java/com/vega/hrm/dto/CustomTokenResponse.java new file mode 100644 index 0000000..79ae8cc --- /dev/null +++ b/vega-hrm-auth/src/main/java/com/vega/hrm/dto/CustomTokenResponse.java @@ -0,0 +1,14 @@ +package com.vega.hrm.dto; + +import com.google.api.client.auth.oauth2.TokenResponse; +import com.google.api.client.util.Key; + +public class CustomTokenResponse extends TokenResponse { + + @Key("refresh_token_expires_in") + private Long refreshTokenExpiresIn; + + public Long getRefreshTokenExpiresIn() { + return refreshTokenExpiresIn; + } +} diff --git a/vega-hrm-auth/src/main/java/com/vega/hrm/service/GoogleService.java b/vega-hrm-auth/src/main/java/com/vega/hrm/service/GoogleService.java index 36ae600..22be426 100644 --- a/vega-hrm-auth/src/main/java/com/vega/hrm/service/GoogleService.java +++ b/vega-hrm-auth/src/main/java/com/vega/hrm/service/GoogleService.java @@ -15,12 +15,17 @@ import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.oauth2.Oauth2; import com.vega.hrm.core.component.TokenStore; +import com.vega.hrm.core.entities.UserGoogleToken; import com.vega.hrm.core.models.responses.BaseResponse; import com.vega.hrm.core.dto.GoogleOAuthConfig; import com.google.api.services.oauth2.model.Userinfo; +import com.vega.hrm.core.repositories.UserGoogleTokenRepository; +import com.vega.hrm.dto.CustomTokenResponse; import java.io.IOException; import java.security.GeneralSecurityException; +import java.time.Instant; import java.util.Objects; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.Setter; import org.springframework.stereotype.Service; @@ -30,7 +35,7 @@ import org.springframework.stereotype.Service; public class GoogleService { private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); private final TokenStore tokenStore; - + private final UserGoogleTokenRepository userGoogleTokenRepository; public BaseResponse getGoogleAuthUrl() { var googleOAuthConfig = GoogleOAuthConfig.builder().build(); NetHttpTransport httpTransport = null; @@ -72,9 +77,9 @@ public class GoogleService { .setAccessType("offline") .setApprovalPrompt("force") .build(); - TokenResponse tokenResponse = null; + CustomTokenResponse tokenResponse = null; try { - tokenResponse = flow.newTokenRequest(code).setRedirectUri(googleOAuthConfig.redirectUri).execute(); + tokenResponse = (CustomTokenResponse) flow.newTokenRequest(code).setRedirectUri(googleOAuthConfig.redirectUri).execute(); } catch (IOException e) { return BaseResponse.invalid(e.getMessage()); } @@ -92,7 +97,25 @@ public class GoogleService { } catch (IOException e) { return BaseResponse.invalid(e.getMessage()); } + String email = userInfo.getEmail(); + var userGoogleToken = userGoogleTokenRepository.findUserGoogleTokenByEmail(email); + + if (userGoogleToken == null) { + userGoogleToken = new UserGoogleToken(); + userGoogleToken.setId(UUID.randomUUID()); + userGoogleToken.setEmail(email); + userGoogleToken.setAccessToken(tokenResponse.getAccessToken()); + userGoogleToken.setRefreshToken(tokenResponse.getRefreshToken()); + userGoogleToken.setScope(tokenResponse.getScope()); + userGoogleToken.setExpiresIn(tokenResponse.getExpiresInSeconds()); + userGoogleToken.setRefreshTokenExpiresIn(tokenResponse.getRefreshTokenExpiresIn()); + userGoogleToken.setCreatedAt(Instant.now().plusSeconds(tokenResponse.getExpiresInSeconds())); + userGoogleToken.setRefreshTokenExpiresAt(Instant.now().plusSeconds(tokenResponse.getRefreshTokenExpiresIn())); + userGoogleToken.setCreatedAt(Instant.now()); + userGoogleTokenRepository.save(userGoogleToken); + } + tokenStore.storeToken(email, tokenResponse); return BaseResponse.success("00",true); } diff --git a/vega-hrm-core/src/main/java/com/vega/hrm/core/entities/UserGoogleToken.java b/vega-hrm-core/src/main/java/com/vega/hrm/core/entities/UserGoogleToken.java new file mode 100644 index 0000000..16c1c08 --- /dev/null +++ b/vega-hrm-core/src/main/java/com/vega/hrm/core/entities/UserGoogleToken.java @@ -0,0 +1,73 @@ +package com.vega.hrm.core.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.Instant; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.ColumnDefault; + +@Getter +@Setter +@Entity +@Table(name = "user_google_tokens") +public class UserGoogleToken { + + @Id + @ColumnDefault("gen_random_uuid()") + @Column(name = "id", nullable = false) + private UUID id; + + @Size(max = 255) + @Column(name = "email") + private String email; + + @Size(max = 2048) + @NotNull + @Column(name = "access_token", nullable = false, length = 2048) + private String accessToken; + + @Size(max = 2048) + @NotNull + @Column(name = "refresh_token", nullable = false, length = 2048) + private String refreshToken; + + @Column(name = "expires_in") + private Long expiresIn; + + @Column(name = "refresh_token_expires_in") + private Long refreshTokenExpiresIn; + + @Size(max = 2500) + @Column(name = "scope", length = 2500) + private String scope; + + @Size(max = 50) + @Column(name = "token_type", length = 50) + private String tokenType; + + @NotNull + @Column(name = "expires_at", nullable = false) + private Instant expiresAt; + + @NotNull + @Column(name = "refresh_token_expires_at", nullable = false) + private Instant refreshTokenExpiresAt; + + @ColumnDefault("CURRENT_TIMESTAMP") + @Column(name = "created_at") + private Instant createdAt; + + @ColumnDefault("CURRENT_TIMESTAMP") + @Column(name = "updated_at") + private Instant updatedAt; + +} \ No newline at end of file diff --git a/vega-hrm-core/src/main/java/com/vega/hrm/core/repositories/UserGoogleTokenRepository.java b/vega-hrm-core/src/main/java/com/vega/hrm/core/repositories/UserGoogleTokenRepository.java new file mode 100644 index 0000000..bfd0f83 --- /dev/null +++ b/vega-hrm-core/src/main/java/com/vega/hrm/core/repositories/UserGoogleTokenRepository.java @@ -0,0 +1,11 @@ +package com.vega.hrm.core.repositories; + +import com.vega.hrm.core.entities.BoUser; +import com.vega.hrm.core.entities.UserGoogleToken; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +@Repository +public interface UserGoogleTokenRepository extends JpaRepository { + UserGoogleToken findUserGoogleTokenByEmail(String user); +} diff --git a/vega-hrm-core/src/main/resources/application.properties b/vega-hrm-core/src/main/resources/application.properties new file mode 100644 index 0000000..4b1dcd5 --- /dev/null +++ b/vega-hrm-core/src/main/resources/application.properties @@ -0,0 +1,4 @@ +google.client.clientId = 719251949807-0jqbsmlh0a116cm8vm47oknmc5vpi19q.apps.googleusercontent.com +google.client.clientSecret = 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 +google.redirect.uri=https://localhost:8443/api/auth/google/callback + diff --git a/vega-hrm-core/src/main/resources/youtube.properties b/vega-hrm-core/src/main/resources/youtube.properties new file mode 100644 index 0000000..9c2fc65 --- /dev/null +++ b/vega-hrm-core/src/main/resources/youtube.properties @@ -0,0 +1,3 @@ +# Replace this with an API key available at +# https://console.developers.google.com/project/_/apiui/credential +youtube.apikey=AIzaSyCH_ERSntAWkfZF7XFf877GTQKkE982cKk