cascade delete notes

This commit is contained in:
Maxime Cannoodt
2022-09-11 18:07:06 +02:00
parent 3b08d84b26
commit 654aa3e9c4
3 changed files with 58 additions and 1 deletions

View File

@@ -0,0 +1,17 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_EncryptedEmbed" (
"id" TEXT NOT NULL PRIMARY KEY,
"note_id" TEXT NOT NULL,
"embed_id" TEXT NOT NULL,
"ciphertext" BLOB NOT NULL,
"hmac" TEXT NOT NULL,
"size_bytes" INTEGER NOT NULL,
CONSTRAINT "EncryptedEmbed_note_id_fkey" FOREIGN KEY ("note_id") REFERENCES "EncryptedNote" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_EncryptedEmbed" ("ciphertext", "embed_id", "hmac", "id", "note_id", "size_bytes") SELECT "ciphertext", "embed_id", "hmac", "id", "note_id", "size_bytes" FROM "EncryptedEmbed";
DROP TABLE "EncryptedEmbed";
ALTER TABLE "new_EncryptedEmbed" RENAME TO "EncryptedEmbed";
CREATE UNIQUE INDEX "EncryptedEmbed_note_id_embed_id_key" ON "EncryptedEmbed"("note_id", "embed_id");
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -28,7 +28,7 @@ model EncryptedEmbed {
ciphertext Bytes ciphertext Bytes
hmac String hmac String
size_bytes Int size_bytes Int
note EncryptedNote @relation(fields: [note_id], references: [id]) note EncryptedNote @relation(fields: [note_id], references: [id], onDelete: Cascade)
@@unique([note_id, embed_id], name: "noteId_embedId") @@unique([note_id, embed_id], name: "noteId_embedId")
} }

View File

@@ -4,6 +4,8 @@ import { describe, it, expect } from "vitest";
import prisma from "./db/client"; import prisma from "./db/client";
import { deleteExpiredNotes } from "./tasks/deleteExpiredNotes"; import { deleteExpiredNotes } from "./tasks/deleteExpiredNotes";
import { EventType } from "./logging/EventLogger"; import { EventType } from "./logging/EventLogger";
import { createNote } from "./db/note.dao";
import { EncryptedNote } from "@prisma/client";
// const testNote with base64 ciphertext and hmac // const testNote with base64 ciphertext and hmac
const testNote = { const testNote = {
@@ -273,6 +275,44 @@ describe("Clean expired notes", () => {
testNote.ciphertext.length + testNote.hmac.length testNote.ciphertext.length + testNote.hmac.length
); );
}); });
it("removes notes with embeds", async () => {
// insert a note with embeds and with expiry date in the past using prisma
const note = {
...testNote,
expire_time: new Date(0),
} as EncryptedNote;
const embeds = [
{
embed_id: "EMBED_ID",
ciphertext: Buffer.from("sample_ciphertext").toString("base64"),
hmac: Buffer.from("sample_hmac").toString("base64"),
},
];
const { id } = await createNote(note, embeds);
// make request for note and check that response is 200
const res = await supertest(app).get(`/api/note/${id}`);
expect(res.statusCode).toBe(200);
const embedRes = await supertest(app).get(
`/api/note/${id}/embeds/EMBED_ID`
);
expect(embedRes.statusCode).toBe(200);
// run cleanup
const nDeleted = await deleteExpiredNotes();
expect(nDeleted).toBeGreaterThan(0);
// if the note is added to the expire filter, it returns 410
const res2 = await supertest(app).get(`/api/note/${id}`);
expect(res2.statusCode).toBe(410);
// check that the embed is not found
const embedRes2 = await supertest(app).get(
`/api/note/${id}/embeds/EMBED_ID`
);
expect(embedRes2.statusCode).toBe(404);
});
}); });
function expectCodeOrThrowResponse(res: supertest.Response, expected: number) { function expectCodeOrThrowResponse(res: supertest.Response, expected: number) {