moved two factor setup to a page

This commit is contained in:
Abhinav-grd 2021-06-21 20:53:08 +05:30
parent 6977e720ff
commit 3221dac69d
4 changed files with 99 additions and 175 deletions

View file

@ -1,64 +0,0 @@
import { DeadCenter } from 'pages/gallery';
import React, { useEffect, useState } from 'react';
import { Button } from 'react-bootstrap';
import { setupTwoFactor, TwoFactorSecret } from 'services/userService';
import styled from 'styled-components';
import constants from 'utils/strings/constants';
import EnteSpinner from './EnteSpinner';
import { CodeBlock, FreeFlowText } from './RecoveryKeyModal';
enum SetupMode {
QR_CODE,
MANUAL_CODE,
}
const QRCode = styled.img`
height:200px;
width:200px;
margin:1rem;
`;
export default function SetupTwoFactor() {
const [setupMode, setSetupMode] = useState<SetupMode>(SetupMode.QR_CODE);
const [twoFactorSecret, setTwoFactorSecret] = useState<TwoFactorSecret>(null);
useEffect(() => {
if (twoFactorSecret) {
return;
}
const main = async () => {
const twoFactorSecret = await setupTwoFactor();
setTwoFactorSecret(twoFactorSecret);
};
main();
}, []);
return setupMode === SetupMode.QR_CODE ? (
<>
<p>{constants.TWO_FACTOR_AUTHENTICATION_QR_INSTRUCTION}</p>
<DeadCenter>
{!twoFactorSecret ? <EnteSpinner /> :
<QRCode src={`data:image/png;base64,${twoFactorSecret.qrCode}`} />
}
<Button block variant="link" onClick={() => setSetupMode(SetupMode.MANUAL_CODE)}>
{constants.ENTER_CODE_MANUALLY}
</Button>
</DeadCenter>
</>
) : (<>
<p>{constants.TWO_FACTOR_AUTHENTICATION_MANUAL_CODE_INSTRUCTION}</p>
<CodeBlock height={100}>
{!twoFactorSecret ? <EnteSpinner /> : (
<FreeFlowText>
{twoFactorSecret.secretCode}
</FreeFlowText>
)}
</CodeBlock>
<Button block variant="link" style={{ marginBottom: '1rem' }} onClick={() => setSetupMode(SetupMode.QR_CODE)}>
{constants.SCAN_QR_CODE}
</Button>
</>
);
}

View file

