import React, { useState } from 'react'; import PropTypes from 'prop-types'; import './SecretStorageAccess.scss'; import { deriveKey } from 'matrix-js-sdk/lib/crypto/key_passphrase'; import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; import { getDefaultSSKey, getSSKeyInfo } from '../../../util/matrixUtil'; import { storePrivateKey, hasPrivateKey, getPrivateKey } from '../../../client/state/secretStorageKeys'; import Text from '../../atoms/text/Text'; import Button from '../../atoms/button/Button'; import Input from '../../atoms/input/Input'; import Spinner from '../../atoms/spinner/Spinner'; import { useStore } from '../../hooks/useStore'; function SecretStorageAccess({ onComplete }) { const mx = initMatrix.matrixClient; const sSKeyId = getDefaultSSKey(); const sSKeyInfo = getSSKeyInfo(sSKeyId); const isPassphrase = !!sSKeyInfo.passphrase; const [withPhrase, setWithPhrase] = useState(isPassphrase); const [process, setProcess] = useState(false); const [error, setError] = useState(null); const mountStore = useStore(); mountStore.setItem(true); const toggleWithPhrase = () => setWithPhrase(!withPhrase); const processInput = async ({ key, phrase }) => { setProcess(true); try { const { salt, iterations } = sSKeyInfo.passphrase; const privateKey = key ? mx.keyBackupKeyFromRecoveryKey(key) : await deriveKey(phrase, salt, iterations); const isCorrect = await mx.checkSecretStorageKey(privateKey, sSKeyInfo); if (!mountStore.getItem()) return; if (!isCorrect) { setError(`Incorrect Security ${key ? 'Key' : 'Phrase'}`); setProcess(false); return; } onComplete({ keyId: sSKeyId, key, phrase, privateKey, }); } catch (e) { if (!mountStore.getItem()) return; setError(`Incorrect Security ${key ? 'Key' : 'Phrase'}`); setProcess(false); } }; const handleForm = async (e) => { e.preventDefault(); const password = e.target.password.value; if (password.trim() === '') return; const data = {}; if (withPhrase) data.phrase = password; else data.key = password; processInput(data); }; const handleChange = () => { setError(null); setProcess(false); }; return (