Un riquadro sicuro, l’accesso automatico per le tue persone, le persone e le notifiche sincronizzate con la tua piattaforma. Tutto quello che serve per integrarlo, con esempi pronti da copiare.
Omega Work si mette dentro il tuo gestionale come un modulo: le tue persone lavorano su progetti, attività e bacheche senza uscire dal tuo software, con il tuo colore, e senza un secondo accesso. Si fa a tre livelli, e ognuno aggiunge qualcosa al precedente:
Il riquadro. Incolli un <iframe> nella pagina e le persone entrano con email e password di Omega Work. Non serve scrivere codice sul server.
L’accesso automatico. Il tuo server chiede a Omega Work un biglietto per la persona collegata al tuo gestionale, e il riquadro si apre già dentro, con il suo account. Nessuna password da ricordare.
Il modulo completo. Il tuo gestionale crea e sospende le persone su Omega Work quando abiliti o togli il modulo, riceve le notifiche (per la sua campanella) con un webhook firmato, e può mandare avvisi nella Posta in arrivo di Omega Work.
Entra senza password · GIFIl colore e la forma del tuo gestionale · GIFLe notifiche nella tua campanella · GIF
Tutto si configura dal titolare dello spazio di lavoro: Console di amministrazione → Incorpora. Da lì escono la chiave pubblica del riquadro, le chiavi segrete per il server e il segreto del webhook.
L’indirizzo del riquadro è https://work.omegasuite.it/embed/<chiave pubblica>. La chiave pubblica sta nell’HTML di chiunque apra la pagina, e va bene così: da sola non apre niente. Servono le credenziali di una persona dello spazio (o un biglietto del tuo server), e il browser disegna il riquadro solo dentro i siti autorizzati.
sandbox: il riquadro non può spostare la tua pagina né aprire finestre senza un clic. Non togliere allow-same-origin (senza, Omega Work non può tenere la sessione) e non aggiungere allow-top-navigation.
Dentro il riquadro si lavora: attività, progetti, bacheche, obiettivi, persone. Amministrazione, abbonamento, integrazioni e chiavi si aprono in una scheda di Omega Work.
Per aprire una pagina precisa: ?to=/app/my-tasks, ?to=/app/project/42, ?to=/app/task/1234. Vale solo dentro /app.
Dagli l’altezza che vuoi: Omega Work riempie il riquadro e scorre al suo interno.
Il titolare sceglie l’aspetto di partenza dalla scheda Incorpora. Se lo permette (è acceso di serie), il tuo gestionale può cambiarlo dall’indirizzo del riquadro, dal biglietto dell’accesso automatico, o al volo con un messaggio.
Parametro
Valori
Effetto
theme
light · dark · system
Tema chiaro o scuro forzato, oppure quello del sistema della persona.
accent
158063 (esadecimale, senza #)
Il colore del tuo marchio su azioni principali, selezione e fuoco. Il testo sopra si scurisce da solo se il colore è chiaro.
hide
topbar,rail,sidebar,create,search,help,logout
Toglie le parti elencate: barra in alto, colonna delle sezioni, barra laterale, «Crea», ricerca, aiuto, «Esci».
chrome
none · minimal
none: solo il contenuto, senza shell. minimal: via sezioni e barra laterale, resta la barra in alto.
Il tuo server, con una chiave segreta (omw_sk_live_…, permesso sso), chiede un biglietto per la persona collegata al tuo gestionale. Il biglietto vale 60 secondi e una volta sola; il riquadro lo scambia con una sessione (8 ore al massimo, poi l’SDK ne chiede un altro senza che nessuno se ne accorga).
Browser→ GET /api/work-ticket →Il tuo server→ POST /tickets →Omega Work← biglietto ←Riquadro
// Il TUO backend. La chiave segreta sta in una variabile d'ambiente, mai nel browser.
app.get('/api/work-ticket', requireLogin, async (req, res) => {
const r = await fetch('https://work.omegasuite.it/api/embed/v1/tickets', {
method: 'POST',
headers: {
authorization: `Bearer ${process.env.OMEGA_WORK_SECRET}`,
'content-type': 'application/json',
},
body: JSON.stringify({ email: req.user.email }),
signal: AbortSignal.timeout(10_000),
});
if (!r.ok) return res.status(502).json({ error: 'omega_work_unavailable' });
const { ticket } = await r.json();
res.set('cache-control', 'no-store').json({ ticket });
});
Il biglietto arriva al riquadro in uno di tre modi, dal migliore:
L’SDK (fetchTicket): chiede il biglietto al tuo server, lo passa con un messaggio e ne chiede un altro quando la sessione scade. Non devi fare altro.
Il frammento: src="…/embed/CHIAVE_PUBBLICA_DEL_RIQUADRO#omw_ticket=omw_tk_…". Il frammento non viaggia nelle richieste, non finisce nei log né nel Referer, e Omega Work lo cancella appena lo legge. Non metterlo mai nella query (?ticket=).
Il messaggio: quando il riquadro manda omega-work:need-ticket, rispondi con iframe.contentWindow.postMessage({ type: 'omega-work:auth', ticket }, 'https://work.omegasuite.it').
Regole: la persona deve essere attiva nello spazio. Il titolare entra sempre con la sua password (si può cambiare dalla scheda), gli amministratori di serie sì. Con «solo accesso automatico» il modulo d’accesso con password sparisce dal riquadro, e ogni apertura chiede un biglietto nuovo: chi usa lo stesso computer dopo un collega non si ritrova nel suo account.
Con il permesso members:write il tuo gestionale tiene allineate le persone: quando abiliti il modulo a qualcuno, lo crea su Omega Work; quando glielo togli, lo sospende. L’operazione è idempotente: ripeterla non crea doppioni.
Dalla scheda Incorpora imposta l’indirizzo del tuo server e scegli gli eventi. Omega Work manda una POST nel formato Standard Webhooks, firmata con il segreto whsec_…: verificala sempre, e rifiuta le richieste più vecchie di 5 minuti.
// npm i standardwebhooks
import { Webhook } from 'standardwebhooks';
const wh = new Webhook(process.env.OMEGA_WORK_WEBHOOK_SECRET); // "whsec_…"
// Il corpo va letto GREZZO: la firma è sui byte esatti.
app.post('/omega-work/webhook', express.raw({ type: 'application/json' }), (req, res) => {
let evt;
try {
evt = wh.verify(req.body, req.headers); // controlla firma e orario (±5 min)
} catch {
return res.sendStatus(401);
}
// webhook-id è lo stesso nei nuovi tentativi: usalo per non fare due volte la stessa cosa.
if (evt.type === 'notification.created') {
const { recipient, notification, unread } = evt.data;
notificaNellaCampanella(recipient.email, notification.title ?? 'Nuova notifica su Omega Work', notification.path, unread);
}
res.sendStatus(204);
});
Evento
Quando
notification.created
Una persona riceve una notifica in Omega Work (assegnazioni, menzioni, commenti, scadenze…). Porta il numero di non lette.
member.provisioned
Una persona aggiunta o riattivata dall’API.
member.deactivated
Una persona sospesa dall’API.
session.started
Qualcuno entra nel riquadro (con la password o con l’accesso automatico).
webhook.test
Il bottone «Manda una prova» della scheda.
Nuovi tentativi se il tuo server non risponde 2xx: dopo 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h e 24 h. Il registro delle ultime consegne, con la risposta ricevuta, è nella scheda Incorpora; da lì si ripete una consegna a mano.
Dal tuo gestionale a Omega Work
curl -X POST https://work.omegasuite.it/api/embed/v1/members/mario.rossi%40tuaazienda.it/notifications \
-H "Authorization: Bearer $OMEGA_WORK_SECRET" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ordine-8812-confermato" \
-d '{"title":"Ordine 8812 confermato","text":"Il cliente ha firmato: puoi pianificare la consegna.","path":"/app/project/42"}'
# 201 { "id": 991, "created_at": "…" } — compare nella Posta in arrivo di Mario
Nel browser
A riquadro aperto arrivano anche omega-work:unread (il numero) e, se il titolare condivide il testo, omega-work:notification con titolo e frase: per un avviso a comparsa nel tuo gestionale.
Omega Work parla con la pagina che lo ospita con postMessage, solo verso le origini autorizzate. Dalla tua parte controlla sempreevent.origin === 'https://work.omegasuite.it' e event.source === iframe.contentWindow (l’SDK lo fa per te).
Da Omega Work
Dati
omega-work:ready
Aperto e collegato.
omega-work:navigate
path, title della pagina aperta.
omega-work:unread
count: notifiche non lette.
omega-work:notification
title, text, path (se il titolare condivide il testo).
omega-work:need-ticket
Serve un biglietto: rispondi con omega-work:auth.
omega-work:session-expired
La sessione è scaduta.
omega-work:signed-out
Si vede l’accesso.
omega-work:error
code, message (per esempio cookies_blocked).
Verso Omega Work
Dati
omega-work:auth
ticket
omega-work:set-theme
theme: light · dark · system
omega-work:set-accent
accent: "#rrggbb" o null
omega-work:set-chrome
topbar, rail, sidebar: true/false
omega-work:navigate-to
path: /app/…
Omega Work non accetta dal riquadro comandi che leggono o scrivono dati: per quello c’è l’API del server.
Base: https://work.omegasuite.it/api/embed/v1 · autenticazione Authorization: Bearer omw_sk_live_… · corpo JSON · solo dal tuo server (le richieste partite da un browser vengono rifiutate, e non c’è CORS).
Metodo e percorso
Permesso
Cosa fa
GET /me
—
Lo spazio, la chiave, il riquadro, i posti del piano.
GET /members
members:read
Le persone dello spazio.
GET /members/{email}
members:read
Una persona.
PUT /members/{email}
members:write
Aggiunge o riattiva (idempotente).
DELETE /members/{email}
members:write
Sospende.
POST /tickets
sso
Biglietto di accesso automatico (60 s, monouso).
GET /members/{email}/notifications
notifications:read
Non lette e ultime notifiche.
POST /members/{email}/notifications
notifications:write
Un avviso nella Posta in arrivo.
POST /webhooks/test
—
Un evento di prova al webhook.
Idempotency-Key sulle POST e PUT: la stessa richiesta ripetuta entro 24 ore riceve la stessa risposta (Idempotent-Replayed: true) senza rifarla; la stessa chiave con un corpo diverso risponde 422.
Ogni risposta porta X-Request-Id e RateLimit-Limit / RateLimit-Remaining / RateLimit-Reset.
La versione sta nel percorso (/v1): i cambiamenti che rompono qualcosa arrivano in una /v2, con almeno sei mesi di preavviso.
Content-Security-Policy: frame-ancestors con i soli siti autorizzati, su ogni pagina del riquadro: altrove non si disegna.
Sessione del riquadro separata da quella di work.omegasuite.it, in un cookie __Host-, Secure, HttpOnly, SameSite=None, Partitioned (CHIPS): vive solo dentro il tuo sito.
Nel riquadro non si amministra: console, abbonamento, integrazioni, chiavi e password stanno fuori.
Chiavi segrete con prefisso e cifre di controllo (riconoscibili dagli scanner di segreti), salvate solo come impronta, con permessi minimi, IP ammessi, scadenza, ultimo uso, revoca immediata.
Biglietti opachi, monouso, da 60 secondi, mai nella query dell’indirizzo.
Webhook firmati (Standard Webhooks), solo https, indirizzo controllato a ogni consegna (niente reti interne), redirect non seguiti.
Allargare l’accesso chiede la password del titolare; stringerlo è immediato e chiude le sessioni aperte. Ogni cambio finisce nel registro dello spazio.
Cosa fai tu
La chiave segreta sta solo sul server, in una variabile d’ambiente: mai nel codice del browser, mai in un repository.
L’endpoint che chiede il biglietto controlla la sessione del TUO gestionale e chiede il biglietto solo per la persona collegata.
Verifica la firma di ogni webhook e la sua data; usa webhook-id per non elaborare due volte lo stesso evento.
Non scrivere nei log biglietti, chiavi e segreti.
Una chiave esposta si revoca subito dalla scheda Incorpora, e se ne crea un’altra: due possono restare accese insieme per il cambio senza interruzioni.
Le persone aggiunte dall’API contano nei posti del piano come quelle invitate a mano (gli ospiti no). A posti finiti l’API risponde 409 seat_limit_reached con i numeri e il collegamento per cambiare piano.
Con l’abbonamento fermo lo spazio è in sola lettura: il riquadro si apre e si legge, le scritture dell’API rispondono 402.
Richieste al minuto per chiave: 300 in generale, 120 biglietti, 60 persone, 60 notifiche.
Fino a 10 siti autorizzati e 5 chiavi segrete attive per spazio di lavoro.
Il riquadro è grigio con «rifiutato di connettersi»
Il sito non è tra quelli autorizzati (controlla schema, www e porta), o il riquadro è spento.
Il riquadro non compare affatto
La Content-Security-Policy del tuo sito non ha frame-src https://work.omegasuite.it. La console del browser lo dice.
«Il tuo browser non conserva l’accesso dentro i riquadri»
Il browser blocca anche i cookie partizionati (alcune versioni di Safari 18, estensioni rigide). Omega Work propone di aprire una scheda; su Safari aggiornato funziona.
401 dall’API
Chiave copiata male (manca un pezzo), revocata o scaduta. Le cifre finali di controllo fanno rispondere key_malformed a una chiave troncata.
403 browser_not_allowed
Stai chiamando l’API dal browser: spostala sul server.
Il biglietto viene rifiutato
È scaduto (60 s), è già stato usato (una volta sola), o la persona è sospesa. Chiedine uno nuovo a ogni apertura.