diff --git a/docs/context/CONTEXT_LAST_SESSION.md b/docs/context/CONTEXT_LAST_SESSION.md new file mode 100644 index 0000000..8e4d134 --- /dev/null +++ b/docs/context/CONTEXT_LAST_SESSION.md @@ -0,0 +1,126 @@ +# Contesto Ultima Sessione — NIS2 Agile + +**Data**: 2026-03-07 +**Dominio produzione**: https://nis2.agile.software/ + +--- + +## Cosa è stato fatto in questa sessione + +### Sprint B2B / Integrazioni / Licenze + +#### 1. Migrazione dominio +- DNS A record `nis2.agile.software → 135.181.149.254` via Cloudflare API +- SSL Let's Encrypt certbot (`/etc/letsencrypt/live/nis2.agile.software/`) +- Apache vhost HTTPS abilitato +- Redirect 301 da `nis2.certisource.it → nis2.agile.software` + +#### 2. Test runner +- `public/test-runner.php` — token `Nis2Test2026`, SSE streaming, dark terminal UI +- Bottone `Reset + Simula + Testa Tutto` (dark green, top Test tab) +- `docs/sql/reset-demo.sql` aggiornato: mantiene sempre `cristiano.benassati@gmail.com` (super_admin, `Silvia1978!@`) + +#### 3. Integrazioni B2B (ServicesController) +- `POST /api/services/token` — API Key → JWT 15min +- `POST /api/services/sso` — SSO federato con responsabilità utente, JWT 2h +- `POST /api/services/provision` — provisioning automatico org+utente+api_key da invito +- `logExternalCall()` in BaseController per audit trail chiamate esterne +- `BaseController::base64UrlEncode/Decode` cambiati da private a protected + +#### 4. Sistema Inviti / Licenze +- **`application/controllers/InviteController.php`** — CRUD inviti + - Auth: `requireLicenseAuth()` accetta X-API-Key (`admin:licenses`) O JWT super_admin + - `POST /api/invites/create` — genera token `inv_xxx`, SHA-256 in DB + - `GET /api/invites/list` — lista con filtri status/channel + - `GET /api/invites/{id}` — dettaglio + - `DELETE /api/invites/{id}` — revoca + - `POST /api/invites/{id}/regenerate` — nuovo token + - `GET /api/invites/validate?token=` — pubblica, nessuna auth + - `static resolveInvite()` / `static markUsed()` — usati da provision +- **`ServicesController::provision()`** aggiornato: + - Accetta `invite_token` nel body (B2B flow) O `X-Provision-Secret` (admin diretto) + - Piano e durata forzati dall'invito + - Chiama `InviteController::markUsed()` dopo provisioning riuscito + - Salva `license_max_users` nell'org +- **`public/index.php`** aggiornato: route `/api/invites/*` + +#### 5. DB Migrations applicate in produzione +- **011_provisioning.sql**: `organizations` +provisioned_by, +license_plan, +license_expires_at, +lg231_company_id; `users` +must_change_password, +phone, +job_title; `api_keys` +created_by +- **012_invites.sql**: tabella `invites` (token_hash, plan, duration_months, max_uses, expires_at, channel, restrict_vat/email, status, used_by_org_id) +- **013_license_ext.sql**: `invites` +max_users_per_org, +price_eur, +reseller_name; `organizations` +license_max_users + +#### 6. Pagine HTML nuove +- **`public/integrazioniext.html`** — documentazione partner tecnici (lg231, e-commerce) + - Tab: Services API, Inviti & Licenze, Guida lg231, Webhook, Quick Start +- **`public/licenseExt.html`** — pannello marketing per gestione licenze + - Login JWT super_admin, stats strip, genera licenze, lista/filtri, revoca/rigenera, export CSV +- **`public/mktg-api-doc.html`** — risponde alle 6 domande marketing + - Quick start, endpoint, auth, response format, lista, revoca, spiegazione pagine +- **`public/nis2-license-api.postman.json`** — Postman collection scaricabile +- **`docs/integration/nis2-license-api.postman.json`** — copia in repo + +#### 7. API Key mktg-agile (generata in produzione) +- **Chiave**: `nis2_mktg_8c8bd38e78fccb9faa749d8601051f42` +- **Scope**: `admin:licenses` +- **DB api_keys.id**: 1 +- **Scade**: 2028-03-07 + +#### 8. Documentazione lg231 +- `docs/integration/lg231-nis2-integration.md` — spec completa per agente Claude lg231 +- `public/settings.html` — aggiunto scope `admin:licenses`, `admin:org`, `sso:login` al form API Keys + +--- + +## File creati o modificati +| File | Azione | +|------|--------| +| `application/controllers/InviteController.php` | NUOVO | +| `application/controllers/ServicesController.php` | MODIFICATO (provision + sso + token) | +| `application/controllers/BaseController.php` | MODIFICATO (base64Url protected) | +| `application/config/config.php` | MODIFICATO (PROVISION_SECRET) | +| `public/index.php` | MODIFICATO (route invites) | +| `public/integrazioniext.html` | NUOVO | +| `public/licenseExt.html` | NUOVO | +| `public/mktg-api-doc.html` | NUOVO | +| `public/nis2-license-api.postman.json` | NUOVO | +| `public/settings.html` | MODIFICATO (scopes) | +| `public/js/common.js` | MODIFICATO (sidebar link integrazioniext) | +| `docs/sql/011_provisioning.sql` | NUOVO | +| `docs/sql/012_invites.sql` | NUOVO | +| `docs/sql/013_license_ext.sql` | NUOVO | +| `docs/sql/reset-demo.sql` | MODIFICATO (super_admin persistente) | +| `docs/integration/lg231-nis2-integration.md` | NUOVO | +| `docs/integration/nis2-license-api.postman.json` | NUOVO | + +--- + +## File deployati su Hetzner +Tutti i file sopra tramite `git push + git pull`. Migrations applicate via SSH/mysql. + +--- + +## URL attivi in produzione +| Risorsa | URL | +|---------|-----| +| App | https://nis2.agile.software/ | +| Test runner | https://nis2.agile.software/test-runner.php?t=Nis2Test2026 | +| Doc partner (lg231) | https://nis2.agile.software/integrazioniext.html | +| Pannello licenze (mktg) | https://nis2.agile.software/licenseExt.html | +| Doc API marketing | https://nis2.agile.software/mktg-api-doc.html | +| Postman collection | https://nis2.agile.software/nis2-license-api.postman.json | + +--- + +## Prossimi passi consigliati +1. **mktg-agile**: recepire API Key + integrare `POST /api/invites/create` nel flusso di acquisto +2. **lg231**: leggere `integrazioniext.html` + `docs/integration/lg231-nis2-integration.md` e implementare Nis2Client + provisioning +3. **E-commerce**: usare `GET /api/invites/validate?token=` per mostrare anteprima piano prima dell'attivazione +4. **Controllo utenti per org**: aggiungere check `license_max_users` in `OrganizationController` quando si invitano nuovi utenti +5. **Rinnovo licenze**: endpoint `POST /api/invites/{id}/renew` che estende `license_expires_at` sull'org + +--- + +## Credenziali importanti (non committare) +- Super admin: `cristiano.benassati@gmail.com` / `Silvia1978!@` +- API Key mktg: `nis2_mktg_8c8bd38e78fccb9faa749d8601051f42` (scope: admin:licenses, scade 2028) +- SSH Hetzner: `ssh -i docs/credentials/hetzner_key root@135.181.149.254` diff --git a/public/integrazioniext.html b/public/integrazioniext.html index faf68f5..fbe0c9d 100644 --- a/public/integrazioniext.html +++ b/public/integrazioniext.html @@ -324,9 +324,46 @@ Sistema Inviti / Licenze B2B: NIS2 Agile genera token di invito che abilitano il provisioning automatico di organizzazioni e utenti. L'e-commerce o il partner riceve l'invito, lo consegna al cliente finale (es. lg231), che lo usa per attivarsi automaticamente. - L'accesso si interrompe alla scadenza dell'invito. + L'accesso si interrompe alla scadenza della licenza. +
| Sistema | Ruolo | API usata | Auth |
|---|---|---|---|
| NIS2 Admin o mktg-agile |
+ Genera i token licenza, fissa piano/durata/utenti/prezzo | +POST /api/invites/create |
+ API Key admin:licenses | +
| E-commerce | +Riceve token all'acquisto, lo consegna al cliente con l'ordine | +— (semplice consegna token) | +API Key admin:licenses | +
| lg231 / partner | +Valida il token, fa provisioning automatico per il cliente | +GET /api/invites/validatePOST /api/services/provision |
+ invite_token nel body | +
| Cliente finale | +Apre invite_url e si registra in autonomia via wizard | +onboarding.html?invite=inv_... |
+ nessuna auth | +
| NIS2 Admin | +Monitora uso licenze, revoca, rigenera | +GET /api/invites/listDELETE /api/invites/{id} |
+ API Key o JWT super_admin | +
nis2_mktg_8c8bd38e78fccb9faa749d8601051f42
+ · Scope: admin:licenses · Scade: 2028-03-07
+ · Doc completa: mktg-api-doc.html
+ · Pannello web: licenseExt.html
+ inv_ viene restituito in chiaro UNA SOLA VOLTA
alla creazione. Nel DB è conservato solo il hash SHA-256. Il token_prefix (es: inv_a1b2c3...)
@@ -729,14 +791,45 @@ curl -H "X-API-Key: nis2_TUA_CHIAVE" \
curl -H "X-API-Key: nis2_TUA_CHIAVE" \
"https://nis2.agile.software/api/services/risks/feed?level=high,critical"| Destinatario | Risorsa | URL |
|---|---|---|
| App NIS2 Agile | https://nis2.agile.software | |
| Specifiche OpenAPI | GET /api/services/openapi.json | |
| Test Runner | test-runner.php | |
| Amministratore | cristiano.benassati@gmail.com | |
| Documento tecnico lg231 | docs/integration/lg231-nis2-integration.md | |
| mktg-agile / E-commerce | +Documentazione API licenze + Quick Start | +mktg-api-doc.html | +
| mktg-agile / E-commerce | +Pannello web gestione licenze | +licenseExt.html | +
| mktg-agile / E-commerce | +Postman Collection (import diretto) | +nis2-license-api.postman.json | +
| lg231 / Partner tecnici | +Questa pagina — tab Guida lg231 | +integrazioniext.html | +
| lg231 (agente Claude) | +Spec tecnica completa per implementazione | +docs/integration/lg231-nis2-integration.md |
+
| Tutti | +Health check (no auth) | +GET https://nis2.agile.software/api/services/status |
+
| Tutti | +App NIS2 Agile | +https://nis2.agile.software | +
nis2_mktg_8c8bd38e78fccb9faa749d8601051f42
+ https://nis2.agile.software/api
+ curl nis2.agile.software/api/services/status
+ # Crea licenza in 1 chiamata: +curl -X POST https://nis2.agile.software/api/invites/create \ + -H "X-API-Key: nis2_mktg_8c8bd38e78fccb9faa749d8601051f42" \ + -H "Content-Type: application/json" \ + -d '{"plan":"professional","duration_months":12,"label":"Ordine #123","channel":"ecommerce","max_users_per_org":10,"price_eur":990}' + +# Risposta → prendi invites[0].token (inv_xxx) e invites[0].invite_url +# Consegna invite_url al cliente — lui clicca e si attiva in autonomia+