mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 22:49:45 +01:00
feat: initial work
This commit is contained in:
@@ -9,9 +9,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/js": "^5.9.55",
|
"@mdi/js": "^5.9.55",
|
||||||
"@mdi/react": "^1.4.0",
|
"@mdi/react": "^1.4.0",
|
||||||
"@notesnook/desktop": "./desktop/",
|
"@notesnook/desktop": "file:./desktop/",
|
||||||
"@rebass/forms": "^4.0.6",
|
"@rebass/forms": "^4.0.6",
|
||||||
"@streetwritersco/tinymce-plugins": "^1.1.2",
|
"@streetwritersco/tinymce-plugins": "file:../notesnook/packages/tinymce-plugins",
|
||||||
"@tinymce/tinymce-react": "^3.12.6",
|
"@tinymce/tinymce-react": "^3.12.6",
|
||||||
"clipboard": "^2.0.6",
|
"clipboard": "^2.0.6",
|
||||||
"cogo-toast": "^4.2.3",
|
"cogo-toast": "^4.2.3",
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
"tinymce": "5.8.1",
|
"tinymce": "5.8.1",
|
||||||
"uzip": "^0.20201231.0",
|
"uzip": "^0.20201231.0",
|
||||||
"wouter": "^2.7.3",
|
"wouter": "^2.7.3",
|
||||||
|
"xxhash-wasm": "^0.4.2",
|
||||||
"zustand": "^3.3.1"
|
"zustand": "^3.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -12,10 +12,21 @@ function onMessage(ev) {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case "encrypt": {
|
case "encrypt": {
|
||||||
const { passwordOrKey, data: _data } = data;
|
const { passwordOrKey, data: _data } = data;
|
||||||
const cipher = encrypt.call(context, passwordOrKey, _data);
|
const cipher = encrypt.call(context, passwordOrKey, _data, "base64");
|
||||||
sendMessage("encrypt", cipher, messageId);
|
sendMessage("encrypt", cipher, messageId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "encryptBinary": {
|
||||||
|
const { passwordOrKey, data: _data } = data;
|
||||||
|
const cipher = encrypt.call(
|
||||||
|
context,
|
||||||
|
passwordOrKey,
|
||||||
|
_data,
|
||||||
|
"uint8array"
|
||||||
|
);
|
||||||
|
sendMessage("encryptBinary", cipher, messageId, [cipher.cipher.buffer]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "decrypt": {
|
case "decrypt": {
|
||||||
const { passwordOrKey, cipher } = data;
|
const { passwordOrKey, cipher } = data;
|
||||||
const plainText = decrypt.call(context, passwordOrKey, cipher);
|
const plainText = decrypt.call(context, passwordOrKey, cipher);
|
||||||
@@ -125,7 +136,7 @@ const _getKey = (passwordOrKey) => {
|
|||||||
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
||||||
* @param {{type: "plain" | "uint8array", data: string | Uint8Array}} plainData - the plaintext data
|
* @param {{type: "plain" | "uint8array", data: string | Uint8Array}} plainData - the plaintext data
|
||||||
*/
|
*/
|
||||||
const encrypt = (passwordOrKey, plainData) => {
|
const encrypt = (passwordOrKey, plainData, outputType) => {
|
||||||
const { sodium } = this;
|
const { sodium } = this;
|
||||||
|
|
||||||
if (plainData.type === "plain") {
|
if (plainData.type === "plain") {
|
||||||
@@ -149,7 +160,7 @@ const encrypt = (passwordOrKey, plainData) => {
|
|||||||
undefined,
|
undefined,
|
||||||
nonce,
|
nonce,
|
||||||
key,
|
key,
|
||||||
"base64"
|
outputType
|
||||||
);
|
);
|
||||||
const iv = sodium.to_base64(nonce);
|
const iv = sodium.to_base64(nonce);
|
||||||
sodium.memzero(nonce);
|
sodium.memzero(nonce);
|
||||||
@@ -171,14 +182,20 @@ const encrypt = (passwordOrKey, plainData) => {
|
|||||||
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
||||||
* @param {{salt: string, iv: string, cipher: string}} cipher - the cipher data
|
* @param {{salt: string, iv: string, cipher: string}} cipher - the cipher data
|
||||||
*/
|
*/
|
||||||
const decrypt = (passwordOrKey, { iv, cipher, salt, output }) => {
|
const decrypt = (passwordOrKey, { iv, cipher, salt, output, inputType }) => {
|
||||||
const { sodium } = this;
|
const { sodium } = this;
|
||||||
|
|
||||||
const { key } = _getKey({ salt, ...passwordOrKey });
|
const { key } = _getKey({ salt, ...passwordOrKey });
|
||||||
|
const input =
|
||||||
|
inputType === "uint8array"
|
||||||
|
? input
|
||||||
|
: inputType === "base64"
|
||||||
|
? sodium.from_base64(cipher)
|
||||||
|
: sodium.decode(cipher);
|
||||||
|
|
||||||
const data = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
|
const data = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||||
undefined,
|
undefined,
|
||||||
sodium.from_base64(cipher),
|
input,
|
||||||
undefined,
|
undefined,
|
||||||
sodium.from_base64(iv),
|
sodium.from_base64(iv),
|
||||||
key,
|
key,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/security#csp-meta-tag -->
|
/security#csp-meta-tag -->
|
||||||
<meta
|
<meta
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="script-src 'self' https://analytics.streetwriters.co https://cdn.paddle.com 'unsafe-inline';"
|
content="script-src 'self' https://analytics.streetwriters.co https://cdn.paddle.com 'unsafe-inline' 'unsafe-eval';"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="apple-touch-icon"
|
rel="apple-touch-icon"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import StorageInterface from "../interfaces/storage";
|
import StorageInterface from "../interfaces/storage";
|
||||||
|
import FS from "../interfaces/fs";
|
||||||
import EventSource from "eventsource";
|
import EventSource from "eventsource";
|
||||||
import Config from "../utils/config";
|
import Config from "../utils/config";
|
||||||
import http from "notes-core/utils/http";
|
import http from "notes-core/utils/http";
|
||||||
@@ -12,13 +13,8 @@ import { isTesting } from "../utils/platform";
|
|||||||
var db;
|
var db;
|
||||||
async function initializeDatabase() {
|
async function initializeDatabase() {
|
||||||
const { default: Database } = await import("notes-core/api");
|
const { default: Database } = await import("notes-core/api");
|
||||||
db = new Database(StorageInterface, EventSource);
|
db = new Database(StorageInterface, EventSource, FS);
|
||||||
|
|
||||||
// db.host({
|
|
||||||
// API_HOST: "http://localhost:5264",
|
|
||||||
// AUTH_HOST: "http://localhost:8264",
|
|
||||||
// SSE_HOST: "http://localhost:7264",
|
|
||||||
// });
|
|
||||||
if (isTesting()) {
|
if (isTesting()) {
|
||||||
db.host({
|
db.host({
|
||||||
API_HOST: "https://api.notesnook.com",
|
API_HOST: "https://api.notesnook.com",
|
||||||
@@ -27,9 +23,9 @@ async function initializeDatabase() {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
db.host({
|
db.host({
|
||||||
API_HOST: "http://192.168.10.23:5264",
|
API_HOST: "http://localhost:5264",
|
||||||
AUTH_HOST: "http://192.168.10.23:8264",
|
AUTH_HOST: "http://localhost:8264",
|
||||||
SSE_HOST: "http://192.168.10.23:7264",
|
SSE_HOST: "http://localhost:7264",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
146
apps/web/src/components/editor/plugins/attachmentpicker.js
Normal file
146
apps/web/src/components/editor/plugins/attachmentpicker.js
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
import Compressor from "compressorjs";
|
||||||
|
import { db } from "../../../common/db";
|
||||||
|
import fs from "../../../interfaces/fs";
|
||||||
|
|
||||||
|
function register(editor) {
|
||||||
|
editor.ui.registry.addButton("attachment", {
|
||||||
|
icon: "attachment",
|
||||||
|
tooltip: "Attach a file",
|
||||||
|
onAction: () => insertFile(editor),
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.ui.registry.addButton("image", {
|
||||||
|
icon: "image",
|
||||||
|
tooltip: "Insert image",
|
||||||
|
onAction: () => insertImage(editor),
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.addCommand("InsertImage", function () {
|
||||||
|
insertImage(editor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function insertImage(editor) {
|
||||||
|
const image = await pickImage();
|
||||||
|
if (!image) return;
|
||||||
|
|
||||||
|
var content = `<img class="attachment" data-mime="${image.type}" data-hash="${image.hash}" data-filename="${image.filename}" src="${image.dataurl}" data-size="${image.size}"/>`;
|
||||||
|
editor.insertContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function insertFile(editor) {
|
||||||
|
const file = await pickFile();
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
var content = `<span class="attachment" data-mime="${file.type}" data-filename="${file.filename}" data-hash="${file.hash}" data-size="${file.size}"/>`;
|
||||||
|
editor.insertContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
(function init() {
|
||||||
|
global.tinymce.PluginManager.add("attachmentpicker", register);
|
||||||
|
})();
|
||||||
|
|
||||||
|
async function pickFile() {
|
||||||
|
const selectedFile = await showFilePicker({ acceptedFileTypes: "*/*" });
|
||||||
|
if (!selectedFile) return;
|
||||||
|
|
||||||
|
const key = await getEncryptionKey();
|
||||||
|
const buffer = await selectedFile.arrayBuffer();
|
||||||
|
const output = await fs.writeEncrypted(null, {
|
||||||
|
data: buffer,
|
||||||
|
type: "buffer",
|
||||||
|
key,
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.attachments.add({
|
||||||
|
...output,
|
||||||
|
filename: selectedFile.name,
|
||||||
|
type: selectedFile.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
hash: selectedFile.hash,
|
||||||
|
filename: selectedFile.name,
|
||||||
|
type: selectedFile.type,
|
||||||
|
size: selectedFile.size,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pickImage() {
|
||||||
|
const selectedImage = await showFilePicker({ acceptedFileTypes: "image/*" });
|
||||||
|
if (!selectedImage) return;
|
||||||
|
|
||||||
|
const { dataurl, buffer } = await compressImage(selectedImage, "buffer");
|
||||||
|
const key = await getEncryptionKey();
|
||||||
|
|
||||||
|
const output = await fs.writeEncrypted(null, {
|
||||||
|
data: buffer,
|
||||||
|
type: "buffer",
|
||||||
|
key,
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.attachments.add({
|
||||||
|
...output,
|
||||||
|
filename: selectedImage.name,
|
||||||
|
type: selectedImage.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
hash: selectedImage.hash,
|
||||||
|
filename: selectedImage.name,
|
||||||
|
type: selectedImage.type,
|
||||||
|
size: output.length,
|
||||||
|
dataurl,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getEncryptionKey() {
|
||||||
|
const key = await db.user.getEncryptionKey();
|
||||||
|
if (!key) throw new Error("No encryption key found. Are you logged in?");
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Promise<File>}
|
||||||
|
*/
|
||||||
|
function showFilePicker({ acceptedFileTypes }) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.setAttribute("type", "file");
|
||||||
|
input.setAttribute("accept", acceptedFileTypes);
|
||||||
|
input.dispatchEvent(new MouseEvent("click"));
|
||||||
|
input.onchange = async function () {
|
||||||
|
var file = this.files[0];
|
||||||
|
if (!file) return null;
|
||||||
|
resolve(file);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {File} file
|
||||||
|
* @param {"base64"|"buffer"} type
|
||||||
|
*/
|
||||||
|
function compressImage(file, type) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
new Compressor(file, {
|
||||||
|
quality: 0.8,
|
||||||
|
mimeType: file.type,
|
||||||
|
width: 1920,
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Blob} result
|
||||||
|
*/
|
||||||
|
async success(result) {
|
||||||
|
const buffer = await result.arrayBuffer();
|
||||||
|
const base64 = Buffer.from(buffer).toString("base64");
|
||||||
|
resolve({ dataurl: `data:${file.type};base64,${base64}`, buffer });
|
||||||
|
},
|
||||||
|
error(err) {
|
||||||
|
reject(err);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
16
apps/web/src/components/editor/plugins/icons.js
Normal file
16
apps/web/src/components/editor/plugins/icons.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import * as Icons from "@mdi/js";
|
||||||
|
|
||||||
|
function register(editor) {
|
||||||
|
editor.ui.registry.addIcon(
|
||||||
|
"attachment",
|
||||||
|
createSvgElement(Icons.mdiAttachment)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSvgElement(path) {
|
||||||
|
return `<svg height="24" width="24"><path d="${path}" /></svg>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
(function init() {
|
||||||
|
global.tinymce.PluginManager.add("icons", register);
|
||||||
|
})();
|
||||||
@@ -25,12 +25,13 @@ import "tinymce/plugins/media";
|
|||||||
import { processPastedContent } from "@streetwritersco/tinymce-plugins/codeblock";
|
import { processPastedContent } from "@streetwritersco/tinymce-plugins/codeblock";
|
||||||
import "@streetwritersco/tinymce-plugins/inlinecode";
|
import "@streetwritersco/tinymce-plugins/inlinecode";
|
||||||
import "@streetwritersco/tinymce-plugins/shortlink";
|
import "@streetwritersco/tinymce-plugins/shortlink";
|
||||||
import "@streetwritersco/tinymce-plugins/quickimage";
|
|
||||||
import "@streetwritersco/tinymce-plugins/checklist";
|
import "@streetwritersco/tinymce-plugins/checklist";
|
||||||
import "@streetwritersco/tinymce-plugins/collapsibleheaders";
|
import "@streetwritersco/tinymce-plugins/collapsibleheaders";
|
||||||
import "@streetwritersco/tinymce-plugins/paste";
|
import "@streetwritersco/tinymce-plugins/paste";
|
||||||
import "@streetwritersco/tinymce-plugins/shortcuts";
|
import "@streetwritersco/tinymce-plugins/shortcuts";
|
||||||
import "@streetwritersco/tinymce-plugins/keyboardquirks";
|
import "@streetwritersco/tinymce-plugins/keyboardquirks";
|
||||||
|
import "./plugins/attachmentpicker";
|
||||||
|
import "./plugins/icons";
|
||||||
import { Editor } from "@tinymce/tinymce-react";
|
import { Editor } from "@tinymce/tinymce-react";
|
||||||
import { showBuyDialog } from "../../common/dialog-controller";
|
import { showBuyDialog } from "../../common/dialog-controller";
|
||||||
import { useStore as useThemeStore } from "../../stores/theme-store";
|
import { useStore as useThemeStore } from "../../stores/theme-store";
|
||||||
@@ -109,7 +110,7 @@ const plugins = {
|
|||||||
default:
|
default:
|
||||||
"importcss searchreplace autolink directionality media table hr advlist lists imagetools noneditable quickbars autoresize",
|
"importcss searchreplace autolink directionality media table hr advlist lists imagetools noneditable quickbars autoresize",
|
||||||
custom:
|
custom:
|
||||||
"keyboardquirks collapsibleheaders shortlink quickimage paste codeblock inlinecode shortcuts checklist",
|
"icons keyboardquirks collapsibleheaders shortlink attachmentpicker paste codeblock inlinecode shortcuts checklist",
|
||||||
pro: "textpattern",
|
pro: "textpattern",
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -200,7 +201,7 @@ function TinyMCE(props) {
|
|||||||
`,
|
`,
|
||||||
toolbar: simple
|
toolbar: simple
|
||||||
? false
|
? false
|
||||||
: `bold italic underline strikethrough inlinecode | blockquote codeblock | fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent subscript superscript | numlist bullist checklist | forecolor backcolor removeformat | hr | image media link table | ltr rtl | searchreplace`,
|
: `bold italic underline strikethrough inlinecode | blockquote codeblock | fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent subscript superscript | numlist bullist checklist | forecolor backcolor removeformat | hr | image attachment media link table | ltr rtl | searchreplace`,
|
||||||
quickbars_selection_toolbar: false,
|
quickbars_selection_toolbar: false,
|
||||||
mobile: {
|
mobile: {
|
||||||
toolbar_mode: "scrolling",
|
toolbar_mode: "scrolling",
|
||||||
|
|||||||
68
apps/web/src/interfaces/fs.js
Normal file
68
apps/web/src/interfaces/fs.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import NNCrypto from "./nncrypto/index";
|
||||||
|
import localforage from "localforage";
|
||||||
|
import xxhash from "xxhash-wasm";
|
||||||
|
|
||||||
|
const crypto = new NNCrypto();
|
||||||
|
const fs = localforage.createInstance({
|
||||||
|
storeName: "notesnook-fs",
|
||||||
|
name: "NotesnookFS",
|
||||||
|
driver: [localforage.INDEXEDDB, localforage.WEBSQL, localforage.LOCALSTORAGE],
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.hasItem = async function (key) {
|
||||||
|
const keys = await fs.keys();
|
||||||
|
return keys.includes(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We perform 4 steps here:
|
||||||
|
* 1. We convert base64 to Uint8Array (if we get base64, that is)
|
||||||
|
* 2. We hash the Uint8Array.
|
||||||
|
* 3. We encrypt the Uint8Array
|
||||||
|
* 4. We save the encrypted Uint8Array
|
||||||
|
*/
|
||||||
|
async function writeEncrypted(filename, { data, type, key }) {
|
||||||
|
const saveAsBuffer = localforage.supports(localforage.INDEXEDDB);
|
||||||
|
|
||||||
|
if (type === "base64") data = new Uint8Array(Buffer.from(data, "base64"));
|
||||||
|
const { hash, type: hashType } = await hashBuffer(data);
|
||||||
|
if (!filename) filename = hash;
|
||||||
|
|
||||||
|
if (await fs.hasItem(filename)) return { hash, hashType };
|
||||||
|
|
||||||
|
const output = saveAsBuffer
|
||||||
|
? await crypto.encryptBinary(key, data, "buffer")
|
||||||
|
: await crypto.encrypt(key, data, "buffer");
|
||||||
|
|
||||||
|
await fs.setItem(filename, output.cipher);
|
||||||
|
return {
|
||||||
|
hash,
|
||||||
|
hashType,
|
||||||
|
iv: output.iv,
|
||||||
|
length: output.length,
|
||||||
|
salt: output.salt,
|
||||||
|
alg: output.alg,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function hashBuffer(data) {
|
||||||
|
const hasher = await xxhash();
|
||||||
|
return {
|
||||||
|
hash: Buffer.from(hasher.h64Raw(data)).toString("base64"),
|
||||||
|
type: "xxh64",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readEncrypted(filename, key, cipherData) {
|
||||||
|
const readAsBuffer = localforage.supports(localforage.INDEXEDDB);
|
||||||
|
cipherData.cipher = await fs.getItem(filename);
|
||||||
|
if (!cipherData.cipher)
|
||||||
|
throw new Error(`File not found. Filename: ${filename}`);
|
||||||
|
|
||||||
|
return readAsBuffer
|
||||||
|
? await crypto.decryptBinary(key, cipherData, cipherData.outputType)
|
||||||
|
: await crypto.decrypt(key, cipherData, cipherData.outputType);
|
||||||
|
}
|
||||||
|
|
||||||
|
const FS = { writeEncrypted, readEncrypted };
|
||||||
|
export default FS;
|
||||||
@@ -24,10 +24,24 @@ export default class NNCrypto {
|
|||||||
* @param {string} plainData - the plaintext data
|
* @param {string} plainData - the plaintext data
|
||||||
* @param {boolean}
|
* @param {boolean}
|
||||||
*/
|
*/
|
||||||
encrypt = async (passwordOrKey, plainData) => {
|
encrypt = async (passwordOrKey, plainData, type = "plain") => {
|
||||||
await this._initialize();
|
await this._initialize();
|
||||||
return global.ncrypto.encrypt.call(this, passwordOrKey, {
|
return global.ncrypto.encrypt.call(this, passwordOrKey, {
|
||||||
type: "plain",
|
type,
|
||||||
|
data: plainData,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
||||||
|
* @param {string} plainData - the plaintext data
|
||||||
|
* @param {string} type
|
||||||
|
*/
|
||||||
|
encryptBinary = async (passwordOrKey, plainData, type = "plain") => {
|
||||||
|
await this._initialize();
|
||||||
|
return global.ncrypto.encryptBinary.call(this, passwordOrKey, {
|
||||||
|
type,
|
||||||
data: plainData,
|
data: plainData,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,11 +65,49 @@ export default class NNCryptoWorker {
|
|||||||
* @param {string} data - the plaintext data
|
* @param {string} data - the plaintext data
|
||||||
* @param {boolean} compress
|
* @param {boolean} compress
|
||||||
*/
|
*/
|
||||||
encrypt = (passwordOrKey, data) => {
|
encrypt = (passwordOrKey, data, type = "plain") => {
|
||||||
return this._communicate("encrypt", {
|
const payload = { type, data };
|
||||||
passwordOrKey,
|
const transferables = type === "buffer" ? [payload.data] : [];
|
||||||
data: { type: "plain", data },
|
return this._communicate(
|
||||||
});
|
"encrypt",
|
||||||
|
{
|
||||||
|
passwordOrKey,
|
||||||
|
data: payload,
|
||||||
|
},
|
||||||
|
transferables
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
||||||
|
* @param {string} data - the plaintext data
|
||||||
|
* @param {string} type
|
||||||
|
*/
|
||||||
|
encryptBinary = (passwordOrKey, data, type = "plain") => {
|
||||||
|
const payload = { type, data };
|
||||||
|
const transferables = type === "buffer" ? [payload.data] : [];
|
||||||
|
return this._communicate(
|
||||||
|
"encryptBinary",
|
||||||
|
{
|
||||||
|
passwordOrKey,
|
||||||
|
data: payload,
|
||||||
|
},
|
||||||
|
transferables
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
||||||
|
* @param {{alg: string, salt: string, iv: string, cipher: Uint8Array}} cipherData - the cipher data
|
||||||
|
*/
|
||||||
|
decryptBinary = (passwordOrKey, cipherData, outputType = "text") => {
|
||||||
|
cipherData.output = outputType;
|
||||||
|
cipherData.inputType = "uint8array";
|
||||||
|
return this._communicate("decrypt", { passwordOrKey, cipher: cipherData }, [
|
||||||
|
cipherData.cipher,
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,8 +115,9 @@ export default class NNCryptoWorker {
|
|||||||
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
|
||||||
* @param {{alg: string, salt: string, iv: string, cipher: string}} cipherData - the cipher data
|
* @param {{alg: string, salt: string, iv: string, cipher: string}} cipherData - the cipher data
|
||||||
*/
|
*/
|
||||||
decrypt = (passwordOrKey, cipherData) => {
|
decrypt = (passwordOrKey, cipherData, outputType = "text") => {
|
||||||
cipherData.output = "text";
|
cipherData.output = outputType;
|
||||||
|
cipherData.inputType = "base64";
|
||||||
return this._communicate("decrypt", { passwordOrKey, cipher: cipherData });
|
return this._communicate("decrypt", { passwordOrKey, cipher: cipherData });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user