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