nis2-agile/docs/context/CONTEXT_LAST_SESSION.md
DevEnv nis2-agile f7347ccd8c [CONTEXT+MKTG] Contesto sessione + HTML migliorati per comunicazione terze parti
- CONTEXT_LAST_SESSION.md: documento completo di tutto lo sprint B2B
- mktg-api-doc.html: Quick Start box con chiave attiva, flusso visivo 4 step, curl pronti
- integrazioniext.html tab Inviti: tabella "Chi fa cosa" per ruolo, sezione mktg-agile
  con chiave API + 3 curl pronti, Quick Start aggiornato con tabella risorse per destinatario

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 16:37:14 +01:00

127 lines
6.1 KiB
Markdown

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