111 lines
3.2 KiB
JavaScript
111 lines
3.2 KiB
JavaScript
import { HexMix } from "/utils";
|
|
|
|
/**
|
|
* Initializes the send page functionality.
|
|
* This function sets up event listeners and handles the form submission process.
|
|
*/
|
|
export function initializeSendPage() {
|
|
const copyButton = document.getElementById("copyButton");
|
|
const fileInput = document.getElementById("file");
|
|
const form = document.getElementById("secretForm");
|
|
const resultInput = document.getElementById("result");
|
|
const encryptedDataTextarea = document.getElementById("encryptedData");
|
|
|
|
/**
|
|
* Copies the result URL to the clipboard.
|
|
*/
|
|
copyButton.addEventListener("click", async () => {
|
|
resultInput.select();
|
|
await navigator.clipboard.writeText(resultInput.value);
|
|
alert("URL copied to clipboard!");
|
|
});
|
|
|
|
/**
|
|
* Toggles the text input based on file selection.
|
|
* @param {Event} e - The change event.
|
|
*/
|
|
fileInput.addEventListener("change", (e) => {
|
|
const file = e.target.files[0];
|
|
document.getElementById("text").disabled = !!file;
|
|
});
|
|
|
|
/**
|
|
* Handles the form submission.
|
|
* @param {Event} e - The submit event.
|
|
*/
|
|
form.addEventListener("submit", async (e) => {
|
|
e.preventDefault();
|
|
|
|
const formData = new FormData(form);
|
|
const text = formData.get("text");
|
|
const file = formData.get("file");
|
|
const serviceIdentifier = formData.get("serviceIdentifier");
|
|
const service = formData.get("service");
|
|
|
|
let plaintext = text;
|
|
let filetype = "text/plain";
|
|
let filename = "secret.txt";
|
|
|
|
if (file.size > 0) {
|
|
if (file.size > 2097152) {
|
|
alert("Error: Max file size is 2mb.");
|
|
return;
|
|
}
|
|
plaintext = await file.arrayBuffer();
|
|
filetype = file.type;
|
|
filename = file.name;
|
|
}
|
|
|
|
/**
|
|
* Generates a new AES-GCM key.
|
|
* @type {CryptoKey}
|
|
*/
|
|
const key = await window.crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]);
|
|
|
|
const iv = window.crypto.getRandomValues(new Uint8Array(16));
|
|
const exported = await window.crypto.subtle.exportKey("raw", key);
|
|
|
|
/**
|
|
* Encrypts the plaintext.
|
|
* @type {ArrayBuffer}
|
|
*/
|
|
const encrypted = await window.crypto.subtle.encrypt(
|
|
{ name: "AES-GCM", iv },
|
|
key,
|
|
typeof plaintext === "string" ? HexMix.stringToArrayBuffer(plaintext) : plaintext
|
|
);
|
|
|
|
// Convert the encrypted ArrayBuffer to a Base64 string
|
|
const encryptedBase64 = HexMix.arrayBufferToBase64(encrypted);
|
|
encryptedDataTextarea.value = encryptedBase64;
|
|
|
|
const keyHex = HexMix.uint8ToHex(new Uint8Array(exported));
|
|
const ivHex = HexMix.uint8ToHex(iv);
|
|
const keyParams = { key: keyHex, iv: ivHex };
|
|
|
|
const params = JSON.stringify({
|
|
service: service,
|
|
serviceIdentifier: serviceIdentifier,
|
|
text: encryptedBase64,
|
|
iv: ivHex,
|
|
filetype: filetype,
|
|
filename: filename
|
|
});
|
|
|
|
try {
|
|
const response = await fetch("/rest/links", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: params
|
|
});
|
|
const data = await response.json();
|
|
const url = `http://${window.location.host}/rest/links/${data.id}#${btoa(JSON.stringify(keyParams))}`;
|
|
resultInput.value = url;
|
|
} catch (err) {
|
|
alert(`Error: ${err.message}`);
|
|
}
|
|
});
|
|
}
|