Skip to Content

Scrivere Actions Personalizzate

Le Actions sono funzioni JavaScript personalizzate che vengono eseguite in punti specifici della pipeline di autenticazione Auris. Consentono di estendere il comportamento della piattaforma senza fare fork o modificare Auris — aggiungi claim personalizzati ai token, blocca i login in base a dati esterni, chiama webhook, applica regole di business o integra servizi di terze parti.

Quando usare Actions vs altri punti di estensione

MeccanismoAdatto Per
ActionsLogica che deve essere eseguita in modo sincrono durante il flusso auth (blocca un login, aggiungi claim, modifica metadata utente)
Custom ClaimsArricchimento del token statico o basato su attributi che non richiede chiamate esterne o logica condizionale
WebhookNotifiche asincrone dopo che gli eventi si verificano (audit logging, analytics, alert Slack)

L’Ambiente Sandbox

Le Actions vengono eseguite in una sandbox JavaScript ristretta.

API Disponibili

APINote
fetch()Fare richieste HTTP a servizi esterni. Fetch API completa.
JSONJSON.parse() e JSON.stringify()
DateCostruzione e manipolazione di date
MathOperazioni matematiche
console.log()L’output viene catturato e visibile nei log delle action
Promise, async/awaitIl codice asincrono è completamente supportato
URL, URLSearchParamsParsing e costruzione URL
crypto.randomUUID()Generazione UUID

API Bloccate

BloccatoMotivo
require(), importNessun accesso al sistema di moduli
processNessun accesso alle variabili d’ambiente o alle info di processo
global, globalThisNessun accesso allo scope globale
fs, child_processNessun filesystem o avvio processi

Le Actions hanno un timeout di esecuzione configurabile (default: 5 secondi, max: 30 secondi). Se un’action supera il timeout, viene terminata e si applica il comportamento di fallimento configurato (consenti o nega la richiesta).


Tipi di Trigger

TriggerQuando si AttivaUsi Comuni
pre-loginPrima della verifica delle credenzialiBlocca login per dominio email, controlla blocklist esterne
post-loginDopo l’autenticazione riuscita, prima dell’emissione del tokenAggiungi claim personalizzati, sincronizza con sistemi esterni
pre-signupPrima della creazione di un nuovo utenteValida il dominio email, controlla i requisiti di invito
post-signupDopo la creazione di un nuovo utenteInvia webhook di benvenuto, assegna all’organizzazione
post-change-passwordDopo un cambio passwordNotifica sistemi esterni, invalida sessioni cached
pre-m2m-tokenPrima dell’emissione di un token M2MLimita scope, valida client contro regole esterne

L’Oggetto Context

Ogni action riceve un oggetto context con informazioni sulla richiesta corrente:

{ 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: 'IT', city: 'Milan' }, }, application: { id: 'app-456', name: 'Dashboard', type: 'WEB' }, tenant: { id: 'tenant-789', name: 'acme-corp' }, }

Il Tipo di Ritorno ActionResult

interface ActionResult { allow: boolean // true = procedi, false = blocca la richiesta message?: string // Messaggio di errore mostrato all'utente se allow=false claims?: Record<string, any> // Claim personalizzati da aggiungere al token metadata?: Record<string, any> // Metadata da impostare sul record utente }

Esempi Pratici

Blocca login per dominio email

// Trigger: 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: 'Gli indirizzi email personali non sono consentiti. Usa la tua email aziendale.', } } return { allow: true }

Aggiungi claim personalizzati in base ai ruoli

// Trigger: 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, }, }

Registra eventi di autenticazione su un webhook esterno

// Trigger: 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 critico -- registra ma non bloccare il login console.log('Webhook fallito:', err.message) } return { allow: true }

Restrizione geografica del login

// Trigger: pre-login const allowedCountries = ['IT', 'DE', 'FR', 'ES', 'GB', 'US'] const country = context.request.geoip?.country if (country && !allowedCountries.includes(country)) { return { allow: false, reason: 'Il login non è disponibile dalla tua posizione attuale.', } } return { allow: true }

Ordine di Esecuzione

Quando più actions sono configurate per lo stesso trigger, vengono eseguite nell’ordine definito dal campo order (ascendente). I claim e i metadata di tutte le actions vengono uniti. Se due actions impostano la stessa chiave del claim, l’ultima action nell’ordine vince.

Se una qualsiasi action restituisce allow: false, l’intera pipeline viene interrotta e la richiesta negata.


L’Editor Blueprint Visuale

Per i team che preferiscono un approccio visuale, Auris fornisce un editor Blueprint — un costruttore di regole visuale basato su nodi.

Tipo di NodoColoreScopo
TriggerArancioneIl punto di ingresso
CondizioneCianoControlla un campo rispetto a un valore
Logic GateViolaCombina condizioni con AND/OR
DenyRosaBlocca la richiesta con un messaggio di errore
Set ClaimsBluAggiungi coppie chiave-valore al token
Set MetadataSmeraldoAggiorna i metadata utente
LogVerdeScrivi sui log delle action

Debug delle Actions

Log delle Action

Ogni esecuzione di action viene registrata. Visualizza i log in Console → Actions → [Nome Action] → tab Log.

Utilizzo di console.log

console.log('Ruoli utente:', JSON.stringify(context.user.roles)) console.log('IP richiesta:', context.request.ip) // Questo output appare nel tab Log dell'action return { allow: true }

Gestione degli Errori

Se un’action lancia un errore non gestito, il comportamento dipende dall’impostazione modalità di fallimento dell’action:

Modalità di FallimentoComportamento
allow (default)La richiesta procede. L’errore viene registrato.
denyLa richiesta viene bloccata con un messaggio di errore generico.

Consigli per le Performance

  1. Mantieni le actions veloci — Punta a meno di 100ms di tempo di esecuzione.
  2. Usa try/catch per le chiamate esterne — Non lasciare mai che un’API esterna non critica blocchi un login.
  3. Evita chiamate esterne sequenziali — Usa Promise.all() per eseguirle in parallelo.
  4. Imposta timeout appropriati — Usa AbortController con fetch().
const controller = new AbortController() setTimeout(() => controller.abort(), 3000) // 3 secondi di timeout const response = await fetch('https://slow-api.example.com/check', { signal: controller.signal, })

Permessi Richiesti

OperazionePermesso
Visualizza actionsview:actions
Crea, modifica, elimina actionsmanage:actions
Visualizza log actionview:actions

Guide Correlate