intended-server/static/js/send.js

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