mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 22:03:58 +00:00
- Rename packages/opencode → packages/tfcode (directory only) - Rename bin/opencode → bin/tfcode (CLI binary) - Rename .opencode → .tfcode (config directory) - Update package.json name and bin field - Update config directory path references (.tfcode) - Keep internal code references as 'opencode' for easy upstream sync - Keep @opencode-ai/* workspace package names This minimal branding approach allows clean merges from upstream opencode repository while providing tfcode branding for users.
124 lines
4.0 KiB
TypeScript
124 lines
4.0 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import {
|
|
parseJwtClaims,
|
|
extractAccountIdFromClaims,
|
|
extractAccountId,
|
|
type IdTokenClaims,
|
|
} from "../../src/plugin/codex"
|
|
|
|
function createTestJwt(payload: object): string {
|
|
const header = Buffer.from(JSON.stringify({ alg: "none" })).toString("base64url")
|
|
const body = Buffer.from(JSON.stringify(payload)).toString("base64url")
|
|
return `${header}.${body}.sig`
|
|
}
|
|
|
|
describe("plugin.codex", () => {
|
|
describe("parseJwtClaims", () => {
|
|
test("parses valid JWT with claims", () => {
|
|
const payload = { email: "test@example.com", chatgpt_account_id: "acc-123" }
|
|
const jwt = createTestJwt(payload)
|
|
const claims = parseJwtClaims(jwt)
|
|
expect(claims).toEqual(payload)
|
|
})
|
|
|
|
test("returns undefined for JWT with less than 3 parts", () => {
|
|
expect(parseJwtClaims("invalid")).toBeUndefined()
|
|
expect(parseJwtClaims("only.two")).toBeUndefined()
|
|
})
|
|
|
|
test("returns undefined for invalid base64", () => {
|
|
expect(parseJwtClaims("a.!!!invalid!!!.b")).toBeUndefined()
|
|
})
|
|
|
|
test("returns undefined for invalid JSON payload", () => {
|
|
const header = Buffer.from("{}").toString("base64url")
|
|
const invalidJson = Buffer.from("not json").toString("base64url")
|
|
expect(parseJwtClaims(`${header}.${invalidJson}.sig`)).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe("extractAccountIdFromClaims", () => {
|
|
test("extracts chatgpt_account_id from root", () => {
|
|
const claims: IdTokenClaims = { chatgpt_account_id: "acc-root" }
|
|
expect(extractAccountIdFromClaims(claims)).toBe("acc-root")
|
|
})
|
|
|
|
test("extracts chatgpt_account_id from nested https://api.openai.com/auth", () => {
|
|
const claims: IdTokenClaims = {
|
|
"https://api.openai.com/auth": { chatgpt_account_id: "acc-nested" },
|
|
}
|
|
expect(extractAccountIdFromClaims(claims)).toBe("acc-nested")
|
|
})
|
|
|
|
test("prefers root over nested", () => {
|
|
const claims: IdTokenClaims = {
|
|
chatgpt_account_id: "acc-root",
|
|
"https://api.openai.com/auth": { chatgpt_account_id: "acc-nested" },
|
|
}
|
|
expect(extractAccountIdFromClaims(claims)).toBe("acc-root")
|
|
})
|
|
|
|
test("extracts from organizations array as fallback", () => {
|
|
const claims: IdTokenClaims = {
|
|
organizations: [{ id: "org-123" }, { id: "org-456" }],
|
|
}
|
|
expect(extractAccountIdFromClaims(claims)).toBe("org-123")
|
|
})
|
|
|
|
test("returns undefined when no accountId found", () => {
|
|
const claims: IdTokenClaims = { email: "test@example.com" }
|
|
expect(extractAccountIdFromClaims(claims)).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe("extractAccountId", () => {
|
|
test("extracts from id_token first", () => {
|
|
const idToken = createTestJwt({ chatgpt_account_id: "from-id-token" })
|
|
const accessToken = createTestJwt({ chatgpt_account_id: "from-access-token" })
|
|
expect(
|
|
extractAccountId({
|
|
id_token: idToken,
|
|
access_token: accessToken,
|
|
refresh_token: "rt",
|
|
}),
|
|
).toBe("from-id-token")
|
|
})
|
|
|
|
test("falls back to access_token when id_token has no accountId", () => {
|
|
const idToken = createTestJwt({ email: "test@example.com" })
|
|
const accessToken = createTestJwt({
|
|
"https://api.openai.com/auth": { chatgpt_account_id: "from-access" },
|
|
})
|
|
expect(
|
|
extractAccountId({
|
|
id_token: idToken,
|
|
access_token: accessToken,
|
|
refresh_token: "rt",
|
|
}),
|
|
).toBe("from-access")
|
|
})
|
|
|
|
test("returns undefined when no tokens have accountId", () => {
|
|
const token = createTestJwt({ email: "test@example.com" })
|
|
expect(
|
|
extractAccountId({
|
|
id_token: token,
|
|
access_token: token,
|
|
refresh_token: "rt",
|
|
}),
|
|
).toBeUndefined()
|
|
})
|
|
|
|
test("handles missing id_token", () => {
|
|
const accessToken = createTestJwt({ chatgpt_account_id: "acc-123" })
|
|
expect(
|
|
extractAccountId({
|
|
id_token: "",
|
|
access_token: accessToken,
|
|
refresh_token: "rt",
|
|
}),
|
|
).toBe("acc-123")
|
|
})
|
|
})
|
|
})
|