From 4c1d855690d7614d0423e090b6f5b0107863e9c0 Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:52:13 -0500 Subject: [PATCH] feat: Create Recipe From HTML or JSON (#4274) Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com> --- .../developers-guide/migration-guide.md | 4 + .../community-guide/bulk-url-import.md | 4 +- .../getting-started/installation/security.md | 4 +- .../components/global/RecipeJsonEditor.vue | 6 +- frontend/lang/messages/en-US.json | 7 + frontend/lib/api/types/recipe.ts | 9 +- frontend/lib/api/user/recipes/recipe.ts | 13 +- frontend/lib/icons/icons.ts | 4 +- frontend/pages/g/_groupSlug/r/create.vue | 5 + frontend/pages/g/_groupSlug/r/create/html.vue | 171 ++++++++++++++++++ frontend/pages/g/_groupSlug/r/create/url.vue | 10 +- frontend/pages/g/_groupSlug/r/create/zip.vue | 2 +- mealie/routes/recipe/recipe_crud_routes.py | 34 +++- mealie/schema/recipe/__init__.py | 4 +- mealie/schema/recipe/recipe_scraper.py | 12 +- .../services/scraper/recipe_bulk_scraper.py | 4 +- mealie/services/scraper/recipe_scraper.py | 5 +- mealie/services/scraper/scraper.py | 18 +- mealie/services/scraper/scraper_strategies.py | 24 ++- .../test_recipe_create_from_image.py | 2 +- .../user_recipe_tests/test_recipe_crud.py | 161 ++++++++++------- tests/unit_tests/test_recipe_parser.py | 2 +- tests/utils/api_routes/__init__.py | 18 +- 23 files changed, 408 insertions(+), 115 deletions(-) create mode 100644 frontend/pages/g/_groupSlug/r/create/html.vue diff --git a/docs/docs/contributors/developers-guide/migration-guide.md b/docs/docs/contributors/developers-guide/migration-guide.md index 5640a796d61a..f28c6d7c2497 100644 --- a/docs/docs/contributors/developers-guide/migration-guide.md +++ b/docs/docs/contributors/developers-guide/migration-guide.md @@ -15,6 +15,10 @@ We have renamed the `updateAt` field to `updatedAt`. While the API will still ac ### Backend Endpoint Changes These endpoints have moved, but are otherwise unchanged: +- `/recipes/create-url` -> `/recipes/create/url` +- `/recipes/create-url/bulk` -> `/recipes/create/url/bulk` +- `/recipes/create-from-zip` -> `/recipes/create/zip` +- `/recipes/create-from-image` -> `/recipes/create/image` - `/groups/webhooks` -> `/households/webhooks` - `/groups/shopping/items` -> `/households/shopping/items` - `/groups/shopping/lists` -> `/households/shopping/lists` diff --git a/docs/docs/documentation/community-guide/bulk-url-import.md b/docs/docs/documentation/community-guide/bulk-url-import.md index 7361c91ec6f7..5498290d168e 100644 --- a/docs/docs/documentation/community-guide/bulk-url-import.md +++ b/docs/docs/documentation/community-guide/bulk-url-import.md @@ -23,7 +23,7 @@ function import_from_file () { do echo $line curl -X 'POST' \ - "$3/api/recipes/create-url" \ + "$3/api/recipes/create/url" \ -H "Authorization: Bearer $2" \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ @@ -81,7 +81,7 @@ def import_from_file(input_file, token, mealie_url): data = { 'url': line } - response = requests.post(mealie_url + "/api/recipes/create-url", headers=headers, json=data) + response = requests.post(mealie_url + "/api/recipes/create/url", headers=headers, json=data) print(response.text) input_file="list" diff --git a/docs/docs/documentation/getting-started/installation/security.md b/docs/docs/documentation/getting-started/installation/security.md index e83ec86b658e..29f6b19da283 100644 --- a/docs/docs/documentation/getting-started/installation/security.md +++ b/docs/docs/documentation/getting-started/installation/security.md @@ -18,7 +18,7 @@ Use your best judgement when deciding what to do. By default, the API is **not** rate limited. This leaves Mealie open to a potential **Denial of Service Attack**. While it's possible to perform a **Denial of Service Attack** on any endpoint, there are a few key endpoints that are more vulnerable than others. -- `/api/recipes/create-url` +- `/api/recipes/create/url` - `/api/recipes/{id}/image` These endpoints are used to scrape data based off a user provided URL. It is possible for a malicious user to issue multiple requests to download an arbitrarily large external file (e.g a Debian ISO) and sufficiently saturate a CPU assigned to the container. While we do implement some protections against this by chunking the response, and using a timeout strategy, it's still possible to overload the CPU if an attacker issues multiple requests concurrently. @@ -33,7 +33,7 @@ If you'd like to mitigate this risk, we suggest that you rate limit the API in g ## Server Side Request Forgery -- `/api/recipes/create-url` +- `/api/recipes/create/url` - `/api/recipes/{id}/image` Given the nature of these APIs it's possible to perform a **Server Side Request Forgery** attack. This is where a malicious user can issue a request to an internal network resource, and potentially exfiltrate data. We _do_ perform some checks to mitigate access to resources within your network but at the end of the day, users of Mealie are allowed to trigger HTTP requests on **your server**. diff --git a/frontend/components/global/RecipeJsonEditor.vue b/frontend/components/global/RecipeJsonEditor.vue index 99067f8e4ae3..1e5c580a6cb2 100644 --- a/frontend/components/global/RecipeJsonEditor.vue +++ b/frontend/components/global/RecipeJsonEditor.vue @@ -1,7 +1,7 @@