client-index.ts
Raw
1async function encrypt(
2 content: Uint8Array<ArrayBuffer>,
3 password: string,
4): Promise<ArrayBuffer> {
5 const iv = crypto.getRandomValues(new Uint8Array(16));
6 const salt = crypto.getRandomValues(new Uint8Array(16));
7 const keyMaterial = await crypto.subtle.importKey(
8 "raw",
9 new TextEncoder().encode(password),
10 { name: "PBKDF2" },
11 false,
12 ["deriveBits", "deriveKey"],
13 );
14 const key = await crypto.subtle.deriveKey(
15 {
16 name: "PBKDF2",
17 salt: salt,
18 iterations: 100000,
19 hash: "SHA-512",
20 },
21 keyMaterial,
22 { name: "AES-CBC", length: 256 },
23 false,
24 ["encrypt"],
25 );
26 const encryptedContent = await crypto.subtle.encrypt(
27 { name: "AES-CBC", iv: iv },
28 key,
29 content,
30 );
31 return new Uint8Array([...salt, ...iv, ...new Uint8Array(encryptedContent)])
32 .buffer;
33}
34
35async function uploadFile() {
36 (
37 document.getElementById("upload-dialog") as HTMLDialogElement | null
38 )?.showModal();
39 const passwordInput = document.getElementById(
40 "password",
41 ) as HTMLInputElement | null;
42 const fileInput = document.getElementById("file") as HTMLInputElement | null;
43 const filenameInput = document.getElementById(
44 "filename",
45 ) as HTMLInputElement | null;
46 const encryptedInput = document.getElementById(
47 "encrypted",
48 ) as HTMLInputElement | null;
49 const form = document.getElementById("uploadForm") as HTMLFormElement | null;
50
51 if (
52 !passwordInput ||
53 !fileInput ||
54 !filenameInput ||
55 !encryptedInput ||
56 !form
57 ) {
58 console.error("Missing required elements.");
59 console.error(
60 passwordInput,
61 fileInput,
62 filenameInput,
63 encryptedInput,
64 form,
65 );
66 return;
67 }
68
69 const password = passwordInput.value;
70 if (!password) {
71 form.submit();
72 return;
73 }
74
75 const file = fileInput.files?.[0];
76 if (!file) {
77 return;
78 }
79
80 const content = await file.arrayBuffer();
81 const encryptedContent = await encrypt(new Uint8Array(content), password);
82
83 const myFile = new File([encryptedContent], file.name);
84 const dataTransfer = new DataTransfer();
85 dataTransfer.items.add(myFile);
86
87 fileInput.files = dataTransfer.files;
88 encryptedInput.checked = true;
89 console.log("encryption done");
90 form.submit();
91}
92
93const jsguards = document.getElementsByClassName("jsguard");
94for (let i = 0; i < jsguards.length; i++) {
95 jsguards[i].remove();
96}
97
98(document.getElementById("uploadForm") as HTMLFormElement | null)?.reset();
99window.uploadFile = uploadFile;
100//disable bfcache, otherwise dialog will stay open when navigating back
101window.addEventListener("unload", () => {});
102window.addEventListener("beforeunload", () => {});
103