MCPcopy Create free account
hub / github.com/chainreactors/EvilProxy / exchangeDeviceCode

Method exchangeDeviceCode

internal/auth/kimi/kimi.go:266–343  ·  view source on GitHub ↗

exchangeDeviceCode attempts to exchange the device code for an access token. Returns (token, error, shouldContinue).

(ctx context.Context, deviceCode string)

Source from the content-addressed store, hash-verified

264// exchangeDeviceCode attempts to exchange the device code for an access token.
265// Returns (token, error, shouldContinue).
266func (c *DeviceFlowClient) exchangeDeviceCode(ctx context.Context, deviceCode string) (*KimiTokenData, error, bool) {
267 data := url.Values{}
268 data.Set("client_id", kimiClientID)
269 data.Set("device_code", deviceCode)
270 data.Set("grant_type", "urn:ietf:params:oauth:grant-type:device_code")
271
272 req, err := http.NewRequestWithContext(ctx, http.MethodPost, kimiTokenURL, strings.NewReader(data.Encode()))
273 if err != nil {
274 return nil, fmt.Errorf("kimi: failed to create token request: %w", err), false
275 }
276 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
277 req.Header.Set("Accept", "application/json")
278 for k, v := range c.commonHeaders() {
279 req.Header.Set(k, v)
280 }
281
282 resp, err := c.httpClient.Do(req)
283 if err != nil {
284 return nil, fmt.Errorf("kimi: token request failed: %w", err), false
285 }
286 defer func() {
287 if errClose := resp.Body.Close(); errClose != nil {
288 log.Errorf("kimi token exchange: close body error: %v", errClose)
289 }
290 }()
291
292 bodyBytes, err := io.ReadAll(resp.Body)
293 if err != nil {
294 return nil, fmt.Errorf("kimi: failed to read token response: %w", err), false
295 }
296
297 // Parse response - Kimi returns 200 for both success and pending states
298 var oauthResp struct {
299 Error string `json:"error"`
300 ErrorDescription string `json:"error_description"`
301 AccessToken string `json:"access_token"`
302 RefreshToken string `json:"refresh_token"`
303 TokenType string `json:"token_type"`
304 ExpiresIn float64 `json:"expires_in"`
305 Scope string `json:"scope"`
306 }
307
308 if err = json.Unmarshal(bodyBytes, &oauthResp); err != nil {
309 return nil, fmt.Errorf("kimi: failed to parse token response: %w", err), false
310 }
311
312 if oauthResp.Error != "" {
313 switch oauthResp.Error {
314 case "authorization_pending":
315 return nil, nil, true // Continue polling
316 case "slow_down":
317 return nil, nil, true // Continue polling (with increased interval handled by caller)
318 case "expired_token":
319 return nil, fmt.Errorf("kimi: device code expired"), false
320 case "access_denied":
321 return nil, fmt.Errorf("kimi: access denied by user"), false
322 default:
323 return nil, fmt.Errorf("kimi: OAuth error: %s - %s", oauthResp.Error, oauthResp.ErrorDescription), false

Callers 1

PollForTokenMethod · 0.95

Calls 4

commonHeadersMethod · 0.95
DoMethod · 0.65
CloseMethod · 0.65
SetMethod · 0.45

Tested by

no test coverage detected