feat: add attachment upload & download

This commit is contained in:
thecodrr
2021-09-20 12:10:08 +05:00
parent 7dfb12d2e1
commit 0dd2cf3595
5 changed files with 67 additions and 12 deletions

View File

@@ -13,6 +13,7 @@
"@rebass/forms": "^4.0.6",
"@streetwritersco/tinymce-plugins": "file:../notesnook/packages/tinymce-plugins",
"@tinymce/tinymce-react": "^3.12.6",
"axios": "^0.21.4",
"clipboard": "^2.0.6",
"cogo-toast": "^4.2.3",
"compressorjs": "^1.0.7",

View File

@@ -188,7 +188,7 @@ const decrypt = (passwordOrKey, { iv, cipher, salt, output, inputType }) => {
const { key } = _getKey({ salt, ...passwordOrKey });
const input =
inputType === "uint8array"
? input
? cipher
: inputType === "base64"
? sodium.from_base64(cipher)
: sodium.decode(cipher);
@@ -199,10 +199,12 @@ const decrypt = (passwordOrKey, { iv, cipher, salt, output, inputType }) => {
undefined,
sodium.from_base64(iv),
key,
output
output !== "base64" ? output : "uint8array"
);
sodium.memzero(key);
return data;
return output === "base64"
? sodium.to_base64(data, sodium.base64_variants.ORIGINAL)
: data;
};
if (self.document) {

View File

@@ -47,7 +47,7 @@ async function pickFile() {
const key = await getEncryptionKey();
const buffer = await selectedFile.arrayBuffer();
const output = await fs.writeEncrypted(null, {
data: buffer,
data: new Uint8Array(buffer),
type: "buffer",
key,
});
@@ -59,7 +59,7 @@ async function pickFile() {
});
return {
hash: selectedFile.hash,
hash: output.hash,
filename: selectedFile.name,
type: selectedFile.type,
size: selectedFile.size,
@@ -74,7 +74,7 @@ async function pickImage() {
const key = await getEncryptionKey();
const output = await fs.writeEncrypted(null, {
data: buffer,
data: new Uint8Array(buffer),
type: "buffer",
key,
});
@@ -86,7 +86,7 @@ async function pickImage() {
});
return {
hash: selectedImage.hash,
hash: output.hash,
filename: selectedImage.name,
type: selectedImage.type,
size: output.length,

View File

@@ -1,6 +1,7 @@
import NNCrypto from "./nncrypto/index";
import localforage from "localforage";
import xxhash from "xxhash-wasm";
import axios from "axios";
const crypto = new NNCrypto();
const fs = localforage.createInstance({
@@ -48,12 +49,13 @@ async function writeEncrypted(filename, { data, type, key }) {
async function hashBuffer(data) {
const hasher = await xxhash();
return {
hash: Buffer.from(hasher.h64Raw(data)).toString("base64"),
hash: Buffer.from(hasher.h64Raw(data)).toString("hex"),
type: "xxh64",
};
}
async function readEncrypted(filename, key, cipherData) {
console.log("Reading encrypted file", filename);
const readAsBuffer = localforage.supports(localforage.INDEXEDDB);
cipherData.cipher = await fs.getItem(filename);
if (!cipherData.cipher)
@@ -64,5 +66,55 @@ async function readEncrypted(filename, key, cipherData) {
: await crypto.decrypt(key, cipherData, cipherData.outputType);
}
const FS = { writeEncrypted, readEncrypted };
async function uploadFile(filename, requestOptions) {
console.log("Request to upload file", filename, requestOptions);
const { url } = requestOptions;
let cipher = await fs.getItem(filename);
if (!cipher) throw new Error(`File not found. Filename: ${filename}`);
const readAsBuffer = localforage.supports(localforage.INDEXEDDB);
if (!readAsBuffer)
cipher = Uint8Array.from(window.atob(cipher), (c) => c.charCodeAt(0));
const response = await axios.request({
url: url,
method: "PUT",
headers: {
"Content-Type": "",
},
data: new Blob([cipher.buffer]),
onUploadProgress: (ev) => {
console.log("Uploading file", filename, ev);
},
});
console.log("File uploaded:", filename, response);
return isSuccessStatusCode(response.status);
}
async function downloadFile(filename, requestOptions) {
const { url, headers } = requestOptions;
console.log("Request to download file", filename, url, headers);
if (await fs.hasItem(filename)) return true;
const response = await axios.get(url, {
headers: headers,
responseType: "blob",
onDownloadProgress: (ev) => {
console.log("Downloading file", filename, ev);
},
});
console.log("File downloaded", filename, url, response);
if (!isSuccessStatusCode(response.status)) return false;
const blob = new Blob([response.data]);
await fs.setItem(filename, new Uint8Array(await blob.arrayBuffer()));
return true;
}
const FS = { writeEncrypted, readEncrypted, uploadFile, downloadFile };
export default FS;
function isSuccessStatusCode(statusCode) {
return statusCode >= 200 && statusCode <= 299;
}

View File

@@ -81,12 +81,12 @@ export default class NNCryptoWorker {
/**
*
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
* @param {string} data - the plaintext data
* @param {string|Uint8Array} data - the plaintext data
* @param {string} type
*/
encryptBinary = (passwordOrKey, data, type = "plain") => {
const payload = { type, data };
const transferables = type === "buffer" ? [payload.data] : [];
const transferables = type === "buffer" ? [payload.data.buffer] : [];
return this._communicate(
"encryptBinary",
{
@@ -106,7 +106,7 @@ export default class NNCryptoWorker {
cipherData.output = outputType;
cipherData.inputType = "uint8array";
return this._communicate("decrypt", { passwordOrKey, cipher: cipherData }, [
cipherData.cipher,
cipherData.cipher.buffer,
]);
};