[FEAT] Services API, Webhook, Whistleblowing, Normative + integrazioni
Sprint completo — prodotto presentation-ready:
Services API (read-only, API Key + scope):
- GET /api/services/status|compliance-summary|risks-feed|incidents-feed
- GET /api/services/controls-status|assets-critical|suppliers-risk|policies-approved
- GET /api/services/openapi (spec OpenAPI 3.0.3 JSON)
Webhook Outbound (Stripe-like HMAC-SHA256):
- CRUD api_keys + webhook_subscriptions (Settings → 2 nuovi tab)
- WebhookService: retry 3x backoff (0s/5min/30min), delivery log
- Trigger auto in IncidentController, RiskController, PolicyController
- Delivery log, test ping, processRetry
Nuovi moduli:
- WhistleblowingController (Art.32 NIS2): anonimato garantito, timeline, token tracking
- NormativeController: feed NIS2/ACN/DORA con ACK tracciato per audit
Frontend:
- whistleblowing.html: form submit anonimo/firmato + gestione CISO
- normative.html: feed con presa visione documentata + progress bar ACK
- public/docs/api.html: documentazione API dark theme (Swagger-like)
- settings.html: tab API Keys + tab Webhook
- integrations/: guide per lg231, SustainAI, AllRisk, SIEM (widget + codice)
- Sidebar: Segnalazioni + Normative aggiunte a common.js
DB: migration 007 (api_keys, webhook_subscriptions, webhook_deliveries),
008 (whistleblowing_reports + timeline),
009 (normative_updates + normative_ack + seed NIS2/ACN/DORA/ISO)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
3f4b451e2a
commit
86e9bdded2
@@ -0,0 +1,87 @@
|
||||
-- ============================================================
|
||||
-- NIS2 Agile - Migration 007: Services API & Webhooks
|
||||
-- Tabelle per API Keys esterne, Webhook subscriptions e delivery log
|
||||
-- ============================================================
|
||||
|
||||
-- ── API KEYS ─────────────────────────────────────────────────
|
||||
-- Chiavi API per accesso esterno ai servizi NIS2
|
||||
-- Separate dai JWT sessione, con scopo e permessi specifici
|
||||
|
||||
CREATE TABLE IF NOT EXISTS api_keys (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id INT UNSIGNED NOT NULL,
|
||||
created_by INT UNSIGNED NOT NULL,
|
||||
name VARCHAR(100) NOT NULL, -- Nome descrittivo es. "SIEM Integration"
|
||||
key_prefix VARCHAR(12) NOT NULL, -- Prefisso visibile es. "nis2_abc123"
|
||||
key_hash VARCHAR(64) NOT NULL, -- SHA-256 della chiave completa
|
||||
scopes JSON NOT NULL, -- Array di scope: ["read:risks","read:incidents","read:all"]
|
||||
last_used_at TIMESTAMP NULL DEFAULT NULL,
|
||||
expires_at TIMESTAMP NULL DEFAULT NULL,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX idx_org (organization_id),
|
||||
INDEX idx_key_hash (key_hash),
|
||||
INDEX idx_active (is_active)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── WEBHOOK SUBSCRIPTIONS ────────────────────────────────────
|
||||
-- Sottoscrizioni webhook outbound: quando avvengono eventi NIS2,
|
||||
-- NIS2 notifica sistemi esterni (SIEM, GRC, 231 Agile, SustainAI)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS webhook_subscriptions (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id INT UNSIGNED NOT NULL,
|
||||
created_by INT UNSIGNED NOT NULL,
|
||||
name VARCHAR(100) NOT NULL, -- Es. "231 Agile Notify"
|
||||
url VARCHAR(512) NOT NULL, -- URL destinazione POST
|
||||
secret VARCHAR(64) NOT NULL, -- Usato per HMAC-SHA256 firma
|
||||
events JSON NOT NULL, -- Array eventi: ["incident.created","risk.high_created"]
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
last_triggered_at TIMESTAMP NULL DEFAULT NULL,
|
||||
failure_count INT UNSIGNED DEFAULT 0, -- Errori consecutivi (auto-pause se >10)
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX idx_org (organization_id),
|
||||
INDEX idx_active (is_active)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── WEBHOOK DELIVERIES ───────────────────────────────────────
|
||||
-- Log di ogni tentativo di consegna webhook (audit + retry)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
subscription_id INT UNSIGNED NOT NULL,
|
||||
organization_id INT UNSIGNED NOT NULL,
|
||||
event_type VARCHAR(60) NOT NULL, -- Es. "incident.created"
|
||||
event_id VARCHAR(36) NOT NULL, -- UUID dell'evento
|
||||
payload MEDIUMTEXT NOT NULL, -- JSON payload inviato
|
||||
status ENUM('pending','delivered','failed','retrying') DEFAULT 'pending',
|
||||
http_status SMALLINT UNSIGNED NULL, -- Codice HTTP risposta
|
||||
response_body TEXT NULL, -- Risposta del server (max 2KB)
|
||||
attempt TINYINT UNSIGNED DEFAULT 1, -- Tentativo corrente (max 3)
|
||||
next_retry_at TIMESTAMP NULL DEFAULT NULL, -- Prossimo retry schedulato
|
||||
delivered_at TIMESTAMP NULL DEFAULT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX idx_subscription (subscription_id),
|
||||
INDEX idx_org (organization_id),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_event (event_type, event_id),
|
||||
INDEX idx_retry (status, next_retry_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── FOREIGN KEYS ─────────────────────────────────────────────
|
||||
ALTER TABLE api_keys
|
||||
ADD CONSTRAINT fk_apikeys_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_apikeys_user FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE webhook_subscriptions
|
||||
ADD CONSTRAINT fk_webhooksub_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_webhooksub_user FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE webhook_deliveries
|
||||
ADD CONSTRAINT fk_webhookdel_sub FOREIGN KEY (subscription_id) REFERENCES webhook_subscriptions(id) ON DELETE CASCADE;
|
||||
@@ -0,0 +1,65 @@
|
||||
-- ============================================================
|
||||
-- NIS2 Agile - Migration 008: Whistleblowing (Art.32 NIS2)
|
||||
-- Canale segnalazioni anomalie di sicurezza con anonimato garantito
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS whistleblowing_reports (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id INT UNSIGNED NOT NULL,
|
||||
report_code VARCHAR(20) NOT NULL UNIQUE, -- Es. WB-2026-001
|
||||
|
||||
-- Mittente (opzionale — anonimato garantito)
|
||||
is_anonymous TINYINT(1) NOT NULL DEFAULT 1,
|
||||
submitted_by INT UNSIGNED NULL, -- NULL se anonimo
|
||||
anonymous_token VARCHAR(64) NULL, -- Token per tracking anonimo
|
||||
contact_email VARCHAR(255) NULL, -- Email facoltativa per follow-up
|
||||
|
||||
-- Contenuto segnalazione
|
||||
category ENUM(
|
||||
'security_incident', 'policy_violation', 'unauthorized_access',
|
||||
'data_breach', 'supply_chain_risk', 'corruption', 'fraud',
|
||||
'nis2_non_compliance', 'other'
|
||||
) NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
evidence_files JSON NULL, -- Array path files allegati
|
||||
nis2_article VARCHAR(20) NULL, -- Articolo NIS2 violato
|
||||
|
||||
-- Gestione
|
||||
priority ENUM('critical', 'high', 'medium', 'low') NOT NULL DEFAULT 'medium',
|
||||
status ENUM('received', 'under_review', 'investigating', 'resolved', 'closed', 'rejected') NOT NULL DEFAULT 'received',
|
||||
assigned_to INT UNSIGNED NULL, -- Utente incaricato
|
||||
resolution_notes TEXT NULL, -- Note risoluzione (visibili al segnalante se email fornita)
|
||||
closed_at TIMESTAMP NULL,
|
||||
closed_by INT UNSIGNED NULL,
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX idx_org (organization_id),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_priority (priority),
|
||||
INDEX idx_token (anonymous_token),
|
||||
INDEX idx_code (report_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── Timeline segnalazione ──────────────────────────────────
|
||||
CREATE TABLE IF NOT EXISTS whistleblowing_timeline (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
report_id INT UNSIGNED NOT NULL,
|
||||
event_type ENUM('received','status_change','assigned','note_added','closed') NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
new_status VARCHAR(30) NULL,
|
||||
created_by INT UNSIGNED NULL, -- NULL = sistema
|
||||
is_visible_to_reporter TINYINT(1) NOT NULL DEFAULT 0, -- Se visibile al segnalante anonimo
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX idx_report (report_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── Foreign Keys ──────────────────────────────────────────
|
||||
ALTER TABLE whistleblowing_reports
|
||||
ADD CONSTRAINT fk_wb_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE whistleblowing_timeline
|
||||
ADD CONSTRAINT fk_wb_timeline_report FOREIGN KEY (report_id) REFERENCES whistleblowing_reports(id) ON DELETE CASCADE;
|
||||
@@ -0,0 +1,78 @@
|
||||
-- ============================================================
|
||||
-- NIS2 Agile - Migration 009: Normative Updates (NIS2/ACN Feed)
|
||||
-- Feed aggiornamenti normativi con ACK per utente (audit trail)
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS normative_updates (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
-- Update metadata
|
||||
title VARCHAR(255) NOT NULL,
|
||||
source ENUM('nis2_directive','dlgs_138_2024','acn_guideline','dora','enisa','iso27001','other') NOT NULL,
|
||||
source_label VARCHAR(100) NULL,
|
||||
reference VARCHAR(100) NULL, -- Es. "Art. 21 par. 5", "Circolare ACN 2026-01"
|
||||
summary TEXT NOT NULL,
|
||||
content LONGTEXT NULL, -- Testo completo (opzionale)
|
||||
impact_level ENUM('critical','high','medium','low','informational') NOT NULL DEFAULT 'medium',
|
||||
affected_domains JSON NULL, -- Array domini NIS2 impattati
|
||||
action_required TINYINT(1) NOT NULL DEFAULT 0, -- Richiede azione da parte dell'org
|
||||
effective_date DATE NULL, -- Data entrata in vigore
|
||||
url VARCHAR(512) NULL, -- Link fonte ufficiale
|
||||
is_published TINYINT(1) NOT NULL DEFAULT 1,
|
||||
published_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX idx_source (source),
|
||||
INDEX idx_impact (impact_level),
|
||||
INDEX idx_published (is_published, published_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── ACK per organizzazione ────────────────────────────────
|
||||
-- Ogni org traccia la presa visione degli aggiornamenti normativi
|
||||
CREATE TABLE IF NOT EXISTS normative_ack (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
normative_update_id INT UNSIGNED NOT NULL,
|
||||
organization_id INT UNSIGNED NOT NULL,
|
||||
acknowledged_by INT UNSIGNED NOT NULL,
|
||||
acknowledged_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
notes TEXT NULL, -- Note opzionali dell'org sull'impatto
|
||||
|
||||
UNIQUE KEY uk_ack (normative_update_id, organization_id),
|
||||
INDEX idx_org (organization_id),
|
||||
INDEX idx_update (normative_update_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── Foreign Keys ──────────────────────────────────────────
|
||||
ALTER TABLE normative_ack
|
||||
ADD CONSTRAINT fk_norm_ack_update FOREIGN KEY (normative_update_id) REFERENCES normative_updates(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_norm_ack_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_norm_ack_user FOREIGN KEY (acknowledged_by) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
-- ── Seed: aggiornamenti normativi iniziali ────────────────
|
||||
INSERT INTO normative_updates (title, source, reference, summary, impact_level, action_required, effective_date, url) VALUES
|
||||
('D.Lgs. 138/2024 — Attuazione Direttiva NIS2 in Italia',
|
||||
'dlgs_138_2024', 'D.Lgs. 4 settembre 2024, n. 138',
|
||||
'Recepimento della Direttiva NIS2 nell\'ordinamento italiano. Estende l\'ambito di applicazione, obblighi di notifica incidenti (Art.23), misure di sicurezza (Art.21), sanzioni fino a €10M.',
|
||||
'critical', 1, '2024-10-18',
|
||||
'https://www.gazzettaufficiale.it/eli/id/2024/10/01/24G00171/SG'),
|
||||
|
||||
('ACN — Linee Guida Misure di Sicurezza NIS2 (Art.21)',
|
||||
'acn_guideline', 'Circolare ACN n.1/2025',
|
||||
'L\'Agenzia per la Cybersicurezza Nazionale ha pubblicato le linee guida operative per l\'implementazione delle 10 misure di sicurezza previste dall\'Art.21 NIS2.',
|
||||
'high', 1, '2025-01-15', NULL),
|
||||
|
||||
('ENISA — NIS2 Implementation Report 2025',
|
||||
'enisa', 'ENISA/2025/NIS2-IMPL',
|
||||
'Report ENISA sullo stato di implementazione NIS2 nei 27 stati membri. Include benchmark di settore e best practice emergenti.',
|
||||
'medium', 0, '2025-06-01',
|
||||
'https://www.enisa.europa.eu'),
|
||||
|
||||
('DORA — Digital Operational Resilience Act (Applicabilità NIS2)',
|
||||
'dora', 'Reg. UE 2022/2554',
|
||||
'Il DORA entra in piena applicazione a gennaio 2025 per enti finanziari. Le organizzazioni NIS2 del settore bancario/finanziario devono allineare i requisiti DORA con NIS2.',
|
||||
'high', 1, '2025-01-17', NULL),
|
||||
|
||||
('ISO/IEC 27001:2022 — Controlli aggiornati Annex A',
|
||||
'iso27001', 'ISO/IEC 27001:2022',
|
||||
'La revisione 2022 introduce 11 nuovi controlli (es. threat intelligence, ICT supply chain security, data masking, monitoring). Mappatura con NIS2 Art.21 disponibile.',
|
||||
'medium', 0, '2022-10-25', NULL);
|
||||
Reference in New Issue
Block a user