import React, { useState } from 'react'; import Image from 'next/image'; import { useRouter } from 'next/router'; import { faCheck, faX } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import Button from '~/components/basic/buttons/Button'; import InputField from '~/components/basic/InputField'; import passwordCheck from '~/components/utilities/checks/PasswordCheck'; import Aes256Gcm from '~/components/utilities/cryptography/aes-256-gcm'; import EmailVerifyOnPasswordReset from './api/auth/EmailVerifyOnPasswordReset'; import getBackupEncryptedPrivateKey from './api/auth/getBackupEncryptedPrivateKey'; import resetPasswordOnAccountRecovery from './api/auth/resetPasswordOnAccountRecovery'; const queryString = require('query-string'); const nacl = require('tweetnacl'); const jsrp = require('jsrp'); nacl.util = require('tweetnacl-util'); const client = new jsrp.client(); export default function PasswordReset() { const router = useRouter(); const parsedUrl = queryString.parse(router.asPath.split('?')[1]); const token = parsedUrl.token; const email = parsedUrl.to?.replace(' ', '+').trim(); const [verificationToken, setVerificationToken] = useState(''); const [step, setStep] = useState(1); const [backupKey, setBackupKey] = useState(''); const [privateKey, setPrivateKey] = useState(''); const [newPassword, setNewPassword] = useState(''); const [backupKeyError, setBackupKeyError] = useState(false); const [passwordErrorLength, setPasswordErrorLength] = useState(false); const [passwordErrorNumber, setPasswordErrorNumber] = useState(false); const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false); // Unencrypt the private key with a backup key const getEncryptedKeyHandler = async () => { try { const result = await getBackupEncryptedPrivateKey({ verificationToken }); setPrivateKey( Aes256Gcm.decrypt({ ciphertext: result.encryptedPrivateKey, iv: result.iv, tag: result.tag, secret: backupKey }) ); setStep(3); } catch { setBackupKeyError(true); } }; // If everything is correct, reset the password const resetPasswordHandler = async () => { let errorCheck = false; errorCheck = passwordCheck({ password: newPassword, setPasswordErrorLength, setPasswordErrorNumber, setPasswordErrorLowerCase, currentErrorCheck: errorCheck }); if (!errorCheck) { // Generate a random pair of a public and a private key const { ciphertext, iv, tag } = Aes256Gcm.encrypt({ text: privateKey, secret: newPassword .slice(0, 32) .padStart( 32 + (newPassword.slice(0, 32).length - new Blob([newPassword]).size), '0' ) }) as { ciphertext: string; iv: string; tag: string }; client.init( { username: email, password: newPassword }, async () => { client.createVerifier( async (err: any, result: { salt: string; verifier: string }) => { const response = await resetPasswordOnAccountRecovery({ verificationToken, encryptedPrivateKey: ciphertext, iv, tag, salt: result.salt, verifier: result.verifier }); // if everything works, go the main dashboard page. if (response?.status === 200) { router.push('/login'); } } ); } ); } }; // Click a button to confirm email const stepConfirmEmail = (
Confirm your email
Enter your backup key
You can find it in your emrgency kit. You had to download the enrgency kit during signup.
Enter new password
Make sure you save it somewhere save.