diff --git a/plugin b/plugin index 73733c0..834850a 160000 --- a/plugin +++ b/plugin @@ -1 +1 @@ -Subproject commit 73733c0292cb3f0d6775c69c734e80c690932777 +Subproject commit 834850afae81abce873da8be8792614ab8cc0b76 diff --git a/server/package-lock.json b/server/package-lock.json index 5b8f895..6089296 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -12,6 +12,7 @@ "@prisma/client": "^4.0.0", "bloom-filters": "^3.0.0", "body-parser": "^1.20.0", + "class-transformer": "^0.5.1", "class-validator": "^0.13.2", "crc": "^4.1.1", "dotenv": "^16.0.1", @@ -938,6 +939,11 @@ "node": ">=10" } }, + "node_modules/class-transformer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" + }, "node_modules/class-validator": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.2.tgz", @@ -5977,6 +5983,11 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, + "class-transformer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" + }, "class-validator": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.13.2.tgz", diff --git a/server/package.json b/server/package.json index 603afa1..22c3c02 100644 --- a/server/package.json +++ b/server/package.json @@ -19,6 +19,7 @@ "@prisma/client": "^4.0.0", "bloom-filters": "^3.0.0", "body-parser": "^1.20.0", + "class-transformer": "^0.5.1", "class-validator": "^0.13.2", "crc": "^4.1.1", "dotenv": "^16.0.1", diff --git a/server/prisma/migrations/20220825142403_add_embed_table/migration.sql b/server/prisma/migrations/20220825142403_add_embed_table/migration.sql new file mode 100644 index 0000000..ed1633f --- /dev/null +++ b/server/prisma/migrations/20220825142403_add_embed_table/migration.sql @@ -0,0 +1,10 @@ +-- CreateTable +CREATE TABLE "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 RESTRICT ON UPDATE CASCADE +); diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 7c217e0..9cd0ff8 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -11,12 +11,23 @@ datasource db { } model EncryptedNote { - id String @id @default(cuid()) - insert_time DateTime @default(now()) - expire_time DateTime @default(now()) + id String @id @default(cuid()) + insert_time DateTime @default(now()) + expire_time DateTime @default(now()) ciphertext String hmac String - crypto_version String @default("v1") + crypto_version String @default("v1") + EncryptedEmbed EncryptedEmbed[] +} + +model EncryptedEmbed { + id String @id @default(cuid()) + note_id String + embed_id String + ciphertext Bytes + hmac String + size_bytes Int + note EncryptedNote @relation(fields: [note_id], references: [id]) } model event { diff --git a/server/src/app.ts b/server/src/app.ts index 6ec6bd6..0001959 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -10,7 +10,7 @@ import { deleteExpiredNotes, deleteInterval } from "./tasks/deleteExpiredNotes"; export const app: Express = express(); // Enable JSON body parsing -app.use(express.json({})); +app.use(express.json({ limit: "8MB" })); // configure logging app.use( diff --git a/server/src/controllers/note/note.post.controller.ts b/server/src/controllers/note/note.post.controller.ts index 6defe41..80e022c 100644 --- a/server/src/controllers/note/note.post.controller.ts +++ b/server/src/controllers/note/note.post.controller.ts @@ -12,7 +12,24 @@ import { ValidateIf, ValidationError, Matches, + ValidateNested, + IsString, } from "class-validator"; +import { Type } from "class-transformer"; + +export class EncryptedEmbed { + @IsBase64() + @IsNotEmpty() + ciphertext: string | undefined; + + @IsBase64() + @IsNotEmpty() + hmac: string | undefined; + + @IsString() + @IsNotEmpty() + embedId: string | undefined; +} /** * Request body for creating a note @@ -36,6 +53,10 @@ export class NotePostRequest { @Matches("^v[0-9]+$") crypto_version: string = "v1"; + + @ValidateNested({ each: true }) + @Type(() => EncryptedEmbed) + embeds: EncryptedEmbed[] = []; } export async function postNoteController( diff --git a/server/src/controllers/note/note.router.ts b/server/src/controllers/note/note.router.ts index 180e3e4..ef64c17 100644 --- a/server/src/controllers/note/note.router.ts +++ b/server/src/controllers/note/note.router.ts @@ -5,7 +5,7 @@ import { postNoteController } from "./note.post.controller"; export const notesRoute = express.Router(); -const jsonParser = express.json({ limit: "500k" }); +const jsonParser = express.json({ limit: "8MB" }); const postRateLimit = rateLimit({ windowMs: parseFloat(process.env.POST_LIMIT_WINDOW_SECONDS as string) * 1000,