| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- 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: "[email protected]", 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: "[email protected]" }
- 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: "[email protected]" })
- 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: "[email protected]" })
- 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")
- })
- })
- })
|