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}`); } }); }