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.
This commit is contained in:
2026-02-23 20:06:22 -08:00
committed by Naomi Carrigan
parent ff0ae73fa7
commit fa4c1d8958
4 changed files with 20 additions and 20 deletions
+5 -5
View File
@@ -36,10 +36,6 @@ export class BookService {
if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) {
throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); 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 // Validate rating
if (!validateRating(data.rating)) { if (!validateRating(data.rating)) {
throw new Error("Rating must be an integer between 0 and 10."); 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) {
if (data.coverImage.startsWith("data:")) { 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) { if (sizeInBytes > MAX_LENGTHS.DATA_URL) {
throw new Error("Cover image must be under 5MB."); throw new Error("Cover image must be under 5MB.");
} }
+5 -5
View File
@@ -33,10 +33,6 @@ export class MangaService {
if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) {
throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); 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 // Validate rating
if (!validateRating(data.rating)) { if (!validateRating(data.rating)) {
throw new Error("Rating must be an integer between 0 and 10."); throw new Error("Rating must be an integer between 0 and 10.");
@@ -45,7 +41,11 @@ export class MangaService {
// Validate cover image URL // Validate cover image URL
if (data.coverImage) { if (data.coverImage) {
if (data.coverImage.startsWith("data:")) { 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) { if (sizeInBytes > MAX_LENGTHS.DATA_URL) {
throw new Error("Cover image must be under 5MB."); throw new Error("Cover image must be under 5MB.");
} }
+5 -5
View File
@@ -33,10 +33,6 @@ export class MusicService {
if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) {
throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); 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 // Validate rating
if (data.rating !== undefined && !validateRating(data.rating)) { if (data.rating !== undefined && !validateRating(data.rating)) {
throw new Error("Rating must be an integer between 0 and 10."); throw new Error("Rating must be an integer between 0 and 10.");
@@ -45,7 +41,11 @@ export class MusicService {
// Validate cover art URL // Validate cover art URL
if (data.coverArt) { if (data.coverArt) {
if (data.coverArt.startsWith("data:")) { 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) { if (sizeInBytes > MAX_LENGTHS.DATA_URL) {
throw new Error("Cover image must be under 5MB."); throw new Error("Cover image must be under 5MB.");
} }
+5 -5
View File
@@ -30,10 +30,6 @@ export class ShowService {
if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) { if (!validateStringLength(data.notes, MAX_LENGTHS.NOTES)) {
throw new Error(`Notes must be ${MAX_LENGTHS.NOTES} characters or less.`); 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 // Validate rating
if (!validateRating(data.rating)) { if (!validateRating(data.rating)) {
throw new Error("Rating must be an integer between 0 and 10."); throw new Error("Rating must be an integer between 0 and 10.");
@@ -42,7 +38,11 @@ export class ShowService {
// Validate cover image URL // Validate cover image URL
if (data.coverImage) { if (data.coverImage) {
if (data.coverImage.startsWith("data:")) { 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) { if (sizeInBytes > MAX_LENGTHS.DATA_URL) {
throw new Error("Cover image must be under 5MB."); throw new Error("Cover image must be under 5MB.");
} }