API Reference / Autenticazione

Autenticazione

Le API usano una coppia di token: un access token JWT a vita breve per ogni richiesta e un refresh token a vita lunga per rinnovarlo. Se l'account ha la MFA attiva, il login diventa un flusso in due passi.

01Il modello dei token

Ogni chiamata autenticata porta l'access token nell'header Authorization:

header
Authorization: Bearer <accessToken>
Nota

Tutte le risposte usano lo stesso envelope: { "success": true, "data": … } in caso di successo, { "success": false, "error": { "code", "message" } } in caso di errore. I dettagli nella pagina Errori e envelope.

02Login

POST /api/auth/login token non richiesto

Crea una sessione autenticata. Con credenziali valide restituisce la coppia di token; se l'account ha la MFA attiva restituisce invece una sfida MFA da completare con /auth/mfa/verify-login.

Body
CampoTipoDescrizione
identifierstringrichiestoUsername o indirizzo email dell'utente.
passwordstringrichiestoPassword in chiaro (solo su HTTPS).
rememberbooleanopzionaleSe true il refresh token dura 30 giorni, altrimenti 4 ore.
Esempio di richiesta
curl
curl -X POST https://crm.tuodominio.it/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{ "identifier": "mario.rossi", "password": "•••••••", "remember": true }'
Risposta · 200
json
{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIs…",
    "accessTokenExpiresAt": "2026-07-07T15:24:00.000Z",
    "refreshToken": "9f2c1e6a…",
    "refreshTokenExpiresAt": "2026-08-06T15:09:00.000Z",
    "user": { "id": 42, "username": "mario.rossi",  }
  }
}
Risposta · 200 con MFA attiva
json
{
  "success": true,
  "data": { "mfaRequired": true, "mfaToken": "eyJhbGciOiJIUzI1NiIs…" }
}
Errori
StatoCodiceQuando
401UNAUTHORIZEDCredenziali errate. La risposta è identica per utente inesistente e password errata (anti-enumeration).
429TOO_MANY_REQUESTSAccount temporaneamente bloccato dopo troppi tentativi falliti, o rate limit di rotta superato.
422VALIDATION_ERRORidentifier o password mancanti o fuori misura.
Attenzione

Al primo accesso (o dopo un reset da amministratore) l'utente può avere il flag di cambio password obbligatorio: le API rispondono 403 PASSWORD_CHANGE_REQUIRED finché la password non viene cambiata via POST /api/auth/change-password.

03Verifica MFA

POST /api/auth/mfa/verify-login token non richiesto

Secondo passo del login quando l'account ha la MFA TOTP attiva. Scambia la sfida ricevuta dal login con la coppia di token definitiva.

Body
CampoTipoDescrizione
mfaTokenstringrichiestoLa sfida ricevuta dalla risposta del login (breve scadenza).
codestringrichiestoCodice TOTP a 6 cifre dall'app authenticator.
Risposta · 200

Identica alla risposta di login riuscito: accessToken, refreshToken, scadenze e profilo utente.

04Rinnovo del token

POST /api/auth/refresh token non richiesto

Scambia un refresh token valido con un nuovo access token. Da chiamare quando l'access token è scaduto (o poco prima). Il refresh token resta lo stesso fino alla sua scadenza o revoca.

Body
CampoTipoDescrizione
refreshTokenstringrichiestoIl refresh token ottenuto dal login.
Esempio di richiesta
curl
curl -X POST https://crm.tuodominio.it/api/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{ "refreshToken": "9f2c1e6a…" }'
Errori
StatoCodiceQuando
401UNAUTHORIZEDToken scaduto, revocato o sconosciuto: l'utente deve rifare il login.

05Logout

POST /api/auth/logout token non richiesto

Revoca il refresh token (chiude la sessione). Gli access token già emessi per quella sessione smettono di essere accettati.

Body
CampoTipoDescrizione
refreshTokenstringrichiestoIl refresh token della sessione da chiudere.

06Profilo corrente

GET /api/auth/me bearer richiesto

Restituisce il profilo dell'utente autenticato: identità, ruoli e team. Utile come "chi sono" dopo il login o al bootstrap del client.

Risposta · 200
json
{
  "success": true,
  "data": {
    "user": { "id": 42, "username": "mario.rossi", "roles": ["sales"],  }
  }
}
PATCH /api/auth/me bearer richiesto