@ -28,7 +28,6 @@ import { LogoImage } from 'pages/_app';
import { SetDialogMessage } from './MessageDialog';
import EnteSpinner from './EnteSpinner';
import RecoveryKeyModal from './RecoveryKeyModal';
import TwoFactorModal from './TwoFactorModal';
interface Props {
files: File[];
@ -46,7 +45,6 @@ export default function Sidebar(props: Props) {
}, []);
const [isOpen, setIsOpen] = useState(false);
const [recoverModalView, setRecoveryModalView] = useState(false);
const [twoFactorModal, setTwoFactorModal] = useState(true);
useEffect(() => {
const main = async () => {
if (!isOpen) {
@ -216,18 +214,12 @@ export default function Sidebar(props: Props) {
{constants.DOWNLOAD_RECOVERY_KEY}
</LinkButton>
</>
<>
<TwoFactorModal
show={twoFactorModal}
onHide={() => setTwoFactorModal(false)}
/>
<LinkButton
style={{ marginTop: '30px' }}
onClick={() => setTwoFactorModal(true)}
>
{constants.TWO_FACTOR_AUTHENTICATION}
</LinkButton>
</>
<LinkButton
style={{ marginTop: '30px' }}
onClick={() => router.push('/twoFactor/setup')}
>
{constants.TWO_FACTOR_AUTHENTICATION}
</LinkButton>
<LinkButton
style={{ marginTop: '30px' }}
onClick={() => {

View file

@ -1,97 +0,0 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useEffect, useState } from 'react';
import constants from 'utils/strings/constants';
import MessageDialog from './MessageDialog';
import { DeadCenter } from 'pages/gallery';
import { Button } from 'react-bootstrap';
import { setupTwoFactor, TwoFactorSecret } from 'services/userService';
import styled from 'styled-components';
import EnteSpinner from './EnteSpinner';
import { CodeBlock, FreeFlowText } from './RecoveryKeyModal';
import OtpInput from 'react-otp-input';
const QRCode = styled.img`
height:200px;
width:200px;
margin:20px;
`;
interface Props {
show: boolean;
onHide: () => void;
somethingWentWrong: any;
}
enum SetupMode {
QR_CODE,
MANUAL_CODE,
}
function TwoFactorModal({ somethingWentWrong, ...props }: Props) {
const [setupMode, setSetupMode] = useState<SetupMode>(SetupMode.QR_CODE);
const [twoFactorSecret, setTwoFactorSecret] = useState<TwoFactorSecret>(null);
useEffect(() => {
if (!props.show || twoFactorSecret) {
return;
}
const main = async () => {
const twoFactorSecret = await setupTwoFactor();
setTwoFactorSecret(twoFactorSecret);
};
main();
}, [props.show]);
return (
<MessageDialog
{...props}
attributes={{
title: constants.TWO_FACTOR_AUTHENTICATION,
close: {
text: constants.CANCEL,
variant: 'danger',
},
staticBackdrop: true,
proceed: {
text: constants.CONTINUE,
action: () => null,
disabled: false,
variant: 'success',
},
}}
>
{setupMode === SetupMode.QR_CODE ? (
<>
<p>{constants.TWO_FACTOR_AUTHENTICATION_QR_INSTRUCTION}</p>
<DeadCenter>
{!twoFactorSecret ? <EnteSpinner /> :
<QRCode src={`data:image/png;base64,${twoFactorSecret.qrCode}`} />
}
<Button block variant="link" onClick={() => setSetupMode(SetupMode.MANUAL_CODE)}>
{constants.ENTER_CODE_MANUALLY}
</Button>
</DeadCenter>
</>
) : (<>
<p>{constants.TWO_FACTOR_AUTHENTICATION_MANUAL_CODE_INSTRUCTION}</p>
<CodeBlock height={100}>
{!twoFactorSecret ? <EnteSpinner /> : (
<FreeFlowText>
{twoFactorSecret.secretCode}
</FreeFlowText>
)}
</CodeBlock>
<Button block variant="link" onClick={() => setSetupMode(SetupMode.QR_CODE)}>
{constants.SCAN_QR_CODE}
</Button>
</>
)}
{setupMode && <OtpInput
value={this.state.otp}
onChange={this.handleChange}
numInputs={6}
separator={<span>-</span>}
/>}
</MessageDialog >
);
}
export default TwoFactorModal;

View file

@ -0,0 +1,93 @@
import EnteSpinner from 'components/EnteSpinner';
import LogoImg from 'components/LogoImg';
import { CodeBlock, FreeFlowText } from 'components/RecoveryKeyModal';
import { DeadCenter } from 'pages/gallery';
import React, { useEffect, useState } from 'react';
import { Button, Card } from 'react-bootstrap';
import { enableTwoFactor, setupTwoFactor, TwoFactorSecret } from 'services/userService';
import styled from 'styled-components';
import constants from 'utils/strings/constants';
import Container from 'components/Container';
import { useRouter } from 'next/router';
import VerifyTwoFactor from 'components/VerifyTwoFactor';
enum SetupMode {
QR_CODE,
MANUAL_CODE,
}
const QRCode = styled.img`
height:200px;
width:200px;
margin:1rem;
`;
export default function SetupTwoFactor() {
const [setupMode, setSetupMode] = useState<SetupMode>(SetupMode.QR_CODE);
const [twoFactorSecret, setTwoFactorSecret] = useState<TwoFactorSecret>(null);
const router = useRouter();
useEffect(() => {
if (twoFactorSecret) {
return;
}
const main = async () => {
const twoFactorSecret = await setupTwoFactor();
setTwoFactorSecret(twoFactorSecret);
};
main();
}, []);
return (
<Container>
<Card style={{ minWidth: '300px' }} className="text-center">
<Card.Body style={{ padding: '40px 30px', minHeight: '400px' }}>
<DeadCenter>
<Card.Title style={{ marginBottom: '32px' }}>
<LogoImg src='/icon.svg' />
{constants.TWO_FACTOR_AUTHENTICATION}
</Card.Title>
{setupMode === SetupMode.QR_CODE ? (
<>
<p>{constants.TWO_FACTOR_AUTHENTICATION_QR_INSTRUCTION}</p>
<DeadCenter>
{!twoFactorSecret ? <EnteSpinner /> :
<QRCode src={`data:image/png;base64,${twoFactorSecret.qrCode}`} />
}
<Button block variant="link" onClick={() => setSetupMode(SetupMode.MANUAL_CODE)}>
{constants.ENTER_CODE_MANUALLY}
</Button>
</DeadCenter>
</>
) : (<>
<p>{constants.TWO_FACTOR_AUTHENTICATION_MANUAL_CODE_INSTRUCTION}</p>
<CodeBlock height={100}>
{!twoFactorSecret ? <EnteSpinner /> : (
<FreeFlowText>
{twoFactorSecret.secretCode}
</FreeFlowText>
)}
</CodeBlock>
<Button block variant="link" style={{ marginBottom: '1rem' }} onClick={() => setSetupMode(SetupMode.QR_CODE)}>
{constants.SCAN_QR_CODE}
</Button>
</>
)}
<div
style={{
height: '1px',
marginBottom: '20px',
width: '100%',
}}
/>
<VerifyTwoFactor callback={enableTwoFactor} back={router.back} buttonText={constants.ENABLE} />
<Button variant="link" onClick={router.back}>
{constants.GO_BACK}
</Button>
</DeadCenter>
</Card.Body>
</Card>
</Container>
);
}