mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
fix(ui): guard auth success on registered account
This commit is contained in:
1 parent
09eb01f16e
commit
a3478ace44
2 files changed
+66
-2
No files matched your search
@@ -133,6 +133,7 @@ export function useCliproxyAuthFlow() {
|
|||||||
const data = (await response.json()) as {
|
const data = (await response.json()) as {
|
||||||
status?: string;
|
status?: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
|
account?: unknown;
|
||||||
url?: string;
|
url?: string;
|
||||||
auth_url?: string;
|
auth_url?: string;
|
||||||
verification_url?: string;
|
verification_url?: string;
|
||||||
@@ -141,8 +142,22 @@ export function useCliproxyAuthFlow() {
|
|||||||
pollFailureCountRef.current = 0;
|
pollFailureCountRef.current = 0;
|
||||||
|
|
||||||
if (data.status === 'ok') {
|
if (data.status === 'ok') {
|
||||||
|
const hasAccount = typeof data.account === 'object' && data.account !== null;
|
||||||
|
if (!hasAccount) {
|
||||||
|
stopPolling();
|
||||||
|
const errorMsg = 'Authenticated account could not be registered';
|
||||||
|
toast.error(errorMsg);
|
||||||
|
setState((prev) => ({
|
||||||
|
...prev,
|
||||||
|
isAuthenticating: false,
|
||||||
|
error: errorMsg,
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
stopPolling();
|
stopPolling();
|
||||||
queryClient.invalidateQueries({ queryKey: ['cliproxy-auth'] });
|
queryClient.invalidateQueries({ queryKey: ['cliproxy-auth'] });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['cliproxy-accounts'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['account-quota'] });
|
queryClient.invalidateQueries({ queryKey: ['account-quota'] });
|
||||||
toast.success(`${provider} authentication successful`);
|
toast.success(`${provider} authentication successful`);
|
||||||
openedAuthUrlRef.current = false;
|
openedAuthUrlRef.current = false;
|
||||||
@@ -270,8 +285,10 @@ export function useCliproxyAuthFlow() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const success = data.success === true;
|
const success = data.success === true;
|
||||||
if (response.ok && success) {
|
const hasAccount = typeof data.account === 'object' && data.account !== null;
|
||||||
|
if (response.ok && success && hasAccount) {
|
||||||
queryClient.invalidateQueries({ queryKey: ['cliproxy-auth'] });
|
queryClient.invalidateQueries({ queryKey: ['cliproxy-auth'] });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['cliproxy-accounts'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['account-quota'] });
|
queryClient.invalidateQueries({ queryKey: ['account-quota'] });
|
||||||
// Note: No toast here - DeviceCodeDialog's useDeviceCode hook handles success toast
|
// Note: No toast here - DeviceCodeDialog's useDeviceCode hook handles success toast
|
||||||
// via deviceCodeCompleted WebSocket event to avoid duplicate toasts
|
// via deviceCodeCompleted WebSocket event to avoid duplicate toasts
|
||||||
@@ -279,7 +296,11 @@ export function useCliproxyAuthFlow() {
|
|||||||
setState(INITIAL_STATE);
|
setState(INITIAL_STATE);
|
||||||
} else {
|
} else {
|
||||||
const errorMsg =
|
const errorMsg =
|
||||||
typeof data.error === 'string' ? data.error : 'Authentication failed';
|
typeof data.error === 'string'
|
||||||
|
? data.error
|
||||||
|
: success
|
||||||
|
? 'Authenticated account could not be registered'
|
||||||
|
: 'Authentication failed';
|
||||||
toast.error(errorMsg);
|
toast.error(errorMsg);
|
||||||
setState((prev) => ({
|
setState((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
@@ -416,6 +437,7 @@ export function useCliproxyAuthFlow() {
|
|||||||
if (response.ok && success && hasAccount) {
|
if (response.ok && success && hasAccount) {
|
||||||
stopPolling();
|
stopPolling();
|
||||||
queryClient.invalidateQueries({ queryKey: ['cliproxy-auth'] });
|
queryClient.invalidateQueries({ queryKey: ['cliproxy-auth'] });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['cliproxy-accounts'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['account-quota'] });
|
queryClient.invalidateQueries({ queryKey: ['account-quota'] });
|
||||||
toast.success(`${currentProvider} authentication successful`);
|
toast.success(`${currentProvider} authentication successful`);
|
||||||
setState(INITIAL_STATE);
|
setState(INITIAL_STATE);
|
||||||
|
|||||||
@@ -196,4 +196,46 @@ describe('useCliproxyAuthFlow', () => {
|
|||||||
expect(toast.error).toHaveBeenCalledWith('Authenticated account could not be registered');
|
expect(toast.error).toHaveBeenCalledWith('Authenticated account could not be registered');
|
||||||
expect(toast.success).not.toHaveBeenCalled();
|
expect(toast.success).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('treats status ok responses without an account as failures', async () => {
|
||||||
|
vi.stubGlobal(
|
||||||
|
'fetch',
|
||||||
|
vi.fn((input: RequestInfo | URL) => {
|
||||||
|
const url = String(input);
|
||||||
|
|
||||||
|
if (url.includes('/start-url')) {
|
||||||
|
return Promise.resolve(
|
||||||
|
createJsonResponse({
|
||||||
|
success: true,
|
||||||
|
authUrl: 'https://auth.example/status-only',
|
||||||
|
state: 'state-status-only',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.includes('/status?state=state-status-only')) {
|
||||||
|
return Promise.resolve(createJsonResponse({ status: 'ok' }));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(new Error(`Unexpected fetch: ${url}`));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const { result } = renderHook(() => useCliproxyAuthFlow(), { wrapper });
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await result.current.startAuth('codex', { startEndpoint: 'start-url' });
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
vi.advanceTimersByTime(3000);
|
||||||
|
await Promise.resolve();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.error).toBe('Authenticated account could not be registered');
|
||||||
|
expect(result.current.isAuthenticating).toBe(false);
|
||||||
|
expect(toast.error).toHaveBeenCalledWith('Authenticated account could not be registered');
|
||||||
|
expect(toast.success).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user