Skip to Content

Écrire des Actions Personnalisées

Les Actions sont des fonctions JavaScript personnalisées qui s’exécutent à des points spécifiques du pipeline d’authentification Auris. Elles permettent d’étendre le comportement de la plateforme sans fork ou modification d’Auris — ajoute des claims personnalisés aux tokens, bloque des connexions en fonction de données externes, appelle des webhooks, applique des règles métier ou intègre des services tiers.

Quand utiliser les Actions vs autres points d’extension

MécanismeAdapté pour
ActionsLogique devant s’exécuter de façon synchrone pendant le flux auth (bloquer une connexion, ajouter des claims, modifier les metadata utilisateur)
Custom ClaimsEnrichissement de token statique ou basé sur des attributs ne nécessitant pas d’appels externes ou de logique conditionnelle
WebhookNotifications asynchrones après que les événements se produisent (audit logging, analytics, alertes Slack)

L’Environnement Sandbox

Les Actions s’exécutent dans une sandbox JavaScript restreinte.

APIs Disponibles

APINotes
fetch()Effectuer des requêtes HTTP vers des services externes. API Fetch complète.
JSONJSON.parse() et JSON.stringify()
DateConstruction et manipulation de dates
MathOpérations mathématiques
console.log()La sortie est capturée et visible dans les logs d’action
Promise, async/awaitLe code asynchrone est entièrement supporté
URL, URLSearchParamsParsing et construction d’URL
crypto.randomUUID()Génération d’UUID

APIs Bloquées

BloquéRaison
require(), importPas d’accès au système de modules
processPas d’accès aux variables d’environnement ou aux infos de processus
global, globalThisPas d’accès au scope global
fs, child_processPas de système de fichiers ou de lancement de processus

Les Actions ont un timeout d’exécution configurable (défaut : 5 secondes, max : 30 secondes). Si une action dépasse le timeout, elle est terminée et le comportement de fallback configuré s’applique (autoriser ou refuser la requête).


Types de Déclencheurs

DéclencheurQuand il s’activeUsages courants
pre-loginAvant la vérification des credentialsBloquer les connexions par domaine e-mail, vérifier des blocklists externes
post-loginAprès une authentification réussie, avant l’émission du tokenAjouter des claims personnalisés, synchroniser avec des systèmes externes
pre-signupAvant la création d’un nouvel utilisateurValider le domaine e-mail, vérifier les exigences d’invitation
post-signupAprès la création d’un nouvel utilisateurEnvoyer un webhook de bienvenue, assigner à une organisation
post-change-passwordAprès un changement de mot de passeNotifier des systèmes externes, invalider des sessions en cache
pre-m2m-tokenAvant l’émission d’un token M2MRestreindre les scopes, valider le client par rapport à des règles externes

L’Objet Context

Chaque action reçoit un objet context avec des informations sur la requête courante :

{ user: { id: 'user-123', email: '[email protected]', username: 'alice', firstName: 'Alice', lastName: 'Smith', roles: ['editor', 'viewer'], metadata: { plan: 'pro', company: 'Acme' }, }, request: { ip: '203.0.113.42', userAgent: 'Mozilla/5.0...', geoip: { country: 'FR', city: 'Paris' }, }, application: { id: 'app-456', name: 'Dashboard', type: 'WEB' }, tenant: { id: 'tenant-789', name: 'acme-corp' }, }

Le Type de Retour ActionResult

