Commit Graph

21 Commits

Author SHA1 Message Date
davide 5654964d09 fix(security): sanitize error logging and remove Zod schema details from responses
- Stripe webhook: log only error.message instead of full error objects
  to avoid exposing stack traces in aggregated logs
- Admin products POST: return only first Zod error message instead of
  the full error array which reveals internal schema structure
2026-05-19 10:11:47 +02:00
davide 8cf038443f fix(security): remove hardcoded default credentials from config files
- .env.example: replace weak default INITIAL_ADMIN_PASSWORD and
  AUTH_SECRET with instructive placeholders requiring manual generation
- docker-compose.yml: parameterize POSTGRES_USER, POSTGRES_PASSWORD,
  POSTGRES_DB and DATABASE_URL via environment variables with local fallbacks
2026-05-19 10:11:30 +02:00
davide d4b3398de5 fix(security): enforce order status state machine in admin endpoint
Add VALID_TRANSITIONS map and validate each status change before updating
the database. Prevents skipping payment (e.g. PENDING→FULFILLED) or
reopening closed orders.
2026-05-19 10:11:16 +02:00
davide f4eedaffe2 fix(security): replace in-memory rate limiting with persistent DB-backed limiter
- Add LoginAttempt model to Prisma schema with migration
- Create rate-limit.ts utility (10 attempts / 15 min window, DB-backed)
- Apply rate limiting to login endpoint (replaces in-memory Map)
- Apply rate limiting to change-password endpoint (previously unprotected)
- Rate limit state survives server restarts and works across multiple instances
2026-05-19 10:10:57 +02:00
davide 45a50dc906 fix(security): whitelist allowed keys in admin settings endpoint
Reject any key not in the explicit allowlist before writing to the database,
preventing arbitrary configuration injection by a malicious admin.
2026-05-19 10:10:42 +02:00
davide fcfa0707a1 fix(security): replace localStorage user state with server-side session
- Add GET /api/auth/me endpoint returning current user from httpOnly cookie
- Add UserContext + useUser() hook that fetches from /api/auth/me on mount
- Wrap root layout with UserProvider
- Remove all localStorage.setItem/getItem('user') calls from login, register,
  navbar, account pages, change-password, and checkout
- mustChangePassword redirect now reads from refreshed server session
2026-05-19 10:10:24 +02:00
davide 0395a78008 fix(security): add HTTP security headers (CSP, HSTS, X-Frame-Options)
- middleware.ts: set X-Frame-Options, X-Content-Type-Options,
  Referrer-Policy, Permissions-Policy, Content-Security-Policy on all responses
- Caddyfile: add Strict-Transport-Security (HSTS 1y), X-Frame-Options,
  X-Content-Type-Options at reverse proxy level
2026-05-19 10:10:08 +02:00
davide 2a6c3a1222 fix(security): validate file uploads with magic bytes, remove SVG from favicon whitelist
- Add validateImageMagicBytes() to storage.ts reading first 12 bytes
  to verify JPEG/PNG/WebP/ICO signatures regardless of declared MIME type
- Remove image/svg+xml from favicon upload whitelist (SVG can embed scripts)
- Apply magic bytes check in product image and favicon upload endpoints
2026-05-19 10:09:53 +02:00
davide d958a4b9a5 docs: add network ports section to README
Sezione dedicata alle porte con distinzione tra porte pubbliche (80,
443), interne Docker (3000, 5432, 1025) e solo sviluppo (8025).
Include comandi UFW pronti per Ubuntu/Debian.
2026-05-19 09:19:16 +02:00
davide 4a7cd9fbd4 docs: expand admin guide with field-by-field documentation
Aggiunta documentazione campo per campo per tutte le sezioni: Product

Types, Categorie, Admin Users, Impostazioni (generale, footer, favicon).

