mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-01 01:45:33 +08:00
fix: refresh Claude auth status after login flow (#617)
* fix: refresh Claude auth status after login flow * fix: rely on refreshed auth status after login --------- Co-authored-by: HolyCode User <noreply@holycode.local>
This commit is contained in:
@@ -16,6 +16,10 @@ type ClaudeCredentialsStatus = {
|
|||||||
error?: string;
|
error?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hasErrorCode = (error: unknown, code: string): boolean => (
|
||||||
|
error instanceof Error && 'code' in error && error.code === code
|
||||||
|
);
|
||||||
|
|
||||||
export class ClaudeProviderAuth implements IProviderAuth {
|
export class ClaudeProviderAuth implements IProviderAuth {
|
||||||
/**
|
/**
|
||||||
* Checks whether the Claude Code CLI is available on this host.
|
* Checks whether the Claude Code CLI is available on this host.
|
||||||
@@ -77,6 +81,8 @@ export class ClaudeProviderAuth implements IProviderAuth {
|
|||||||
* Checks Claude credentials in the same priority order used by Claude Code.
|
* Checks Claude credentials in the same priority order used by Claude Code.
|
||||||
*/
|
*/
|
||||||
private async checkCredentials(): Promise<ClaudeCredentialsStatus> {
|
private async checkCredentials(): Promise<ClaudeCredentialsStatus> {
|
||||||
|
const missingCredentialsError = 'Claude CLI is not authenticated. Run claude /login or configure ANTHROPIC_API_KEY.';
|
||||||
|
|
||||||
if (process.env.ANTHROPIC_API_KEY?.trim()) {
|
if (process.env.ANTHROPIC_API_KEY?.trim()) {
|
||||||
return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
|
return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
|
||||||
}
|
}
|
||||||
@@ -110,15 +116,33 @@ export class ClaudeProviderAuth implements IProviderAuth {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
email,
|
email: null,
|
||||||
method: 'credentials_file',
|
method: null,
|
||||||
error: 'OAuth token has expired. Please re-authenticate with claude login',
|
error: 'Claude login has expired. Run claude /login again.',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return { authenticated: false, email: null, method: null };
|
return {
|
||||||
} catch {
|
authenticated: false,
|
||||||
return { authenticated: false, email: null, method: null };
|
email: null,
|
||||||
|
method: null,
|
||||||
|
error: missingCredentialsError,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
let errorMessage = 'Unable to read Claude credentials. Run claude /login again.';
|
||||||
|
|
||||||
|
if (hasErrorCode(error, 'ENOENT')) {
|
||||||
|
errorMessage = missingCredentialsError;
|
||||||
|
} else if (error instanceof SyntaxError) {
|
||||||
|
errorMessage = 'Claude credentials are unreadable. Run claude /login again.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
authenticated: false,
|
||||||
|
email: null,
|
||||||
|
method: null,
|
||||||
|
error: errorMessage,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,34 +70,39 @@ export function useProviderAuthStatus(
|
|||||||
}));
|
}));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const checkProviderAuthStatus = useCallback(async (provider: LLMProvider) => {
|
const checkProviderAuthStatus = useCallback(async (provider: LLMProvider): Promise<ProviderAuthStatus> => {
|
||||||
setProviderLoading(provider);
|
setProviderLoading(provider);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await authenticatedFetch(PROVIDER_AUTH_STATUS_ENDPOINTS[provider]);
|
const response = await authenticatedFetch(PROVIDER_AUTH_STATUS_ENDPOINTS[provider]);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
setProviderStatus(provider, {
|
const status: ProviderAuthStatus = {
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
email: null,
|
email: null,
|
||||||
method: null,
|
method: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: FALLBACK_STATUS_ERROR,
|
error: FALLBACK_STATUS_ERROR,
|
||||||
});
|
};
|
||||||
return;
|
setProviderStatus(provider, status);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = (await response.json()) as ProviderAuthStatusApiResponse;
|
const payload = (await response.json()) as ProviderAuthStatusApiResponse;
|
||||||
setProviderStatus(provider, toProviderAuthStatus(payload.data));
|
const status = toProviderAuthStatus(payload.data);
|
||||||
|
setProviderStatus(provider, status);
|
||||||
|
return status;
|
||||||
} catch (caughtError) {
|
} catch (caughtError) {
|
||||||
console.error(`Error checking ${provider} auth status:`, caughtError);
|
console.error(`Error checking ${provider} auth status:`, caughtError);
|
||||||
setProviderStatus(provider, {
|
const status: ProviderAuthStatus = {
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
email: null,
|
email: null,
|
||||||
method: null,
|
method: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: toErrorMessage(caughtError),
|
error: toErrorMessage(caughtError),
|
||||||
});
|
};
|
||||||
|
setProviderStatus(provider, status);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
}, [setProviderLoading, setProviderStatus]);
|
}, [setProviderLoading, setProviderStatus]);
|
||||||
|
|
||||||
|
|||||||
@@ -213,12 +213,19 @@ export function useSettingsController({ isOpen, initialTab }: UseSettingsControl
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleLoginComplete = useCallback((exitCode: number) => {
|
const handleLoginComplete = useCallback((exitCode: number) => {
|
||||||
if (exitCode !== 0 || !loginProvider) {
|
if (!loginProvider) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSaveStatus('success');
|
void (async () => {
|
||||||
void checkProviderAuthStatus(loginProvider);
|
const authStatus = await checkProviderAuthStatus(loginProvider);
|
||||||
|
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
console.warn(`Login process exited with code ${exitCode}; refreshing auth status before setting save status.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSaveStatus(authStatus.authenticated ? 'success' : 'error');
|
||||||
|
})();
|
||||||
}, [checkProviderAuthStatus, loginProvider]);
|
}, [checkProviderAuthStatus, loginProvider]);
|
||||||
|
|
||||||
const saveSettings = useCallback(async () => {
|
const saveSettings = useCallback(async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user