implement encryption of secret text
This commit is contained in:
parent
8899fbb368
commit
04225c44aa
|
@ -1,11 +1,13 @@
|
|||
import React, { useState } from "react";
|
||||
|
||||
import { ProgressIndicator, Header2, Button, IconArrow, Label, FileInput, TextArea, CenteredContainer, Spacer, TextAlignWrapper, GlobalStyle } from '@intended/intended-ui';
|
||||
import HexMix from "../utils/hexmix";
|
||||
|
||||
const JustPage = () => {
|
||||
const [secretInput, setSecretInput] = useState("");
|
||||
const [fileInput, setFileInput] = useState<File | null>(null);
|
||||
const [fileName, setFileName] = useState("");
|
||||
const [encryptedSecret, setEncryptedSecret] = useState("");
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setSecretInput(e.target.value);
|
||||
|
@ -17,6 +19,59 @@ const JustPage = () => {
|
|||
setFileName(file.name);
|
||||
};
|
||||
|
||||
const postContents = async () => {
|
||||
if (!window.crypto.subtle) {
|
||||
alert('Browser does not support SubtleCrypto');
|
||||
return;
|
||||
}
|
||||
|
||||
const key = await window.crypto.subtle.generateKey(
|
||||
{
|
||||
name: 'AES-GCM',
|
||||
length: 256
|
||||
},
|
||||
true,
|
||||
['encrypt', 'decrypt']
|
||||
);
|
||||
const encoded = HexMix.stringToArrayBuffer(secretInput);
|
||||
const iv = window.crypto.getRandomValues(new Uint8Array(16));
|
||||
const exported = await window.crypto.subtle.exportKey('raw', key);
|
||||
const encrypted = await window.crypto.subtle.encrypt(
|
||||
{
|
||||
name: 'AES-GCM',
|
||||
iv
|
||||
},
|
||||
key,
|
||||
encoded
|
||||
);
|
||||
|
||||
// encrypted will be sent to lumen backend
|
||||
HexMix.arrayBufferToString(encrypted, (result: string) => {
|
||||
setEncryptedSecret(result);
|
||||
});
|
||||
|
||||
const keyHex = HexMix.uint8ToHex(new Uint8Array(exported));
|
||||
const ivHex = HexMix.uint8ToHex(iv);
|
||||
|
||||
const formData = new FormData();
|
||||
const blobData = new Blob([encrypted]);
|
||||
|
||||
formData.append('blob', blobData);
|
||||
formData.append('filetype', 'text/plain');
|
||||
formData.append('filename', 'secret.txt');
|
||||
|
||||
try {
|
||||
await fetch(`${window.location.origin}/just`, {
|
||||
body: formData,
|
||||
method: "POST"
|
||||
});
|
||||
const url = `${window.location.origin}/just/for#${keyHex}.${ivHex}`;
|
||||
window.location.href = url
|
||||
} catch (err: any) {
|
||||
alert(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<React.StrictMode>
|
||||
<GlobalStyle />
|
||||
|
@ -39,12 +94,13 @@ const JustPage = () => {
|
|||
</TextAlignWrapper>
|
||||
<Spacer space="1.6rem" />
|
||||
<FileInput id="fileInput" value={fileName} handleFile={handleFile} />
|
||||
{ encryptedSecret ? "" : encryptedSecret }
|
||||
{ fileInput ? "" : ""}
|
||||
<Spacer space="4rem" />
|
||||
<div
|
||||
style={{ display: "flex", justifyContent: "flex-end", width: "100%" }}
|
||||
>
|
||||
<Button variant="secondary" onClick={() => window.location.href = "/just/for"}>
|
||||
<Button variant="secondary" onClick={postContents}>
|
||||
<IconArrow arrowDirection="right" />
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
"noUnusedParameters": true,
|
||||
"lib": ["es2015", "dom"]
|
||||
},
|
||||
"exclude": [
|
||||
"/node_modules/**/*",
|
||||
|
|
Loading…
Reference in New Issue