Alexander Bocken 0a49e20c02 refactor: migrate recipe forms to SvelteKit actions with secure image upload
Refactor recipe add/edit routes from client-side fetch to proper SvelteKit
form actions with progressive enhancement and comprehensive security improvements.

**Security Enhancements:**
- Implement 5-layer image validation (file size, MIME type, extension, magic bytes, Sharp structure)
- Replace insecure base64 JSON encoding with FormData for file uploads
- Add file-type@19 dependency for magic bytes validation
- Validate actual file type via magic bytes to prevent file type spoofing

**Progressive Enhancement:**
- Forms now work without JavaScript using native browser submission
- Add use:enhance for improved client-side UX when JS is available
- Serialize complex nested data (ingredients/instructions) via JSON in hidden fields
- Translation workflow integrated via programmatic form submission

**Bug Fixes:**
- Add type="button" to all interactive buttons in CreateIngredientList and CreateStepList
  to prevent premature form submission when clicking on ingredients/steps
- Fix SSR errors by using season_local state instead of get_season() DOM query
- Fix redirect handling in form actions (redirects were being caught as errors)
- Fix TranslationApproval to handle recipes without images using null-safe checks
- Add reactive effect to sync editableEnglish.images with germanData.images length
- Detect and hide 150x150 placeholder images in CardAdd component

**Features:**
- Make image uploads optional for recipe creation (use placeholder based on short_name)
- Handle three image scenarios in edit: keep existing, upload new, rename on short_name change
- Automatic image file renaming across full/thumb/placeholder directories when short_name changes
- Change detection for partial translation updates in edit mode

**Technical Changes:**
- Create imageValidation.ts utility with comprehensive file validation
- Create recipeFormHelpers.ts for data extraction, validation, and serialization
- Refactor /api/rezepte/img/add endpoint to use FormData instead of base64
- Update CardAdd component to upload via FormData immediately with proper error handling
- Use Image API for placeholder detection (avoids CORS issues with fetch)
2026-01-13 15:12:07 +01:00
2023-06-24 15:35:36 +02:00
2023-06-24 15:35:36 +02:00
2025-12-16 11:32:38 +01:00
2023-06-24 15:33:41 +02:00
2024-02-18 15:23:14 +01:00
2023-06-24 15:35:36 +02:00
2025-09-04 11:52:28 +02:00

Personal Homepage

My own homepage, bocken.org, built with svelte-kit.

TODO

General

  • Admin user management -> move to authentik via oIDC
    • login to authentik
    • only let rezepte_users edit recipes -> currently only letting them log in, should be changed
    • get user info from authentik (more than email and name)
    • upload pfp
  • upload/change pfp
  • registration only with minimal permissions
  • logout without /logout page
  • preferences page
  • change password
  • css dark mode @media (prefers-color-scheme: dark) {}
  • dark mode toggle

Rezepte

  • Do not list recipes that are all-year as "seasonal"
  • nutrition facts
  • verify randomize arrays based on day
  • notes for next time
  • refactor, like, a lot
  • expose json-ld for recipes https://json-ld.org/ https://schema.org/Recipe
  • reference other recipes in recipe
    • add a link to the recipe
    • add ingredients to the ingredients list
    • include steps?
  • add favoriting ability when logged in
    • favorite button on recipe
    • store favorites in DB -> add to user object
    • favorite API endpoint (requires auth of user)
      • set
      • retrieve
    • favorite page/MediaScroller
  • graceful degradation for JS-less browsers
    • use js-only class with display:none and remove it with JS
    • disable search -> use form action instead on submit?
    • do not blur images without js
    • correct Recipe Card rendering

Glaube

  • just keep it md rendered
  • Google Speech to Text API integration?
  • Gebete

Outside of this sveltekit project but planned to run on the server as well

  • create LDAP and OpenID

E-Mail

  • emailwiz setup
  • fail2ban
  • LDAP?

Dendrite

  • setup dendrite
  • Connect to LDAP/OIDC (waiting on upstream)
  • Serve some web-frontend -> Just element?

Gitea

  • consistent theming
  • OpenID Connect
  • sane landing page

Jellyfin

  • connect to LDAP
  • consitent theming

Webtrees

  • setup Oauth2proxy -> not necessary, authentik has proxy integrated
  • connect to OIDC using Oauth2proxy (using authentik)
  • consistent theming
  • auto-login if not logged in

Jitsi

  • consistent theming
  • move away from docker
  • find a way to improve max video quality without jitsi becoming unreliable

Searx

  • investigate SearxNG as more reliable alternative
  • consistent theming

Photoprism

  • consistent theming
  • OIDC integration (waiting on upstream)

Nextcloud

  • consistent theming
  • collabora integration

Transmission

  • move behind authentik
Description
My personal website built to learn SvelteKit. The largest part is the Recipes subsection.
https://bocken.org
Readme AGPL-3.0 93 MiB
Languages
Svelte 64.1%
TypeScript 33.3%
CSS 1.7%
Python 0.5%
JavaScript 0.2%
Other 0.2%