Description
Description
The qwen-portal provider in /packages/ai/src/utils/oauth/qwen-portal.ts is not actually implementing OAuth. Despite being classified as an OAuth provider, it uses a manual token copy-paste flow rather than proper OAuth 2.0 Device Code Flow.
Current implementation is functionally:
// BAD: Just asks user to manually paste token
const token = await options.onPrompt({
message: "Paste your Qwen OAuth token or API key",
placeholder: "sk-...",
});
This is not OAuth - it's a manual API key flow falsely labeled as OAuth. The provider:
- Has no OAuth 2.0 authorization code exchange
- Has no PKCE implementation
- Has no token refresh mechanism
- Is treated as a static API key in
refreshOAuthToken() (line 411 in index.ts)
Steps to Reproduce
- Run
omp auth login qwen-portal
- Observe the prompt: "Paste your Qwen OAuth token or API key"
- Note that there's no device code flow, no browser opening with verification code
- Compare with working OAuth providers like
github-copilot or openai-codex which open browser and use device code flow
Expected Behavior
- Browser opens to
https://chat.qwen.ai/api/v1/oauth2/device/code
- User sees device code and verification URL
- After authorization, tokens are automatically exchanged
- Refresh tokens are properly supported
Working reference: OmniRoute implementation at https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/oauth/providers/qwen.ts
Endpoints:
- Device code URL:
https://chat.qwen.ai/api/v1/oauth2/device/code
- Token URL:
https://chat.qwen.ai/api/v1/oauth2/token
- Scope:
openid profile email model.completion
- Method: OAuth 2.0 Device Authorization Grant (RFC 8628)
Error Output
Platform
Windows (WSL)
omp version
14.0.3
Bun version
1.3.11
Provider
None
Area
Authentication / Login
Additional context
Reference Implementation:
Working implementation pattern from OmniRoute:
// 1. Request device code
const response = await fetch(deviceCodeUrl, {
method: "POST",
body: new URLSearchParams({
client_id: config.clientId,
scope: config.scope,
code_challenge: codeChallenge,
code_challenge_method: "S256",
}),
});
// 2. Poll for token
const tokenResponse = await fetch(tokenUrl, {
method: "POST",
body: new URLSearchParams({
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
device_code: deviceCode,
code_verifier: codeVerifier,
}),
});
// 3. Returns proper OAuth credentials
return {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresIn: tokens.expires_in,
idToken: tokens.id_token,
email, // from JWT decode
};
Impact:
- Users expect OAuth capabilities (token refresh, revocation)
- Security: Device code flow is CLI standard (GitHub, etc.)
- UX: Manual copy-paste breaks OAuth workflows
- Classification mismatch causes confusion
Acceptance Criteria
PR
See PR: fix-qwen-oauth-device-code-flow branch
- Commit:
085d0c5a6 - feat(oauth): add proper Qwen Code OAuth device flow
Description
Description
The
qwen-portalprovider in/packages/ai/src/utils/oauth/qwen-portal.tsis not actually implementing OAuth. Despite being classified as an OAuth provider, it uses a manual token copy-paste flow rather than proper OAuth 2.0 Device Code Flow.Current implementation is functionally:
This is not OAuth - it's a manual API key flow falsely labeled as OAuth. The provider:
refreshOAuthToken()(line 411 in index.ts)Steps to Reproduce
omp auth login qwen-portalgithub-copilotoropenai-codexwhich open browser and use device code flowExpected Behavior
https://chat.qwen.ai/api/v1/oauth2/device/codeWorking reference: OmniRoute implementation at https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/oauth/providers/qwen.ts
Endpoints:
https://chat.qwen.ai/api/v1/oauth2/device/codehttps://chat.qwen.ai/api/v1/oauth2/tokenopenid profile email model.completionError Output
Platform
Windows (WSL)
omp version
14.0.3
Bun version
1.3.11
Provider
None
Area
Authentication / Login
Additional context
Reference Implementation:
/src/lib/oauth/providers/qwen.ts/src/lib/oauth/constants/oauth.tslines 57-64Working implementation pattern from OmniRoute:
Impact:
Acceptance Criteria
qwen-codecreated (not modifying existingqwen-portal)refreshOAuthToken()supports Qwen Code withrefreshQwenCodeToken()implementationid_tokenoraccess_tokenqwen-portalunchanged)PR
See PR:
fix-qwen-oauth-device-code-flowbranch085d0c5a6- feat(oauth): add proper Qwen Code OAuth device flow