import React, { useRef } from 'react'; import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { useDarkTheme } from '../hooks'; import { selectToken } from '../preferences/preferenceSlice'; interface ConnectorAuthProps { provider: string; onSuccess: (data: { session_token: string; user_email: string }) => void; onError: (error: string) => void; label?: string; isConnected?: boolean; userEmail?: string; onDisconnect?: () => void; errorMessage?: string; } const ConnectorAuth: React.FC = ({ provider, onSuccess, onError, label, isConnected = false, userEmail = '', onDisconnect, errorMessage, }) => { const { t } = useTranslation(); const token = useSelector(selectToken); const [isDarkTheme] = useDarkTheme(); const completedRef = useRef(false); const intervalRef = useRef(null); const cleanup = () => { if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; } window.removeEventListener('message', handleAuthMessage as any); }; const handleAuthMessage = (event: MessageEvent) => { const successGeneric = event.data?.type === 'connector_auth_success'; const successProvider = event.data?.type === `${provider}_auth_success`; const errorProvider = event.data?.type === `${provider}_auth_error`; if (successGeneric || successProvider) { completedRef.current = true; cleanup(); onSuccess({ session_token: event.data.session_token, user_email: event.data.user_email || t('modals.uploadDoc.connectors.auth.connectedUser'), }); } else if (errorProvider) { completedRef.current = true; cleanup(); onError( event.data.error || t('modals.uploadDoc.connectors.auth.authFailed'), ); } }; const handleAuth = async () => { try { completedRef.current = false; cleanup(); const apiHost = import.meta.env.VITE_API_HOST; const authResponse = await fetch( `${apiHost}/api/connectors/auth?provider=${provider}`, { headers: { Authorization: `Bearer ${token}` }, }, ); if (!authResponse.ok) { throw new Error( `${t('modals.uploadDoc.connectors.auth.authUrlFailed')}: ${authResponse.status}`, ); } const authData = await authResponse.json(); if (!authData.success || !authData.authorization_url) { throw new Error( authData.error || t('modals.uploadDoc.connectors.auth.authUrlFailed'), ); } const authWindow = window.open( authData.authorization_url, `${provider}-auth`, 'width=500,height=600,scrollbars=yes,resizable=yes', ); if (!authWindow) { throw new Error(t('modals.uploadDoc.connectors.auth.popupBlocked')); } window.addEventListener('message', handleAuthMessage as any); const checkClosed = window.setInterval(() => { if (authWindow.closed) { clearInterval(checkClosed); window.removeEventListener('message', handleAuthMessage as any); if (!completedRef.current) { onError(t('modals.uploadDoc.connectors.auth.authCancelled')); } } }, 1000); intervalRef.current = checkClosed; } catch (error) { onError( error instanceof Error ? error.message : t('modals.uploadDoc.connectors.auth.authFailed'), ); } }; return ( <> {errorMessage && (
{errorMessage}
)} {isConnected ? (
{t('modals.uploadDoc.connectors.auth.connectedAs', { email: userEmail, })}
{onDisconnect && ( )}
) : ( )} ); }; export default ConnectorAuth;