From fa4c1d8958eea93c27e586f23463968967943682 Mon Sep 17 00:00:00 2001 From: Hikari Date: Mon, 23 Feb 2026 20:06:22 -0800 Subject: [PATCH] fix: correct base64 cover image validation for books, shows, manga, music Remove premature URL length check that ran before data URL detection, causing all base64 uploads to be incorrectly rejected. Also fix size calculation to use only the base64 data portion (after the comma) rather than the full data URL string, matching the correct pattern already in game.service.ts. --- api/src/app/services/book.service.ts | 10 +++++----- api/src/app/services/manga.service.ts | 10 +++++----- api/src/app/services/music.service.ts | 10 +++++----- api/src/app/services/show.service.ts | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/api/src/app/services/book.service.ts b/api/src/app/services/book.service.ts index 638d302..5fcf34c 100644 --- a/api/src/app/services/book.service.ts +++ b/api/src/app/services/book.service.ts @@ -36,10 +36,6 @@ export class BookService { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); } - if (!validateStringLength(data.coverImage, MAX_LENGTHS.URL)) { - throw new Error(`Cover image URL must be ${MAX_LENGTHS.URL} characters or less.`); - } - // Validate rating if (!validateRating(data.rating)) { throw new Error("Rating must be an integer between 0 and 10."); @@ -47,7 +43,11 @@ export class BookService { if (data.coverImage) { if (data.coverImage.startsWith("data:")) { - const sizeInBytes = data.coverImage.length * 0.75; + const base64Data = data.coverImage.split(",")[1]; + if (!base64Data) { + throw new Error("Invalid image data URL format."); + } + const sizeInBytes = base64Data.length * 0.75; if (sizeInBytes > MAX_LENGTHS.DATA_URL) { throw new Error("Cover image must be under 5MB."); } diff --git a/api/src/app/services/manga.service.ts b/api/src/app/services/manga.service.ts index 1fa19b5..40beb10 100644 --- a/api/src/app/services/manga.service.ts +++ b/api/src/app/services/manga.service.ts @@ -33,10 +33,6 @@ export class MangaService { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); } - if (!validateStringLength(data.coverImage, MAX_LENGTHS.URL)) { - throw new Error(`Cover image URL must be ${MAX_LENGTHS.URL} characters or less.`); - } - // Validate rating if (!validateRating(data.rating)) { throw new Error("Rating must be an integer between 0 and 10."); @@ -45,7 +41,11 @@ export class MangaService { // Validate cover image URL if (data.coverImage) { if (data.coverImage.startsWith("data:")) { - const sizeInBytes = data.coverImage.length * 0.75; + const base64Data = data.coverImage.split(",")[1]; + if (!base64Data) { + throw new Error("Invalid image data URL format."); + } + const sizeInBytes = base64Data.length * 0.75; if (sizeInBytes > MAX_LENGTHS.DATA_URL) { throw new Error("Cover image must be under 5MB."); } diff --git a/api/src/app/services/music.service.ts b/api/src/app/services/music.service.ts index c0480d8..0652c0b 100644 --- a/api/src/app/services/music.service.ts +++ b/api/src/app/services/music.service.ts @@ -33,10 +33,6 @@ export class MusicService { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); } - if (!validateStringLength(data.coverArt, MAX_LENGTHS.URL)) { - throw new Error(`Cover art URL must be ${MAX_LENGTHS.URL} characters or less.`); - } - // Validate rating if (data.rating !== undefined && !validateRating(data.rating)) { throw new Error("Rating must be an integer between 0 and 10."); @@ -45,7 +41,11 @@ export class MusicService { // Validate cover art URL if (data.coverArt) { if (data.coverArt.startsWith("data:")) { - const sizeInBytes = data.coverArt.length * 0.75; + const base64Data = data.coverArt.split(",")[1]; + if (!base64Data) { + throw new Error("Invalid image data URL format."); + } + const sizeInBytes = base64Data.length * 0.75; if (sizeInBytes > MAX_LENGTHS.DATA_URL) { throw new Error("Cover image must be under 5MB."); } diff --git a/api/src/app/services/show.service.ts b/api/src/app/services/show.service.ts index cda0ec9..5d5aed9 100644 --- a/api/src/app/services/show.service.ts +++ b/api/src/app/services/show.service.ts @@ -30,10 +30,6 @@ export class ShowService { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); } - if (!validateStringLength(data.coverImage, MAX_LENGTHS.URL)) { - throw new Error(`Cover image URL must be ${MAX_LENGTHS.URL} characters or less.`); - } - // Validate rating if (!validateRating(data.rating)) { throw new Error("Rating must be an integer between 0 and 10."); @@ -42,7 +38,11 @@ export class ShowService { // Validate cover image URL if (data.coverImage) { if (data.coverImage.startsWith("data:")) { - const sizeInBytes = data.coverImage.length * 0.75; + const base64Data = data.coverImage.split(",")[1]; + if (!base64Data) { + throw new Error("Invalid image data URL format."); + } + const sizeInBytes = base64Data.length * 0.75; if (sizeInBytes > MAX_LENGTHS.DATA_URL) { throw new Error("Cover image must be under 5MB."); }