diff --git a/src/app/molecules/import-e2e-room-keys/ImportE2ERoomKeys.jsx b/src/app/molecules/import-e2e-room-keys/ImportE2ERoomKeys.jsx new file mode 100644 index 0000000..3542c01 --- /dev/null +++ b/src/app/molecules/import-e2e-room-keys/ImportE2ERoomKeys.jsx @@ -0,0 +1,108 @@ +import React, { useState, useEffect, useRef } from 'react'; +import './ImportE2ERoomKeys.scss'; +import EventEmitter from 'events'; + +import initMatrix from '../../../client/initMatrix'; +import decryptMegolmKeyFile from '../../../util/decryptE2ERoomKeys'; + +import Text from '../../atoms/text/Text'; +import IconButton from '../../atoms/button/IconButton'; +import Button from '../../atoms/button/Button'; +import Input from '../../atoms/input/Input'; +import Spinner from '../../atoms/spinner/Spinner'; + +import CirclePlusIC from '../../../../public/res/ic/outlined/circle-plus.svg'; + +const viewEvent = new EventEmitter(); + +async function tryDecrypt(file, password) { + try { + const arrayBuffer = await file.arrayBuffer(); + viewEvent.emit('importing', true); + viewEvent.emit('status', 'Decrypting file...'); + const keys = await decryptMegolmKeyFile(arrayBuffer, password); + + viewEvent.emit('status', 'Decrypting messages...'); + await initMatrix.matrixClient.importRoomKeys(JSON.parse(keys)); + + viewEvent.emit('status', null); + viewEvent.emit('importing', false); + } catch (e) { + viewEvent.emit('status', e.friendlyText || 'Something went wrong!'); + viewEvent.emit('importing', false); + } +} + +function ImportE2ERoomKeys() { + const [keyFile, setKeyFile] = useState(null); + const [status, setStatus] = useState(null); + const [isImporting, setIsImporting] = useState(false); + const inputRef = useRef(null); + const passwordRef = useRef(null); + + useEffect(() => { + const handleIsImporting = (isImp) => setIsImporting(isImp); + const handleStatus = (msg) => setStatus(msg); + viewEvent.on('importing', handleIsImporting); + viewEvent.on('status', handleStatus); + + return () => { + viewEvent.removeListener('importing', handleIsImporting); + viewEvent.removeListener('status', handleStatus); + } + }, []); + + function importE2ERoomKeys() { + const password = passwordRef.current.value; + if (password === '' || keyFile === null) return; + if (isImporting) return; + + tryDecrypt(keyFile, password); + } + + function handleFileChange(e) { + const file = e.target.files.item(0); + passwordRef.current.value = ''; + setKeyFile(file); + setStatus(null); + } + function removeImportKeysFile() { + inputRef.current.value = null; + passwordRef.current.value = null; + setKeyFile(null); + setStatus(null); + } + + useEffect(() => { + if (!isImporting && status === null) { + removeImportKeysFile(); + } + }, [isImporting, status]); + + return ( +