Invitations
POST /api/auth/admin/create-user oblige un administrateur à choisir le mot de passe du nouvel utilisateur et ne lui envoie rien — praticable pour un script, inutilisable pour accueillir un client. Le flux d'invitation comble cette lacune : l'administrateur fournit { email, name, role } sans mot de passe, Sovrium envoie par e-mail un lien à usage unique, et l'invité définit son propre mot de passe puis atterrit dans une session authentifiée.
auth:
strategies:
- type: emailAndPassword
invitationTokenExpiry: '72h' # default; accepts '30s' / '15m' / '72h' / '7d' / ms
emailTemplates:
invitation:
subject: 'You are invited to join, $name'
text: |
Hi $name,
$inviterName invited you to join.
Set your password: $url
This invitation expires in 72 hours.Les deux points de terminaison
| Point de terminaison | Comportement |
|---|---|
POST /api/auth/admin/invite-user |
Accepte { email, name, role } (sans mot de passe). Renvoie 200 avec { user, invitationSent: true }. 401 si l'appelant n'est pas authentifié et 404 s'il n'a pas le droit d'inviter ce rôle — jamais 403, afin que le point de terminaison ne divulgue rien ; 400 pour une saisie invalide ; 422 lorsque l'e-mail correspond déjà à un utilisateur entièrement intégré. |
POST /api/auth/admin/accept-invitation |
Sous-tend la page publique /accept-invitation?token=.... L'invité définit un mot de passe et atterrit authentifié. 400 pour un jeton invalide, 410 pour un jeton expiré. |
Les jetons réutilisent la table auth.verification (la même forme que Better Auth emploie pour la réinitialisation de mot de passe), expirent après invitationTokenExpiry — 72h par défaut — et sont à usage unique, consommés à la première acceptation réussie. Un rejeu est rejeté plutôt que de ré-intégrer silencieusement.
Le corps de l'e-mail est rendu à partir du modèle invitation et substitue $name, $url, $email et $inviterName.
allowSignUp: false ne bloque pas les invitations. Fermer l'auto-inscription publique est précisément le moment où vous avez besoin de ce flux. La création d'utilisateur pilotée par un administrateur reste disponible dès que l'authentification est configurée — voir Contrôle de l'inscription.
Invitations déléguées
Par défaut, seul le rôle équivalent administrateur peut inviter. Un rôle qui déclare canInvite: true le peut également, sans devenir équivalent administrateur pour autant :
auth:
roles:
- name: engineer
level: 80
- name: customer-admin
level: 40
canInvite: true
- name: customer-member
level: 20
scopeTables:
- clientscustomer-admin peut désormais intégrer ses propres collègues. Trois limites accompagnent cette autorisation, et aucune n'est configurable :
| Limite | Effet |
|---|---|
| Le plafond de niveau tient | Le level du rôle invité doit être inférieur ou égal à celui de l'invitant. customer-admin peut inviter customer-member ou un pair, jamais engineer. |
| Les rôles de rang administrateur sont exclus | Un rôle d'exploitation qui atteint le tableau de bord d'administration ne peut jamais être invité, quels que soient les niveaux. |
| Les locataires ne s'élargissent pas | La personne invitée hérite des lignes de portée de l'invitant, et de rien d'autre — un invitant ne peut donc transmettre qu'un accès qu'il détient déjà. |
Une invitation refusée répond 404, jamais 403 : l'appelant n'apprend donc rien sur les rôles existants.
L'autorisation couvre l'émission, pas la liste des invitations. canInvite ouvre POST /api/auth/admin/invite-user, et rien d'autre. Lister, relancer et révoquer les invitations restent réservés à l'équivalent administrateur et répondent 404 à un appelant canInvite — y compris la page Invitations de la console d'administration. Ces points de terminaison parcourent toutes les invitations de l'application : un appelant limité à un locataire y verrait les personnes invitées par les autres. 200 à l'invitation et 404 à la liste, pour la même personne, est la forme voulue.
Attribution de rôle
Sovrium fournit trois rôles par défaut — admin, member, viewer — de niveaux hiérarchiques 80, 40 et 10, et accepte des rôles personnalisés déclarés dans le bloc auth.
Une invitation porte un role explicite. Lorsqu'aucun n'est fourni à la création, un nouvel utilisateur reçoit auth.defaultRole, qui lui-même retombe sur member :
auth:
strategies:
- type: emailAndPassword
defaultRole: viewer
roles:
- name: editor
description: Can edit content
level: 30defaultRole est validé contre les rôles intégrés plus vos roles[] déclarés : une faute de frappe échoue donc à sovrium validate au lieu de n'attribuer discrètement rien. Le premier administrateur d'amorçage est toujours créé avec le rôle admin et une adresse vérifiée, quel que soit defaultRole.
Les rôles pilotent chaque décision d'autorisation de la plateforme : les permissions de table, l'accès par champ, l'accès aux pages et l'API d'administration elle-même. Un rôle peut être changé après coup via POST /api/auth/admin/set-role.
Depuis la console
Tout le cycle de vie est également disponible dans la console d'administration : un opérateur n'a donc jamais besoin de passer par l'API pour intégrer quelqu'un.
L'annuaire des comptes, à /_admin/users, porte une commande Invite qui ouvre la page Invitations, à /_admin/users/invitations. Vous y émettez une invitation, voyez celles encore en attente, en renvoyez une, et en révoquez une qui ne devrait pas être acceptée.
C'est une page sœur plutôt qu'un panneau de l'annuaire, pour une raison qui mérite d'être connue : invite-user crée immédiatement la ligne du compte et n'envoie le lien qu'ensuite, si bien qu'une personne invitée mais n'ayant pas encore accepté figure déjà dans l'annuaire. Afficher la liste des invitations en attente à côté de cette grille placerait la même adresse dans deux tableaux voulant dire deux choses différentes — « ce compte existe » et « cette invitation est en attente » — sans moyen de savoir à quelle ligne une commande se rapporte.
Le sélecteur de rôle propose tous les rôles que votre application peut attribuer, et pas seulement les trois intégrés : les options sont le même ensemble que celui accepté par le point de terminaison d'invitation, donc un editor ou un reviewer personnalisé déclaré sous auth.roles[] y figure. Un sélecteur plus étroit que cette limite masquerait des rôles réellement utilisés par l'application — sur une application dont les rôles sont entièrement personnalisés, les rôles intégrés n'ont aucun membre en commun avec eux — et un sélecteur plus large proposerait une valeur que le point de terminaison refusera à coup sûr.
La console est en anglais. /_admin se situe hors de l'espace de noms des langues, et aucune surface de la console n'est traduite.
Invitation ou create-user
| Vous voulez | Utilisez |
|---|---|
| Qu'un client choisisse son propre mot de passe | invite-user — il reçoit un lien et ne voit jamais un secret défini par autrui. |
| Un compte de service ou d'amorçage, sans boîte e-mail | create-user — vous définissez le mot de passe, rien n'est envoyé. |
| Accueillir alors que SMTP n'est pas configuré | create-user — un e-mail d'invitation ne serait jamais délivré. |
L'accueil est découplé de l'attribution d'accès — quand c'est un administrateur qui invite. Un invitant équivalent administrateur crée le compte sans accorder aucune portée de locataire ; relier la personne aux données qu'elle peut atteindre est une étape distincte via l'API des enregistrements, si bien que vous pouvez inviter d'abord et attribuer ensuite, ou l'inverse. Un invitant canInvite fait exception : la personne invitée hérite des lignes de portée de cet invitant, car voir quelqu'un limité à un locataire intégrer un collègue dans un locataire qu'il ne partage pas serait le résultat surprenant. Voir Affectations et gardes d'atterrissage.
Pages connexes
- Gestion des utilisateurs — amorçage administrateur et API create-user.
- Contrôle de l'inscription —
allowSignUpetinvitationTokenExpiry. - Rôles & RBAC — le modèle de rôle complet et les permissions par champ.
- Modèles d'e-mail — l'objet et le corps de l'e-mail
invitation. - Affectations et gardes d'atterrissage — accorder à un utilisateur sa portée de locataire.
Dernière mise à jour 1 septembre 2026
Cette documentation a été rédigée avec de l'IA : des erreurs ou du contenu obsolète sont donc possibles. Sovrium est en bêta. Les contributions et corrections sont les bienvenues.