import { alpha, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, InputAdornment, Slide, Stack, TextField, Typography, useMediaQuery } from '@mui/material'; import React, { useState, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import Iconify from '../Iconify'; import shakeScreen from '@/functions/system/shakeScreen'; import notificationIcon from '../../assets/icons/UltimaLogoNew.png'; import UltimaLogo from '../../assets/icons/UltimaLogoNew.png'; import ProvidersButton from './ProvidersButton'; import { signIn } from '@/functions/auth/signIn'; import { useNavigate } from 'react-router'; import { ipcRenderer } from 'electron'; import { saveSession } from '@/functions/auth/saveSession'; const SignIn = ({ page, handleChangePage }: { page: 'signin' | 'signup' | 'providers'; handleChangePage: (page: 'signin' | 'signup' | 'providers') => void; }) => { const navigate = useNavigate(); const [hidePassword, setHidePassword] = useState(true); const isSmall = useMediaQuery('(max-height: 700px)'); const [credentials, setCredentials] = useState(''); const [password, setPassword] = useState(''); const [crError, setCrError] = useState(false); const [passwordError, setPasswordError] = useState(false); const [ppDialog, setPPDialog] = useState(false); const [pp, setPP] = useState(''); const [userId, setUserId] = useState(null); const epkRef = useRef(null); const [sessionData, setSessionData] = useState(null); const [callState, setCallState] = useState(null); const handleSignIn = async () => { if (!credentials || !password) { if (!credentials) setCrError(true); if (!password) setPasswordError(true); shakeScreen(); setTimeout(() => { setCrError(false); setPasswordError(false); }, 1500); return; } setCallState('loading'); try { const { data } = await signIn({ provider: 'credentials', data: { credentials, password } }); console.log("data", data); setUserId(data.d.userId); setSessionData(data.d); epkRef.current = data.d.epk; const { exists } = await ipcRenderer.invoke('check-keys', data.d.userId); if (exists) { setCallState('success'); setTimeout(() => { navigate('/'); }, 500); } else { setPPDialog(true); } } catch (error) { setCallState('error'); console.error('Error signing in:', error); if (error?.response?.data) { new Notification('Error signing in.', { body: error?.response?.data?.data, icon: notificationIcon }); } } finally { setTimeout(() => { setCallState(null); setCrError(false); setPasswordError(false); }, 1500); } }; const handlePageChange = (page: 'signin' | 'signup' | 'providers') => { if (callState === 'loading') return; handleChangePage(page); setCallState(null); }; // ^(?:(?:@(?:[a-z0-9-*~][a-z0-9-*._~]*)?/[a-z0-9-._~])|[a-z0-9-~])[a-z0-9-._~]*$ const handleFinishSign = async () => { if (pp.length !== 6) return; try { const { success, error } = await ipcRenderer.invoke('save-keys', { userId, epk: epkRef.current, passphrase: pp }); if (success) { saveSession(sessionData); navigate('/'); } else if(error) { throw error; } } catch (error) { console.error('Error saving keys:', error); } }; return ( This device is new on your account. By our security policy, new devices must confirm their identity
using generated passphrase, for privacy, encryption and security.
theme.shape.borderRadius, border: (theme) => `1px dashed ${theme.palette.divider}` }}> { const value = e.target.value; if (/^\d*$/.test(value) && value.length <= 6) { setPP(value); } }} placeholder="Enter passphrase" inputProps={{ maxLength: 6 }} sx={{ '& .MuiInputBase-input': { textAlign: 'center', fontWeight: 'bold', fontSize: '1.2rem', letterSpacing: '0.5rem' } }} />
{!isSmall && ( Ultima )} Ready to dive in? Welcome Back `0 0 12px ${theme.palette.primary.light}` }}>! Don't have an account? handlePageChange('signup')} component="span" sx={{ color: 'primary.light', cursor: 'pointer', fontSize: 15, fontWeight: 550 }}>Sign Up
setCredentials(e.target.value)} placeholder="johndoe@gmail.com" error={crError || callState === 'error'} sx={{ '& .MuiFilledInput-root': { borderColor: crError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'primary.main', color: crError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'inherit', } }} slotProps={{ input: { endAdornment: ( ) } }} /> setPassword(e.target.value)} placeholder='********' type={hidePassword ? 'password' : 'text'} error={passwordError || callState === 'error'} sx={{ '& .MuiFilledInput-root': { borderColor: passwordError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'primary.main', color: passwordError || callState === 'error' ? 'error.main' : callState === 'success' ? 'success.main' : 'inherit', } }} slotProps={{ input: { endAdornment: ( setHidePassword((prev) => !prev)} sx={{ p: 0, color: 'inherit', pt: 0.5 }}> ) } }} />
); }; export default SignIn;