73 lines
2.1 KiB
Go
73 lines
2.1 KiB
Go
package helper
|
|
|
|
import (
|
|
"authentication/models"
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
func ExtractEmailFromToken(tokenString string) (string, error) {
|
|
// Remove "Bearer " prefix if it exists
|
|
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
|
|
|
|
// Handle null/empty token cases
|
|
if tokenString == "" || tokenString == "null" || tokenString == "undefined" {
|
|
return "", errors.New("no valid token provided")
|
|
}
|
|
|
|
token, err := jwt.ParseWithClaims(tokenString, &models.AccessToken{}, func(token *jwt.Token) (interface{}, error) {
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
return nil, errors.New("unexpected signing method")
|
|
}
|
|
secretKey := os.Getenv("JWT_SECRET_KEY")
|
|
if secretKey == "" {
|
|
return nil, errors.New("JWT secret key not set")
|
|
}
|
|
return []byte(secretKey), nil
|
|
})
|
|
|
|
if err == nil && token.Valid {
|
|
if claims, ok := token.Claims.(*models.AccessToken); ok {
|
|
if claims.Email != "" && strings.Contains(claims.Email, "@") {
|
|
log.Printf("Successfully extracted email from AccessToken: %s", claims.Email)
|
|
return claims.Email, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// If AccessToken parsing failed, try MapClaims for backward compatibility
|
|
log.Printf("AccessToken parsing failed: %v, trying MapClaims fallback", err)
|
|
token, err = jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
|
return nil, errors.New("unexpected signing method")
|
|
}
|
|
secretKey := os.Getenv("JWT_SECRET_KEY")
|
|
if secretKey == "" {
|
|
return nil, errors.New("JWT secret key not set")
|
|
}
|
|
return []byte(secretKey), nil
|
|
})
|
|
|
|
if err != nil {
|
|
log.Printf("MapClaims parsing also failed: %v", err)
|
|
return "", errors.New("invalid token signature")
|
|
}
|
|
|
|
// Extract claims from MapClaims
|
|
claims, ok := token.Claims.(jwt.MapClaims)
|
|
if !ok || !token.Valid {
|
|
return "", errors.New("invalid token claims")
|
|
}
|
|
|
|
if email, ok := claims["email"].(string); ok && strings.Contains(email, "@") {
|
|
log.Printf("Successfully extracted email from MapClaims: %s", email)
|
|
return email, nil
|
|
}
|
|
|
|
return "", errors.New("email not found in token")
|
|
}
|