diff --git a/packages/core/__e2e__/monographs.test.js b/packages/core/__e2e__/monographs.test.js
index 82447afe5..0509e6b1d 100644
--- a/packages/core/__e2e__/monographs.test.js
+++ b/packages/core/__e2e__/monographs.test.js
@@ -17,25 +17,22 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { databaseTest, noteTest, StorageInterface } from "../__tests__/utils";
-import { login } from "./utils";
-import { test, expect, beforeEach, afterAll } from "vitest";
+import { databaseTest, noteTest } from "../__tests__/utils";
+import { login, logout } from "./utils";
+import { test, expect, afterAll } from "vitest";
const TEST_TIMEOUT = 30 * 1000;
-beforeEach(() => {
- StorageInterface.clear();
-});
-
afterAll(async () => {
const db = await databaseTest();
+ await login(db);
await db.monographs.init();
for (const id of db.monographs.monographs) {
await db.monographs.unpublish(id);
}
- StorageInterface.clear();
+ await logout(db);
}, TEST_TIMEOUT);
// test("get monographs", () =>
@@ -62,6 +59,8 @@ test(
const note = db.notes.note(id);
expect(monograph.id).toBe(monographId);
expect(monograph.title).toBe(note.title);
+
+ await logout(db);
}),
TEST_TIMEOUT
);
@@ -83,6 +82,8 @@ test(
await db.monographs.publish(id);
monograph = await db.monographs.get(monographId);
expect(monograph.title).toBe(editedTitle);
+
+ await logout(db);
}),
TEST_TIMEOUT
);
@@ -99,6 +100,8 @@ test(
await db.monographs.unpublish(id);
expect(db.monographs.all.find((m) => m.id === id)).toBeUndefined();
+
+ await logout(db);
}),
TEST_TIMEOUT
);
diff --git a/packages/core/__e2e__/token-manager.test.js b/packages/core/__e2e__/token-manager.test.js
index 112a6dfd2..75ebdf650 100644
--- a/packages/core/__e2e__/token-manager.test.js
+++ b/packages/core/__e2e__/token-manager.test.js
@@ -17,42 +17,43 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import DB from "../src/api";
-import StorageInterface from "../__mocks__/storage.mock";
+import { databaseTest } from "../__tests__/utils";
import { login } from "./utils";
import { test, expect } from "vitest";
-test("refresh token concurrently", async () => {
- const db = new DB();
- db.setup(StorageInterface);
- await db.init();
+test(
+ "refresh token concurrently",
+ async () =>
+ databaseTest().then(async (db) => {
+ await expect(login(db)).resolves.not.toThrow();
- await expect(login(db)).resolves.not.toThrow();
+ const token = await db.user.tokenManager.getToken();
+ expect(token).toBeDefined();
- const token = await db.user.tokenManager.getToken();
- expect(token).toBeDefined();
+ expect(
+ await Promise.all([
+ db.user.tokenManager._refreshToken(true),
+ db.user.tokenManager._refreshToken(true),
+ db.user.tokenManager._refreshToken(true),
+ db.user.tokenManager._refreshToken(true)
+ ])
+ ).toHaveLength(4);
+ }),
+ 30000
+);
- expect(
- await Promise.all([
- db.user.tokenManager._refreshToken(true),
- db.user.tokenManager._refreshToken(true),
- db.user.tokenManager._refreshToken(true),
- db.user.tokenManager._refreshToken(true)
- ])
- ).toHaveLength(4);
-}, 30000);
+test(
+ "refresh token using the same refresh_token multiple time",
+ async () =>
+ databaseTest().then(async (db) => {
+ await expect(login(db)).resolves.not.toThrow();
-test("refresh token using the same refresh_token multiple time", async () => {
- const db = new DB();
- db.setup(StorageInterface);
- await db.init();
-
- await expect(login(db)).resolves.not.toThrow();
-
- const token = await db.user.tokenManager.getToken();
- expect(token).toBeDefined();
- for (let i = 0; i <= 5; ++i) {
- await db.user.tokenManager._refreshToken(true);
- await db.user.tokenManager.saveToken(token);
- }
-}, 30000);
+ const token = await db.user.tokenManager.getToken();
+ expect(token).toBeDefined();
+ for (let i = 0; i <= 5; ++i) {
+ await db.user.tokenManager._refreshToken(true);
+ await db.user.tokenManager.saveToken(token);
+ }
+ }),
+ 30000
+);
diff --git a/packages/core/__e2e__/utils.js b/packages/core/__e2e__/utils.js
index 6fbabf8ed..279ffc305 100644
--- a/packages/core/__e2e__/utils.js
+++ b/packages/core/__e2e__/utils.js
@@ -34,3 +34,7 @@ export async function login(db) {
await db.user.authenticatePassword(user.email, user.password, user.hashed);
}
+
+export async function logout(db) {
+ await db.user.logout(true);
+}
diff --git a/packages/core/__mocks__/storage.mock.js b/packages/core/__mocks__/storage.mock.js
deleted file mode 100644
index e649fe1f4..000000000
--- a/packages/core/__mocks__/storage.mock.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-This file is part of the Notesnook project (https://notesnook.com/)
-
-Copyright (C) 2023 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-var storage = {};
-
-async function read(key) {
- return new Promise((resolve) => resolve(storage[key]));
-}
-
-async function readMulti(keys) {
- return new Promise((resolve) => {
- const result = [];
- keys.forEach((key) => {
- result.push([key, storage[key]]);
- });
- resolve(result);
- });
-}
-
-async function write(key, data) {
- return new Promise((resolve) => resolve((storage[key] = data)));
-}
-function remove(key) {
- delete storage[key];
-}
-function clear() {
- storage = {};
-}
-function getAllKeys() {
- return Object.keys(storage);
-}
-
-function encrypt(password, data) {
- return new Promise((resolve, reject) => {
- if (typeof data === "object") reject("data cannot be object.");
- resolve({
- iv: "some iv",
- cipher: data,
- salt: "i am some salt",
- length: data.length,
- key: password
- });
- });
-}
-
-function decrypt(key, data) {
- if (
- !key ||
- !data.key ||
- key.password === data.key.password ||
- key.key.password === data.key.password
- )
- return Promise.resolve(data.cipher);
- else throw new Error("Wrong password");
-}
-
-async function deriveCryptoKey(name, data) {
- storage[name] = { key: data.password, salt: "salt" };
-}
-
-async function getCryptoKey(name) {
- return storage[name].key;
-}
-
-async function hash(password) {
- return password;
-}
-
-async function generateCryptoKey(password, salt) {
- return { password, salt };
-}
-
-module.exports = {
- read,
- readMulti,
- write,
- remove,
- clear,
- encrypt,
- decrypt,
- deriveCryptoKey,
- generateCryptoKey,
- getCryptoKey,
- getAllKeys,
- hash
-};
diff --git a/packages/core/__tests__/backup.test.js b/packages/core/__tests__/backup.test.js
index 2782af79e..1d4b3c177 100644
--- a/packages/core/__tests__/backup.test.js
+++ b/packages/core/__tests__/backup.test.js
@@ -18,8 +18,9 @@ along with this program. If not, see .
*/
import {
- StorageInterface,
+ TEST_NOTE,
databaseTest,
+ loginFakeUser,
noteTest,
notebookTest
} from "./utils";
@@ -27,11 +28,7 @@ import v52Backup from "./__fixtures__/backup.v5.2.json";
import v52BackupCopy from "./__fixtures__/backup.v5.2.copy.json";
import v56BackupCopy from "./__fixtures__/backup.v5.6.json";
import qclone from "qclone";
-import { beforeEach, test, expect, describe } from "vitest";
-
-beforeEach(() => {
- StorageInterface.clear();
-});
+import { test, expect, describe } from "vitest";
test("export backup", () =>
noteTest().then(() =>
@@ -44,46 +41,44 @@ test("export backup", () =>
));
test("export encrypted backup", () =>
- noteTest().then(() =>
- notebookTest().then(async ({ db }) => {
- const exp = await db.backup.export("node", true);
- let backup = JSON.parse(exp);
- expect(backup.type).toBe("node");
- expect(backup.date).toBeGreaterThan(0);
- expect(backup.data.iv).toBe("some iv");
- })
- ));
+ notebookTest().then(async ({ db }) => {
+ await loginFakeUser(db);
+ await db.notes.add(TEST_NOTE);
+ const exp = await db.backup.export("node", true);
+ let backup = JSON.parse(exp);
+ expect(backup.type).toBe("node");
+ expect(backup.date).toBeGreaterThan(0);
+ expect(backup.data.iv).not.toBeUndefined();
+ }));
test("import backup", () =>
- noteTest().then(() =>
- notebookTest().then(async ({ db, id }) => {
- const exp = await db.backup.export("node");
- StorageInterface.clear();
- await db.backup.import(JSON.parse(exp));
- expect(db.notebooks.notebook(id).data.id).toBe(id);
- })
- ));
+ notebookTest().then(async ({ db, id }) => {
+ await db.notes.add(TEST_NOTE);
+ const exp = await db.backup.export("node");
+ await db.storage.clear();
+ await db.backup.import(JSON.parse(exp));
+ expect(db.notebooks.notebook(id).data.id).toBe(id);
+ }));
test("import encrypted backup", () =>
- noteTest().then(() =>
- notebookTest().then(async ({ db, id }) => {
- const exp = await db.backup.export("node", true);
- StorageInterface.clear();
- await db.backup.import(JSON.parse(exp), "password");
- expect(db.notebooks.notebook(id).data.id).toBe(id);
- })
- ));
+ notebookTest().then(async ({ db, id }) => {
+ await loginFakeUser(db);
+ await db.notes.add(TEST_NOTE);
+ const exp = await db.backup.export("node", true);
+ await db.storage.clear();
+ await db.backup.import(JSON.parse(exp), "password");
+ expect(db.notebooks.notebook(id).data.id).toBe(id);
+ }));
test("import tempered backup", () =>
- noteTest().then(() =>
- notebookTest().then(async ({ db }) => {
- const exp = await db.backup.export("node");
- StorageInterface.clear();
- const backup = JSON.parse(exp);
- backup.data.hello = "world";
- await expect(db.backup.import(backup)).rejects.toThrow(/tempered/);
- })
- ));
+ notebookTest().then(async ({ db }) => {
+ await db.notes.add(TEST_NOTE);
+ const exp = await db.backup.export("node");
+ await db.storage.clear();
+ const backup = JSON.parse(exp);
+ backup.data.hello = "world";
+ await expect(db.backup.import(backup)).rejects.toThrow(/tempered/);
+ }));
describe.each([
["v5.2", v52Backup],
diff --git a/packages/core/__tests__/content.test.js b/packages/core/__tests__/content.test.js
index 76823de8e..5322be31c 100644
--- a/packages/core/__tests__/content.test.js
+++ b/packages/core/__tests__/content.test.js
@@ -17,12 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { StorageInterface, databaseTest } from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(() => {
- StorageInterface.clear();
-});
+import { databaseTest } from "./utils";
+import { test, expect } from "vitest";
test("adding a deleted content should not throw", () =>
databaseTest().then(async (db) => {
diff --git a/packages/core/__tests__/db.test.js b/packages/core/__tests__/db.test.js
index 58a8b2d86..dcd47991d 100644
--- a/packages/core/__tests__/db.test.js
+++ b/packages/core/__tests__/db.test.js
@@ -17,14 +17,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import DB from "../src/api";
import Constants from "../src/utils/constants";
-import StorageInterface from "../__mocks__/storage.mock";
import { test, expect } from "vitest";
+import { databaseTest } from "./utils";
-test("db.host should change HOST", () => {
- const db = new DB();
- db.setup(StorageInterface);
- db.host({ API_HOST: "hello world" });
- expect(Constants.API_HOST).toBe("hello world");
-});
+test("db.host should change HOST", () =>
+ databaseTest().then((db) => {
+ db.host({ API_HOST: "hello world" });
+ expect(Constants.API_HOST).toBe("hello world");
+ }));
diff --git a/packages/core/__tests__/lookup.test.js b/packages/core/__tests__/lookup.test.js
index 2bc1db8f5..422c7a964 100644
--- a/packages/core/__tests__/lookup.test.js
+++ b/packages/core/__tests__/lookup.test.js
@@ -17,18 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import {
- StorageInterface,
- noteTest,
- TEST_NOTE,
- notebookTest,
- TEST_NOTEBOOK2
-} from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(async () => {
- StorageInterface.clear();
-});
+import { noteTest, TEST_NOTE, notebookTest, TEST_NOTEBOOK2 } from "./utils";
+import { test, expect } from "vitest";
const content = {
...TEST_NOTE.content,
diff --git a/packages/core/__tests__/note-history.test.js b/packages/core/__tests__/note-history.test.js
index 1430100d3..20e692352 100644
--- a/packages/core/__tests__/note-history.test.js
+++ b/packages/core/__tests__/note-history.test.js
@@ -17,12 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { delay, noteTest, StorageInterface, TEST_NOTE } from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(async () => {
- StorageInterface.clear();
-});
+import { delay, noteTest, TEST_NOTE } from "./utils";
+import { test, expect } from "vitest";
// async function sessionTest(db, noteId) {
// let note = await db.notes.note(noteId).data;
diff --git a/packages/core/__tests__/notebooks.test.js b/packages/core/__tests__/notebooks.test.js
index 46c82efd3..8ae6eaf6a 100644
--- a/packages/core/__tests__/notebooks.test.js
+++ b/packages/core/__tests__/notebooks.test.js
@@ -17,19 +17,9 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import {
- StorageInterface,
- notebookTest,
- TEST_NOTEBOOK,
- TEST_NOTE,
- delay
-} from "./utils";
+import { notebookTest, TEST_NOTEBOOK, TEST_NOTE, delay } from "./utils";
import { makeTopic } from "../src/collections/topics";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(async () => {
- StorageInterface.clear();
-});
+import { test, expect } from "vitest";
test("add a notebook", () =>
notebookTest().then(({ db, id }) => {
@@ -153,7 +143,7 @@ test("merge notebook with topic removed that is edited in the local notebook", (
const newNotebook = { ...notebook.data, remote: true };
newNotebook.topics.splice(0, 1); // remove hello topic
- await StorageInterface.write("lastSynced", Date.now());
+ await db.storage.write("lastSynced", Date.now());
await delay(500);
diff --git a/packages/core/__tests__/notes.test.js b/packages/core/__tests__/notes.test.js
index 89d8a4056..e2a7cb1bd 100644
--- a/packages/core/__tests__/notes.test.js
+++ b/packages/core/__tests__/notes.test.js
@@ -19,19 +19,15 @@ along with this program. If not, see .
import { groupArray } from "../src/utils/grouping";
import {
- StorageInterface,
databaseTest,
noteTest,
groupedTest,
TEST_NOTE,
TEST_NOTEBOOK,
- IMG_CONTENT
+ IMG_CONTENT,
+ loginFakeUser
} from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(async () => {
- StorageInterface.clear();
-});
+import { test, expect } from "vitest";
test("add invalid note", () =>
databaseTest().then(async (db) => {
@@ -314,40 +310,12 @@ test("grouping items where item.title is empty or undefined shouldn't throw", ()
test("note content should not contain image base64 data after save", () =>
noteTest().then(async ({ db, id }) => {
- StorageInterface.write(`_uk_@email@email.com`, {
- key: { password: "password" }
- });
-
- await db.user.setUser({
- email: "email@email.com",
- attachmentsKey: {
- cipher: "{}",
- iv: "iv",
- salt: "salt",
- length: 100,
- key: { password: "password" }
- }
- });
-
- await db.attachments.add(
- {
- iv: "iv",
- length: 100,
- alg: "xha-stream",
- hash: "d3eab72e94e3cd35",
- hashType: "xxh64",
- type: "image/jpeg",
- chunkSize: 512,
- filename: "hello",
- key: {},
- salt: "hellowrold"
- },
- id
- );
+ await loginFakeUser(db);
await db.notes.add({ id, content: { type: "tiptap", data: IMG_CONTENT } });
const note = db.notes.note(id);
const content = await note.content();
+
expect(content).not.toContain(`src="data:image/png;`);
expect(content).not.toContain(`src=`);
}));
diff --git a/packages/core/__tests__/settings.test.js b/packages/core/__tests__/settings.test.js
index b76b67893..fbb22fae1 100644
--- a/packages/core/__tests__/settings.test.js
+++ b/packages/core/__tests__/settings.test.js
@@ -17,12 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { databaseTest, StorageInterface } from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(() => {
- StorageInterface.clear();
-});
+import { databaseTest } from "./utils";
+import { test, expect } from "vitest";
test("settings' dateModified should not update on init", () =>
databaseTest().then(async (db) => {
diff --git a/packages/core/__tests__/shortcuts.test.js b/packages/core/__tests__/shortcuts.test.js
index 735f84904..749737f88 100644
--- a/packages/core/__tests__/shortcuts.test.js
+++ b/packages/core/__tests__/shortcuts.test.js
@@ -17,12 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { databaseTest, notebookTest, StorageInterface } from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(() => {
- StorageInterface.clear();
-});
+import { databaseTest, notebookTest } from "./utils";
+import { test, expect } from "vitest";
test("create a shortcut of an invalid item should throw", () =>
databaseTest().then(async (db) => {
diff --git a/packages/core/__tests__/storage.test.js b/packages/core/__tests__/storage.test.js
index 8bb2adff3..8d18c734b 100644
--- a/packages/core/__tests__/storage.test.js
+++ b/packages/core/__tests__/storage.test.js
@@ -17,26 +17,35 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import StorageInterface from "../__mocks__/storage.mock";
+import { NodeStorageInterface } from "../__mocks__/node-storage.mock";
import Storage from "../src/database/storage";
import { test, expect } from "vitest";
-const storage = new Storage(StorageInterface);
test("add a value", async () => {
+ const storage = new Storage(new NodeStorageInterface());
await storage.write("hello", "world");
+
let value = await storage.read("hello");
+
expect(value).toBe("world");
});
test("remove", async () => {
+ const storage = new Storage(new NodeStorageInterface());
+ await storage.write("hello", "world");
await storage.remove("hello");
+
let value = await storage.read("hello");
+
expect(value).toBeUndefined();
});
test("clear", async () => {
+ const storage = new Storage(new NodeStorageInterface());
await storage.write("hello", "world");
storage.clear();
+
let value = await storage.read("hello");
+
expect(value).toBeUndefined();
});
diff --git a/packages/core/__tests__/tags.test.js b/packages/core/__tests__/tags.test.js
index 5c78cc624..5fcdb562c 100644
--- a/packages/core/__tests__/tags.test.js
+++ b/packages/core/__tests__/tags.test.js
@@ -17,12 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { noteTest, TEST_NOTE, StorageInterface } from "./utils";
-import { beforeEach, test, expect, describe } from "vitest";
-
-beforeEach(async () => {
- StorageInterface.clear();
-});
+import { noteTest, TEST_NOTE } from "./utils";
+import { test, expect, describe } from "vitest";
function checkColorValue(note, value) {
expect(note.data.color).toBe(value);
diff --git a/packages/core/__tests__/topics.test.js b/packages/core/__tests__/topics.test.js
index 17963e341..5898c41ce 100644
--- a/packages/core/__tests__/topics.test.js
+++ b/packages/core/__tests__/topics.test.js
@@ -17,16 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import {
- delay,
- notebookTest,
- noteTest,
- StorageInterface,
- TEST_NOTE
-} from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(() => StorageInterface.clear());
+import { delay, notebookTest, TEST_NOTE } from "./utils";
+import { test, expect } from "vitest";
test("get empty topic", () =>
notebookTest().then(({ db, id }) => {
@@ -133,16 +125,15 @@ test("delete a topic", () =>
}));
test("delete note from edited topic", () =>
- notebookTest().then(async ({ id }) =>
- noteTest().then(async ({ db, id: noteId }) => {
- let topics = db.notebooks.notebook(id).topics;
- await topics.add("Home");
- let topic = topics.topic("Home");
- await db.notes.addToNotebook({ id, topic: topic._topic.title }, noteId);
- await topics.add({ id: topic._topic.id, title: "Hello22" });
- await db.notes.delete(noteId);
- })
- ));
+ notebookTest().then(async ({ db, id }) => {
+ const noteId = await db.notes.add(TEST_NOTE);
+ let topics = db.notebooks.notebook(id).topics;
+ await topics.add("Home");
+ let topic = topics.topic("Home");
+ await db.notes.addToNotebook({ id, topic: topic._topic.title }, noteId);
+ await topics.add({ id: topic._topic.id, title: "Hello22" });
+ await db.notes.delete(noteId);
+ }));
test("editing one topic should not update dateEdited of all", () =>
notebookTest().then(async ({ db, id }) => {
diff --git a/packages/core/__tests__/trash.test.js b/packages/core/__tests__/trash.test.js
index 42711377a..e0acabdb9 100644
--- a/packages/core/__tests__/trash.test.js
+++ b/packages/core/__tests__/trash.test.js
@@ -19,16 +19,13 @@ along with this program. If not, see .
import dayjs from "dayjs";
import {
- StorageInterface,
noteTest,
notebookTest,
TEST_NOTE,
TEST_NOTEBOOK,
databaseTest
} from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(() => StorageInterface.clear());
+import { test, expect } from "vitest";
test("trash should be empty", () =>
databaseTest().then((db) => {
diff --git a/packages/core/__tests__/utils/index.js b/packages/core/__tests__/utils/index.js
index 5544c61f0..e32e3d530 100644
--- a/packages/core/__tests__/utils/index.js
+++ b/packages/core/__tests__/utils/index.js
@@ -18,12 +18,14 @@ along with this program. If not, see .
*/
import DB from "../../src/api";
-import StorageInterface from "../../__mocks__/storage.mock";
+import { NodeStorageInterface } from "../../__mocks__/node-storage.mock";
import dayjs from "dayjs";
import { groupArray } from "../../src/utils/grouping";
import FS from "../../__mocks__/fs.mock";
import Compressor from "../../__mocks__/compressor.mock";
import { expect } from "vitest";
+import EventSource from "eventsource";
+import { randomBytes } from "../../src/utils/random";
const TEST_NOTEBOOK = {
title: "Test Notebook",
@@ -39,7 +41,7 @@ const TEST_NOTEBOOK2 = {
function databaseTest() {
let db = new DB();
- db.setup(StorageInterface, null, FS, Compressor);
+ db.setup(new NodeStorageInterface(), EventSource, FS, Compressor);
return db.init().then(() => db);
}
@@ -94,6 +96,29 @@ function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
+async function loginFakeUser(db) {
+ const email = "johndoe@example.com";
+ const userSalt = randomBytes(16).toString("base64");
+ await db.storage.deriveCryptoKey(`_uk_@${email}`, {
+ password: "password",
+ salt: userSalt
+ });
+
+ const userEncryptionKey = await db.storage.getCryptoKey(`_uk_@${email}`);
+
+ const key = await db.storage.generateRandomKey();
+ const attachmentsKey = await db.storage.encrypt(
+ { password: userEncryptionKey },
+ JSON.stringify(key)
+ );
+
+ await db.user.setUser({
+ email,
+ salt: userSalt,
+ attachmentsKey: attachmentsKey
+ });
+}
+
export {
databaseTest,
notebookTest,
@@ -101,10 +126,10 @@ export {
groupedTest,
IMG_CONTENT,
IMG_CONTENT_WITHOUT_HASH,
- StorageInterface,
TEST_NOTEBOOK,
TEST_NOTEBOOK2,
TEST_NOTE,
LONG_TEXT,
- delay
+ delay,
+ loginFakeUser
};
diff --git a/packages/core/__tests__/vault.test.js b/packages/core/__tests__/vault.test.js
index a9767f706..bdb1b2b4a 100644
--- a/packages/core/__tests__/vault.test.js
+++ b/packages/core/__tests__/vault.test.js
@@ -17,12 +17,8 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { StorageInterface, databaseTest, noteTest, TEST_NOTE } from "./utils";
-import { beforeEach, test, expect } from "vitest";
-
-beforeEach(async () => {
- StorageInterface.clear();
-});
+import { databaseTest, noteTest, TEST_NOTE } from "./utils";
+import { test, expect } from "vitest";
test("create vault", () =>
databaseTest().then(async (db) => {
@@ -113,11 +109,9 @@ test("save a locked note", () =>
await db.vault.save(note);
const content = await db.content.raw(note.contentId);
- const contentData = JSON.parse(content.data.cipher);
- expect(contentData.iv).toBeUndefined();
- expect(contentData.cipher).toBeUndefined();
- expect(contentData.key).toBeUndefined();
+ expect(content.data.cipher).toBeTypeOf("string");
+ expect(() => JSON.parse()).toThrow();
}));
test("save an edited locked note", () =>
@@ -132,11 +126,9 @@ test("save an edited locked note", () =>
});
const content = await db.content.raw(note.contentId);
- const contentData = JSON.parse(content.data.cipher);
- expect(contentData.iv).toBeUndefined();
- expect(contentData.cipher).toBeUndefined();
- expect(contentData.key).toBeUndefined();
+ expect(content.data.cipher).toBeTypeOf("string");
+ expect(() => JSON.parse(content.data.cipher)).toThrow();
}));
test("change vault password", () =>
diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json
index aca08d348..cb0227b20 100644
--- a/packages/core/package-lock.json
+++ b/packages/core/package-lock.json
@@ -32,6 +32,7 @@
"@types/katex": "^0.16.1",
"@types/prismjs": "^1.26.0",
"@types/showdown": "^2.0.0",
+ "@vitest/coverage-v8": "^0.34.1",
"abortcontroller-polyfill": "^1.7.3",
"cross-env": "^7.0.3",
"dotenv": "^16.0.1",
@@ -61,6 +62,25 @@
"license": "GPL-3.0-or-later",
"devDependencies": {}
},
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@@ -413,6 +433,63 @@
"node": ">=12"
}
},
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
"node_modules/@microsoft/signalr": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-6.0.11.tgz",
@@ -559,6 +636,12 @@
"integrity": "sha512-FnF3p2FJZ1kJT/0C/lmBzw7HSlH3RhtACVYyrwUsJoCmFNuiLpusWT2FWWB7P9A48CaYpvD6Q2fprn7sZeffpw==",
"dev": true
},
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
"node_modules/@types/katex": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.1.tgz",
@@ -589,6 +672,31 @@
"integrity": "sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==",
"dev": true
},
+ "node_modules/@vitest/coverage-v8": {
+ "version": "0.34.1",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.34.1.tgz",
+ "integrity": "sha512-lRgUwjTMr8idXEbUPSNH4jjRZJXJCVY3BqUa+LDXyJVe3pldxYMn/r0HMqatKUGTp0Kyf1j5LfFoY6kRqRp7jw==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.1",
+ "@bcoe/v8-coverage": "^0.2.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^4.0.1",
+ "istanbul-reports": "^3.1.5",
+ "magic-string": "^0.30.1",
+ "picocolors": "^1.0.0",
+ "std-env": "^3.3.3",
+ "test-exclude": "^6.0.0",
+ "v8-to-istanbul": "^9.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "vitest": ">=0.32.0 <1"
+ }
+ },
"node_modules/@vitest/expect": {
"version": "0.34.1",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.1.tgz",
@@ -836,11 +944,27 @@
"tslib": "^2.3.1"
}
},
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -917,6 +1041,18 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
"node_modules/cross-env": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
@@ -1191,6 +1327,12 @@
"node": ">=8"
}
},
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -1214,6 +1356,26 @@
"node": "*"
}
},
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/happy-dom": {
"version": "10.9.0",
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-10.9.0.tgz",
@@ -1228,6 +1390,15 @@
"whatwg-mimetype": "^3.0.0"
}
},
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/hast-util-parse-selector": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
@@ -1258,6 +1429,12 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
"node_modules/html-to-text": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",
@@ -1303,6 +1480,22 @@
"node": ">=0.10.0"
}
},
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
"node_modules/is-alphabetical": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@@ -1363,6 +1556,56 @@
"whatwg-fetch": "^3.4.1"
}
},
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
+ "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
@@ -1450,6 +1693,18 @@
"get-func-name": "^2.0.0"
}
},
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/magic-string": {
"version": "0.30.2",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz",
@@ -1462,11 +1717,20 @@
"node": ">=12"
}
},
- "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"node_modules/mime-db": {
"version": "1.52.0",
@@ -1476,6 +1740,18 @@
"node": ">= 0.6"
}
},
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/mlly": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz",
@@ -1598,6 +1874,15 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
"node_modules/otplib": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/otplib/-/otplib-12.0.1.tgz",
@@ -1641,6 +1926,15 @@
"url": "https://ko-fi.com/killymxi"
}
},
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -1844,6 +2138,21 @@
"url": "https://ko-fi.com/killymxi"
}
},
+ "node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -1871,6 +2180,15 @@
"integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
"dev": true
},
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@@ -1919,6 +2237,32 @@
"url": "https://github.com/sponsors/antfu"
}
},
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/thirty-two": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz",
@@ -2013,6 +2357,20 @@
"requires-port": "^1.0.0"
}
},
+ "node_modules/v8-to-istanbul": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
+ "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
"node_modules/vite": {
"version": "4.4.9",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
@@ -2250,6 +2608,12 @@
"node": ">=8"
}
},
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
"node_modules/ws": {
"version": "7.5.9",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
@@ -2269,9 +2633,31 @@
"optional": true
}
}
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
}
},
"dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
"@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@@ -2426,6 +2812,51 @@
"dev": true,
"optional": true
},
+ "@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
+ "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
"@microsoft/signalr": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-6.0.11.tgz",
@@ -2559,6 +2990,12 @@
"integrity": "sha512-FnF3p2FJZ1kJT/0C/lmBzw7HSlH3RhtACVYyrwUsJoCmFNuiLpusWT2FWWB7P9A48CaYpvD6Q2fprn7sZeffpw==",
"dev": true
},
+ "@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
"@types/katex": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.1.tgz",
@@ -2589,6 +3026,25 @@
"integrity": "sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==",
"dev": true
},
+ "@vitest/coverage-v8": {
+ "version": "0.34.1",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.34.1.tgz",
+ "integrity": "sha512-lRgUwjTMr8idXEbUPSNH4jjRZJXJCVY3BqUa+LDXyJVe3pldxYMn/r0HMqatKUGTp0Kyf1j5LfFoY6kRqRp7jw==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.2.1",
+ "@bcoe/v8-coverage": "^0.2.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^4.0.1",
+ "istanbul-reports": "^3.1.5",
+ "magic-string": "^0.30.1",
+ "picocolors": "^1.0.0",
+ "std-env": "^3.3.3",
+ "test-exclude": "^6.0.0",
+ "v8-to-istanbul": "^9.1.0"
+ }
+ },
"@vitest/expect": {
"version": "0.34.1",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.1.tgz",
@@ -2773,11 +3229,27 @@
"tslib": "^2.3.1"
}
},
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
"cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -2829,6 +3301,18 @@
"integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
"dev": true
},
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
"cross-env": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
@@ -3021,6 +3505,12 @@
"tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0"
}
},
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
@@ -3034,6 +3524,20 @@
"integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
"dev": true
},
+ "glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
"happy-dom": {
"version": "10.9.0",
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-10.9.0.tgz",
@@ -3048,6 +3552,12 @@
"whatwg-mimetype": "^3.0.0"
}
},
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
"hast-util-parse-selector": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
@@ -3070,6 +3580,12 @@
"space-separated-tokens": "^2.0.0"
}
},
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
"html-to-text": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",
@@ -3102,6 +3618,22 @@
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
},
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
"is-alphabetical": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@@ -3146,6 +3678,44 @@
"whatwg-fetch": "^3.4.1"
}
},
+ "istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true
+ },
+ "istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ }
+ },
+ "istanbul-reports": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
+ "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ }
+ },
"jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
@@ -3215,6 +3785,15 @@
"get-func-name": "^2.0.0"
}
},
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
"magic-string": {
"version": "0.30.2",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz",
@@ -3222,14 +3801,15 @@
"dev": true,
"requires": {
"@jridgewell/sourcemap-codec": "^1.4.15"
- },
- "dependencies": {
- "@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
- }
+ }
+ },
+ "make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "requires": {
+ "semver": "^7.5.3"
}
},
"mime-db": {
@@ -3237,6 +3817,15 @@
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
},
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
"mlly": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz",
@@ -3327,6 +3916,15 @@
"boolbase": "^1.0.0"
}
},
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
"otplib": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/otplib/-/otplib-12.0.1.tgz",
@@ -3363,6 +3961,12 @@
"peberminta": "^0.9.0"
}
},
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true
+ },
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -3510,6 +4114,15 @@
"parseley": "^0.12.0"
}
},
+ "semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3533,6 +4146,12 @@
"integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
"dev": true
},
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@@ -3571,6 +4190,26 @@
"acorn": "^8.10.0"
}
},
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
"thirty-two": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz",
@@ -3647,6 +4286,17 @@
"requires-port": "^1.0.0"
}
},
+ "v8-to-istanbul": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
+ "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ }
+ },
"vite": {
"version": "4.4.9",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
@@ -3760,10 +4410,23 @@
"stackback": "0.0.2"
}
},
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
"ws": {
"version": "7.5.9",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
- "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q=="
+ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "requires": {}
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
}
}
}
diff --git a/packages/core/package.json b/packages/core/package.json
index a43b963a9..e6f2337f0 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -13,6 +13,7 @@
"@types/katex": "^0.16.1",
"@types/prismjs": "^1.26.0",
"@types/showdown": "^2.0.0",
+ "@vitest/coverage-v8": "^0.34.1",
"abortcontroller-polyfill": "^1.7.3",
"cross-env": "^7.0.3",
"dotenv": "^16.0.1",
diff --git a/packages/core/src/api/sync/__tests__/collector.test.js b/packages/core/src/api/sync/__tests__/collector.test.js
index 3ba403577..511744e0e 100644
--- a/packages/core/src/api/sync/__tests__/collector.test.js
+++ b/packages/core/src/api/sync/__tests__/collector.test.js
@@ -17,18 +17,9 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import {
- databaseTest,
- TEST_NOTE,
- delay,
- StorageInterface
-} from "../../../../__tests__/utils";
+import { databaseTest, TEST_NOTE, delay } from "../../../../__tests__/utils";
import Collector from "../collector";
-import { test, beforeEach, expect } from "vitest";
-
-beforeEach(async () => {
- StorageInterface.clear();
-});
+import { test, expect } from "vitest";
test("newly created note should get included in collector", () =>
databaseTest().then(async (db) => {
diff --git a/packages/core/src/database/backup.js b/packages/core/src/database/backup.js
index b2d239156..a17ce3454 100644
--- a/packages/core/src/database/backup.js
+++ b/packages/core/src/database/backup.js
@@ -49,6 +49,8 @@ export default class Backup {
async export(type, encrypt = false) {
if (!validTypes.some((t) => t === type))
throw new Error("Invalid type. It must be one of 'mobile' or 'web'.");
+ if (encrypt && !(await this._db.user.getUser()))
+ throw new Error("Please login to create encrypted backups.");
let keys = await this._db.storage.getAllKeys();
let data = filterData(
diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts
index fc4de3443..e968aec1b 100644
--- a/packages/core/vitest.config.ts
+++ b/packages/core/vitest.config.ts
@@ -25,6 +25,9 @@ export default defineConfig({
test: {
environment: "happy-dom",
setupFiles: ["./globals.setup.js"],
+ coverage: {
+ reporter: ["text", "html"]
+ },
include: [
...(IS_E2E ? ["__e2e__/**/*.test.js"] : []),
"__tests__/**/*.test.js",