diff --git a/internal/handlers/token.go b/internal/handlers/token.go index 22bb1a7..09444a3 100644 --- a/internal/handlers/token.go +++ b/internal/handlers/token.go @@ -88,7 +88,7 @@ func (h *TokenHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - idToken, err := generateIDToken(h.issuerURL, clientID) + idToken, err := h.generateIDToken(h.issuerURL, clientID) if err != nil { log.Printf("Error generating ID token: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) @@ -139,9 +139,21 @@ func generateRefreshToken(clientID string) string { } // Helper function to generate a mock ID token -func generateIDToken(issuerURL, clientID string) (string, error) { +func (h *TokenHandler) generateIDToken(issuerURL, clientID string) (string, error) { // Generate a subject ID based on client ID sub := "user-" + clientID - - return jwt.GenerateIDToken(issuerURL, clientID, sub) + + // Check if there's a configured email in the token config + var email string + tokenConfig := h.store.GetTokenConfig() + if tokenConfig != nil { + if userInfoConfig, ok := tokenConfig["user_info"].(map[string]interface{}); ok { + if configuredEmail, ok := userInfoConfig["email"].(string); ok { + email = configuredEmail + } + } + } + + // If no email is configured, pass empty string (don't default to generated email) + return jwt.GenerateIDToken(issuerURL, clientID, sub, email) } diff --git a/internal/jwt/jwt.go b/internal/jwt/jwt.go index 22ec28c..2908c65 100644 --- a/internal/jwt/jwt.go +++ b/internal/jwt/jwt.go @@ -37,7 +37,7 @@ func InitKeys() error { } // GenerateIDToken creates a signed JWT ID token -func GenerateIDToken(issuer, clientID, sub string) (string, error) { +func GenerateIDToken(issuer, clientID, sub, email string) (string, error) { if privateKey == nil { if err := InitKeys(); err != nil { return "", err @@ -53,6 +53,11 @@ func GenerateIDToken(issuer, clientID, sub string) (string, error) { "iat": now.Unix(), "nonce": generateNonce(), } + + // Only include email claim if an email is provided + if email != "" { + claims["email"] = email + } token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) token.Header["kid"] = keyID diff --git a/internal/jwt/jwt_test.go b/internal/jwt/jwt_test.go index 24a7897..742d2c7 100644 --- a/internal/jwt/jwt_test.go +++ b/internal/jwt/jwt_test.go @@ -34,8 +34,9 @@ func TestGenerateIDToken(t *testing.T) { issuer := "http://localhost:8080" clientID := "test-client" sub := "user-123" + email := "user-123@example.com" - tokenString, err := GenerateIDToken(issuer, clientID, sub) + tokenString, err := GenerateIDToken(issuer, clientID, sub, email) if err != nil { t.Fatalf("Failed to generate ID token: %v", err) } @@ -62,6 +63,10 @@ func TestGenerateIDToken(t *testing.T) { if claims["aud"] != clientID { t.Errorf("Expected audience %s, got %v", clientID, claims["aud"]) } + + if claims["email"] != email { + t.Errorf("Expected email %s, got %v", email, claims["email"]) + } } func TestGenerateAccessToken(t *testing.T) { @@ -153,8 +158,9 @@ func TestVerifyToken(t *testing.T) { issuer := "http://localhost:8080" clientID := "test-client" sub := "user-123" + email := "user-123@example.com" - tokenString, err := GenerateIDToken(issuer, clientID, sub) + tokenString, err := GenerateIDToken(issuer, clientID, sub, email) if err != nil { t.Fatalf("Failed to generate ID token: %v", err) } @@ -186,8 +192,9 @@ func TestTokenFormat(t *testing.T) { issuer := "http://localhost:8080" clientID := "test-client" sub := "user-123" + email := "user-123@example.com" - tokenString, err := GenerateIDToken(issuer, clientID, sub) + tokenString, err := GenerateIDToken(issuer, clientID, sub, email) if err != nil { t.Fatalf("Failed to generate ID token: %v", err) } diff --git a/pkg/oauth/google.go b/pkg/oauth/google.go index 3a44988..4dd5da6 100644 --- a/pkg/oauth/google.go +++ b/pkg/oauth/google.go @@ -50,6 +50,7 @@ func (p *GoogleProvider) ExchangeCodeForToken(code string) (map[string]interface // Generate proper JWT tokens sub := "user-" + authRequest.ClientID + email := authRequest.ClientID + "@example.com" scopes := []string{"openid", "email", "profile"} accessToken, err := jwt.GenerateAccessToken(p.IssuerURL, authRequest.ClientID, sub, scopes) @@ -57,7 +58,7 @@ func (p *GoogleProvider) ExchangeCodeForToken(code string) (map[string]interface return nil, &Error{Code: "server_error", Description: "Failed to generate access token"} } - idToken, err := jwt.GenerateIDToken(p.IssuerURL, authRequest.ClientID, sub) + idToken, err := jwt.GenerateIDToken(p.IssuerURL, authRequest.ClientID, sub, email) if err != nil { return nil, &Error{Code: "server_error", Description: "Failed to generate ID token"} }