This commit is contained in:
2025-08-23 16:22:46 -04:00
parent 0c50b05324
commit 3e02ef57b9
9 changed files with 196 additions and 18 deletions

View File

@ -37,6 +37,7 @@ func (s *applicationService) Create(ctx context.Context, req *domain.CreateAppli
Type: req.Type,
CallbackURL: req.CallbackURL,
HMACKey: generateHMACKey(), // TODO: Use proper key generation
TokenPrefix: req.TokenPrefix,
TokenRenewalDuration: req.TokenRenewalDuration,
MaxTokenDuration: req.MaxTokenDuration,
Owner: req.Owner,

View File

@ -3,6 +3,7 @@ package services
import (
"context"
"fmt"
"strings"
"time"
"github.com/google/uuid"
@ -72,8 +73,8 @@ func (s *tokenService) CreateStaticToken(ctx context.Context, req *domain.Create
return nil, fmt.Errorf("some requested permissions are invalid")
}
// Generate secure token
tokenInfo, err := s.tokenGen.GenerateTokenWithInfo()
// Generate secure token with custom prefix
tokenInfo, err := s.tokenGen.GenerateTokenWithInfoAndPrefix(app.TokenPrefix, "static")
if err != nil {
s.logger.Error("Failed to generate secure token", zap.Error(err))
return nil, fmt.Errorf("failed to generate token: %w", err)
@ -239,12 +240,21 @@ func (s *tokenService) GenerateUserToken(ctx context.Context, appID, userID stri
}
// Generate JWT token using JWT manager
tokenString, err := s.jwtManager.GenerateToken(userToken)
jwtTokenString, err := s.jwtManager.GenerateToken(userToken)
if err != nil {
s.logger.Error("Failed to generate JWT token", zap.Error(err))
return "", fmt.Errorf("failed to generate token: %w", err)
}
// Add custom prefix wrapper for user tokens if application has one
var finalToken string
if app.TokenPrefix != "" {
// For user JWT tokens, we wrap the JWT with custom prefix
finalToken = app.TokenPrefix + "UT-" + jwtTokenString
} else {
finalToken = jwtTokenString
}
s.logger.Info("User token generated successfully",
zap.String("app_id", appID),
zap.String("user_id", userID),
@ -252,7 +262,7 @@ func (s *tokenService) GenerateUserToken(ctx context.Context, appID, userID stri
zap.Time("expires_at", userToken.ExpiresAt),
zap.Time("max_valid_at", userToken.MaxValidAt))
return tokenString, nil
return finalToken, nil
}
// VerifyToken verifies a token and returns verification response
@ -389,8 +399,27 @@ func (s *tokenService) verifyStaticToken(ctx context.Context, req *domain.Verify
func (s *tokenService) verifyUserToken(ctx context.Context, req *domain.VerifyRequest, app *domain.Application) (*domain.VerifyResponse, error) {
s.logger.Debug("Verifying user token", zap.String("app_id", req.AppID))
// Extract JWT token from potentially prefixed format
jwtToken := req.Token
if app.TokenPrefix != "" {
expectedPrefix := app.TokenPrefix + "UT-"
if strings.HasPrefix(req.Token, expectedPrefix) {
jwtToken = strings.TrimPrefix(req.Token, expectedPrefix)
} else {
// Token doesn't have expected prefix
s.logger.Warn("User token missing expected prefix",
zap.String("app_id", req.AppID),
zap.String("expected_prefix", expectedPrefix))
return &domain.VerifyResponse{
Valid: false,
Permitted: false,
Error: "Invalid token format",
}, nil
}
}
// Check if token is revoked first
isRevoked, err := s.jwtManager.IsTokenRevoked(req.Token)
isRevoked, err := s.jwtManager.IsTokenRevoked(jwtToken)
if err != nil {
s.logger.Error("Failed to check token revocation status", zap.Error(err))
return &domain.VerifyResponse{
@ -410,7 +439,7 @@ func (s *tokenService) verifyUserToken(ctx context.Context, req *domain.VerifyRe
}
// Validate JWT token
claims, err := s.jwtManager.ValidateToken(req.Token)
claims, err := s.jwtManager.ValidateToken(jwtToken)
if err != nil {
s.logger.Warn("JWT token validation failed", zap.Error(err), zap.String("app_id", req.AppID))
return &domain.VerifyResponse{