Fix contatti + rinomina servizi + orario sabato

- Contatti: rate-limit per IP reale (X-Forwarded-For) invece dell'IP del
  proxy Traefik, condiviso da tutti; controllo spostato dopo la validazione
  così bot/honeypot non consumano la quota. Honeypot rinominato da "website"
  a "hp_field" per non farlo riempire dall'autofill del browser (falsi 400).
- Servizi: "Performance Class" -> "Class" (titolo/card/H1/footer); migrazione
  DB invertita e guardata.
- One to One: migrazione titolo prod "Personal training" -> "One to One".
- Footer: orario sabato 8-17 (non 8-19), seed + migrazione guardata.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-21 17:58:26 +02:00
parent 22c9cadb43
commit b17b5c831a
9 changed files with 42 additions and 21 deletions
+4 -3
View File
@@ -1,6 +1,6 @@
export interface ContactData {
firstName: string; lastName: string; phone: string;
email: string; message: string; website: string;
email: string; message: string; hpField: string;
}
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -20,9 +20,10 @@ export function validateContact(data: unknown):
phone: str(d.phone, 40),
email: str(d.email, 200),
message: str(d.message, 5000),
website: str(d.website, 200),
// Honeypot: nome neutro per non farlo riempire dall'autofill del browser.
hpField: str(d.hp_field, 200),
};
if (value.website) return { ok: false, error: 'Richiesta non valida.' };
if (value.hpField) return { ok: false, error: 'Richiesta non valida.' };
if (!value.firstName) return { ok: false, error: 'Il nome è obbligatorio.' };
if (!value.lastName) return { ok: false, error: 'Il cognome è obbligatorio.' };
if (!value.phone) return { ok: false, error: 'Il telefono è obbligatorio.' };