import Button from '@mui/material/Button'; import { styled } from '@mui/material/styles'; import TextField from '@mui/material/TextField'; import React, { useCallback, useEffect, useState } from 'react'; import AuthenticationPage from '../../components/UI/AuthenticationPage'; import { colors } from '../../components/UI/styles'; import type { ChangeEvent, FormEvent } from 'react'; import type { AuthenticationPageProps, TranslatedProps, User } from '../../interface'; const StyledAuthForm = styled('form')` width: 350px; display: flex; flex-direction: column; gap: 16px; `; const ErrorMessage = styled('div')` color: ${colors.errorText}; `; function useNetlifyIdentifyEvent(eventName: 'login', callback: (login: User) => void): void; function useNetlifyIdentifyEvent(eventName: 'logout', callback: () => void): void; function useNetlifyIdentifyEvent(eventName: 'error', callback: (err: Error) => void): void; function useNetlifyIdentifyEvent( eventName: 'login' | 'logout' | 'error', // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (input?: any) => void, ): void { useEffect(() => { window.netlifyIdentity?.on(eventName, callback); }, [callback, eventName]); } export interface GitGatewayAuthenticationPageProps extends TranslatedProps { handleAuth: (email: string, password: string) => Promise; } const GitGatewayAuthenticationPage = ({ inProgress = false, config, onLogin, handleAuth, t, }: GitGatewayAuthenticationPageProps) => { const [loggedIn, setLoggedIn] = useState(false); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [errors, setErrors] = useState<{ identity?: string; server?: string; email?: string; password?: string; }>({}); useEffect(() => { if (!loggedIn && window.netlifyIdentity && window.netlifyIdentity.currentUser()) { onLogin(window.netlifyIdentity.currentUser()); window.netlifyIdentity.close(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const handleIdentityLogin = useCallback( (user: User) => { onLogin(user); window.netlifyIdentity?.close(); }, [onLogin], ); useNetlifyIdentifyEvent('login', handleIdentityLogin); const handleIdentityLogout = useCallback(() => { window.netlifyIdentity?.open(); }, []); useNetlifyIdentifyEvent('logout', handleIdentityLogout); const handleIdentityError = useCallback( (err: Error) => { if (err?.message?.match(/^Failed to load settings from.+\.netlify\/identity$/)) { window.netlifyIdentity?.close(); setErrors({ identity: t('auth.errors.identitySettings') }); } }, [t], ); useNetlifyIdentifyEvent('error', handleIdentityError); const handleIdentity = useCallback(() => { const user = window.netlifyIdentity?.currentUser(); if (user) { onLogin(user); } else { window.netlifyIdentity?.open(); } }, [onLogin]); const handleEmailChange = useCallback((event: ChangeEvent) => { setEmail(event.target.value); }, []); const handlePasswordChange = useCallback((event: ChangeEvent) => { setPassword(event.target.value); }, []); const handleLogin = useCallback( async (e: FormEvent) => { e.preventDefault(); const validationErrors: typeof errors = {}; if (!email) { validationErrors.email = t('auth.errors.email'); } if (!password) { validationErrors.password = t('auth.errors.password'); } if (Object.keys(validationErrors).length > 0) { setErrors(validationErrors); return; } let response: User | string; try { response = await handleAuth(email, password); } catch (e: unknown) { if (e instanceof Error) { response = e.message; } else { response = 'Unknown authentication error'; } } if (typeof response === 'string') { setErrors({ server: response }); setLoggedIn(false); return; } onLogin(response); }, [email, handleAuth, onLogin, password, t], ); if (window.netlifyIdentity) { if (errors.identity) { return ( {errors.identity} } t={t} /> ); } else { return ( ); } } return ( {!errors.server ? null : {String(errors.server)}} } t={t} /> ); }; export default GitGatewayAuthenticationPage;