diff --git a/frontend/src/components/account/CreateAccountModal.vue b/frontend/src/components/account/CreateAccountModal.vue index cff7ae1c59..49ea1a1401 100644 --- a/frontend/src/components/account/CreateAccountModal.vue +++ b/frontend/src/components/account/CreateAccountModal.vue @@ -2870,7 +2870,7 @@ import ProxySelector from '@/components/common/ProxySelector.vue' import GroupSelector from '@/components/common/GroupSelector.vue' import ModelWhitelistSelector from '@/components/account/ModelWhitelistSelector.vue' import QuotaLimitCard from '@/components/account/QuotaLimitCard.vue' -import { applyInterceptWarmup } from '@/components/account/credentialsBuilder' +import { applyInterceptWarmup, applyRefreshTokenFallback } from '@/components/account/credentialsBuilder' import { formatDateTimeLocalInput, parseDateTimeLocalInput } from '@/utils/format' import { createStableObjectKeyResolver } from '@/utils/stableObjectKey' import { @@ -4405,6 +4405,7 @@ const handleOpenAIBatchRT = async (refreshTokenInput: string, clientId?: string) } const credentials = oauthClient.buildCredentials(tokenInfo) + applyRefreshTokenFallback(credentials, refreshTokens[i]) if (clientId) { credentials.client_id = clientId } diff --git a/frontend/src/components/account/__tests__/credentialsBuilder.spec.ts b/frontend/src/components/account/__tests__/credentialsBuilder.spec.ts index be2a8d521c..98bdacf7bc 100644 --- a/frontend/src/components/account/__tests__/credentialsBuilder.spec.ts +++ b/frontend/src/components/account/__tests__/credentialsBuilder.spec.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest' -import { applyInterceptWarmup } from '../credentialsBuilder' +import { applyInterceptWarmup, applyRefreshTokenFallback } from '../credentialsBuilder' describe('applyInterceptWarmup', () => { it('create + enabled=true: should set intercept_warmup_requests to true', () => { @@ -44,3 +44,23 @@ describe('applyInterceptWarmup', () => { expect('intercept_warmup_requests' in creds).toBe(false) }) }) + +describe('applyRefreshTokenFallback', () => { + it('adds the original refresh token when credentials do not include one', () => { + const creds: Record = { access_token: 'tok' } + applyRefreshTokenFallback(creds, 'rt-original') + expect(creds.refresh_token).toBe('rt-original') + }) + + it('does not overwrite a refresh token returned by the upstream response', () => { + const creds: Record = { access_token: 'tok', refresh_token: 'rt-new' } + applyRefreshTokenFallback(creds, 'rt-original') + expect(creds.refresh_token).toBe('rt-new') + }) + + it('ignores empty fallback refresh tokens', () => { + const creds: Record = { access_token: 'tok' } + applyRefreshTokenFallback(creds, ' ') + expect('refresh_token' in creds).toBe(false) + }) +}) diff --git a/frontend/src/components/account/credentialsBuilder.ts b/frontend/src/components/account/credentialsBuilder.ts index b8008e8bfb..d15609e59a 100644 --- a/frontend/src/components/account/credentialsBuilder.ts +++ b/frontend/src/components/account/credentialsBuilder.ts @@ -9,3 +9,16 @@ export function applyInterceptWarmup( delete credentials.intercept_warmup_requests } } + +export function applyRefreshTokenFallback( + credentials: Record, + refreshToken: string +): void { + const fallback = refreshToken.trim() + const current = + typeof credentials.refresh_token === 'string' ? credentials.refresh_token.trim() : '' + + if (!current && fallback) { + credentials.refresh_token = fallback + } +}