Files
qwen-code/packages/cli/src/ui/hooks/useQwenAuth.ts

109 lines
2.7 KiB
TypeScript

/**
* @license
* Copyright 2025 Qwen
* SPDX-License-Identifier: Apache-2.0
*/
import { useState, useCallback, useEffect } from 'react';
import {
AuthType,
qwenOAuth2Events,
QwenOAuth2Event,
type DeviceAuthorizationData,
} from '@qwen-code/qwen-code-core';
export interface QwenAuthState {
deviceAuth: DeviceAuthorizationData | null;
authStatus:
| 'idle'
| 'polling'
| 'success'
| 'error'
| 'timeout'
| 'rate_limit';
authMessage: string | null;
}
export const useQwenAuth = (
pendingAuthType: AuthType | undefined,
isAuthenticating: boolean,
) => {
const [qwenAuthState, setQwenAuthState] = useState<QwenAuthState>({
deviceAuth: null,
authStatus: 'idle',
authMessage: null,
});
const isQwenAuth = pendingAuthType === AuthType.QWEN_OAUTH;
// Set up event listeners when authentication starts
useEffect(() => {
if (!isQwenAuth || !isAuthenticating) {
// Reset state when not authenticating or not Qwen auth
setQwenAuthState({
deviceAuth: null,
authStatus: 'idle',
authMessage: null,
});
return;
}
setQwenAuthState((prev) => ({
...prev,
authStatus: 'idle',
}));
// Set up event listeners
const handleDeviceAuth = (deviceAuth: DeviceAuthorizationData) => {
setQwenAuthState((prev) => ({
...prev,
deviceAuth: {
verification_uri: deviceAuth.verification_uri,
verification_uri_complete: deviceAuth.verification_uri_complete,
user_code: deviceAuth.user_code,
expires_in: deviceAuth.expires_in,
device_code: deviceAuth.device_code,
},
authStatus: 'polling',
}));
};
const handleAuthProgress = (
status: 'success' | 'error' | 'polling' | 'timeout' | 'rate_limit',
message?: string,
) => {
setQwenAuthState((prev) => ({
...prev,
authStatus: status,
authMessage: message || null,
}));
};
// Add event listeners
qwenOAuth2Events.on(QwenOAuth2Event.AuthUri, handleDeviceAuth);
qwenOAuth2Events.on(QwenOAuth2Event.AuthProgress, handleAuthProgress);
// Cleanup event listeners when component unmounts or auth finishes
return () => {
qwenOAuth2Events.off(QwenOAuth2Event.AuthUri, handleDeviceAuth);
qwenOAuth2Events.off(QwenOAuth2Event.AuthProgress, handleAuthProgress);
};
}, [isQwenAuth, isAuthenticating]);
const cancelQwenAuth = useCallback(() => {
// Emit cancel event to stop polling
qwenOAuth2Events.emit(QwenOAuth2Event.AuthCancel);
setQwenAuthState({
deviceAuth: null,
authStatus: 'idle',
authMessage: null,
});
}, []);
return {
qwenAuthState,
cancelQwenAuth,
};
};