import { describe, it, expect } from 'vitest'; import { parseJwtClaims, extractAccountId } from './openai.js'; function base64UrlEncode(obj: unknown): string { return Buffer.from(JSON.stringify(obj)).toString('base64url'); } function makeJwt(payload: Record): string { const header = base64UrlEncode({ alg: 'none', typ: 'JWT' }); const body = base64UrlEncode(payload); // Signature is ignored by parseJwtClaims. return `${header}.${body}.sig`; } describe('OpenAI OAuth helpers', () => { it('parseJwtClaims returns undefined for non-jwt strings', () => { expect(parseJwtClaims('not-a-jwt')).toBeUndefined(); }); it('parseJwtClaims parses base64url payload', () => { const token = makeJwt({ chatgpt_account_id: 'acct_123' }); const claims = parseJwtClaims(token); expect(claims?.chatgpt_account_id).toBe('acct_123'); }); it('extractAccountId prefers chatgpt_account_id', () => { const tokens = { access_token: makeJwt({ chatgpt_account_id: 'acct_a' }), refresh_token: 'rt', id_token: makeJwt({ chatgpt_account_id: 'acct_b' }), }; expect(extractAccountId(tokens)).toBe('acct_b'); }); it('extractAccountId falls back to organizations[0].id', () => { const tokens = { access_token: makeJwt({ organizations: [{ id: 'org_1' }] }), refresh_token: 'rt', }; expect(extractAccountId(tokens)).toBe('org_1'); }); });