feat(recipe): validate heroImageUrl content type before persisting
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package com.recipeapp.recipe;
|
||||
|
||||
import com.recipeapp.common.ConflictException;
|
||||
import com.recipeapp.common.ResourceNotFoundException;
|
||||
import com.recipeapp.common.ValidationException;
|
||||
import com.recipeapp.household.HouseholdRepository;
|
||||
import com.recipeapp.household.entity.Household;
|
||||
import com.recipeapp.recipe.dto.*;
|
||||
@@ -60,6 +61,8 @@ public class RecipeService {
|
||||
Household household = householdRepository.findById(householdId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Household not found"));
|
||||
|
||||
validateHeroImageUrl(request.heroImageUrl());
|
||||
|
||||
Recipe recipe = new Recipe(household, request.name(),
|
||||
request.serves() != null ? request.serves().shortValue() : 0,
|
||||
request.cookTimeMin() != null ? request.cookTimeMin().shortValue() : 0,
|
||||
@@ -80,6 +83,8 @@ public class RecipeService {
|
||||
Recipe recipe = findRecipe(householdId, recipeId);
|
||||
Household household = recipe.getHousehold();
|
||||
|
||||
validateHeroImageUrl(request.heroImageUrl());
|
||||
|
||||
recipe.setName(request.name());
|
||||
recipe.setServes(request.serves() != null ? request.serves().shortValue() : 0);
|
||||
recipe.setCookTimeMin(request.cookTimeMin() != null ? request.cookTimeMin().shortValue() : 0);
|
||||
@@ -183,6 +188,18 @@ public class RecipeService {
|
||||
return new IngredientCategoryResponse(category.getId(), category.getName());
|
||||
}
|
||||
|
||||
// ── Image validation ──
|
||||
|
||||
private static final java.util.regex.Pattern ALLOWED_IMAGE_PATTERN =
|
||||
java.util.regex.Pattern.compile("^data:image/(jpeg|jpg|png|gif|webp);base64,");
|
||||
|
||||
private void validateHeroImageUrl(String heroImageUrl) {
|
||||
if (heroImageUrl == null || heroImageUrl.isBlank()) return;
|
||||
if (!ALLOWED_IMAGE_PATTERN.matcher(heroImageUrl).find()) {
|
||||
throw new ValidationException("Ungültiger Bildtyp. Erlaubt sind: JPEG, PNG, GIF, WebP.");
|
||||
}
|
||||
}
|
||||
|
||||
// ── Private helpers ──
|
||||
|
||||
private Recipe findRecipe(UUID householdId, UUID recipeId) {
|
||||
|
||||
Reference in New Issue
Block a user