chore(frontend): changed source code to src folder from root

This commit is contained in:
akhilmhdh
2023-01-16 00:34:22 +05:30
parent c563548a1c
commit 63e9d83ba4
193 changed files with 280 additions and 33 deletions
+291
View File
@@ -0,0 +1,291 @@
import { 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 jsrp from 'jsrp';
import queryString from 'query-string';
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 { getTranslatedStaticProps } from '~/components/utilities/withTranslateProps';
import EmailVerifyOnPasswordReset from './api/auth/EmailVerifyOnPasswordReset';
import getBackupEncryptedPrivateKey from './api/auth/getBackupEncryptedPrivateKey';
import resetPasswordOnAccountRecovery from './api/auth/resetPasswordOnAccountRecovery';
const client = new jsrp.client();
export default function PasswordReset() {
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);
const router = useRouter();
const parsedUrl = queryString.parse(router.asPath.split('?')[1]);
const token = parsedUrl.token as string;
const email = (parsedUrl.to as string)?.replace(' ', '+').trim();
// 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 () => {
const errorCheck = passwordCheck({
password: newPassword,
setPasswordErrorLength,
setPasswordErrorNumber,
setPasswordErrorLowerCase,
errorCheck: false,
});
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 = (
<div className='bg-bunker flex flex-col items-center w-full py-6 max-w-xs md:max-w-lg mx-auto my-32 px-4 md:px-6 mx-1 rounded-xl drop-shadow-xl'>
<p className='text-4xl text-center font-semibold mb-8 flex justify-center text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary'>
Confirm your email
</p>
<Image
src='/images/envelope.svg'
height={262}
width={410}
alt='verify email'
></Image>
<div className='flex flex-col items-center justify-center md:p-2 max-h-24 max-w-md mx-auto text-lg px-4 mt-4 mb-2'>
<Button
text='Confirm Email'
onButtonPressed={async () => {
const response = await EmailVerifyOnPasswordReset({
email,
code: token,
});
if (response.status == 200) {
setVerificationToken((await response.json()).token);
setStep(2);
} else {
console.log('ERROR', response);
router.push('/email-not-verified');
}
}}
size='lg'
/>
</div>
</div>
);
// Input backup key
const stepInputBackupKey = (
<div className='bg-bunker flex flex-col items-center w-full pt-6 pb-3 max-w-xs md:max-w-lg mx-auto my-32 px-4 md:px-6 mx-1 rounded-xl drop-shadow-xl'>
<p className='text-2xl md:text-3xl w-max mx-auto flex justify-center font-semibold text-bunker-100 mb-4'>
Enter your backup key
</p>
<div className='flex flex-row items-center justify-center md:pb-4 mt-4 md:mx-2'>
<p className='text-sm flex justify-center text-gray-400 w-max max-w-md'>
You can find it in your emrgency kit. You had to download the enrgency
kit during signup.
</p>
</div>
<div className='flex items-center justify-center w-full md:p-2 rounded-lg mt-4 md:mt-0 max-h-24 md:max-h-28'>
<InputField
label='Backup Key'
onChangeHandler={setBackupKey}
type='password'
value={backupKey}
placeholder=''
isRequired
error={backupKeyError}
errorText='Something is wrong with the backup key'
/>
</div>
<div className='flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm'>
<div className='text-l mt-6 m-8 px-8 py-3 text-lg'>
<Button
text='Submit Backup Key'
onButtonPressed={() => getEncryptedKeyHandler()}
size='lg'
/>
</div>
</div>
</div>
);
// Enter new password
const stepEnterNewPassword = (
<div className='bg-bunker flex flex-col items-center w-full pt-6 pb-3 max-w-xs md:max-w-lg mx-auto my-32 px-4 md:px-6 mx-1 rounded-xl drop-shadow-xl'>
<p className='text-2xl md:text-3xl w-max mx-auto flex justify-center font-semibold text-bunker-100'>
Enter new password
</p>
<div className='flex flex-row items-center justify-center md:pb-4 mt-1 md:mx-2'>
<p className='text-sm flex justify-center text-gray-400 w-max max-w-md'>
Make sure you save it somewhere save.
</p>
</div>
<div className='flex items-center justify-center w-full md:p-2 rounded-lg mt-4 md:mt-0 max-h-24 md:max-h-28'>
<InputField
label='New Password'
onChangeHandler={(password) => {
setNewPassword(password);
passwordCheck({
password,
setPasswordErrorLength,
setPasswordErrorNumber,
setPasswordErrorLowerCase,
errorCheck: false,
});
}}
type='password'
value={newPassword}
isRequired
error={
passwordErrorLength && passwordErrorLowerCase && passwordErrorNumber
}
autoComplete='new-password'
id='new-password'
/>
</div>
{passwordErrorLength || passwordErrorLowerCase || passwordErrorNumber ? (
<div className='w-full mt-3 bg-white/5 px-2 mx-2 flex flex-col items-start py-2 rounded-md max-w-md mb-2'>
<div className={`text-gray-400 text-sm mb-1`}>
Password should contain at least:
</div>
<div className='flex flex-row justify-start items-center ml-1'>
{passwordErrorLength ? (
<FontAwesomeIcon icon={faX} className='text-md text-red mr-2.5' />
) : (
<FontAwesomeIcon
icon={faCheck}
className='text-md text-primary mr-2'
/>
)}
<div
className={`${
passwordErrorLength ? 'text-gray-400' : 'text-gray-600'
} text-sm`}
>
14 characters
</div>
</div>
<div className='flex flex-row justify-start items-center ml-1'>
{passwordErrorLowerCase ? (
<FontAwesomeIcon icon={faX} className='text-md text-red mr-2.5' />
) : (
<FontAwesomeIcon
icon={faCheck}
className='text-md text-primary mr-2'
/>
)}
<div
className={`${
passwordErrorLowerCase ? 'text-gray-400' : 'text-gray-600'
} text-sm`}
>
1 lowercase character
</div>
</div>
<div className='flex flex-row justify-start items-center ml-1'>
{passwordErrorNumber ? (
<FontAwesomeIcon icon={faX} className='text-md text-red mr-2.5' />
) : (
<FontAwesomeIcon
icon={faCheck}
className='text-md text-primary mr-2'
/>
)}
<div
className={`${
passwordErrorNumber ? 'text-gray-400' : 'text-gray-600'
} text-sm`}
>
1 number
</div>
</div>
</div>
) : (
<div className='py-2'></div>
)}
<div className='flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm'>
<div className='text-l mt-6 m-8 px-8 py-3 text-lg'>
<Button
text='Submit New Password'
onButtonPressed={() => resetPasswordHandler()}
size='lg'
/>
</div>
</div>
</div>
);
return (
<div className='bg-bunker-800 h-screen w-full flex flex-col items-center justify-center'>
{step === 1 && stepConfirmEmail}
{step === 2 && stepInputBackupKey}
{step === 3 && stepEnterNewPassword}
</div>
);
}
export const getServerSideProps = getTranslatedStaticProps([]);