Files
OmniRoute/tests/unit/cline-workos-auth-token-shape.test.ts
Syed Raheemuddin 975b29c275 feat(core): improve observability for dual-auth fallback execution (#11828)
* feat(core): improve observability for dual-auth fallback execution

* refactor(executors): keep the clinepass auth decision in buildClinepassHeaders

The clinepass case no longer re-decides OAuth vs BYOK off
credentials.authType; it always delegates to buildClinepassHeaders(),
which already keys the decision off credentials.accessToken, and only
the debug log line branches. The OAuth test now uses the real credential
shape ({ accessToken }) instead of an OAuth token stored in apiKey, and
a parity test pins the executor output to buildClinepassHeaders() for
both credential shapes so the two paths cannot drift apart.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-09-19 00:02:02 -03:00

180 lines
7.1 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
applyClineProtocolHeaders,
buildClineHeaders,
buildClinepassHeaders,
getClineAccessToken,
getClineAuthorizationHeader,
resolveClineTaskId,
} from "../../src/shared/utils/clineAuth.ts";
import { buildProviderHeaders } from "../../open-sse/services/provider.ts";
import { DefaultExecutor } from "../../open-sse/executors/default.ts";
test("getClineAccessToken prefixes the token with workos:", () => {
assert.equal(getClineAccessToken("abc123"), "workos:abc123");
});
test("getClineAccessToken is idempotent when already prefixed", () => {
assert.equal(getClineAccessToken("workos:abc123"), "workos:abc123");
});
test("getClineAccessToken trims and rejects empty / non-string input", () => {
assert.equal(getClineAccessToken(" abc123 "), "workos:abc123");
assert.equal(getClineAccessToken(" "), "");
assert.equal(getClineAccessToken(""), "");
assert.equal(getClineAccessToken(undefined), "");
assert.equal(getClineAccessToken(null), "");
assert.equal(getClineAccessToken(42), "");
});
test("getClineAuthorizationHeader builds a workos-prefixed bearer header", () => {
assert.equal(getClineAuthorizationHeader("abc123"), "Bearer workos:abc123");
assert.equal(getClineAuthorizationHeader(""), "");
});
test("buildClineHeaders emits the full cline client header set", () => {
const headers = buildClineHeaders("abc123", {}, { taskId: "task-123" });
assert.equal(headers.Authorization, "Bearer workos:abc123");
assert.equal(headers["HTTP-Referer"], "https://cline.bot");
assert.equal(headers["X-Title"], "Cline");
assert.equal(headers["X-CLIENT-TYPE"], "omniroute");
assert.equal(headers["X-Task-ID"], "task-123");
assert.equal(headers["X-IS-MULTIROOT"], "false");
assert.ok(/^Cline\//.test(headers["User-Agent"]));
assert.ok(!/9router/i.test(JSON.stringify(headers)));
});
test("buildClineHeaders merges extra headers and omits Authorization with no token", () => {
const headers = buildClineHeaders("", {
Accept: "application/json",
"x-task-id": "configured-task-must-not-leak",
});
assert.equal(headers.Accept, "application/json");
assert.ok(!("Authorization" in headers));
assert.ok(!("X-Task-ID" in headers));
assert.ok(!("x-task-id" in headers));
// Client-identification headers are still present even without a token.
assert.equal(headers["X-CLIENT-TYPE"], "omniroute");
});
test("resolveClineTaskId forwards client task identity but does not invent one", () => {
assert.equal(resolveClineTaskId({ "x-task-id": "client-task-123" }), "client-task-123");
assert.equal(resolveClineTaskId({}), undefined);
assert.equal(resolveClineTaskId(null), undefined);
});
test("required Cline protocol headers override conflicting configured casing", () => {
const headers = applyClineProtocolHeaders(
{
"user-agent": "other-client/1",
"x-client-type": "other-client",
"x-task-id": "stored-task",
},
{ clientVersion: "3.8.49", taskId: "request-task" }
);
assert.equal(headers["User-Agent"], "Cline/3.8.49");
assert.equal(headers["X-CLIENT-TYPE"], "omniroute");
assert.equal(headers["X-Task-ID"], "request-task");
assert.ok(!("user-agent" in headers));
assert.ok(!("x-client-type" in headers));
assert.ok(!("x-task-id" in headers));
});
test("ClinePass BYOK and OAuth auth modes both carry the full protocol headers", () => {
const byok = buildClinepassHeaders({ apiKey: "sk-pass" }, undefined, {
taskId: "task-byok",
});
assert.equal(byok.Authorization, "Bearer sk-pass");
assert.equal(byok["X-Task-ID"], "task-byok");
assert.equal(byok["X-CLIENT-TYPE"], "omniroute");
const oauth = buildClinepassHeaders({ accessToken: "oauth-token" }, undefined, {
taskId: "task-oauth",
});
assert.equal(oauth.Authorization, "Bearer workos:oauth-token");
assert.equal(oauth["X-Task-ID"], "task-oauth");
assert.equal(oauth["X-CLIENT-TYPE"], "omniroute");
});
test("buildProviderHeaders uses the cline workos auth token shape", () => {
const headers = buildProviderHeaders("cline", { apiKey: "tok-abc" }, true);
assert.equal(headers.Authorization, "Bearer workos:tok-abc");
assert.equal(headers["HTTP-Referer"], "https://cline.bot");
assert.equal(headers["X-CLIENT-TYPE"], "omniroute");
});
test("buildProviderHeaders honors an accessToken for cline", () => {
const headers = buildProviderHeaders("cline", { accessToken: "acc-xyz" }, false);
assert.equal(headers.Authorization, "Bearer workos:acc-xyz");
});
test("DefaultExecutor.buildHeaders uses the cline workos auth token shape", () => {
const executor = new DefaultExecutor("cline");
const headers = executor.buildHeaders({ apiKey: "tok-abc" }, true, {
"X-Task-ID": "task-from-client",
});
assert.equal(headers.Authorization, "Bearer workos:tok-abc");
assert.equal(headers["HTTP-Referer"], "https://cline.bot");
assert.equal(headers["X-CLIENT-TYPE"], "omniroute");
assert.equal(headers["X-Title"], "Cline");
assert.equal(headers["X-Task-ID"], "task-from-client");
const withoutTaskId = executor.buildHeaders({ apiKey: "tok-abc" }, true, {});
assert.ok(!("X-Task-ID" in withoutTaskId));
});
test("DefaultExecutor labels internal health checks separately from user traffic", () => {
const executor = new DefaultExecutor("cline");
const headers = executor.buildHeaders({ apiKey: "tok-abc" }, true, {
"X-Internal-Test": "combo-health-check",
});
assert.equal(headers["X-CLIENT-TYPE"], "omniroute-internal-health-check");
// BaseExecutor reapplies the required protocol headers immediately before dispatch.
applyClineProtocolHeaders(headers, { taskId: headers["X-Task-ID"] });
assert.equal(headers["X-CLIENT-TYPE"], "omniroute-internal-health-check");
});
test("DefaultExecutor handles dual-auth logging for clinepass provider", () => {
const executor = new DefaultExecutor("clinepass");
// API key auth mode
const apiKeyHeaders = executor.buildHeaders(
{ apiKey: "sk-cline-123", authType: "apikey" },
true,
{}
);
assert.equal(apiKeyHeaders["Authorization"], "Bearer sk-cline-123");
// OAuth token auth mode — real OAuth credential shape (accessToken, not apiKey;
// see #11828 review) so this exercises the effectiveKey || credentials?.accessToken
// fallback that actually runs in production.
const oauthHeaders = executor.buildHeaders(
{ accessToken: "workos_tok_456", authType: "oauth" },
true,
{}
);
assert.equal(oauthHeaders["Authorization"], "Bearer workos:workos_tok_456");
});
test("DefaultExecutor clinepass authType branch matches buildClinepassHeaders() directly (parity)", () => {
const executor = new DefaultExecutor("clinepass");
const apiKeyCredentials = { apiKey: "sk-cline-789", authType: "apikey" };
const oauthCredentials = { accessToken: "workos_tok_789", authType: "oauth" };
for (const credentials of [apiKeyCredentials, oauthCredentials]) {
const viaExecutor = executor.buildHeaders(credentials, true, {});
const viaDirectCall = buildClinepassHeaders(credentials, credentials.apiKey);
assert.equal(
viaExecutor["Authorization"],
viaDirectCall["Authorization"],
`Authorization mismatch for ${JSON.stringify(credentials)}`
);
}
});