import React, { useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Paper, Grid, CircularProgress, Box, Alert, Typography, useTheme, AlertTitle, } from '@mui/material'; import { useParams } from 'react-router-dom'; import Onboarding from './Onboarding'; import Welcome from './Welcome'; import RobotProfile from './RobotProfile'; import Recovery from './Recovery'; import { TorIcon } from '../../components/Icons'; import { genKey } from '../../pgp'; import { AppContext, type UseAppStoreType } from '../../contexts/AppContext'; import { validateTokenEntropy } from '../../utils'; import { FederationContext, type UseFederationStoreType } from '../../contexts/FederationContext'; import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext'; const RobotPage = (): JSX.Element => { const { torStatus, windowSize, settings, page, client } = useContext(AppContext); const { garage } = useContext(GarageContext); const { federation } = useContext(FederationContext); const { t } = useTranslation(); const params = useParams(); const urlToken = settings.selfhostedClient ? params.token : null; const width = Math.min(windowSize.width * 0.8, 28); const maxHeight = windowSize.height * 0.85 - 3; const theme = useTheme(); const [badToken, setBadToken] = useState(''); const [inputToken, setInputToken] = useState(''); const [view, setView] = useState<'welcome' | 'onboarding' | 'recovery' | 'profile'>( garage.currentSlot !== null ? 'profile' : 'welcome', ); useEffect(() => { const token = urlToken ?? garage.currentSlot; if (token !== undefined && token !== null && page === 'robot') { setInputToken(token); if (client !== 'mobile' || torStatus === 'ON' || !settings.useProxy) { setView('profile'); } } }, [torStatus, page]); useEffect(() => { if (inputToken.length < 20) { setBadToken(t('The token is too short')); } else if (!validateTokenEntropy(inputToken).hasEnoughEntropy) { setBadToken(t('Not enough entropy, make it more complex')); } else { setBadToken(''); } }, [inputToken]); const getGenerateRobot = (token: string): void => { setInputToken(token); genKey(token) .then((key) => { garage.createRobot(token, Object.keys(federation.coordinators), { token, pubKey: key.publicKeyArmored, encPrivKey: key.encryptedPrivateKeyArmored, }); void garage.fetchRobot(federation, token); garage.setCurrentSlot(token); }) .catch((error) => { console.error('Error:', error); }); }; const logoutRobot = (): void => { setInputToken(''); garage.deleteSlot(); }; if (settings.useProxy && client === 'mobile' && !(torStatus === 'ON')) { return ( {t('Connecting to TOR')} {t('Connection encrypted and anonymized using TOR.')} {t( 'This ensures maximum privacy, however you might feel the app behaves slow. If connection is lost, restart the app.', )} ); } else { return ( {view === 'welcome' ? ( ) : null} {view === 'onboarding' ? ( ) : null} {view === 'profile' ? ( ) : null} {view === 'recovery' ? ( ) : null} ); } }; export default RobotPage;