API Utenti
L’Users API fornisce la gestione completa del ciclo di vita degli account utente all’interno di un tenant: creazione, lettura, aggiornamento, disabilitazione ed eliminazione degli utenti; assegnazione dei ruoli; importazione ed esportazione massiva degli utenti; e gestione dei numeri di telefono e delle impostazioni di autenticazione a due fattori per i singoli account.
Tutti gli endpoint in questa sezione richiedono l’header x-tenant e, salvo diversa indicazione, richiedono il permesso manage:users.
Gestione Utenti
/api/usersRequires: manage:usersElenca tutti gli utenti nel tenant. Supporta paginazione e filtraggio per ruolo, stato dell’account e query di ricerca. Restituisce oggetti utente con informazioni di riepilogo (non include lo stato 2FA o i dettagli della sessione — usa l’endpoint utente individuale per quelli).
Parametri di query
| Parametro | Tipo | Descrizione |
|---|---|---|
page | integer | Numero di pagina (default: 1) |
limit | integer | Elementi per pagina (default: 20, max: 100) |
search | string | Ricerca full-text su email, username, firstName, lastName |
role | string | Filtra per nome ruolo |
status | active | disabled | locked | Filtra per stato dell’account |
Risposta di successo
{
"ok": true,
"data": {
"data": [
{
"id": "usr_abc123",
"email": "[email protected]",
"username": "alice",
"firstName": "Alice",
"lastName": "Rossi",
"enabled": true,
"emailVerified": true,
"createdAt": "2025-01-15T10:30:00Z",
"roles": ["editor", "viewer"]
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 87,
"totalPages": 5
}
}
}/api/usersRequires: manage:usersCrea un nuovo account utente nel tenant. L’utente viene creato sia nel database Auris che nel realm Keycloak sottostante. Se password viene omessa, l’account viene creato senza password (l’utente deve impostarne una tramite un magic link o il flusso di reset password).
Corpo della richiesta
{
"email": "[email protected]",
"username": "bob",
"firstName": "Roberto",
"lastName": "Bianchi",
"password": "PasswordIniziale123",
"roles": ["viewer"],
"enabled": true
}Tutti i campi eccetto email sono opzionali.
Risposta di successo
{
"ok": true,
"data": {
"id": "usr_def456",
"email": "[email protected]",
"username": "bob",
"firstName": "Roberto",
"lastName": "Bianchi",
"enabled": true,
"emailVerified": false,
"createdAt": "2025-02-18T09:00:00Z",
"roles": ["viewer"]
}
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
EMAIL_TAKEN | 409 | Esiste già un utente con questa email nel tenant |
USERNAME_TAKEN | 409 | L’username è già in uso |
VALIDATION_ERROR | 400 | Il corpo della richiesta non ha superato la validazione dello schema |
/api/users/[id]Requires: manage:usersRecupera un singolo utente tramite il suo ID. Restituisce i dettagli completi dell’utente incluse le appartenenze ai ruoli, lo stato 2FA, il numero di telefono, le appartenenze ai gruppi e le informazioni sull’ultimo login.
Risposta di successo
{
"ok": true,
"data": {
"id": "usr_abc123",
"email": "[email protected]",
"username": "alice",
"firstName": "Alice",
"lastName": "Rossi",
"enabled": true,
"emailVerified": true,
"phoneNumber": "+39 02 1234567",
"phoneNumberVerified": true,
"createdAt": "2025-01-15T10:30:00Z",
"lastLoginAt": "2025-02-17T14:22:00Z",
"roles": ["editor", "viewer"],
"twoFactor": {
"totpEnabled": true,
"smsEnabled": false,
"webauthnEnabled": false
}
}
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
NOT_FOUND | 404 | L’utente non esiste in questo tenant |
/api/users/[id]Requires: manage:usersAggiorna i campi del profilo di un utente. Tutti i campi sono opzionali — vengono aggiornati solo i campi forniti. Per disabilitare un utente senza eliminarlo, imposta enabled: false.
Corpo della richiesta
{
"firstName": "Alicia",
"lastName": "Rossi-Bianchi",
"enabled": false
}Risposta di successo
{
"ok": true,
"data": {
"id": "usr_abc123",
"email": "[email protected]",
"firstName": "Alicia",
"lastName": "Rossi-Bianchi",
"enabled": false
}
}/api/users/[id]Requires: manage:usersSoft-delete di un utente. L’account utente viene disabilitato e contrassegnato come eliminato nel database Auris, e il suo account Keycloak viene rimosso. Le sessioni attive vengono invalidate immediatamente.
Il soft-delete è irreversibile tramite API. Il record utente viene conservato nel database per la coerenza del log di audit ma non può essere recuperato o a cui accedere. Usa enabled: false tramite PUT /api/users/[id] se vuoi disabilitare temporaneamente senza eliminazione.
Risposta di successo
{
"ok": true,
"data": { "deleted": true }
}Assegnazione Ruoli
/api/users/[id]/rolesRequires: manage:usersElenca tutti i ruoli attualmente assegnati a un utente.
Risposta di successo
{
"ok": true,
"data": [
{
"id": "role_123",
"name": "editor",
"description": "Può creare e modificare contenuti",
"color": "#3b82f6"
}
]
}/api/users/[id]/rolesRequires: manage:usersAssegna un ruolo a un utente. Il ruolo deve esistere nel tenant. Assegnare lo stesso ruolo due volte è un no-op (idempotente).
Corpo della richiesta
{
"roleId": "role_123"
}Risposta di successo
{
"ok": true,
"data": { "assigned": true }
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
NOT_FOUND | 404 | Il ruolo non esiste in questo tenant |
SELF_ROLE_CHANGE | 403 | Non puoi modificare i tuoi stessi ruoli |
/api/users/[id]/rolesRequires: manage:usersRimuove un ruolo da un utente. Rimuovere un ruolo che l’utente non ha è un no-op (idempotente).
Corpo della richiesta
{
"roleId": "role_123"
}Risposta di successo
{
"ok": true,
"data": { "removed": true }
}Importazione Massiva
/api/users/importRequires: manage:usersImporta utenti in massa da un file CSV o JSON. L’importazione viene eseguita in modo asincrono — l’endpoint restituisce immediatamente un job ID. Effettua il polling su GET /api/users/import/[id] per monitorare l’avanzamento.
Formato della richiesta: multipart/form-data
| Campo | Tipo | Descrizione |
|---|---|---|
file | binary | File CSV o JSON |
format | csv | json | Formato del file |
sendWelcomeEmail | boolean | Invia email di benvenuto ai nuovi utenti (default: false) |
Formato CSV (la prima riga è l’intestazione):
email,firstName,lastName,username,password,roles
[email protected],Alice,Rossi,alice,,viewer
[email protected],Roberto,Bianchi,bob,TempPass123,editorFormato JSON:
[
{
"email": "[email protected]",
"firstName": "Alice",
"lastName": "Rossi",
"roles": ["viewer"]
}
]Risposta di successo (job creato)
{
"ok": true,
"data": {
"jobId": "import_xyz789",
"status": "pending",
"totalRows": 142,
"createdAt": "2025-02-18T10:00:00Z"
}
}/api/users/importRequires: manage:usersElenca tutti i job di importazione per il tenant corrente, ordinati per data di creazione decrescente.
Risposta di successo
{
"ok": true,
"data": {
"data": [
{
"id": "import_xyz789",
"fileName": "utenti-2025-02.csv",
"format": "csv",
"status": "completed",
"totalRows": 142,
"processedRows": 142,
"successCount": 140,
"errorCount": 2,
"createdAt": "2025-02-18T10:00:00Z",
"completedAt": "2025-02-18T10:01:34Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 5, "totalPages": 1 }
}
}/api/users/import/[id]Requires: manage:usersOttieni lo stato corrente e i dettagli degli errori di un job di importazione.
Risposta di successo
{
"ok": true,
"data": {
"id": "import_xyz789",
"status": "completed",
"totalRows": 142,
"processedRows": 142,
"successCount": 140,
"errorCount": 2,
"errors": [
{
"row": 45,
"email": "cattiva@",
"error": "Indirizzo email non valido"
},
{
"row": 98,
"email": "[email protected]",
"error": "Email già esistente"
}
]
}
}Stati del job di importazione: pending, processing, completed, failed, partial.
Esportazione Massiva
/api/users/exportRequires: manage:usersAvvia un’esportazione utenti. L’esportazione viene eseguita in modo asincrono. Effettua il polling su GET /api/users/export per trovare il job, poi scarica usando GET /api/users/export/[id]/download una volta che lo stato è completed.
Corpo della richiesta
{
"format": "csv"
}format è "csv" o "json".
Risposta di successo
{
"ok": true,
"data": {
"id": "export_abc123",
"status": "pending",
"format": "csv",
"createdAt": "2025-02-18T11:00:00Z"
}
}/api/users/exportRequires: manage:usersElenca tutti i job di esportazione.
/api/users/export/[id]/downloadRequires: manage:usersScarica il file di esportazione una volta che lo stato del job è completed. Restituisce il file binario grezzo con un header Content-Disposition appropriato.
I file di esportazione vengono memorizzati temporaneamente e scadono dopo 24 ore. Scaricali prontamente dopo il completamento del job.
Gestione Numero di Telefono
Questi endpoint consentono agli utenti autenticati di gestire il proprio numero di telefono. Non è richiesto alcun permesso speciale oltre a un access token valido.
/api/user/phone/setRequires: authenticated userImposta o aggiorna il numero di telefono dell’utente autenticato. Dopo l’impostazione, il numero deve essere verificato usando POST /api/user/phone/verify. Viene inviato un SMS OTP al numero fornito.
Corpo della richiesta
{
"phoneNumber": "+39021234567"
}Il numero di telefono deve essere in formato E.164 (formato internazionale con prefisso paese).
Risposta di successo
{
"ok": true,
"data": {
"sent": true,
"phoneNumber": "+39021234567"
}
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
INVALID_PHONE | 400 | Il numero non è in formato E.164 |
PHONE_TAKEN | 409 | Il numero è già associato a un altro account |
SMS_RATE_LIMITED | 429 | Troppe richieste SMS (max 5 all’ora) |
/api/user/phone/verifyRequires: authenticated userVerifica il numero di telefono con il codice OTP ricevuto via SMS. In caso di successo, phoneNumberVerified viene impostato a true sull’account utente.
Corpo della richiesta
{
"code": "482910"
}Risposta di successo
{
"ok": true,
"data": { "verified": true }
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
INVALID_OTP | 400 | Il codice è errato |
OTP_EXPIRED | 400 | Il codice è scaduto (TTL: 10 minuti) |
MAX_ATTEMPTS | 400 | Superati i massimi tentativi di verifica |
Autenticazione a Due Fattori
/api/user/2fa/sms/enableRequires: authenticated userAbilita SMS OTP come metodo 2FA per l’utente autenticato. Richiede un numero di telefono verificato. Viene inviato un OTP per confermare che il telefono può ricevere codici prima dell’abilitazione.
Corpo della richiesta
{
"code": "123456"
}Fornisci l’OTP inviato al numero di telefono verificato dell’utente.
Risposta di successo
{
"ok": true,
"data": { "smsEnabled": true }
}Codici di errore
| Codice | HTTP | Descrizione |
|---|---|---|
PHONE_NOT_VERIFIED | 400 | L’utente non ha un numero di telefono verificato |
INVALID_OTP | 400 | Il codice di conferma è errato |
/api/user/2fa/webauthn/enableRequires: authenticated userAvvia la cerimonia di registrazione WebAuthn passkey per abilitare WebAuthn come metodo 2FA. Restituisce una sfida di registrazione. Il client deve completare la cerimonia usando l’API WebAuthn del browser e inviare l’AuthenticatorAttestationResponse a POST /api/user/2fa/webauthn/challenge.
Richiesta: Nessun corpo richiesto.
Risposta di successo (opzioni di registrazione)
{
"ok": true,
"data": {
"challenge": "sfida-base64url",
"rp": { "name": "Auris", "id": "api.altovar.net" },
"user": {
"id": "id-utente-base64url",
"name": "[email protected]",
"displayName": "Alice Rossi"
},
"pubKeyCredParams": [{ "type": "public-key", "alg": -7 }],
"timeout": 60000,
"attestation": "none"
}
}Usa la libreria @simplewebauthn/browser per gestire questa sfida nel browser.
Pagine Correlate
- Gestione degli Utenti — Guida alla gestione del ciclo di vita degli utenti
- Importazione ed Esportazione — Migrazione massiva utenti tramite CSV/JSON
- SCIM 2.0 Provisioning — Provisioning automatico degli utenti
- Utenti e Ruoli — Gestisci gli utenti dalla Console
- API Importazione ed Esportazione Utenti — Endpoint di importazione ed esportazione massiva