Add Google OAuth authentication support
- Add Google OAuth token verification and user lookup/creation - Add GoogleAuthRequest and GoogleAuthResponse DTOs - Add GoogleLogin handler in auth_handler.go - Add google_auth.go service for token verification - Add FindByGoogleID repository method for user lookup - Add GoogleID field to User model - Add Google OAuth configuration (client ID, enabled flag) - Add i18n translations for Google auth error messages - Add Google verification email template support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,10 +16,11 @@ import (
|
||||
|
||||
// AuthHandler handles authentication endpoints
|
||||
type AuthHandler struct {
|
||||
authService *services.AuthService
|
||||
emailService *services.EmailService
|
||||
cache *services.CacheService
|
||||
appleAuthService *services.AppleAuthService
|
||||
authService *services.AuthService
|
||||
emailService *services.EmailService
|
||||
cache *services.CacheService
|
||||
appleAuthService *services.AppleAuthService
|
||||
googleAuthService *services.GoogleAuthService
|
||||
}
|
||||
|
||||
// NewAuthHandler creates a new auth handler
|
||||
@@ -36,6 +37,11 @@ func (h *AuthHandler) SetAppleAuthService(appleAuth *services.AppleAuthService)
|
||||
h.appleAuthService = appleAuth
|
||||
}
|
||||
|
||||
// SetGoogleAuthService sets the Google auth service (called after initialization)
|
||||
func (h *AuthHandler) SetGoogleAuthService(googleAuth *services.GoogleAuthService) {
|
||||
h.googleAuthService = googleAuth
|
||||
}
|
||||
|
||||
// Login handles POST /api/auth/login/
|
||||
func (h *AuthHandler) Login(c *gin.Context) {
|
||||
var req requests.LoginRequest
|
||||
@@ -427,3 +433,52 @@ func (h *AuthHandler) AppleSignIn(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GoogleSignIn handles POST /api/auth/google-sign-in/
|
||||
func (h *AuthHandler) GoogleSignIn(c *gin.Context) {
|
||||
var req requests.GoogleSignInRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, responses.ErrorResponse{
|
||||
Error: i18n.LocalizedMessage(c, "error.invalid_request_body"),
|
||||
Details: map[string]string{
|
||||
"validation": err.Error(),
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if h.googleAuthService == nil {
|
||||
log.Error().Msg("Google auth service not configured")
|
||||
c.JSON(http.StatusInternalServerError, responses.ErrorResponse{
|
||||
Error: i18n.LocalizedMessage(c, "error.google_signin_not_configured"),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
response, err := h.authService.GoogleSignIn(c.Request.Context(), h.googleAuthService, &req)
|
||||
if err != nil {
|
||||
status := http.StatusUnauthorized
|
||||
message := i18n.LocalizedMessage(c, "error.google_signin_failed")
|
||||
|
||||
if errors.Is(err, services.ErrUserInactive) {
|
||||
message = i18n.LocalizedMessage(c, "error.account_inactive")
|
||||
} else if errors.Is(err, services.ErrGoogleSignInFailed) {
|
||||
message = i18n.LocalizedMessage(c, "error.invalid_google_token")
|
||||
}
|
||||
|
||||
log.Debug().Err(err).Msg("Google Sign In failed")
|
||||
c.JSON(status, responses.ErrorResponse{Error: message})
|
||||
return
|
||||
}
|
||||
|
||||
// Send welcome email for new users (async)
|
||||
if response.IsNewUser && h.emailService != nil && response.User.Email != "" {
|
||||
go func() {
|
||||
if err := h.emailService.SendGoogleWelcomeEmail(response.User.Email, response.User.FirstName); err != nil {
|
||||
log.Error().Err(err).Str("email", response.User.Email).Msg("Failed to send Google welcome email")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user