Skip to Content

API Utilisateurs

L’Users API fournit la gestion complète du cycle de vie des comptes utilisateur au sein d’un tenant : création, lecture, mise à jour, désactivation et suppression des utilisateurs ; assignation des rôles ; import et export massif des utilisateurs ; et gestion des numéros de téléphone et des paramètres d’authentification à deux facteurs pour les comptes individuels.

Tous les endpoints de cette section nécessitent le header x-tenant et, sauf indication contraire, nécessitent la permission manage:users.


Gestion des Utilisateurs

GET/api/usersRequires: manage:users

Liste tous les utilisateurs du tenant. Supporte la pagination et le filtrage par rôle, statut du compte et requête de recherche. Retourne des objets utilisateur avec des informations de résumé (n’inclut pas le statut 2FA ou les détails de session — utilise l’endpoint utilisateur individuel pour ceux-là).

Paramètres de query

ParamètreTypeDescription
pageintegerNuméro de page (défaut : 1)
limitintegerÉléments par page (défaut : 20, max : 100)
searchstringRecherche full-text sur email, username, firstName, lastName
rolestringFiltre par nom de rôle
statusactive | disabled | lockedFiltre par statut du compte

Réponse de succès

{ "ok": true, "data": { "data": [ { "id": "usr_abc123", "email": "[email protected]", "username": "alice", "firstName": "Alice", "lastName": "Dupont", "enabled": true, "emailVerified": true, "createdAt": "2025-01-15T10:30:00Z", "roles": ["editor", "viewer"] } ], "pagination": { "page": 1, "limit": 20, "total": 87, "totalPages": 5 } } }

POST/api/usersRequires: manage:users

Crée un nouveau compte utilisateur dans le tenant. L’utilisateur est créé à la fois dans la base de données Auris et dans le realm Keycloak sous-jacent. Si password est omis, le compte est créé sans mot de passe (l’utilisateur doit en définir un via un magic link ou le flux de réinitialisation de mot de passe).

Corps de la requête

{ "email": "[email protected]", "username": "bob", "firstName": "Robert", "lastName": "Martin", "password": "MotDePasseInitial123", "roles": ["viewer"], "enabled": true }

Tous les champs sauf email sont optionnels.

Réponse de succès

{ "ok": true, "data": { "id": "usr_def456", "email": "[email protected]", "username": "bob", "firstName": "Robert", "lastName": "Martin", "enabled": true, "emailVerified": false, "createdAt": "2025-02-18T09:00:00Z", "roles": ["viewer"] } }

Codes d’erreur

CodeHTTPDescription
EMAIL_TAKEN409Un utilisateur avec cet email existe déjà dans le tenant
USERNAME_TAKEN409Le nom d’utilisateur est déjà utilisé
VALIDATION_ERROR400Le corps de la requête n’a pas passé la validation du schéma

GET/api/users/[id]Requires: manage:users

Récupère un seul utilisateur par son ID. Retourne les détails complets de l’utilisateur incluant les appartenances aux rôles, le statut 2FA, le numéro de téléphone, les appartenances aux groupes et les informations du dernier login.

Réponse de succès

{ "ok": true, "data": { "id": "usr_abc123", "email": "[email protected]", "username": "alice", "firstName": "Alice", "lastName": "Dupont", "enabled": true, "emailVerified": true, "phoneNumber": "+33 1 23 45 67 89", "phoneNumberVerified": true, "createdAt": "2025-01-15T10:30:00Z", "lastLoginAt": "2025-02-17T14:22:00Z", "roles": ["editor", "viewer"], "twoFactor": { "totpEnabled": true, "smsEnabled": false, "webauthnEnabled": false } } }

Codes d’erreur

CodeHTTPDescription
NOT_FOUND404L’utilisateur n’existe pas dans ce tenant

PUT/api/users/[id]Requires: manage:users

Met à jour les champs du profil d’un utilisateur. Tous les champs sont optionnels — seuls les champs fournis sont mis à jour. Pour désactiver un utilisateur sans le supprimer, définis enabled: false.

Corps de la requête

{ "firstName": "Alicia", "lastName": "Dupont-Martin", "enabled": false }

