From 06d9e6a1b1d1e639e4df90d61136804a7bed0b7e Mon Sep 17 00:00:00 2001 From: Maxim Kiselev Date: Mon, 11 May 2026 07:56:49 +0700 Subject: [PATCH] fix(import): replace external image URL with local path after download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When importing a recipe from a URL, the image is fetched and saved locally as full.jpg, but the 'image' field in recipe.json kept the original URL. Two consequences: 1. The source URL leaks back to the user on edit (visible in the image field), even though the frontend serves the local copy via the cookbook.recipe.image API route. 2. Re-saving the recipe without changing the image still satisfies the change check on line 283 only because the strings match — but if anything mutates the field (e.g. a filter or user edit that does not intend to re-fetch), the importer would re-download from the external host on every save. After setImageData() succeeds, rewrite the field to the user-relative path of the local file (//full.jpg) and re-write recipe.json. The path is resolvable by the existing local-path branch on line 297 should it ever be needed. --- lib/Service/RecipeService.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/Service/RecipeService.php b/lib/Service/RecipeService.php index 8abcbbdad..1cb77a961 100755 --- a/lib/Service/RecipeService.php +++ b/lib/Service/RecipeService.php @@ -310,6 +310,17 @@ public function addRecipe($json, $importedHtml = null) { // If image data was fetched, write it to disk if ($full_image_data) { $this->imageService->setImageData($recipe_folder, $full_image_data); + + // Replace external URL in JSON with the user-relative path to the local copy. + // Avoids leaking the source URL on edit and prevents re-downloading on the next + // save (the image_changed check on line above compares this field). The frontend + // renders `imageUrl` (an API route), not this field, so any stable non-URL value + // is safe. + if (isset($json['image']) && strpos($json['image'], 'http') === 0) { + $userFilesRoot = '/' . $this->user_id . '/files'; + $json['image'] = substr($recipe_folder->getPath(), strlen($userFilesRoot)) . '/full.jpg'; + $recipe_file->putContent(json_encode($json)); + } } // Write .nomedia file to avoid gallery indexing