feat: multi-feature update

This commit is contained in:
chaos
2026-06-15 06:16:16 +08:00
parent 6f415428d3
commit 04d30f9dd1
58 changed files with 4610 additions and 419 deletions
+42 -1
View File
@@ -94,12 +94,53 @@ func (p *GenericOAuthProvider) ExchangeToken(ctx context.Context, code string, c
logger.LogDebug(ctx, "[OAuth-Generic-%s] ExchangeToken: code=%s...", p.config.Slug, code[:min(len(code), 10)])
// Handle pkce.xxx format from some OAuth providers (e.g., dc.hhhl.cc)
// The code is in format: pkce.base64json({token, codeChallenge, codeChallengeMethod})
// We need to send the FULL pkce.xxx code to the token endpoint, not just the extracted token
var extractedCodeChallenge string
if strings.HasPrefix(code, "pkce.") {
encodedPart := code[5:] // Remove "pkce." prefix
decoded, err := base64.RawURLEncoding.DecodeString(encodedPart)
if err == nil {
var pkceData struct {
Token string `json:"token"`
CodeChallenge string `json:"codeChallenge"`
CodeChallengeMethod string `json:"codeChallengeMethod"`
}
if jsonErr := common.Unmarshal(decoded, &pkceData); jsonErr == nil && pkceData.Token != "" {
extractedCodeChallenge = pkceData.CodeChallenge
logger.LogDebug(ctx, "[OAuth-Generic-%s] ExchangeToken: parsed pkce format, token=%s..., codeChallenge=%s",
p.config.Slug, pkceData.Token[:min(len(pkceData.Token), 10)], extractedCodeChallenge)
}
}
}
redirectUri := fmt.Sprintf("%s/oauth/%s", system_setting.ServerAddress, p.config.Slug)
values := url.Values{}
values.Set("grant_type", "authorization_code")
values.Set("code", code)
values.Set("code", code) // Send the full pkce.xxx code
values.Set("redirect_uri", redirectUri)
// Log all parameters being sent for debugging
logger.LogDebug(ctx, "[OAuth-Generic-%s] ExchangeToken: sending to %s with params: grant_type=authorization_code, code=%s, redirect_uri=%s, client_id=%s",
p.config.Slug, p.config.TokenEndpoint, code[:min(len(code), 20)], redirectUri, p.config.ClientId)
// Add PKCE code_verifier if enabled
if p.config.PKCEEnabled && c != nil {
if codeVerifier, exists := c.Get("pkce_code_verifier"); exists {
if verifier, ok := codeVerifier.(string); ok && verifier != "" {
values.Set("code_verifier", verifier)
logger.LogDebug(ctx, "[OAuth-Generic-%s] ExchangeToken: PKCE code_verifier added", p.config.Slug)
}
}
// Some OAuth providers expect code_challenge to be sent during token exchange
if extractedCodeChallenge != "" {
values.Set("code_challenge", extractedCodeChallenge)
values.Set("code_challenge_method", "S256")
logger.LogDebug(ctx, "[OAuth-Generic-%s] ExchangeToken: PKCE code_challenge added: %s", p.config.Slug, extractedCodeChallenge)
}
}
// Determine auth style
authStyle := p.config.AuthStyle
if authStyle == AuthStyleAutoDetect {