mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-20 02:17:05 +00:00
fix(codex): harden duplicate-email account actions
This commit is contained in:
1 parent
80341f18c3
commit
22f091689f
6 files changed
+103
-7
No files matched your search
@@ -1,6 +1,9 @@
|
||||
const PERSONAL_PLAN_PARTS = new Set(['free', 'plus', 'pro']);
|
||||
const BUSINESS_PLAN_PARTS = new Set(['team']);
|
||||
|
||||
// Keep variant parsing aligned with src/cliproxy/accounts/email-account-identity.ts.
|
||||
// This browser copy stays local because the server module is not bundle-safe for the UI.
|
||||
|
||||
export type AccountAudience = 'business' | 'personal' | 'unknown';
|
||||
|
||||
export interface AccountIdentityPresentation {
|
||||
|
||||
@@ -912,15 +912,17 @@ export const api = {
|
||||
body: JSON.stringify({ accountId }),
|
||||
}),
|
||||
remove: (provider: string, accountId: string) =>
|
||||
request(`/cliproxy/auth/accounts/${provider}/${accountId}`, { method: 'DELETE' }),
|
||||
request(`/cliproxy/auth/accounts/${provider}/${encodeURIComponent(accountId)}`, {
|
||||
method: 'DELETE',
|
||||
}),
|
||||
pause: (provider: string, accountId: string) =>
|
||||
request<{ provider: string; accountId: string; paused: boolean }>(
|
||||
`/cliproxy/auth/accounts/${provider}/${accountId}/pause`,
|
||||
`/cliproxy/auth/accounts/${provider}/${encodeURIComponent(accountId)}/pause`,
|
||||
{ method: 'POST' }
|
||||
),
|
||||
resume: (provider: string, accountId: string) =>
|
||||
request<{ provider: string; accountId: string; paused: boolean }>(
|
||||
`/cliproxy/auth/accounts/${provider}/${accountId}/resume`,
|
||||
`/cliproxy/auth/accounts/${provider}/${encodeURIComponent(accountId)}/resume`,
|
||||
{ method: 'POST' }
|
||||
),
|
||||
/** Solo mode: activate one account, pause all others */
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { api } from '@/lib/api-client';
|
||||
|
||||
function createEmptyJsonResponse(status = 200): Response {
|
||||
return new Response('{}', {
|
||||
status,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
|
||||
describe('cliproxy account API client', () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('encodes duplicate-email account ids for account auth actions', async () => {
|
||||
const fetchMock = vi.fn(() => Promise.resolve(createEmptyJsonResponse()));
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
|
||||
const accountId = 'kaidu.kd@gmail.com#04a0f049-team';
|
||||
const encodedAccountId = encodeURIComponent(accountId);
|
||||
|
||||
await api.cliproxy.accounts.remove('codex', accountId);
|
||||
await api.cliproxy.accounts.pause('codex', accountId);
|
||||
await api.cliproxy.accounts.resume('codex', accountId);
|
||||
|
||||
expect(fetchMock.mock.calls[0]?.[0]).toBe(
|
||||
`/api/cliproxy/auth/accounts/codex/${encodedAccountId}`
|
||||
);
|
||||
expect(fetchMock.mock.calls[1]?.[0]).toBe(
|
||||
`/api/cliproxy/auth/accounts/codex/${encodedAccountId}/pause`
|
||||
);
|
||||
expect(fetchMock.mock.calls[2]?.[0]).toBe(
|
||||
`/api/cliproxy/auth/accounts/codex/${encodedAccountId}/resume`
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user