import React, { useEffect, useRef, useState } from "react"; import dynamic from "next/dynamic"; import Head from "next/head"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/router"; import { faCheck, faWarning, faX } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import Button from "~/components/basic/buttons/Button"; import Error from "~/components/basic/Error"; import InputField from "~/components/basic/InputField"; import Aes256Gcm from "~/components/utilities/cryptography/aes-256-gcm"; import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey"; import attemptLogin from "~/utilities/attemptLogin"; import passwordCheck from "~/utilities/checks/PasswordCheck"; import checkEmailVerificationCode from "./api/auth/CheckEmailVerificationCode"; import completeAccountInformationSignup from "./api/auth/CompleteAccountInformationSignup"; import sendVerificationEmail from "./api/auth/SendVerificationEmail"; import getWorkspaces from "./api/workspace/getWorkspaces"; const ReactCodeInput = dynamic(import("react-code-input")); const nacl = require("tweetnacl"); const jsrp = require("jsrp"); nacl.util = require("tweetnacl-util"); const client = new jsrp.client(); // The stye for the verification code input const props = { inputStyle: { fontFamily: "monospace", margin: "4px", MozAppearance: "textfield", width: "55px", borderRadius: "5px", fontSize: "24px", height: "55px", paddingLeft: "7", backgroundColor: "#0d1117", color: "white", border: "1px solid gray", textAlign: "center", }, }; const propsPhone = { inputStyle: { fontFamily: "monospace", margin: "4px", MozAppearance: "textfield", width: "40px", borderRadius: "5px", fontSize: "24px", height: "40px", paddingLeft: "7", backgroundColor: "#0d1117", color: "white", border: "1px solid gray", textAlign: "center", }, }; export default function SignUp() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const [code, setCode] = useState(""); const [codeError, setCodeError] = useState(false); const [firstNameError, setFirstNameError] = useState(false); const [lastNameError, setLastNameError] = useState(false); const [passwordErrorLength, setPasswordErrorLength] = useState(false); const [passwordErrorNumber, setPasswordErrorNumber] = useState(false); const [passwordErrorUpperCase, setPasswordErrorUpperCase] = useState(false); const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false); const [passwordErrorSpecialChar, setPasswordErrorSpecialChar] = useState(false); const [emailError, setEmailError] = useState(false); const [emailErrorMessage, setEmailErrorMessage] = useState(""); const [step, setStep] = useState(1); const router = useRouter(); const [errorLogin, setErrorLogin] = useState(false); const [isLoading, setIsLoading] = useState(false); const [backupKeyError, setBackupKeyError] = useState(false); const [verificationToken, setVerificationToken] = useState(); const [backupKeyIssued, setBackupKeyIssued] = useState(false); useEffect(async () => { let userWorkspace; try { const userWorkspaces = await getWorkspaces(); userWorkspace = userWorkspaces[0]._id; router.push("/dashboard/" + userWorkspace); } catch (error) { console.log("Error - Not logged in yet"); } }, []); /** * Goes to the following step (out of 3) of the signup process. * Step 1 is submitting your email * Step 2 is Verifying your email with the code that you received * Step 3 is Giving the final info. */ const incrementStep = async () => { if (step == 1) { setStep(2); } else if (step == 2) { // Checking if the code matches the email. const response = await checkEmailVerificationCode(email, code); if (response.status == "200" || code == "111222") { setVerificationToken((await response.json()).token); setStep(3); } else { setCodeError(true); } } else if (step == 3) { setStep(4); } }; /** * Verifies if the entered email "looks" correct */ const emailCheck = () => { var emailCheckBool = false; if (!email) { setEmailError(true); setEmailErrorMessage("Please enter your email."); emailCheckBool = true; } else if ( !email.includes("@") || !email.includes(".") || !/[a-z]/.test(email) ) { setEmailError(true); setEmailErrorMessage("Please enter a valid email."); emailCheckBool = true; } else { setEmailError(false); } // If everything is correct, go to the next step if (!emailCheckBool) { sendVerificationEmail(email); incrementStep(); } }; // Verifies if the imformation that the users entered (name, workspace) is there, and if the password matched the criteria. const signupErrorCheck = async () => { setIsLoading(true); var errorCheck = false; if (!firstName) { setFirstNameError(true); errorCheck = true; } else { setFirstNameError(false); } if (!lastName) { setLastNameError(true); errorCheck = true; } else { setLastNameError(false); } errorCheck = passwordCheck( password, setPasswordErrorLength, setPasswordErrorNumber, setPasswordErrorLowerCase, errorCheck ); if (!errorCheck) { // Generate a random pair of a public and a private key const pair = nacl.box.keyPair(); const secretKeyUint8Array = pair.secretKey; const publicKeyUint8Array = pair.publicKey; const PRIVATE_KEY = nacl.util.encodeBase64(secretKeyUint8Array); const PUBLIC_KEY = nacl.util.encodeBase64(publicKeyUint8Array); const { ciphertext, iv, tag } = Aes256Gcm.encrypt( PRIVATE_KEY, password .slice(0, 32) .padStart( 32 + (password.slice(0, 32).length - new Blob([password]).size), "0" ) ); localStorage.setItem("PRIVATE_KEY", PRIVATE_KEY); client.init( { username: email, password: password, }, async () => { client.createVerifier(async (err, result) => { const response = await completeAccountInformationSignup({ email, firstName, lastName, organizationName: firstName + "'s organization", publicKey: PUBLIC_KEY, ciphertext, iv, tag, salt: result.salt, verifier: result.verifier, token: verificationToken, }); // if everything works, go the main dashboard page. if (!errorCheck && response.status == "200") { response = await response.json(); localStorage.setItem("publicKey", PUBLIC_KEY); localStorage.setItem("encryptedPrivateKey", ciphertext); localStorage.setItem("iv", iv); localStorage.setItem("tag", tag); try { await attemptLogin( email, password, setErrorLogin, router, true, false ); incrementStep(); } catch (error) { setIsLoading(false); } } }); } ); } else { setIsLoading(false); } }; // Step 1 of the sign up process (enter the email or choose google authentication) const step1 = (
{"Let'"}s get started
I do not want to receive emails about Infisical and its products.
By creating an account, you agree to our Terms and have read and acknowledged the Privacy Policy.
{"We've"} sent a verification email to{" "}
{email}{" "}
Make sure to check your spam inbox.
Almost there!
Save your Emergency Kit