Corretto Base Price da centesimi a euro dopo la fix del form.
2026-05-19 09:17:38 +02:00
davide 7afb609386 fix: hide slug field in product type form, auto-generate from name
Lo slug viene calcolato automaticamente dal nome senza che l'utente
debba compilarlo — il campo è rimosso dal form ma continua ad essere
inviato nel payload e visibile nella tabella.
2026-05-19 09:17:17 +02:00
davide 46d1596dce fix: update tsconfig target from deprecated ES5 to ES2017 2026-05-19 09:01:51 +02:00
davide 3b800463f5 fix: accept price in currency units instead of cents in product form
Il campo prezzo del form admin ora accetta valori in unità (es. 19.99)
invece di centesimi (1999). La conversione *100 avviene al submit,
il DB e Stripe continuano a ricevere centesimi.
2026-05-19 08:58:46 +02:00
davide 2c6c847d76 feat: replace Docker named volumes with local bind mounts and add backup script
- docker-compose.yml: sostituisce pgdata/uploads/caddy_data/caddy_config con bind mount su ./data/
- app/public/.gitkeep: crea cartella richiesta dal Dockerfile durante il build
- scripts/backup.sh: backup automatico di DB (pg_dump) e uploads con rotazione 30 giorni
- docs/BACKUP.md: guida completa backup, ripristino e setup cron
- .gitignore: aggiorna con data/ e backups/
2026-05-19 08:49:28 +02:00
davide b62c02adc1 feat: add favicon upload and footer customization to admin settings
- Admin settings page now has sections for general settings, footer, and favicon
- Footer component reads footer_copyright and footer_links from DB
- New API route POST /api/admin/upload/favicon saves uploaded image and updates favicon_url in DB
- Textarea support added for footer_links JSON field
2026-05-18 22:50:07 +02:00
davide b33eee8bea docs: add favicon, reorganize docs and add customization guide
- Add icon.png as default favicon (cropped to remove transparent padding)
- Fix layout.tsx to use icon.png as fallback when favicon_url is not set in DB
- Move ADMIN_GUIDE.md to docs/ folder
- Add docs/CUSTOMIZATION.md with guide on how to customize icon, title, footer
2026-05-18 22:49:22 +02:00
davide e82e20b0f1 docs: add localhost vs production comparison and fix Caddyfile example
- Add new section summarising the 4 differences between local dev and
  production: domain/HTTPS, env vars, server requirements, backups
- Update production Caddyfile example to include /uploads/* static
  file handler (required for image serving)
2026-05-18 17:55:12 +02:00
davide aab9d24800 docs: add comprehensive admin panel user guide (Italian)
Covers all admin sections with step-by-step instructions:
login, dashboard, products (detailed field reference including image
upload with aspect ratio guidance), product types, categories,
orders, customers, reviews, admin users, settings, and recommended
onboarding flow.
2026-05-18 17:55:05 +02:00
davide 676b173414 feat: add product image upload to admin panel
- Add storage.ts utility (saveImage, deleteImageFile) for local disk operations
- Add POST /api/admin/products/[id]/images: validates MIME type and 5MB limit, saves file, creates MediaAsset record
- Add DELETE /api/admin/products/[id]/images?imageId=: removes file and DB record
- Add Images section to product edit form (hidden for new products until saved)
- Display images in square aspect-ratio grid matching storefront display
- Support multi-file upload; hover to reveal delete button
2026-05-18 17:54:09 +02:00
davide b3097670c0 infra: add persistent uploads volume and configure Caddy to serve static images
- Add named Docker volume `uploads` mounted at /app/public/uploads in app container
- Share same volume with Caddy at /srv/uploads for direct static file serving
- Add Caddy `handle /uploads/*` block so images bypass Next.js (standalone mode does not serve runtime public files)
- Create uploads directory with correct nextjs:nodejs ownership in Dockerfile
- Add mkdir safeguard in entrypoint.sh
2026-05-18 17:54:00 +02:00
davide a8d4c158b8 Commit iniziale 2026-05-18 15:25:38 +02:00