moved two factor setup to a page
This commit is contained in:
parent
6977e720ff
commit
3221dac69d
|
@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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={() => {
|
||||
|
|
|
@ -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;
|
93
src/pages/twoFactor/setup/index.tsx
Normal file
93
src/pages/twoFactor/setup/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue