MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / refreshAccessToken

Function refreshAccessToken

packages/oauth/src/oauth.ts:208–272  ·  view source on GitHub ↗
(
  config: OAuthFlowConfig,
  refreshToken: string,
  options: RefreshOptions,
)

Source from the content-addressed store, hash-verified

206}
207
208export async function refreshAccessToken(
209 config: OAuthFlowConfig,
210 refreshToken: string,
211 options: RefreshOptions,
212): Promise<TokenInfo> {
213 const maxRetries = options.maxRetries ?? 3;
214 const backoff = options.backoffMs ?? ((attempt) => 2 ** attempt * 1000);
215 const sleep =
216 options.sleep ??
217 ((ms: number) =>
218 new Promise<void>((resolve) => {
219 setTimeout(resolve, ms);
220 }));
221 const url = `${config.oauthHost.replace(/\/$/, '')}/api/oauth/token`;
222
223 let lastError: Error | undefined;
224 for (let attempt = 0; attempt < maxRetries; attempt += 1) {
225 let status: number;
226 let data: Record<string, unknown>;
227 try {
228 ({ status, data } = await postForm(
229 url,
230 {
231 client_id: config.clientId,
232 grant_type: 'refresh_token',
233 refresh_token: refreshToken,
234 },
235 options.deviceHeaders,
236 ));
237 } catch (error) {
238 // Transport-level failure (DNS, connection refused, timeout). Treat
239 // as retryable to match Python's `aiohttp.ClientError` handling.
240 lastError = error instanceof Error ? error : new OAuthError(String(error));
241 if (attempt < maxRetries - 1) {
242 await sleep(backoff(attempt));
243 continue;
244 }
245 throw lastError instanceof Error ? lastError : new OAuthError(String(lastError));
246 }
247
248 if (status === 200 && typeof data['access_token'] === 'string') {
249 return tokenFromResponse(data);
250 }
251
252 const errorCode = typeof data['error'] === 'string' ? data['error'] : '';
253 const detail = extractApiErrorMessage(data);
254 if (status === 401 || status === 403 || errorCode === 'invalid_grant') {
255 throw new OAuthUnauthorizedError(detail ?? 'Token refresh unauthorized.');
256 }
257
258 const desc = detail ?? `Token refresh failed (HTTP ${status}).`;
259 if (RETRYABLE_STATUSES.has(status)) {
260 lastError = new RetryableRefreshError(desc);
261 if (attempt < maxRetries - 1) {
262 await sleep(backoff(attempt));
263 continue;
264 }
265 // fall through: out of retries, surface the retryable error

Callers 3

refreshTokenFunction · 0.90
oauth.test.tsFile · 0.90
constructorMethod · 0.90

Calls 5

extractApiErrorMessageFunction · 0.90
postFormFunction · 0.85
tokenFromResponseFunction · 0.85
hasMethod · 0.65
sleepFunction · 0.50

Tested by 1

refreshTokenFunction · 0.72