2021-04-05 06:17:31 +00:00
|
|
|
import React, { useState, useEffect } from 'react';
|
2020-09-12 21:53:41 +00:00
|
|
|
import constants from 'utils/strings/constants';
|
2021-03-22 14:06:06 +00:00
|
|
|
import { logoutUser, putAttributes } from 'services/userService';
|
2021-04-05 06:17:31 +00:00
|
|
|
import { getData, LS_KEYS } from 'utils/storage/localStorage';
|
2020-09-12 21:53:41 +00:00
|
|
|
import { useRouter } from 'next/router';
|
2021-04-05 09:56:13 +00:00
|
|
|
import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage';
|
2021-02-16 11:43:21 +00:00
|
|
|
import { B64EncryptionResult } from 'services/uploadService';
|
2021-04-05 05:44:56 +00:00
|
|
|
import CryptoWorker, {
|
|
|
|
setSessionKeys,
|
2021-04-05 05:50:40 +00:00
|
|
|
generateAndSaveIntermediateKeyAttributes,
|
2021-04-05 05:44:56 +00:00
|
|
|
} from 'utils/crypto';
|
2021-04-05 06:17:31 +00:00
|
|
|
import PasswordForm from 'components/PasswordForm';
|
2021-04-05 09:56:13 +00:00
|
|
|
import { KeyAttributes } from 'types';
|
2020-09-12 21:53:41 +00:00
|
|
|
|
2021-04-02 03:56:21 +00:00
|
|
|
export interface KEK {
|
2021-03-18 09:56:40 +00:00
|
|
|
key: string;
|
|
|
|
opsLimit: number;
|
|
|
|
memLimit: number;
|
|
|
|
}
|
|
|
|
|
2020-09-12 21:53:41 +00:00
|
|
|
export default function Generate() {
|
|
|
|
const [token, setToken] = useState<string>();
|
|
|
|
const router = useRouter();
|
2020-09-13 06:30:07 +00:00
|
|
|
const key = getKey(SESSION_KEYS.ENCRYPTION_KEY);
|
2020-10-01 01:29:24 +00:00
|
|
|
|
2020-09-12 21:53:41 +00:00
|
|
|
useEffect(() => {
|
2020-09-14 09:32:01 +00:00
|
|
|
router.prefetch('/gallery');
|
2020-09-13 06:30:07 +00:00
|
|
|
const user = getData(LS_KEYS.USER);
|
2020-09-12 21:53:41 +00:00
|
|
|
if (!user?.token) {
|
2021-02-09 09:33:54 +00:00
|
|
|
router.push('/');
|
2020-09-13 06:30:07 +00:00
|
|
|
} else if (key) {
|
2020-09-12 21:53:41 +00:00
|
|
|
router.push('/gallery');
|
|
|
|
} else {
|
|
|
|
setToken(user.token);
|
|
|
|
}
|
|
|
|
}, []);
|
|
|
|
|
2021-04-05 06:17:31 +00:00
|
|
|
const onSubmit = async (passphrase, setFieldError) => {
|
|
|
|
const cryptoWorker = await new CryptoWorker();
|
2021-04-05 09:56:13 +00:00
|
|
|
const masterKey: string = await cryptoWorker.generateEncryptionKey();
|
|
|
|
const recoveryKey: string = await cryptoWorker.generateEncryptionKey();
|
2021-04-05 06:17:31 +00:00
|
|
|
const kekSalt: string = await cryptoWorker.generateSaltToDeriveKey();
|
|
|
|
let kek: KEK;
|
2020-09-12 21:53:41 +00:00
|
|
|
try {
|
2021-04-05 06:17:31 +00:00
|
|
|
kek = await cryptoWorker.deriveSensitiveKey(passphrase, kekSalt);
|
2020-09-12 21:53:41 +00:00
|
|
|
} catch (e) {
|
2021-04-05 06:17:31 +00:00
|
|
|
setFieldError('confirm', constants.PASSWORD_GENERATION_FAILED);
|
|
|
|
return;
|
2020-09-12 21:53:41 +00:00
|
|
|
}
|
2021-04-05 09:56:13 +00:00
|
|
|
const masterKeyEncryptedWithKek: B64EncryptionResult = await cryptoWorker.encryptToB64(
|
|
|
|
masterKey,
|
2021-04-05 06:17:31 +00:00
|
|
|
kek.key
|
|
|
|
);
|
2021-04-05 09:56:13 +00:00
|
|
|
const masterKeyEncryptedWithRecoveryKey: B64EncryptionResult = await cryptoWorker.encryptToB64(
|
|
|
|
masterKey,
|
|
|
|
recoveryKey
|
|
|
|
);
|
|
|
|
const recoveryKeyEncryptedWithMasterKey: B64EncryptionResult = await cryptoWorker.encryptToB64(
|
|
|
|
recoveryKey,
|
|
|
|
masterKey
|
|
|
|
);
|
|
|
|
|
2021-04-05 06:17:31 +00:00
|
|
|
const keyPair = await cryptoWorker.generateKeyPair();
|
|
|
|
const encryptedKeyPairAttributes: B64EncryptionResult = await cryptoWorker.encryptToB64(
|
|
|
|
keyPair.privateKey,
|
|
|
|
key
|
|
|
|
);
|
|
|
|
|
2021-04-05 09:56:13 +00:00
|
|
|
const keyAttributes: KeyAttributes = {
|
2021-04-05 06:17:31 +00:00
|
|
|
kekSalt,
|
2021-04-05 09:56:13 +00:00
|
|
|
encryptedKey: masterKeyEncryptedWithKek.encryptedData,
|
|
|
|
keyDecryptionNonce: masterKeyEncryptedWithKek.nonce,
|
2021-04-05 06:17:31 +00:00
|
|
|
publicKey: keyPair.publicKey,
|
|
|
|
encryptedSecretKey: encryptedKeyPairAttributes.encryptedData,
|
|
|
|
secretKeyDecryptionNonce: encryptedKeyPairAttributes.nonce,
|
|
|
|
opsLimit: kek.opsLimit,
|
|
|
|
memLimit: kek.memLimit,
|
2021-04-05 09:56:13 +00:00
|
|
|
masterKeyEncryptedWithRecoveryKey:
|
|
|
|
masterKeyEncryptedWithRecoveryKey.encryptedData,
|
|
|
|
masterKeyDecryptionNonce: masterKeyEncryptedWithRecoveryKey.nonce,
|
|
|
|
recoveryKeyEncryptedWithMasterKey:
|
|
|
|
recoveryKeyEncryptedWithMasterKey.encryptedData,
|
|
|
|
recoveryKeyDecryptionNonce: recoveryKeyEncryptedWithMasterKey.nonce,
|
2021-04-05 06:17:31 +00:00
|
|
|
};
|
|
|
|
await putAttributes(token, getData(LS_KEYS.USER).name, keyAttributes);
|
|
|
|
await generateAndSaveIntermediateKeyAttributes(
|
|
|
|
passphrase,
|
|
|
|
keyAttributes,
|
|
|
|
key
|
|
|
|
);
|
|
|
|
|
2021-04-05 09:56:13 +00:00
|
|
|
setSessionKeys(masterKey);
|
2021-04-05 06:17:31 +00:00
|
|
|
router.push('/gallery');
|
2021-02-09 09:33:54 +00:00
|
|
|
};
|
2020-10-01 01:29:24 +00:00
|
|
|
|
2021-02-09 09:33:54 +00:00
|
|
|
return (
|
2021-04-05 06:17:31 +00:00
|
|
|
<>
|
|
|
|
<PasswordForm
|
|
|
|
callback={onSubmit}
|
|
|
|
buttonText={constants.SET_PASSPHRASE}
|
2021-04-05 06:35:58 +00:00
|
|
|
back={logoutUser}
|
2021-04-05 06:17:31 +00:00
|
|
|
/>
|
|
|
|
</>
|
2021-02-09 09:33:54 +00:00
|
|
|
);
|
2020-09-12 21:53:41 +00:00
|
|
|
}
|