import { useState } from "react"; import { Helmet } from "react-helmet"; import { faXmark } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, useNavigate, useSearch } from "@tanstack/react-router"; import { Mfa } from "@app/components/auth/Mfa"; import InputField from "@app/components/basic/InputField"; import checkPassword from "@app/components/utilities/checks/password/checkPassword"; import SecurityClient from "@app/components/utilities/SecurityClient"; import { Button } from "@app/components/v2"; import { useToggle } from "@app/hooks"; import { completeAccountSignupInvite, useSelectOrganization, verifySignupInvite } from "@app/hooks/api/auth/queries"; import { MfaMethod } from "@app/hooks/api/auth/types"; import { fetchOrganizations } from "@app/hooks/api/organization/queries"; import { isLoggedIn } from "@app/hooks/api/reactQuery"; type Errors = { tooShort?: string; tooLong?: string; noLetterChar?: string; noNumOrSpecialChar?: string; repeatedChar?: string; escapeChar?: string; lowEntropy?: string; breached?: string; }; export const SignupInvitePage = () => { const [password, setPassword] = useState(""); const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const [firstNameError, setFirstNameError] = useState(false); const [lastNameError, setLastNameError] = useState(false); const [isLoading, setIsLoading] = useState(false); const [step, setStep] = useState(1); const [errors, setErrors] = useState({}); const [shouldShowMfa, toggleShowMfa] = useToggle(false); const [requiredMfaMethod, setRequiredMfaMethod] = useState(MfaMethod.EMAIL); const [mfaSuccessCallback, setMfaSuccessCallback] = useState<() => void>(() => {}); const navigate = useNavigate(); const search = useSearch({ from: "/_restrict-login-signup/signupinvite" }); const parsedUrl = search; const token = parsedUrl.token as string; const organizationId = parsedUrl.organization_id as string; const email = (parsedUrl.to as string)?.replace(" ", "+").trim(); const queryParams = new URLSearchParams(window.location.search); const metadata = queryParams.get("metadata") || undefined; const { mutateAsync: selectOrganization } = useSelectOrganization(); const loggedIn = isLoggedIn(); // Verifies if the information that the users entered (name, workspace) is there, and if the password matched the criteria. const signupErrorCheck = async () => { setIsLoading(true); let errorCheck = await checkPassword({ password, setErrors }); if (!firstName) { setFirstNameError(true); errorCheck = true; } else { setFirstNameError(false); } if (!lastName) { setLastNameError(true); errorCheck = true; } else { setLastNameError(false); } if (!errorCheck) { try { const { token: jwtToken } = await completeAccountSignupInvite({ email, password, firstName, lastName, tokenMetadata: metadata }); // unset temporary signup JWT token and set JWT token SecurityClient.setSignupToken(""); SecurityClient.setToken(jwtToken); const userOrgs = await fetchOrganizations(); const orgId = userOrgs[0].id; if (!orgId) throw new Error("You are not part of any organization"); const completeSignupFlow = async () => { const { token: mfaToken, isMfaEnabled, mfaMethod } = await selectOrganization({ organizationId: orgId }); if (isMfaEnabled) { SecurityClient.setMfaToken(mfaToken); if (mfaMethod) { setRequiredMfaMethod(mfaMethod); } toggleShowMfa.on(); setMfaSuccessCallback(() => completeSignupFlow); return; } localStorage.setItem("orgData.id", orgId); navigate({ to: "/organization/projects" }); }; await completeSignupFlow(); } catch (error) { setIsLoading(false); console.error(error); } } else { setIsLoading(false); } }; // Step 4 of the sign up process (download the emergency kit pdf) const stepConfirmEmail = (

Confirm your email

); // Because this is the invite signup - we directly go to the last step of signup (email is already verified) const main = (

Almost there!

{ setPassword(pass); checkPassword({ password: pass, setErrors }); }} type="password" value={password} isRequired error={Object.keys(errors).length > 0} autoComplete="new-password" id="new-password" /> {Object.keys(errors).length > 0 && (
Password should contain at least:
{Object.keys(errors).map((key) => { if (errors[key as keyof Errors]) { return (

{errors[key as keyof Errors]}

); } return null; })}
)}
); return (
Sign Up {shouldShowMfa ? ( toggleShowMfa.off()} /> ) : ( <>
Infisical Logo
{step === 1 && stepConfirmEmail} {step === 2 && main} )}
); };