interface ActionResult { allow: boolean // true = continuer, false = bloquer la requête message?: string // Message d'erreur affiché à l'utilisateur si allow=false claims?: Record<string, any> // Claims personnalisés à ajouter au token metadata?: Record<string, any> // Metadata à définir sur l'enregistrement utilisateur }

Exemples Pratiques

Bloquer les connexions par domaine e-mail

// Déclencheur : pre-login const blockedDomains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com'] const domain = context.user.email.split('@')[1] if (blockedDomains.includes(domain)) { return { allow: false, message: 'Les adresses e-mail personnelles ne sont pas autorisées. Utilise ton e-mail professionnel.', } } return { allow: true }

Ajouter des claims personnalisés selon les rôles

// Déclencheur : post-login const plan = context.user.metadata?.plan || 'free' const featureFlags = { free: { maxProjects: 3, analytics: false, exportEnabled: false }, pro: { maxProjects: 50, analytics: true, exportEnabled: true }, enterprise: { maxProjects: -1, analytics: true, exportEnabled: true }, } return { allow: true, claims: { plan, features: featureFlags[plan] || featureFlags.free, 'https://myapp.com/roles': context.user.roles, }, }

Enregistrer des événements d’authentification sur un webhook externe

// Déclencheur : post-login try { await fetch('https://hooks.example.com/auth-events', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ event: 'user.login', userId: context.user.id, email: context.user.email, ip: context.request.ip, country: context.request.geoip?.country, timestamp: new Date().toISOString(), }), }) } catch (err) { // Non critique -- enregistrer mais ne pas bloquer la connexion console.log('Webhook échoué :', err.message) } return { allow: true }

Restriction géographique de connexion

// Déclencheur : pre-login const allowedCountries = ['FR', 'BE', 'CH', 'DE', 'ES', 'GB', 'US'] const country = context.request.geoip?.country if (country && !allowedCountries.includes(country)) { return { allow: false, reason: 'La connexion n\'est pas disponible depuis ta localisation actuelle.', } } return { allow: true }

Ordre d’Exécution

Quand plusieurs actions sont configurées pour le même déclencheur, elles s’exécutent dans l’ordre défini par le champ order (ascendant). Les claims et metadata de toutes les actions sont fusionnés. Si deux actions définissent la même clé de claim, la dernière action dans l’ordre gagne.

Si une action retourne allow: false, tout le pipeline est interrompu et la requête refusée.


L’Éditeur Blueprint Visuel

Pour les équipes qui préfèrent une approche visuelle, Auris fournit un éditeur Blueprint — un constructeur de règles visuel basé sur des nœuds.

Type de NœudCouleurObjectif
TriggerOrangeLe point d’entrée
ConditionCyanVérifie un champ par rapport à une valeur
Logic GateVioletCombine des conditions avec AND/OR
DenyRoseBloque la requête avec un message d’erreur
Set ClaimsBleuAjoute des paires clé-valeur au token
Set MetadataÉmeraudeMet à jour les metadata utilisateur
LogVertÉcrit dans les logs d’action

Débogage des Actions

Logs d’Action

Chaque exécution d’action est enregistrée. Affiche les logs dans Console → Actions → [Nom de l’Action] → onglet Logs.

Utilisation de console.log

console.log('Rôles utilisateur :', JSON.stringify(context.user.roles)) console.log('IP de la requête :', context.request.ip) // Cette sortie apparaît dans l'onglet Logs de l'action return { allow: true }

Gestion des Erreurs

Si une action lance une erreur non gérée, le comportement dépend du paramètre mode de fallback de l’action :

Mode de FallbackComportement
allow (défaut)La requête continue. L’erreur est enregistrée.
denyLa requête est bloquée avec un message d’erreur générique.

Conseils de Performance

  1. Garde les actions rapides — Vise moins de 100ms de temps d’exécution.
  2. Utilise try/catch pour les appels externes — Ne laisse jamais une API externe non critique bloquer une connexion.
  3. Évite les appels externes séquentiels — Utilise Promise.all() pour les exécuter en parallèle.
  4. Définis des timeouts appropriés — Utilise AbortController avec fetch().
const controller = new AbortController() setTimeout(() => controller.abort(), 3000) // timeout de 3 secondes const response = await fetch('https://slow-api.example.com/check', { signal: controller.signal, })

Permissions Requises

OpérationPermission
Visualiser les actionsview:actions
Créer, modifier, supprimer les actionsmanage:actions
Visualiser les logs d’actionview:actions

Guides Associés