feat(cliproxy): support duplicate-email codex accounts

- keep Codex team and personal auth files as separate identities

- resolve quota and live monitor stats by token file-backed account id

- surface duplicate-aware account labels across the dashboard and variant UI
This commit is contained in:
Tam Nhu Tran committed 2026-03-30 15:30:11 -04:00
1 parent 43ea5554e6
commit c73f33872a
23 files changed
+781 -143

No files matched your search

@@ -116,4 +116,41 @@ describe('registerAccount optional nickname flow', () => {
expect(match).toBeNull();
});
it('treats duplicate Codex emails as distinct accounts and rejects bare-email lookups', async () => {
const result = await withIsolatedHome(async (homeDir) => {
writeTokenFile(homeDir, 'codex-04a0f049-kaidu.kd@gmail.com-team.json');
writeTokenFile(homeDir, 'codex-kaidu.kd@gmail.com-free.json');
const { registerAccount, getProviderAccounts, findAccountByQuery } = await loadAccountManager();
const team = registerAccount(
'codex',
'codex-04a0f049-kaidu.kd@gmail.com-team.json',
'kaidu.kd@gmail.com'
);
const free = registerAccount(
'codex',
'codex-kaidu.kd@gmail.com-free.json',
'kaidu.kd@gmail.com'
);
return {
team,
free,
accounts: getProviderAccounts('codex'),
ambiguousLookup: findAccountByQuery('codex', 'kaidu.kd@gmail.com'),
teamLookup: findAccountByQuery('codex', 'kaidu.kd@gmail.com#04a0f049-team'),
freeLookup: findAccountByQuery('codex', free.id),
};
});
expect(result.team.id).toBe('kaidu.kd@gmail.com');
expect(result.free.id).toBe('kaidu.kd@gmail.com#free');
expect(result.accounts.map((account) => account.id).sort()).toEqual([
'kaidu.kd@gmail.com#04a0f049-team',
'kaidu.kd@gmail.com#free',
]);
expect(result.ambiguousLookup).toBeNull();
expect(result.teamLookup?.id).toBe('kaidu.kd@gmail.com#04a0f049-team');
expect(result.freeLookup?.id).toBe('kaidu.kd@gmail.com#free');
});
});
@@ -17,6 +17,7 @@ let buildCodexQuotaWindows: typeof import('../../../src/cliproxy/quota-fetcher-c
let buildCodexCoreUsageSummary: typeof import('../../../src/cliproxy/quota-fetcher-codex').buildCodexCoreUsageSummary;
let fetchCodexQuota: typeof import('../../../src/cliproxy/quota-fetcher-codex').fetchCodexQuota;
let getUnknownCodexWindowLabels: typeof import('../../../src/cliproxy/quota-fetcher-codex').getUnknownCodexWindowLabels;
let registerAccount: typeof import('../../../src/cliproxy/account-manager').registerAccount;
function createCodexAccount(
accountId: string,
@@ -40,6 +41,7 @@ beforeEach(async () => {
);
mock.module('../../../src/cliproxy/config-generator', () => configGenerator);
mock.module('../../../src/cliproxy/account-manager', () => accountManager);
({ registerAccount } = accountManager);
({
buildCodexQuotaWindows,
@@ -409,6 +411,55 @@ describe('Codex Quota Fetcher', () => {
expect(result.actionHint).toContain('ccs cliproxy auth codex');
});
it('uses the registry token file for duplicate-email Codex accounts', async () => {
createValidCodexAccount(
'kaidu.kd@gmail.com',
'workspace-team',
'codex-04a0f049-kaidu.kd@gmail.com-team.json'
);
createValidCodexAccount(
'kaidu.kd@gmail.com',
'workspace-free',
'codex-kaidu.kd@gmail.com-free.json'
);
registerAccount(
'codex',
'codex-04a0f049-kaidu.kd@gmail.com-team.json',
'kaidu.kd@gmail.com'
);
const freeAccount = registerAccount(
'codex',
'codex-kaidu.kd@gmail.com-free.json',
'kaidu.kd@gmail.com'
);
const fetchSpy = mock((input: RequestInfo | URL, init?: RequestInit) =>
Promise.resolve(
new Response(
JSON.stringify({
plan_type: 'free',
rate_limit: {
primary_window: { used_percent: 10, reset_after_seconds: 3600 },
},
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
}
)
)
) as typeof fetch;
global.fetch = fetchSpy;
const result = await fetchCodexQuota(freeAccount.id);
const requestInit = fetchSpy.mock.calls[0]?.[1] as RequestInit | undefined;
const headers = new Headers(requestInit?.headers);
expect(result.success).toBe(true);
expect(headers.get('ChatGPT-Account-Id')).toBe('workspace-free');
});
it('maps 403 responses to forbidden metadata', async () => {
createValidCodexAccount('forbidden@example.com', 'workspace-forbidden');
@@ -288,4 +288,45 @@ describe('buildCliproxyStatsFromUsageResponse', () => {
});
expect(stats.requestsByProvider).toEqual({ codex: 1, 'ccs-internal-managed': 2 });
});
it('derives duplicate-email Codex account ids from auth file metadata', () => {
const usage = createInternallyBucketedUsage([
createDetail({ auth_index: 'codex-team', source: 'kaidu.kd@gmail.com' }),
createDetail({
auth_index: 'codex-free',
source: 'kaidu.kd@gmail.com',
timestamp: '2025-03-26T10:01:00.000Z',
failed: true,
}),
]);
const authFiles: CliproxyManagementAuthFile[] = [
{
auth_index: 'codex-team',
provider: 'codex',
email: 'kaidu.kd@gmail.com',
name: 'codex-04a0f049-kaidu.kd@gmail.com-team.json',
},
{
auth_index: 'codex-free',
provider: 'codex',
email: 'kaidu.kd@gmail.com',
name: 'codex-kaidu.kd@gmail.com-free.json',
},
];
const stats = buildCliproxyStatsFromUsageResponse(usage, { authFiles });
expect(stats.accountStats['codex:kaidu.kd@gmail.com#04a0f049-team']).toMatchObject({
provider: 'codex',
source: 'kaidu.kd@gmail.com#04a0f049-team',
successCount: 1,
failureCount: 0,
});
expect(stats.accountStats['codex:kaidu.kd@gmail.com#free']).toMatchObject({
provider: 'codex',
source: 'kaidu.kd@gmail.com#free',
successCount: 0,
failureCount: 1,
});
});
});