
# Aggiornare le impostazioni di identità

`PATCH /v1/identity-settings` · permesso `identity-settings:write`

Aggiorna le impostazioni del nome utente dell'ambiente con una merge patch JSON (`application/merge-patch+json`, RFC 7396). `If-Match` è obbligatorio: se manca si ottiene `428`, con una versione obsoleta `412`. Se le impostazioni non sono mai state scritte la versione è `"0"` e la prima scrittura crea la riga. Una patch che non cambia nulla non scrive nulla e mantiene la versione.

## Richiesta

| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| `If-Match` | header | sì | L'`ETag` delle impostazioni come ultima lettura (`"0"` se mai scritte). Mancante: `428`; obsoleto: `412`. |
| `username_identifier` | string | no | `required`, `optional` oppure `off`. Non può essere `null`. |
| `username_min_length` | integer | no | 3-64, non maggiore di `username_max_length`. Non può essere `null`. |
| `username_max_length` | integer | no | 3-64, non minore di `username_min_length`. Non può essere `null`. |
| `reserved_usernames` | string[] \| null | no | Al massimo 1000 nomi; sostituisce l'intero elenco (RFC 7396 non unisce gli array). `null` o `[]` lo svuota. Ogni voce è normalizzata, i duplicati vengono scartati e l'elenco è salvato ordinato. |
| `verification_policy` | string | no | `before_sign_in` (predefinito) o `after_sign_in`. `after_sign_in` interrompe la pulizia degli account non verificati. Non può essere `null`. |
| `unverified_account_ttl_days` | integer | no | 1-30 (predefinito 7): giorni per cui una registrazione non verificata viene conservata in un ambiente `before_sign_in` prima di essere eliminata. Non può essere `null`. |

Le impostazioni del nome utente si applicano solo alle scritture successive; non modificano mai gli utenti esistenti. Le impostazioni di verifica agiscono anche sulle registrazioni esistenti (vedere sotto).

## Regole di applicazione

- `off` (predefinito): una richiesta che scrive un nome utente (`POST /v1/users`, `PATCH /v1/users/{id}`) fallisce con `422` e codice `identifier_type_disabled` (puntatore `/username`). Cancellare un nome utente esistente resta consentito, e una patch utente che non tocca il nome utente non viene ricontrollata. L'accesso non risolve gli account tramite nome utente.
- `optional`: un nome utente può essere impostato. `required`: creare un utente tramite l'API di gestione senza nome utente fallisce con `422` (`required`), e una patch di gestione non può cancellarlo. Chiedere il nome utente nel modulo di registrazione spetta al login ospitato; la creazione social e just-in-time (JIT) non lo chiede mai.
- Lunghezza: un nome utente più corto di `username_min_length` o più lungo di `username_max_length` fallisce con `422` (`invalid`).
- Nomi riservati: un nome utente la cui forma normalizzata è in `reserved_usernames` fallisce con `422` e codice `username_reserved`. Una voce di elenco non valida fallisce con `422` e puntatore `/reserved_usernames/<i>`.
- Gli utenti esistenti non vengono modificati quando l'impostazione cambia; le regole si applicano solo alle scritture successive.

## Pulizia degli account non verificati

`verification_policy` e `unverified_account_ttl_days` controllano la pulizia automatica delle registrazioni mai verificate. La pulizia viene eseguita solo se l'indirizzo email (o il numero di telefono) è un identificatore obbligatorio, come avviene per impostazione predefinita per l'email.

- `before_sign_in` (predefinito): un utente creato tramite registrazione non può ricevere token prima di aver verificato l'identificatore obbligatorio. Un utente registrato che, `unverified_account_ttl_days` giorni (1-30, predefinito 7) dopo la registrazione, non ha ancora un indirizzo email o un numero di telefono verificato, non ha mai ricevuto un token e non ha un'identità social o aziendale (SAML/OIDC) viene eliminato definitivamente. La pulizia viene eseguita periodicamente (ogni ora per impostazione predefinita).
- `after_sign_in`: gli utenti ricevono token prima della verifica (`email_verified: false`); la pulizia non viene eseguita e nessun utente viene eliminato.
- Mai eliminati: gli utenti creati tramite l'API di gestione, l'importazione, SCIM, un invito o la federazione just-in-time, gli utenti bloccati e quelli la cui eliminazione è già iniziata. Sono idonee solo le registrazioni create dopo l'avvio della pulizia nell'ambiente.
- L'eliminazione è irreversibile: l'utente viene eliminato definitivamente, viene conservata una lapide con motivo `unverified_expired` e viene pubblicato l'evento `user.deleted`.
- Una modifica della policy o del periodo ha effetto all'esecuzione successiva. Ridurre `unverified_account_ttl_days` rende subito idonee le registrazioni non verificate più vecchie; tornare da `after_sign_in` a `before_sign_in` elimina le registrazioni non verificate scadute all'esecuzione successiva.

## Risposta

`200 OK` con le impostazioni aggiornate e il nuovo `ETag`.

```json
{
  "username_identifier": "optional",
  "username_min_length": 3,
  "username_max_length": 32,
  "reserved_usernames": ["admin", "root", "support"],
  "verification_policy": "before_sign_in",
  "unverified_account_ttl_days": 7,
  "updated_at": "2026-10-05T09:30:00.123456Z"
}
```

## Errori

| HTTP | code | Quando |
|---|---|---|
| 400 | `unknown_field` | La patch contiene un campo sconosciuto o di sola lettura, oppure non è un oggetto JSON (`malformed_request`). |
| 412 | `precondition_failed` | `If-Match` non corrisponde alla versione attuale. |
| 415 | `unsupported_media_type` | Il content type non è `application/merge-patch+json`. |
| 422 | `validation_failed` | Un valore non è valido, `min` supera `max`, oppure un campo che non può essere `null` è stato impostato a `null` (`code: invalid`). |
| 428 | `precondition_required` | L'header `If-Match` è mancante. |
| 401 | `unauthenticated` | La credenziale è mancante, non valida o revocata. |
| 403 | `insufficient_permissions` | La credenziale non ha il permesso richiesto. |
| 429 | `rate_limited` | Il limite di velocità è stato superato; riprova dopo il periodo `Retry-After`. |
| 503 | `service_unavailable` | Una dipendenza è temporaneamente non disponibile; riprova dopo il periodo `Retry-After`. |

## Esempio

```bash
curl -X PATCH https://api.eu.keenauth.com/v1/identity-settings \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "0"' \
  -d '{"username_identifier":"optional","username_max_length":32,"reserved_usernames":["admin","root","support"]}'
```