Aggiorna il profilo dell'utente autenticato. Tutti e quattro i campi sono richiesti (è una sostituzione del profilo, non una patch parziale).

Body
CampoTipoDescrizione
firstNamestringrichiesto1–120 caratteri.
lastNamestringrichiesto1–120 caratteri.
usernamestringrichiesto3–100 caratteri.
emailstringrichiestoEmail valida (normalizzata in minuscolo).

07Gestione password

POST /api/auth/change-password bearer richiesto

Cambia la password dell'utente autenticato. È anche l'unica rotta utilizzabile quando è attivo il flag di cambio password obbligatorio (403 PASSWORD_CHANGE_REQUIRED sulle altre).

Body
CampoTipoDescrizione
currentPasswordstringrichiestoLa password attuale (errata → 401).
newPasswordstringrichiestoLa nuova password (vincoli di robustezza applicati lato server).
confirmPasswordstringrichiestoDeve coincidere con newPassword.
Attenzione

Al cambio password tutte le sessioni vengono revocate (ogni refresh token attivo). Il client deve rifare il login subito dopo.

POST /api/auth/forgot-password token non richiesto

Avvia il reset self-service: body { "identifier": "username o email" }. Se l'account esiste viene inviata un'email con un link a token monouso e scadenza; la risposta 200 è sempre identica, che l'account esista o no (anti-enumeration). Rate-limited come il login.

POST /api/auth/reset-password token non richiesto

Completa il reset col token ricevuto via email: body { "token", "newPassword", "confirmPassword" }. Il token è monouso: riutilizzarlo o usarne uno scaduto → errore.

POST /api/auth/password-breach-check bearer richiesto

Verifica se una password compare in data-breach noti (k-anonymity: la password non lascia il server in chiaro). Body { "password" } → risposta con isPwned, breachCount e available (false se il provider esterno non è raggiungibile: trattala come «non verificabile», non come «sicura»).

08Sessioni e cronologia accessi

GET /api/auth/sessions bearer richiesto

Le sessioni attive dell'utente (una per refresh token non revocato e non scaduto). current: true marca quella da cui stai chiamando.

Risposta · 200
json
{
  "success": true,
  "data": {
    "items": [{
      "id": "318",
      "device": "Chrome · Windows",
      "ipAddress": "93.44.…",
      "createdAt": "2026-07-07T09:12:00.000Z",
      "expiresAt": "2026-08-06T09:12:00.000Z",
      "current": true
    }]
  }
}
DELETE /api/auth/sessions/:id bearer richiesto

Revoca una singola sessione (il suo refresh token smette di funzionare e gli access token di quella sessione vengono rifiutati). Sessione inesistente o non tua → 404.

DELETE /api/auth/sessions bearer richiesto

«Disconnetti ovunque tranne qui»: revoca tutte le altre sessioni e risponde con { "revokedCount": n }.

GET /api/auth/login-history bearer richiesto

Gli ultimi accessi (riusciti e falliti) dell'utente: items di { at, status, device, ipAddress }. Query limit opzionale (default 10, massimo 50).

09Gestione MFA

Attivazione e disattivazione dell'autenticazione a due fattori (TOTP) per l'utente autenticato. La verifica in fase di login è descritta sopra.

MetodoEndpointBodyCosa fa
POST/api/auth/mfa/setup·Genera il segreto TOTP: risponde con secret e otpauthUrl (QR per l'app authenticator). La MFA resta disattiva finché non confermi.
POST/api/auth/mfa/enable{ "code" }Conferma con un codice TOTP valido: attiva la MFA e risponde con i recoveryCodes.
POST/api/auth/mfa/disable{ "code" }Disattiva la MFA (richiede un codice TOTP o di recupero valido).
Attenzione

I codici di recupero vengono mostrati una sola volta nella risposta di enable (il server ne conserva solo l'hash): falli salvare subito all'utente. Ogni codice è monouso e vale come secondo fattore al login.

Sicurezza

Non conservare mai i token nel localStorage di pagine esposte a contenuti terzi. Le rotte di autenticazione hanno rate limiting dedicato e lockout per account: gli errori 429 vanno gestiti con backoff, non con retry immediati.