refactor(open-sse): single-source OAuth token URLs via PROVIDERS (C2)

OAUTH_ENDPOINTS.{openai,anthropic,iflow}.token now reference PROVIDERS.*.tokenUrl
(values identical) so each backend token URL is declared once. qwen left as-is
(its appConstants/PROVIDERS values intentionally differ). Add verify-oauth-urls
script; URLs byte-for-byte equal, gate clean.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
decolua
2026-06-13 20:22:36 +07:00
co-authored by Cursor
parent 6597b81e5e
commit 22f6c42738
4 changed files with 103 additions and 4 deletions
+4 -3
View File
@@ -1,4 +1,5 @@
import { platform, arch } from "os";
import { PROVIDERS } from "./providers.js";
// === Gemini CLI ===
export const GEMINI_CLI_VERSION = "0.34.0";
@@ -169,11 +170,11 @@ export const OAUTH_ENDPOINTS = {
auth: "https://accounts.google.com/o/oauth2/auth"
},
openai: {
token: "https://auth.openai.com/oauth/token",
token: PROVIDERS.codex.tokenUrl,
auth: "https://auth.openai.com/oauth/authorize"
},
anthropic: {
token: "https://api.anthropic.com/v1/oauth/token",
token: PROVIDERS.claude.tokenUrl,
auth: "https://api.anthropic.com/v1/oauth/authorize"
},
qwen: {
@@ -181,7 +182,7 @@ export const OAUTH_ENDPOINTS = {
auth: "https://qwen.ai/api/v1/oauth2/device/code"
},
iflow: {
token: "https://iflow.cn/oauth/token",
token: PROVIDERS.iflow.tokenUrl,
auth: "https://iflow.cn/oauth"
},
github: {
File diff suppressed because one or more lines are too long
@@ -0,0 +1,44 @@
{
"oauthEndpoints": {
"google": {
"token": "https://oauth2.googleapis.com/token",
"auth": "https://accounts.google.com/o/oauth2/auth"
},
"openai": {
"token": "https://auth.openai.com/oauth/token",
"auth": "https://auth.openai.com/oauth/authorize"
},
"anthropic": {
"token": "https://api.anthropic.com/v1/oauth/token",
"auth": "https://api.anthropic.com/v1/oauth/authorize"
},
"qwen": {
"token": "https://qwen.ai/api/v1/oauth2/token",
"auth": "https://qwen.ai/api/v1/oauth2/device/code"
},
"iflow": {
"token": "https://iflow.cn/oauth/token",
"auth": "https://iflow.cn/oauth"
},
"github": {
"token": "https://github.com/login/oauth/access_token",
"auth": "https://github.com/login/oauth/authorize",
"deviceCode": "https://github.com/login/device/code"
}
},
"tokenUrls": {
"claude": "https://api.anthropic.com/v1/oauth/token",
"codex": "https://auth.openai.com/oauth/token",
"qwen": "https://chat.qwen.ai/api/v1/oauth2/token",
"iflow": "https://iflow.cn/oauth/token",
"kiro": "https://prod.us-east-1.auth.desktop.kiro.dev/refreshToken",
"xai": "https://auth.x.ai/oauth2/token",
"cline": "https://api.cline.bot/api/v1/auth/token",
"kimi-coding": "https://auth.kimi.com/api/oauth/token"
},
"authUrls": {
"qwen": "https://chat.qwen.ai/api/v1/oauth2/device/code",
"iflow": "https://iflow.cn/oauth",
"kiro": "https://prod.us-east-1.auth.desktop.kiro.dev"
}
}
+54
View File
@@ -0,0 +1,54 @@
// Verify OAuth/token URLs resolve byte-for-byte vs snapshot (backend open-sse).
// Captures every URL executors/tokenRefresh actually use, to guard DRY dedup.
import { readFileSync, writeFileSync, existsSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
import { OAUTH_ENDPOINTS } from "../../open-sse/config/appConstants.js";
import { PROVIDERS } from "../../open-sse/config/providers.js";
const here = dirname(fileURLToPath(import.meta.url));
const snapPath = join(here, "oauth-urls-baseline.json");
// Collect resolved URLs that backend code depends on
const resolved = {
oauthEndpoints: OAUTH_ENDPOINTS,
tokenUrls: {
claude: PROVIDERS.claude?.tokenUrl,
codex: PROVIDERS.codex?.tokenUrl,
qwen: PROVIDERS.qwen?.tokenUrl,
iflow: PROVIDERS.iflow?.tokenUrl,
kiro: PROVIDERS.kiro?.tokenUrl,
xai: PROVIDERS.xai?.tokenUrl,
cline: PROVIDERS.cline?.tokenUrl,
"kimi-coding": PROVIDERS["kimi-coding"]?.tokenUrl,
},
authUrls: {
qwen: PROVIDERS.qwen?.authUrl,
iflow: PROVIDERS.iflow?.authUrl,
kiro: PROVIDERS.kiro?.authUrl,
},
};
const current = JSON.parse(JSON.stringify(resolved));
const mode = process.argv[2];
if (mode === "--snapshot") {
writeFileSync(snapPath, JSON.stringify(current, null, 2));
console.log(`Snapshot OAuth URLs → ${snapPath}`);
process.exit(0);
}
if (!existsSync(snapPath)) {
console.error("No baseline. Run with --snapshot on OLD code first.");
process.exit(1);
}
const baseline = JSON.parse(readFileSync(snapPath, "utf8"));
const a = JSON.stringify(baseline);
const b = JSON.stringify(current);
if (a === b) {
console.log("✅ OAuth URLs byte-for-byte equal.");
process.exit(0);
}
console.error("❌ OAuth URL mismatch:");
console.error("baseline:", a);
console.error("current :", b);
process.exit(1);