[FEAT] Simulazioni Demo + Audit Trail Certificato SHA-256

- 5 scenari reali: Onboarding, Ransomware Art.23, Data Breach Supply Chain,
  Whistleblowing SCADA, Audit Hash Chain Verification
- simulate-nis2.php: 3 aziende (DataCore/MedClinic/EnerNet), 10 fasi, CLI+SSE
- AuditService.php: hash chain SHA-256 stile lg231 (prev_hash+entry_hash)
- Migration 010: prev_hash, entry_hash, severity, performed_by su audit_logs
- AuditController: GET chain-verify + GET export-certified
- reset-demo.sql: reset dati demo idempotente
- public/simulate.html: web runner SSE con console dark-theme
- Sidebar: link Simulazione Demo + Integrazioni

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-03-07 13:56:53 +01:00
co-authored by Claude Sonnet 4.6
parent b23bbc55fd
commit 874eabb6fc
9 changed files with 1983 additions and 10 deletions
@@ -238,4 +238,79 @@ class AuditController extends BaseController
echo $csv;
exit;
}
/**
* GET /api/audit/chain-verify
* Verifica l'integrità dell'hash chain per l'organizzazione corrente.
* Risponde con: valid, total, hashed, coverage_pct, broken_at, last_hash
*/
public function chainVerify(): void
{
$this->requireOrgRole(['org_admin', 'auditor']);
$orgId = $this->getCurrentOrgId();
$db = Database::getInstance();
$result = AuditService::verifyChain($db, $orgId);
// Se la catena è rotta, registra la violazione
if (!$result['valid'] && $result['broken_at'] !== null) {
$performer = $this->currentUser['email'] ?? 'system';
try {
$ins = $db->prepare(
"INSERT INTO audit_violations
(organization_id, detected_by, broken_at_id, chain_length, notes)
VALUES (:org, :by, :bid, :len, :notes)"
);
$ins->execute([
'org' => $orgId,
'by' => $performer,
'bid' => $result['broken_at'],
'len' => $result['total'],
'notes' => 'Violazione rilevata tramite API chain-verify',
]);
} catch (Throwable $e) {
error_log('[AuditController] chain violation log error: ' . $e->getMessage());
}
$this->logAudit('audit.chain_broken', 'audit_logs', $result['broken_at'], [
'total' => $result['total'],
'coverage_pct' => $result['coverage_pct'],
]);
}
$this->jsonSuccess($result);
}
/**
* GET /api/audit/export-certified
* Genera un export JSON certificato con hash SHA-256 dell'intero contenuto.
* Adatto per ispezioni ACN, audit NIS2 Art.32, certificazione ISO 27001.
*/
public function exportCertified(): void
{
$this->requireOrgRole(['org_admin', 'auditor']);
$orgId = $this->getCurrentOrgId();
$userId = $this->getCurrentUserId();
$email = $this->currentUser['email'] ?? 'system';
$db = Database::getInstance();
$result = AuditService::exportCertified(
$db,
$orgId,
$userId,
$email,
$_GET['purpose'] ?? 'export_certificato',
$_GET['from'] ?? null,
$_GET['to'] ?? null
);
$this->logAudit('audit.export_certified', 'audit_logs', null, [
'records_count' => $result['records_count'],
'chain_valid' => $result['chain_valid'],
'export_hash' => $result['export_hash'],
]);
header('Content-Disposition: attachment; filename="nis2_audit_certified_' . date('Y-m-d') . '.json"');
$this->jsonSuccess($result);
}
}