# 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`