// import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography"; import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; import { useRouter } from "next/router"; import { useCallback, useState } from "react"; import classes from "./classes.module.scss"; // import Confirm from "@Front/Components/DesignSystem/OldModal/Confirm"; import StepEmail from "./StepEmail"; import StepTotp from "./StepTotp"; import Auth from "@Front/Api/Auth/Customer/Auth"; import { ValidationError } from "class-validator"; import StepPassword from "./StepPassword"; import StepNewPassword from "./StepNewPassword"; import CustomerStore from "@Front/Stores/CustomerStore"; import Module from "@Front/Config/Module"; import { TotpCodesReasons } from "le-coffre-resources/dist/Customer/TotpCodes"; import PasswordForgotten from "./PasswordForgotten"; import backgroundImage from "@Assets/images/background_refonte.svg"; import UserStore from "@Front/Stores/UserStore"; import AuthModal from "src/sdk/AuthModal"; import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService"; import MessageBus from "src/sdk/MessageBus"; export enum LoginStep { EMAIL, TOTP, PASSWORD, NEW_PASSWORD, PASSWORD_FORGOTTEN, } export default function Login() { const router = useRouter(); // const error = router.query["error"]; // const [isErrorModalOpen, setIsErrorModalOpen] = useState(false); const [step, setStep] = useState(LoginStep.EMAIL); const [totpCodeUid, setTotpCodeUid] = useState(""); const [totpCode, setTotpCode] = useState(""); const [email, setEmail] = useState(""); const [partialPhoneNumber, setPartialPhoneNumber] = useState(""); const [sessionId, setSessionId] = useState(""); const [validationErrors, setValidationErrors] = useState([]); const [isAuthModalOpen, setIsAuthModalOpen] = useState(false); // const openErrorModal = useCallback(() => { // setIsErrorModalOpen(true); // }, []); // const closeErrorModal = useCallback(() => { // setIsErrorModalOpen(false); // }, []); // useEffect(() => { // if (error === "1") openErrorModal(); // }, [error, openErrorModal]); const onEmailFormSubmit = useCallback(async (e: React.FormEvent | null, values: { [key: string]: string }) => { try { if (!values["email"]) return; setEmail(values["email"]); /* TODO: review const res = await Auth.getInstance().mailVerifySms({ email: values["email"] }); setPartialPhoneNumber(res.partialPhoneNumber); setTotpCodeUid(res.totpCodeUid); */ setStep(LoginStep.TOTP); setValidationErrors([]); } catch (error: any) { setValidationErrors([ { property: "email", constraints: { [error.http_status]: error.message, }, }, ]); return; } }, []); const onSmsCodeSubmit = useCallback( async (e: React.FormEvent | null, values: { [key: string]: string }) => { try { if (!values["totpCode"]) return; /* const res = await Auth.getInstance().verifyTotpCode({ totpCode: values["totpCode"], email }); // If the code is valid setting it in state if (res.validCode) { setTotpCode(values["totpCode"]); setSessionId(res.sessionId); // Store the session ID } */ if ('1234' === values["totpCode"]) { setTotpCode(values["totpCode"]); // For testing, set a mock session ID setSessionId("mock-session-id-123"); } setValidationErrors([]); /* // If it's first connection, show the form for first connection if (res.reason === TotpCodesReasons.FIRST_LOGIN) setStep(LoginStep.NEW_PASSWORD); // If it's password forgotten, show the form for password forgotten else if (res.reason === TotpCodesReasons.RESET_PASSWORD) setStep(LoginStep.PASSWORD_FORGOTTEN); // Else just login normally else setStep(LoginStep.PASSWORD); */ setIsAuthModalOpen(true); } catch (error: any) { setValidationErrors([ { property: "totpCode", constraints: { [error.http_status]: error.message, }, }, ]); return; } }, [email, setStep], ); const onNewPasswordSubmit = useCallback( async (e: React.FormEvent | null, values: { [key: string]: string }) => { try { if (!values["password"] || !values["confirm_password"]) return; if (values["password"] !== values["confirm_password"]) { setValidationErrors([ { property: "confirm_password", constraints: { "400": "Les mots de passe ne correspondent pas.", }, }, ]); return; } const passwordRegex = new RegExp(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d@$!%*?&_\\-]{8,}$/); if (!passwordRegex.test(values["password"])) { setValidationErrors([ { property: "password", constraints: { "400": "Le mot de passe doit contenir au moins 8 caractères dont 1 majuscule, 1 minuscule et 1 chiffre.", }, }, ]); return; } const token = await Auth.getInstance().setPassword({ totpCode, email, password: values["password"] }); // TODO: review //CustomerStore.instance.connect(token.accessToken, token.refreshToken); setValidationErrors([]); router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path); // If set password worked, setting the token and redirecting } catch (error: any) { setValidationErrors([ { property: "password", constraints: { [error.http_status]: error.message, }, }, ]); return; } }, [totpCode, email, router], ); const onPasswordSubmit = useCallback( async (e: React.FormEvent | null, values: { [key: string]: string }) => { try { if (!values["password"]) return; const token = await Auth.getInstance().login({ totpCode, email, password: values["password"] }); // TODO: review //CustomerStore.instance.connect(token.accessToken, token.refreshToken); setValidationErrors([]); router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path); } catch (error: any) { setValidationErrors([ { property: "password", constraints: { [error.http_status]: error.message, }, }, ]); return; } }, [email, router, totpCode], ); const onPasswordForgotClicked = useCallback(async () => { try { const res = await Auth.getInstance().askNewPassword({ email }); setPartialPhoneNumber(res.partialPhoneNumber); setValidationErrors([]); setStep(LoginStep.TOTP); } catch (error: any) { // If token already exists and is still valid redirect to the connect/register page if (error.http_status === 425) { setStep(LoginStep.TOTP); return; } return; } }, [email]); const onSendAnotherCode = useCallback(async () => { try { const res = await Auth.getInstance().sendAnotherCode({ email, totpCodeUid }); setValidationErrors([]); setPartialPhoneNumber(res.partialPhoneNumber); setTotpCodeUid(res.totpCodeUid); } catch (error: any) { setValidationErrors([ { property: "totpCode", constraints: { [error.http_status]: error.message, }, }, ]); return; } }, [email, totpCodeUid]); return (
{step === LoginStep.EMAIL && } {step === LoginStep.TOTP && ( )} {step === LoginStep.PASSWORD && ( )} {step === LoginStep.NEW_PASSWORD && } {step === LoginStep.PASSWORD_FORGOTTEN && ( )} {isAuthModalOpen && { // After 4nk authentication is complete, get the process for the pairing ID MessageBus.getInstance().initMessageListener(); MessageBus.getInstance().isReady().then(async () => { try { // Get the pairing ID const pairingId = await MessageBus.getInstance().getPairingId(); console.log('[Login] Got pairing ID:', pairingId); // Get all processes const processes = await MessageBus.getInstance().getProcesses(); console.log('[Login] Got processes:', Object.keys(processes)); const targetProcess = processes[pairingId]; if (targetProcess) { console.log('[Login] Found target process:', targetProcess); // Connect the user with the process data UserStore.instance.connect(targetProcess); router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path); } else { console.error('[Login] No process found for pairing ID:', pairingId); // Handle the case where no process is found } MessageBus.getInstance().destroyMessageListener(); } catch (error) { console.error('[Login] Error getting process:', error); MessageBus.getInstance().destroyMessageListener(); } }); setIsAuthModalOpen(false); }} />}
{/*
Une erreur est survenue lors de la connexion. Veuillez réessayer.
*/}
); }