Réponse de succès

{ "ok": true, "data": { "id": "usr_abc123", "email": "[email protected]", "firstName": "Alicia", "lastName": "Dupont-Martin", "enabled": false } }

DELETE/api/users/[id]Requires: manage:users

Soft-delete d’un utilisateur. Le compte utilisateur est désactivé et marqué comme supprimé dans la base de données Auris, et son compte Keycloak est retiré. Les sessions actives sont invalidées immédiatement.

Le soft-delete est irréversible via l’API. L’enregistrement utilisateur est conservé dans la base de données pour la cohérence du log d’audit mais ne peut pas être récupéré ou accessible. Utilise enabled: false via PUT /api/users/[id] si tu souhaites désactiver temporairement sans suppression.

Réponse de succès

{ "ok": true, "data": { "deleted": true } }

Assignation des Rôles

GET/api/users/[id]/rolesRequires: manage:users

Liste tous les rôles actuellement assignés à un utilisateur.

Réponse de succès

{ "ok": true, "data": [ { "id": "role_123", "name": "editor", "description": "Peut créer et modifier du contenu", "color": "#3b82f6" } ] }

POST/api/users/[id]/rolesRequires: manage:users

Assigne un rôle à un utilisateur. Le rôle doit exister dans le tenant. Assigner le même rôle deux fois est un no-op (idempotent).

Corps de la requête

{ "roleId": "role_123" }

Réponse de succès

{ "ok": true, "data": { "assigned": true } }

Codes d’erreur

CodeHTTPDescription
NOT_FOUND404Le rôle n’existe pas dans ce tenant
SELF_ROLE_CHANGE403Tu ne peux pas modifier tes propres rôles

DELETE/api/users/[id]/rolesRequires: manage:users

Retire un rôle d’un utilisateur. Retirer un rôle que l’utilisateur n’a pas est un no-op (idempotent).

Corps de la requête

{ "roleId": "role_123" }

Réponse de succès

{ "ok": true, "data": { "removed": true } }

Import Massif

POST/api/users/importRequires: manage:users

Importe des utilisateurs en masse depuis un fichier CSV ou JSON. L’import est exécuté de manière asynchrone — l’endpoint retourne immédiatement un job ID. Effectue un polling sur GET /api/users/import/[id] pour surveiller la progression.

Format de la requête : multipart/form-data

ChampTypeDescription
filebinaryFichier CSV ou JSON
formatcsv | jsonFormat du fichier
sendWelcomeEmailbooleanEnvoie un email de bienvenue aux nouveaux utilisateurs (défaut : false)

Format CSV (la première ligne est l’en-tête) :

email,firstName,lastName,username,password,roles [email protected],Alice,Dupont,alice,,viewer [email protected],Robert,Martin,bob,TempPass123,editor

Format JSON :

[ { "email": "[email protected]", "firstName": "Alice", "lastName": "Dupont", "roles": ["viewer"] } ]

Réponse de succès (job créé)

{ "ok": true, "data": { "jobId": "import_xyz789", "status": "pending", "totalRows": 142, "createdAt": "2025-02-18T10:00:00Z" } }

GET/api/users/importRequires: manage:users

Liste tous les jobs d’import pour le tenant courant, triés par date de création décroissante.

Réponse de succès

