import React, { useEffect, useState } from 'react'; import ReactCodeInput from 'react-code-input'; 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' } } as const; 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' } } as const; 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(() => { const tryAuth = async () => { try { const userWorkspaces = await getWorkspaces(); router.push('/dashboard/' + userWorkspaces[0]._id); } catch (error) { console.log('Error - Not logged in yet'); } }; tryAuth(); }, []); /** * 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 = () => { let 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); let 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, currentErrorCheck: 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({ text: PRIVATE_KEY, secret: password .slice(0, 32) .padStart( 32 + (password.slice(0, 32).length - new Blob([password]).size), '0' ) }) as { ciphertext: string; iv: string; tag: string }; localStorage.setItem('PRIVATE_KEY', PRIVATE_KEY); client.init( { username: email, password: password }, async () => { client.createVerifier( async (err: any, result: { salt: string; verifier: string }) => { 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 (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