From 29f3e1894e207d704df4de05f406d0fa3a51aede Mon Sep 17 00:00:00 2001 From: apeltekci Date: Mon, 9 Mar 2026 16:21:29 +0700 Subject: [PATCH] fix(cline): use workos auth token shape Made-with: Cursor --- open-sse/executors/default.js | 3 ++ open-sse/services/provider.js | 5 +++ src/app/api/providers/[id]/test/testUtils.js | 18 +++------- src/shared/utils/clineAuth.js | 37 ++++++++++++++++++++ 4 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 src/shared/utils/clineAuth.js diff --git a/open-sse/executors/default.js b/open-sse/executors/default.js index a47da86..eba3c61 100644 --- a/open-sse/executors/default.js +++ b/open-sse/executors/default.js @@ -1,5 +1,6 @@ import { BaseExecutor } from "./base.js"; import { PROVIDERS, OAUTH_ENDPOINTS } from "../config/constants.js"; +import { buildClineHeaders } from "../../src/shared/utils/clineAuth.js"; export class DefaultExecutor extends BaseExecutor { constructor(provider) { @@ -65,6 +66,8 @@ export class DefaultExecutor extends BaseExecutor { if (credentials.providerSpecificData?.orgId) { headers["X-Kilocode-OrganizationID"] = credentials.providerSpecificData.orgId; } + } else if (this.provider === "cline") { + Object.assign(headers, buildClineHeaders(credentials.apiKey || credentials.accessToken)); } else { headers["Authorization"] = `Bearer ${credentials.apiKey || credentials.accessToken}`; } diff --git a/open-sse/services/provider.js b/open-sse/services/provider.js index 42931ec..9310136 100644 --- a/open-sse/services/provider.js +++ b/open-sse/services/provider.js @@ -1,4 +1,5 @@ import { PROVIDERS } from "../config/constants.js"; +import { buildClineHeaders } from "../../src/shared/utils/clineAuth.js"; const OPENAI_COMPATIBLE_PREFIX = "openai-compatible-"; const OPENAI_COMPATIBLE_DEFAULTS = { @@ -285,6 +286,10 @@ export function buildProviderHeaders(provider, credentials, stream = true, body case "openrouter": headers["Authorization"] = `Bearer ${credentials.apiKey || credentials.accessToken}`; break; + + case "cline": + Object.assign(headers, buildClineHeaders(credentials.apiKey || credentials.accessToken)); + break; case "glm": case "kimi": diff --git a/src/app/api/providers/[id]/test/testUtils.js b/src/app/api/providers/[id]/test/testUtils.js index 0f08fca..7a11f97 100644 --- a/src/app/api/providers/[id]/test/testUtils.js +++ b/src/app/api/providers/[id]/test/testUtils.js @@ -13,6 +13,7 @@ import { CLINE_CONFIG, KILOCODE_CONFIG, } from "@/lib/oauth/constants/oauth"; +import { buildClineHeaders } from "@/shared/utils/clineAuth"; // OAuth provider test endpoints const OAUTH_TEST_CONFIG = { @@ -58,19 +59,10 @@ const OAUTH_TEST_CONFIG = { }; async function probeClineAccessToken(accessToken) { - const res = await fetch("https://api.cline.bot/api/v1/chat/completions", { - method: "POST", - headers: { - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - "HTTP-Referer": "https://cline.bot", - "X-Title": "Cline", - }, - body: JSON.stringify({ - model: "cl/anthropic/claude-sonnet-4-20250514", - messages: [{ role: "user", content: "test" }], - max_tokens: 1, - stream: false, + const res = await fetch("https://api.cline.bot/api/v1/users/me", { + method: "GET", + headers: buildClineHeaders(accessToken, { + Accept: "application/json", }), }); diff --git a/src/shared/utils/clineAuth.js b/src/shared/utils/clineAuth.js new file mode 100644 index 0000000..a2da21d --- /dev/null +++ b/src/shared/utils/clineAuth.js @@ -0,0 +1,37 @@ +import pkg from "../../../package.json" with { type: "json" }; + +const APP_VERSION = pkg.version || "0.0.0"; + +export function getClineAccessToken(token) { + if (typeof token !== "string") return ""; + const trimmed = token.trim(); + if (!trimmed) return ""; + return trimmed.startsWith("workos:") ? trimmed : `workos:${trimmed}`; +} + +export function getClineAuthorizationHeader(token) { + const accessToken = getClineAccessToken(token); + return accessToken ? `Bearer ${accessToken}` : ""; +} + +export function buildClineHeaders(token, extraHeaders = {}) { + const authorization = getClineAuthorizationHeader(token); + const headers = { + "HTTP-Referer": "https://cline.bot", + "X-Title": "Cline", + "User-Agent": `9Router/${APP_VERSION}`, + "X-PLATFORM": process.platform || "unknown", + "X-PLATFORM-VERSION": process.version || "unknown", + "X-CLIENT-TYPE": "9router", + "X-CLIENT-VERSION": APP_VERSION, + "X-CORE-VERSION": APP_VERSION, + "X-IS-MULTIROOT": "false", + ...extraHeaders, + }; + + if (authorization) { + headers.Authorization = authorization; + } + + return headers; +}