ente/src/pages/credentials/index.tsx

129 lines
4.8 KiB
TypeScript
Raw Normal View History

2021-06-04 07:57:48 +00:00
import React, { useContext, useEffect, useState } from 'react';
import constants from 'utils/strings/constants';
2021-06-03 06:05:43 +00:00
import { clearData, getData, LS_KEYS } from 'utils/storage/localStorage';
2021-05-30 16:56:48 +00:00
import { useRouter } from 'next/router';
import { KeyAttributes, PAGES } from 'types';
2021-05-30 16:56:48 +00:00
import { SESSION_KEYS, getKey } from 'utils/storage/sessionStorage';
2021-04-05 05:44:56 +00:00
import CryptoWorker, {
2021-06-14 14:54:10 +00:00
decryptAndStoreToken,
generateAndSaveIntermediateKeyAttributes,
SaveKeyInSessionStore,
2021-04-05 05:44:56 +00:00
} from 'utils/crypto';
2021-05-30 16:56:48 +00:00
import { logoutUser } from 'services/userService';
import { isFirstLogin } from 'utils/storage';
import SingleInputForm from 'components/SingleInputForm';
import Container from 'components/Container';
2021-05-30 16:56:48 +00:00
import { Button, Card } from 'react-bootstrap';
2021-06-04 07:57:48 +00:00
import { AppContext } from 'pages/_app';
2021-06-04 21:49:24 +00:00
import LogoImg from 'components/LogoImg';
2021-06-12 17:14:21 +00:00
import { logError } from 'utils/sentry';
export default function Credentials() {
const router = useRouter();
2021-04-02 04:03:00 +00:00
const [keyAttributes, setKeyAttributes] = useState<KeyAttributes>();
2021-06-04 07:57:48 +00:00
const appContext = useContext(AppContext);
useEffect(() => {
router.prefetch(PAGES.GALLERY);
const user = getData(LS_KEYS.USER);
const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
const key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
2021-08-13 02:38:38 +00:00
if (
(!user?.token && !user?.encryptedToken) ||
2021-08-16 14:35:53 +00:00
(keyAttributes && !keyAttributes.memLimit)
2021-08-13 02:38:38 +00:00
) {
2021-06-03 06:05:43 +00:00
clearData();
router.push(PAGES.ROOT);
} else if (!keyAttributes) {
router.push(PAGES.GENERATE);
} else if (key) {
router.push(PAGES.GALLERY);
} else {
setKeyAttributes(keyAttributes);
}
2021-06-04 21:49:24 +00:00
appContext.showNavBar(false);
}, []);
const verifyPassphrase = async (passphrase, setFieldError) => {
try {
2020-10-01 11:47:13 +00:00
const cryptoWorker = await new CryptoWorker();
2021-06-07 05:04:50 +00:00
let kek: string = null;
try {
kek = await cryptoWorker.deriveKey(
passphrase,
keyAttributes.kekSalt,
keyAttributes.opsLimit,
2021-08-13 02:38:38 +00:00
keyAttributes.memLimit
2021-06-07 05:04:50 +00:00
);
} catch (e) {
console.error('failed to deriveKey ', e.message);
throw e;
}
try {
const key: string = await cryptoWorker.decryptB64(
keyAttributes.encryptedKey,
keyAttributes.keyDecryptionNonce,
2021-08-13 02:38:38 +00:00
kek
);
if (isFirstLogin()) {
await generateAndSaveIntermediateKeyAttributes(
passphrase,
keyAttributes,
2021-08-13 02:38:38 +00:00
key
);
}
await SaveKeyInSessionStore(SESSION_KEYS.ENCRYPTION_KEY, key);
2021-06-14 14:54:10 +00:00
await decryptAndStoreToken(key);
router.push(PAGES.GALLERY);
} catch (e) {
2021-06-12 17:14:21 +00:00
logError(e);
setFieldError('passphrase', constants.INCORRECT_PASSPHRASE);
}
} catch (e) {
setFieldError(
'passphrase',
2021-08-13 02:38:38 +00:00
`${constants.UNKNOWN_ERROR} ${e.message}`
);
2021-06-07 05:04:50 +00:00
console.error('failed to verifyPassphrase ', e.message);
}
};
return (
<>
<Container>
2021-08-13 02:38:38 +00:00
<Card style={{ minWidth: '320px' }} className="text-center">
2021-06-04 21:49:24 +00:00
<Card.Body style={{ padding: '40px 30px' }}>
<Card.Title style={{ marginBottom: '32px' }}>
2021-08-13 02:38:38 +00:00
<LogoImg src="/icon.svg" />
2021-06-04 21:49:24 +00:00
{constants.PASSWORD}
</Card.Title>
<SingleInputForm
callback={verifyPassphrase}
placeholder={constants.RETURN_PASSPHRASE_HINT}
buttonText={constants.VERIFY_PASSPHRASE}
fieldType="password"
/>
<div
style={{
display: 'flex',
flexDirection: 'column',
marginTop: '12px',
2021-08-13 02:38:38 +00:00
}}>
<Button
variant="link"
onClick={() => router.push(PAGES.RECOVER)}>
{constants.FORGOT_PASSWORD}
</Button>
<Button variant="link" onClick={logoutUser}>
{constants.GO_BACK}
</Button>
</div>
</Card.Body>
</Card>
</Container>
</>
);
}