import { Button } from "../../../elements/Button"; import { Checkbox } from "../../../elements/forms/Checkbox"; import { Component, createRef } from "preact"; import { CopyableBox } from "../../../elements/CopyableBox"; import { DefaultPageProps } from "../../../../types/DefaultPageProps"; import { ErrorMessage } from "../../../elements/ErrorMessage"; import { FileUploadInput } from "../../../elements/FileUploadInput"; import { Form } from "../../../elements/forms/Form"; import { InputWithTitle } from "../../../elements/InputWithTitle"; import { Margin } from "../../../elements/Margin"; import { SecretTitleElement } from "../SecretTitleElement"; import { TextArea } from "../../../elements/forms/TextArea"; import { fileToBase64 } from "../../../../utils/fileToBase64"; import i18next from "i18next"; export class TransitDecrypt extends Component<DefaultPageProps, { plaintext: string }> { errorMessageRef = createRef<ErrorMessage>(); render() { const baseMount = this.props.matches["baseMount"]; const secretItem = this.props.matches["secretItem"]; const title = ( <SecretTitleElement type="transit" baseMount={baseMount} item={secretItem} suffix={i18next.t("transit_decrypt_suffix")} /> ); if (!this.state.plaintext) { return ( <> {title} <Form onSubmit={async (data) => await this.onSubmit(data)}> <Margin> <TextArea name="ciphertext" placeholder={i18next.t("transit_decrypt_input_placeholder")} /> </Margin> <Margin> <FileUploadInput name="ciphertext_file" /> </Margin> <InputWithTitle title={i18next.t("transit_decrypt_decode_checkbox")}> <Checkbox name="decodeBase64Checkbox" /> </InputWithTitle> <Margin> <ErrorMessage ref={this.errorMessageRef} /> </Margin> <Button text={i18next.t("transit_decrypt")} color="primary" type="submit" /> </Form> </> ); } else { return ( <> {title} <CopyableBox title={i18next.t("transit_decrypt_decryption_result_title")} contentString={this.state.plaintext} goBack={() => { this.setState({ plaintext: null }); }} /> </> ); } } async onSubmit(data: FormData): Promise<void> { const baseMount = this.props.matches["baseMount"]; const secretItem = this.props.matches["secretItem"]; const decodeBase64 = data.get("decodeBase64Checkbox") as string; let ciphertext = data.get("ciphertext") as string; const ciphertext_file = data.get("ciphertext_file") as File; if (ciphertext_file.size > 0) { // TODO: please stop using atob ciphertext = atob( (await fileToBase64(ciphertext_file)).replace("data:text/plain;base64,", ""), ); } try { const res = await this.props.api.transitDecrypt(baseMount, secretItem, { ciphertext: ciphertext, }); let plaintext = res.plaintext; if (decodeBase64 == "on") { // Really don't supposed to be doing this... plaintext = atob(plaintext); } this.setState({ plaintext: plaintext }); } catch (e: unknown) { const error = e as Error; this.errorMessageRef.current.setErrorMessage(error.message); } } }