"use client"; import { useEffect, useState } from "react"; import { Button, ButtonVariants } from "./Button"; import { TextInput } from "./Input"; import { useForm } from "react-hook-form"; import { useRouter } from "next/navigation"; import { Spinner } from "./Spinner"; import Alert from "./Alert"; type Inputs = { code: string; }; type Props = { loginName: string | undefined; sessionId: string | undefined; code: string | undefined; authRequestId?: string; organization?: string; submit: boolean; }; export default function TOTPForm({ loginName, code, authRequestId, organization, submit, }: Props) { const { register, handleSubmit, formState } = useForm({ mode: "onBlur", defaultValues: { code: code ? code : "", }, }); const router = useRouter(); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); async function submitCode(values: Inputs, organization?: string) { setLoading(true); let body: any = { code: values.code, }; if (organization) { body.organization = organization; } if (authRequestId) { body.authRequestId = authRequestId; } const res = await fetch("/api/totp/verify", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(body), }); setLoading(false); if (!res.ok) { const response = await res.json(); setError(response.message ?? "An internal error occurred"); return Promise.reject(response.message ?? "An internal error occurred"); } return res.json(); } function setCodeAndContinue(values: Inputs, organization?: string) { return submitCode(values, organization).then((response) => { if (authRequestId && response && response.sessionId) { const params = new URLSearchParams({ sessionId: response.sessionId, authRequest: authRequestId, }); if (organization) { params.append("organization", organization); } return router.push(`/login?` + params); } else { const params = new URLSearchParams( authRequestId ? { loginName: response.factors.user.loginName, authRequestId, } : { loginName: response.factors.user.loginName, } ); if (organization) { params.append("organization", organization); } return router.push(`/signedin?` + params); } }); } const { errors } = formState; useEffect(() => { if (submit && code) { // When we navigate to this page, we always want to be redirected if submit is true and the parameters are valid. setCodeAndContinue({ code }, organization); } }, []); return (
{error && (
{error}
)}
); }