initial commit
This commit is contained in:
86
internal/application/auth/oauth.go
Normal file
86
internal/application/auth/oauth.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"base/pkg/jwt"
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"base/internal/domain/auth"
|
||||
"base/internal/dto"
|
||||
)
|
||||
|
||||
func (s *service) GetOAuthRedirectURL(ctx context.Context, request dto.OAuthRedirectURLRequest) (string, error) {
|
||||
provider := s.oauthService.Client(request.Provider)
|
||||
|
||||
state := uuid.New().String()
|
||||
redirectURL := provider.GetConsentAuthUrl(ctx, state)
|
||||
|
||||
return redirectURL, nil
|
||||
}
|
||||
|
||||
func (s *service) OAuthCallback(ctx context.Context, request dto.OAuthCallbackRequest) (*dto.OAuthCallbackResponse, error) {
|
||||
oauthProvider := s.oauthService.Client(request.Provider)
|
||||
|
||||
token, err := oauthProvider.ExchangeCodeWithToken(ctx, request.Code)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to exchange code for token: %w", err)
|
||||
}
|
||||
|
||||
userInfo, err := oauthProvider.GetUserInfo(ctx, token.AccessToken, token.RefreshToken)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user info: %w", err)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
accessExpiry := now.Add(time.Duration(token.ExpiresIn) * time.Second)
|
||||
refreshExpiry := now.Add(7 * 24 * time.Hour)
|
||||
|
||||
user := &auth.User{
|
||||
ID: uuid.New(), // Will be set by repository if user exists
|
||||
Email: userInfo.Email(),
|
||||
FirstName: userInfo.FirstName(),
|
||||
LastName: userInfo.LastName(),
|
||||
Status: auth.UserStatusActive,
|
||||
EmailVerified: true, // OAuth providers verify email
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
account := &auth.Account{
|
||||
ID: uuid.New(),
|
||||
Provider: request.Provider,
|
||||
AccessToken: &token.AccessToken,
|
||||
RefreshToken: &token.RefreshToken,
|
||||
AccessTokenExpiry: &accessExpiry,
|
||||
RefreshTokenExpiry: &refreshExpiry,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
isNewUser, err := s.userRepo.UpsertWithAccount(ctx, userInfo.Email(), user, account)
|
||||
if err != nil {
|
||||
s.logger.Error().Err(err).Msg("failed to upsert user and account")
|
||||
return nil, fmt.Errorf("failed to upsert user and account: %w", err)
|
||||
}
|
||||
|
||||
tokens, genErr := s.jwtService.GenerateAccessRefreshTokenPair(ctx, &jwt.TokenData{Sub: user.ID.String()})
|
||||
if genErr != nil {
|
||||
return nil, fmt.Errorf("failed to generate tokens: %w", genErr)
|
||||
}
|
||||
|
||||
s.logger.Info().
|
||||
Str("user_id", user.ID.String()).
|
||||
Str("email", user.Email).
|
||||
Bool("is_new_user", isNewUser).
|
||||
Str("provider", request.Provider.String()).
|
||||
Msg("OAuth callback completed successfully")
|
||||
|
||||
return &dto.OAuthCallbackResponse{
|
||||
AccessToken: tokens.AccessToken,
|
||||
RefreshToken: tokens.RefreshToken,
|
||||
IsNewUser: isNewUser,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user