mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-23 19:49:56 +01:00
core: remove orphaned attachments in trash cleanup method
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
This commit is contained in:
@@ -24,6 +24,7 @@ import {
|
||||
SerializedKeyPair
|
||||
} from "@notesnook/crypto";
|
||||
import { IStorage } from "../src/interfaces.js";
|
||||
import { randomBytes } from "crypto";
|
||||
|
||||
export class NodeStorageInterface implements IStorage {
|
||||
storage = {};
|
||||
@@ -112,7 +113,7 @@ export class NodeStorageInterface implements IStorage {
|
||||
password: string,
|
||||
salt?: string | undefined
|
||||
): Promise<SerializedKey> {
|
||||
return { password, salt };
|
||||
return { password, salt: salt || randomBytes(16).toString("base64") };
|
||||
}
|
||||
|
||||
generateCryptoKeyPair(): Promise<SerializedKeyPair> {
|
||||
|
||||
@@ -23,7 +23,8 @@ import {
|
||||
notebookTest,
|
||||
TEST_NOTE,
|
||||
TEST_NOTEBOOK,
|
||||
databaseTest
|
||||
databaseTest,
|
||||
loginFakeUser
|
||||
} from "./utils/index.js";
|
||||
import { test, expect } from "vitest";
|
||||
|
||||
@@ -384,3 +385,20 @@ test("permanently deleted note should not have note fields", () =>
|
||||
"synced"
|
||||
]);
|
||||
}));
|
||||
|
||||
test("trash cleanup should remove orphaned attachments", () =>
|
||||
databaseTest().then(async (db) => {
|
||||
await loginFakeUser(db);
|
||||
|
||||
const hash = await db.attachments.save(
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
|
||||
"image/png",
|
||||
"test.png"
|
||||
);
|
||||
if (!hash) throw new Error("Failed to create attachment");
|
||||
|
||||
await db.trash.cleanup();
|
||||
|
||||
expect(await db.attachments.exists(hash)).toBe(false);
|
||||
expect(await db.attachments.orphaned.count()).toBe(0);
|
||||
}));
|
||||
|
||||
@@ -109,18 +109,17 @@ function delay(ms: number) {
|
||||
|
||||
async function loginFakeUser(db) {
|
||||
const email = "johndoe@example.com";
|
||||
const password = "password";
|
||||
const userSalt = randomBytes(16).toString("base64");
|
||||
await db.storage().deriveCryptoKey({
|
||||
password: "password",
|
||||
password,
|
||||
salt: userSalt
|
||||
});
|
||||
|
||||
const userEncryptionKey = await db.storage().getCryptoKey(`_uk_@${email}`);
|
||||
|
||||
const key = await db.crypto().generateRandomKey();
|
||||
const attachmentsKey = await db
|
||||
.storage()
|
||||
.encrypt({ password: userEncryptionKey }, JSON.stringify(key));
|
||||
.encrypt({ password, salt: userSalt }, JSON.stringify(key));
|
||||
|
||||
await db.user.setUser({
|
||||
email,
|
||||
|
||||
@@ -574,6 +574,14 @@ export class Attachments implements ICollection {
|
||||
);
|
||||
return this.key;
|
||||
}
|
||||
|
||||
async removeOrphaned() {
|
||||
for await (const attachment of this.db.attachments.orphaned.iterate()) {
|
||||
try {
|
||||
await this.db.attachments.remove(attachment.hash, false);
|
||||
} catch (error) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getOutputType(attachment: Attachment): DataFormat {
|
||||
|
||||
@@ -121,8 +121,10 @@ export default class Trash {
|
||||
},
|
||||
{ noteIds: [] as string[], notebookIds: [] as string[] }
|
||||
);
|
||||
|
||||
await this._delete(noteIds, notebookIds);
|
||||
|
||||
await this.db.attachments.removeOrphaned();
|
||||
|
||||
await this.buildCache();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user