package util import ( "fmt" "time" "apskel-pos-be/internal/entities" "github.com/golang-jwt/jwt/v5" ) // GenerateCustomerTokens generates access and refresh tokens for customer func GenerateCustomerTokens(customer *entities.Customer, secret string, tokenTTLMinutes int) (string, string, time.Time, error) { now := time.Now() expiresAt := now.Add(time.Duration(tokenTTLMinutes) * time.Minute) // Create access token claims accessClaims := jwt.MapClaims{ "customer_id": customer.ID.String(), "phone_number": *customer.PhoneNumber, "name": customer.Name, "type": "access", "iat": now.Unix(), "exp": expiresAt.Unix(), } // Create refresh token claims (longer expiration) refreshExpiresAt := now.Add(time.Duration(tokenTTLMinutes*7) * 24 * time.Hour) // 7 days refreshClaims := jwt.MapClaims{ "customer_id": customer.ID.String(), "phone_number": *customer.PhoneNumber, "type": "refresh", "iat": now.Unix(), "exp": refreshExpiresAt.Unix(), } // Generate access token accessToken := jwt.NewWithClaims(jwt.SigningMethodHS256, accessClaims) accessTokenString, err := accessToken.SignedString([]byte(secret)) if err != nil { return "", "", time.Time{}, fmt.Errorf("failed to generate access token: %w", err) } // Generate refresh token refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims) refreshTokenString, err := refreshToken.SignedString([]byte(secret)) if err != nil { return "", "", time.Time{}, fmt.Errorf("failed to generate refresh token: %w", err) } return accessTokenString, refreshTokenString, expiresAt, nil } // ValidateCustomerToken validates a customer JWT token func ValidateCustomerToken(tokenString, secret string) (*jwt.Token, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return []byte(secret), nil }) if err != nil { return nil, fmt.Errorf("failed to parse token: %w", err) } if !token.Valid { return nil, fmt.Errorf("invalid token") } return token, nil } // ExtractCustomerIDFromToken extracts customer ID from JWT token func ExtractCustomerIDFromToken(token *jwt.Token) (string, error) { claims, ok := token.Claims.(jwt.MapClaims) if !ok { return "", fmt.Errorf("invalid token claims") } customerID, ok := claims["customer_id"].(string) if !ok { return "", fmt.Errorf("customer_id not found in token") } return customerID, nil }