{ "ok": true, "data": { "data": [ { "id": "import_xyz789", "fileName": "utilisateurs-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 } } }

GET/api/users/import/[id]Requires: manage:users

Obtenir le statut courant et les détails des erreurs d’un job d’import.

Réponse de succès

{ "ok": true, "data": { "id": "import_xyz789", "status": "completed", "totalRows": 142, "processedRows": 142, "successCount": 140, "errorCount": 2, "errors": [ { "row": 45, "email": "mauvais@", "error": "Adresse email invalide" }, { "row": 98, "email": "[email protected]", "error": "Email déjà existant" } ] } }

Statuts du job d’import : pending, processing, completed, failed, partial.


Export Massif

POST/api/users/exportRequires: manage:users

Lance un export utilisateurs. L’export est exécuté de manière asynchrone. Effectue un polling sur GET /api/users/export pour trouver le job, puis télécharge avec GET /api/users/export/[id]/download une fois le statut completed.

Corps de la requête

{ "format": "csv" }

format est "csv" ou "json".

Réponse de succès

{ "ok": true, "data": { "id": "export_abc123", "status": "pending", "format": "csv", "createdAt": "2025-02-18T11:00:00Z" } }

GET/api/users/exportRequires: manage:users

Liste tous les jobs d’export.


GET/api/users/export/[id]/downloadRequires: manage:users

Télécharge le fichier d’export une fois que le statut du job est completed. Retourne le fichier binaire brut avec un header Content-Disposition approprié.

Les fichiers d’export sont stockés temporairement et expirent après 24 heures. Télécharge-les rapidement après la complétion du job.


Gestion du Numéro de Téléphone

Ces endpoints permettent aux utilisateurs authentifiés de gérer leur propre numéro de téléphone. Aucune permission spéciale n’est requise au-delà d’un access token valide.

POST/api/user/phone/setRequires: authenticated user

Définit ou met à jour le numéro de téléphone de l’utilisateur authentifié. Après la définition, le numéro doit être vérifié en utilisant POST /api/user/phone/verify. Un SMS OTP est envoyé au numéro fourni.

Corps de la requête

{ "phoneNumber": "+33123456789" }

Le numéro de téléphone doit être au format E.164 (format international avec indicatif pays).

Réponse de succès

{ "ok": true, "data": { "sent": true, "phoneNumber": "+33123456789" } }

Codes d’erreur

CodeHTTPDescription
INVALID_PHONE400Le numéro n’est pas au format E.164
PHONE_TAKEN409Le numéro est déjà associé à un autre compte
SMS_RATE_LIMITED429Trop de demandes SMS (max 5 par heure)

POST/api/user/phone/verifyRequires: authenticated user

Vérifie le numéro de téléphone avec le code OTP reçu par SMS. En cas de succès, phoneNumberVerified est défini à true sur le compte utilisateur.

Corps de la requête

{ "code": "482910" }

Réponse de succès

{ "ok": true, "data": { "verified": true } }

Codes d’erreur

CodeHTTPDescription
INVALID_OTP400Le code est incorrect
OTP_EXPIRED400Le code est expiré (TTL : 10 minutes)
MAX_ATTEMPTS400Tentatives de vérification maximales dépassées

Authentification à Deux Facteurs

POST/api/user/2fa/sms/enableRequires: authenticated user

Active SMS OTP comme méthode 2FA pour l’utilisateur authentifié. Nécessite un numéro de téléphone vérifié. Un OTP est envoyé pour confirmer que le téléphone peut recevoir des codes avant l’activation.

Corps de la requête

{ "code": "123456" }

Fournis l’OTP envoyé au numéro de téléphone vérifié de l’utilisateur.

Réponse de succès

{ "ok": true, "data": { "smsEnabled": true } }

Codes d’erreur

CodeHTTPDescription
PHONE_NOT_VERIFIED400L’utilisateur n’a pas de numéro de téléphone vérifié
INVALID_OTP400Le code de confirmation est incorrect

POST/api/user/2fa/webauthn/enableRequires: authenticated user

Initie la cérémonie d’enregistrement WebAuthn passkey pour activer WebAuthn comme méthode 2FA. Retourne un challenge d’enregistrement. Le client doit compléter la cérémonie en utilisant l’API WebAuthn du navigateur et envoyer l’AuthenticatorAttestationResponse à POST /api/user/2fa/webauthn/challenge.

Requête : Aucun corps requis.

Réponse de succès (options d’enregistrement)

{ "ok": true, "data": { "challenge": "challenge-base64url", "rp": { "name": "Auris", "id": "api.altovar.net" }, "user": { "id": "id-utilisateur-base64url", "name": "[email protected]", "displayName": "Alice Dupont" }, "pubKeyCredParams": [{ "type": "public-key", "alg": -7 }], "timeout": 60000, "attestation": "none" } }

Utilise la bibliothèque @simplewebauthn/browser pour gérer ce challenge dans le navigateur.


Pages Associées