Cline/ClinePass requests failed with HTTP 401 ("Please make sure you are using
the latest version of Cline and re-authenticate your Cline account", #3230 /
#2333 / #3644). `getClineAccessToken()` unconditionally prefixed every token
with `workos:`, which is correct for Cline OAuth access tokens (WorkOS JWTs)
but wrong for ClinePass API keys — those are opaque strings (e.g. `clp_…`)
that the API accepts only verbatim, so the `workos:`-prefixed value was
rejected.
Only prefix tokens that look like a WorkOS JWT (`eyJ…`); API keys and other
opaque tokens pass through untouched, and an existing `workos:` prefix is
never doubled.
Also register `clinepass` in the token-refresh handlers. ClinePass shares
Cline's WorkOS auth endpoints, but without the entry expired ClinePass OAuth
tokens were never rotated, so every request kept 401ing. Finally, list
`apikey` first in the ClinePass `authModes` (ClinePass is meant to be used
with an API key from app.cline.bot/settings/api-keys), and add an "Import
from /models" button that pulls the live Cline catalog into custom models.
40 lines
1.5 KiB
JavaScript
40 lines
1.5 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import {
|
|
getClineAccessToken,
|
|
getClineAuthorizationHeader,
|
|
} from "../../open-sse/shared/clineAuth.js";
|
|
|
|
test("getClineAccessToken keeps an existing workos: prefix", () => {
|
|
const token = "workos:eyJhbGciOiJSUzI1NiJ9.eyJwYXAiJ9";
|
|
assert.equal(getClineAccessToken(token), token);
|
|
assert.equal(getClineAccessToken(` ${token} `), token);
|
|
});
|
|
|
|
test("getClineAccessToken prefixes a bare WorkOS JWT with workos:", () => {
|
|
const jwt = "eyJhbGciOiJSUzI1NiJ9.eyJwYXAiJ9";
|
|
assert.equal(getClineAccessToken(jwt), `workos:${jwt}`);
|
|
});
|
|
|
|
test("getClineAccessToken does NOT prefix ClinePass API keys", () => {
|
|
// ClinePass API keys are opaque strings (e.g. clp_…). Sending them as
|
|
// `workos:clp_…` makes api.cline.bot respond 401.
|
|
assert.equal(getClineAccessToken("clp_1234567890abcdef"), "clp_1234567890abcdef");
|
|
assert.equal(getClineAccessToken("sk-9r-abcdef"), "sk-9r-abcdef");
|
|
assert.equal(getClineAccessToken(""), "");
|
|
assert.equal(getClineAccessToken(" "), "");
|
|
assert.equal(getClineAccessToken(undefined), "");
|
|
assert.equal(getClineAccessToken(null), "");
|
|
});
|
|
|
|
test("getClineAuthorizationHeader builds a Bearer header without double prefixing", () => {
|
|
assert.equal(getClineAuthorizationHeader("clp_abc"), "Bearer clp_abc");
|
|
assert.equal(
|
|
getClineAuthorizationHeader("eyJpeg.eyJbG"),
|
|
"Bearer workos:eyJpeg.eyJbG"
|
|
);
|
|
assert.equal(
|
|
getClineAuthorizationHeader("workos:eyJpeg.eyJbG"),
|
|
"Bearer workos:eyJpeg.eyJbG"
|
|
);
|
|
}); |