import React, { useEffect, useState } from "react"; import System from "../../../models/system"; import { AUTH_TOKEN, AUTH_USER } from "../../../utils/constants"; import paths from "../../../utils/paths"; import showToast from "@/utils/toast"; import ModalWrapper from "@/components/ModalWrapper"; import { useModal } from "@/hooks/useModal"; import RecoveryCodeModal from "@/components/Modals/DisplayRecoveryCodeModal"; import { useTranslation } from "react-i18next"; import { t } from "i18next"; const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => { const [username, setUsername] = useState(""); const [recoveryCodeInputs, setRecoveryCodeInputs] = useState( Array(2).fill("") ); const handleRecoveryCodeChange = (index, value) => { const updatedCodes = [...recoveryCodeInputs]; updatedCodes[index] = value; setRecoveryCodeInputs(updatedCodes); }; const handleSubmit = (e) => { e.preventDefault(); const recoveryCodes = recoveryCodeInputs.filter( (code) => code.trim() !== "" ); onSubmit(username, recoveryCodes); }; return (

{t("login.password-reset.title")}

{t("login.password-reset.description")}

setUsername(e.target.value)} className="border-none bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]" required />
{recoveryCodeInputs.map((code, index) => (
handleRecoveryCodeChange(index, e.target.value) } className="border-none bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]" required />
))}
); }; const ResetPasswordForm = ({ onSubmit }) => { const [newPassword, setNewPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const handleSubmit = (e) => { e.preventDefault(); onSubmit(newPassword, confirmPassword); }; return (

Reset Password

Enter your new password.

setNewPassword(e.target.value)} className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" required />
setConfirmPassword(e.target.value)} className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" required />
); }; export default function MultiUserAuth() { const { t } = useTranslation(); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [recoveryCodes, setRecoveryCodes] = useState([]); const [downloadComplete, setDownloadComplete] = useState(false); const [user, setUser] = useState(null); const [token, setToken] = useState(null); const [showRecoveryForm, setShowRecoveryForm] = useState(false); const [showResetPasswordForm, setShowResetPasswordForm] = useState(false); const [customAppName, setCustomAppName] = useState(null); const { isOpen: isRecoveryCodeModalOpen, openModal: openRecoveryCodeModal, closeModal: closeRecoveryCodeModal, } = useModal(); const handleLogin = async (e) => { setError(null); setLoading(true); e.preventDefault(); const data = {}; const form = new FormData(e.target); for (var [key, value] of form.entries()) data[key] = value; const { valid, user, token, message, recoveryCodes } = await System.requestToken(data); if (valid && !!token && !!user) { setUser(user); setToken(token); if (recoveryCodes) { setRecoveryCodes(recoveryCodes); openRecoveryCodeModal(); } else { window.localStorage.setItem(AUTH_USER, JSON.stringify(user)); window.localStorage.setItem(AUTH_TOKEN, token); window.location = paths.home(); } } else { setError(message); setLoading(false); } setLoading(false); }; const handleDownloadComplete = () => setDownloadComplete(true); const handleResetPassword = () => setShowRecoveryForm(true); const handleRecoverySubmit = async (username, recoveryCodes) => { const { success, resetToken, error } = await System.recoverAccount( username, recoveryCodes ); if (success && resetToken) { window.localStorage.setItem("resetToken", resetToken); setShowRecoveryForm(false); setShowResetPasswordForm(true); } else { showToast(error, "error", { clear: true }); } }; const handleResetSubmit = async (newPassword, confirmPassword) => { const resetToken = window.localStorage.getItem("resetToken"); if (resetToken) { const { success, error } = await System.resetPassword( resetToken, newPassword, confirmPassword ); if (success) { window.localStorage.removeItem("resetToken"); setShowResetPasswordForm(false); showToast("Password reset successful", "success", { clear: true }); } else { showToast(error, "error", { clear: true }); } } else { showToast("Invalid reset token", "error", { clear: true }); } }; useEffect(() => { if (downloadComplete && user && token) { window.localStorage.setItem(AUTH_USER, JSON.stringify(user)); window.localStorage.setItem(AUTH_TOKEN, token); window.location = paths.home(); } }, [downloadComplete, user, token]); useEffect(() => { const fetchCustomAppName = async () => { const { appName } = await System.fetchCustomAppName(); setCustomAppName(appName || ""); setLoading(false); }; fetchCustomAppName(); }, []); if (showRecoveryForm) { return ( ); } if (showResetPasswordForm) return ; return ( <>

{t("login.multi-user.welcome")}

{customAppName || "AnythingLLM"}

{t("login.sign-in.start")} {customAppName || "AnythingLLM"}{" "} {t("login.sign-in.end")}

{error &&

Error: {error}

}
); }