async function encrypt( content: Uint8Array, password: string, ): Promise { const iv = crypto.getRandomValues(new Uint8Array(16)); const salt = crypto.getRandomValues(new Uint8Array(16)); const keyMaterial = await crypto.subtle.importKey( "raw", new TextEncoder().encode(password), { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"], ); const key = await crypto.subtle.deriveKey( { name: "PBKDF2", salt: salt, iterations: 100000, hash: "SHA-512", }, keyMaterial, { name: "AES-CBC", length: 256 }, false, ["encrypt"], ); const encryptedContent = await crypto.subtle.encrypt( { name: "AES-CBC", iv: iv }, key, content, ); return new Uint8Array([...salt, ...iv, ...new Uint8Array(encryptedContent)]) .buffer; } async function uploadFile() { ( document.getElementById("upload-dialog") as HTMLDialogElement | null )?.showModal(); const passwordInput = document.getElementById( "password", ) as HTMLInputElement | null; const fileInput = document.getElementById("file") as HTMLInputElement | null; const filenameInput = document.getElementById( "filename", ) as HTMLInputElement | null; const encryptedInput = document.getElementById( "encrypted", ) as HTMLInputElement | null; const form = document.getElementById("uploadForm") as HTMLFormElement | null; if ( !passwordInput || !fileInput || !filenameInput || !encryptedInput || !form ) { console.error("Missing required elements."); console.error( passwordInput, fileInput, filenameInput, encryptedInput, form, ); return; } const password = passwordInput.value; if (!password) { form.submit(); return; } const file = fileInput.files?.[0]; if (!file) { return; } const content = await file.arrayBuffer(); const encryptedContent = await encrypt(new Uint8Array(content), password); const myFile = new File([encryptedContent], file.name); const dataTransfer = new DataTransfer(); dataTransfer.items.add(myFile); fileInput.files = dataTransfer.files; encryptedInput.checked = true; console.log("encryption done"); form.submit(); } const jsguards = document.getElementsByClassName("jsguard"); for (let i = 0; i < jsguards.length; i++) { jsguards[i].remove(); } (document.getElementById("uploadForm") as HTMLFormElement | null)?.reset(); window.uploadFile = uploadFile; //disable bfcache, otherwise dialog will stay open when navigating back window.addEventListener("unload", () => {}); window.addEventListener("beforeunload", () => {});