From a3bf4b1337feddd70718e05d356607cb2ceed0c8 Mon Sep 17 00:00:00 2001 From: Nils-Johan Gynther Date: Sun, 19 Apr 2026 22:00:13 +0200 Subject: [PATCH] fix: update NEXT_STEPS and TEKNISK_BESKRIVNING with completed features and authentication details --- NEXT_STEPS.md | 3 +++ TEKNISK_BESKRIVNING.md | 43 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/NEXT_STEPS.md b/NEXT_STEPS.md index 313dacbb..cd837849 100644 --- a/NEXT_STEPS.md +++ b/NEXT_STEPS.md @@ -12,6 +12,7 @@ |---|---| | Inventorie (CRUD, konsumtion, historik) | ✅ Klart | | Recept (skapa, visa, importera, matchning) | ✅ Klart | +| Receptredigering och borttagning (JWT-autentisering) | ✅ Klart | | Snabbimport (URL/PDF/bild/ICA) | ✅ Klart | | Kvittoimport (Mistral AI, OCR, alias) | ✅ Klart | | Matplanering (veckovy, inköpslista) | ✅ Klart | @@ -24,6 +25,8 @@ | Receptredigering (frontend UX) | ✅ Klart | | Receptbilder (upload URL) | ✅ Klart | | Autentisering (JWT, Auth.js v5, User-modell) | ✅ Klart | +| Klient-side JWT via useAuthFetch() | ✅ Klart | +| SessionProvider i root layout | ✅ Klart | | Användarprofil (firstName, lastName, email) | ✅ Klart | | Produktkategorier — hierarkisk struktur (3 nivåer) | ✅ Klart | | Kategori-seed (supplement, idempotent) | ✅ Klart | diff --git a/TEKNISK_BESKRIVNING.md b/TEKNISK_BESKRIVNING.md index a25dcd94..b5cea212 100644 --- a/TEKNISK_BESKRIVNING.md +++ b/TEKNISK_BESKRIVNING.md @@ -230,7 +230,7 @@ Dessa Server Actions finns kvar men bör migreras om de orsakar problem: ### API-proxy routes (Next.js) -Alla proxy-routes läser auth-token via `auth()` (Auth.js v5) och vidarebefordrar `Authorization: Bearer ` till backend. +Alla proxy-routes använder `withAuth(handler)`-wrappern (från `lib/with-auth.ts`) som läser auth-token via `request.auth` och vidarebefordrar `Authorization: Bearer ` till backend. `withAuth` löser kompatibilitetsproblem med `auth()` standalone i Next.js 16 + NextAuth beta.28. | Route | Metod | Syfte | |-------|-------|-------| @@ -256,14 +256,47 @@ Alla proxy-routes läser auth-token via `auth()` (Auth.js v5) och vidarebefordra ### Autentisering (Auth.js v5) - `auth.ts` — NextAuth-konfiguration med Credentials provider; sparar `accessToken`, `userId`, `username` och `role` i JWT-token och session -- `proxy.ts` — Skyddar alla routes utom `/login`, `/register` och `/api/auth`; blockerar `/admin/*` om sessionens `role` inte är `admin` -- `lib/auth-headers.ts` — `getAuthHeaders()` hämtar Bearer-token från session (server-side) +- `proxy.ts` — Skyddar alla routes utom `/login`, `/register` och `/api/*`; blockerar `/admin/*` om sessionens `role` inte är `admin`. **Next.js 16 använder `proxy.ts` istället för `middleware.ts`.** +- `lib/auth-headers.ts` — `getAuthHeaders()` hämtar Bearer-token från session (server-side, används i Next.js API route-proxies) - `lib/api.ts` — `fetchJson()` lägger automatiskt till auth-headers server-side, redirectar till `/login` vid 401 +- `lib/with-auth.ts` — `withAuth(handler)`-wrapper för Next.js Route Handlers som behöver autentisering via `request.auth`. Löser kompatibilitetsproblemet med `auth()` standalone i Next.js 16 + NextAuth beta. +- `lib/use-auth-fetch.ts` — `useAuthFetch()`-hook för klientkomponenter. Returnerar en `fetch`-funktion som automatiskt lägger till `Authorization: Bearer `. Används i komponenter som gör anrop till endpoints som Caddy routar direkt till NestJS. +- `app/Providers.tsx` — Client component som wrappa appen med `SessionProvider` (krävs för att `useSession()` ska fungera) -### Frontend utbyggbarhet +### Kritisk regel: Caddy-routing och klientkomponenter + +Caddy routar `/api/recipes*`, `/api/products*` och `/api/inventory*` **direkt till NestJS** — Next.js route handlers körs aldrig för dessa sökvägar. Det innebär att klientkomponenter (`'use client'`) som gör `fetch()` till dessa endpoints **inte kan lita på att withAuth eller getAuthHeaders lägger till token automatiskt**. + +**Lösning: använd alltid `useAuthFetch()` i klientkomponenter:** + +```ts +import { useAuthFetch } from '../../../lib/use-auth-fetch'; + +// I komponentfunktionen: +const authFetch = useAuthFetch(); + +// Anrop — Content-Type och Authorization sätts automatiskt: +const res = await authFetch('/api/recipes/1', { method: 'PATCH', body: JSON.stringify(data) }); +const res = await authFetch('/api/recipes', { method: 'POST', body: JSON.stringify(body) }); +const res = await authFetch(`/api/recipes/${id}`, { method: 'DELETE' }); +``` + +Hooken hämtar token via `useSession()` (kräver att `SessionProvider` finns i layout) och är memoizerad med `useCallback`. + +**Endpoints som kräver `useAuthFetch()` i klientkod (Caddy-direktrouting):** + +| Prefix | Destination | Kräver useAuthFetch i klient? | +|--------|-------------|-------------------------------| +| `/api/recipes*` | `recipe-api:8080` direkt | ✅ Ja | +| `/api/products*` | `recipe-api:8080` direkt | ✅ Ja | +| `/api/inventory*` | `recipe-api:8080` direkt | ✅ Ja | +| `/api/admin/*` | `recipe-frontend:3000` via catch-all | Nej (withAuth hanterar) | +| `/api/auth/*` | `recipe-frontend:3000` via catch-all | Nej | +| `/api/categories` | `recipe-frontend:3000` via catch-all | Nej | - Svenska felmeddelanden via `lib/error-handler.ts` (`parseErrorResponse`) -- Centraliserad API-access via `lib/api.ts` (`fetchJson`) +- Centraliserad API-access via `lib/api.ts` (`fetchJson`) — för server-side anrop +- Klientside auth-fetch via `lib/use-auth-fetch.ts` (`useAuthFetch`) — för klientkomponenter som pratar direkt med NestJS - Typade inventory/recipe data i `features/inventory/types.ts` ---