Simon C3: l'analisi gap ACN non è un artefatto normativo e va eliminata; la conformità emerge da C1 (elenco Misure/Requisiti + valutazione per requisito in org_requisito_state). Ricognizione → migrazione → backup → rimozione (sicuro, 0 perdite): - Tabelle acn_assessments/acn_assessment_responses VUOTE (0 righe) -> droppate (mig.049, guard anti-drop se >0 righe). Ricreabili da 036. Nessun dato utente perso. - Integrazione lg231: /api/services/gap-analysis legge 'assessments' generale, NON il modulo ACN -> intatta. Verificato. - RaciController ripuntato su cfg_nis2_misure (fonte canonica) al posto di acn_measures.json (rimosso); validazione measure_code verificata (/raci/objects?type=measure -> 43 misure). Rimossi: AcnAssessmentController, public/acn-gap.html, application/data/acn_measures.json, routing acn-gap, voci sidebar (common.js + common-bi.js), metodi api.js acn*, sezione help 'acn', chiavi i18n acn.*, mapping demo-selectors. Tour demo step 3 RIPUNTATO su misure-requisiti (no step rotto, 10 step). Sidebar BI ora mostra 'Misure e Requisiti' (gap di common-bi.js sanato). Verifiche prod: /acn-gap.html 404, /api/acn-gap/* 404, /misure-requisiti 200, RaciController OK. Cache-buster ?v=20260624, version 1.18.3, SW v1.18.3. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
204 lines
17 KiB
HTML
204 lines
17 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="it">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||
<title>Modello Organizzativo SGSI (ISO 27001) - NIS2 Agile</title>
|
||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||
via JS (wizard/SoA/tabelle) -> parita' funzionale assoluta. BI veste la chrome. -->
|
||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
||
<style>
|
||
.isms-intro { background:#eff6ff; border-left:4px solid var(--primary,#2563eb); padding:14px 18px; border-radius:8px; margin-bottom:20px; font-size:.92rem; line-height:1.6; }
|
||
.isms-steps { display:flex; flex-wrap:wrap; gap:6px; margin-bottom:20px; }
|
||
.isms-step { flex:1 1 140px; min-width:120px; padding:10px 12px; border:1.5px solid var(--gray-200,#e5e7eb); border-radius:10px; background:#fff; cursor:pointer; font-size:.82rem; text-align:center; }
|
||
.isms-step.active { border-color:var(--primary,#2563eb); background:#eff6ff; font-weight:700; }
|
||
.isms-step.done { border-color:#16a34a; }
|
||
.isms-step .num { display:inline-block; width:22px; height:22px; line-height:22px; border-radius:50%; background:var(--gray-100,#f3f4f6); font-weight:700; margin-bottom:4px; }
|
||
.isms-step.done .num { background:#16a34a; color:#fff; }
|
||
.isms-panel { display:none; }
|
||
.isms-panel.active { display:block; }
|
||
.isms-disclaimer { font-size:.8rem; color:#92400e; background:#fffbeb; border:1px solid #fde68a; border-radius:8px; padding:10px 12px; margin:12px 0; }
|
||
.raci-row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; padding:8px 0; border-bottom:1px solid var(--gray-100,#f3f4f6); }
|
||
.raci-row input, .raci-row select { padding:6px 8px; border:1px solid var(--gray-200,#e5e7eb); border-radius:6px; font-size:.85rem; }
|
||
.soa-std { border:1px solid var(--gray-200,#e5e7eb); border-radius:10px; margin-bottom:14px; overflow:hidden; }
|
||
.soa-std-head { background:var(--gray-50,#f9fafb); padding:12px 16px; cursor:pointer; display:flex; justify-content:space-between; align-items:center; }
|
||
.soa-std-body { padding:6px 14px 14px; display:none; }
|
||
.soa-std.open .soa-std-body { display:block; }
|
||
.soa-theme { font-size:.78rem; font-weight:700; text-transform:uppercase; color:var(--gray-500,#6b7280); margin:14px 0 6px; letter-spacing:.04em; }
|
||
.soa-ctrl { padding:12px 0; border-top:1px solid var(--gray-100,#f3f4f6); }
|
||
.soa-ctrl-head { display:flex; gap:10px; align-items:flex-start; justify-content:space-between; flex-wrap:wrap; }
|
||
.soa-code { display:inline-block; background:#eef2ff; color:#3730a3; font-weight:700; font-size:.72rem; padding:2px 8px; border-radius:6px; margin-right:6px; }
|
||
.soa-derived { background:#ecfdf5; color:#065f46; font-size:.68rem; padding:1px 6px; border-radius:5px; }
|
||
.soa-opts { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
|
||
.soa-opt { min-height:34px; padding:5px 10px; border:1.5px solid var(--gray-200,#e5e7eb); border-radius:18px; background:#fff; cursor:pointer; font-size:.8rem; font-weight:600; }
|
||
.soa-opt.sel-implemented,.soa-opt.sel-verified { background:#16a34a; color:#fff; border-color:#16a34a; }
|
||
.soa-opt.sel-in_progress { background:#f59e0b; color:#fff; border-color:#f59e0b; }
|
||
.soa-opt.sel-not_started { background:#9ca3af; color:#fff; border-color:#9ca3af; }
|
||
.soa-justif { width:100%; margin-top:8px; padding:8px; border:1px solid var(--gray-200,#e5e7eb); border-radius:6px; font-size:.84rem; min-height:46px; }
|
||
.isms-field { margin-bottom:14px; }
|
||
.isms-field label { display:block; font-weight:600; font-size:.88rem; margin-bottom:4px; }
|
||
.isms-field textarea, .isms-field input { width:100%; padding:9px; border:1px solid var(--gray-200,#e5e7eb); border-radius:8px; font-size:.9rem; }
|
||
.isms-flags label { display:block; padding:8px 0; font-size:.9rem; }
|
||
.ck-item { display:flex; justify-content:space-between; padding:8px 0; border-bottom:1px solid var(--gray-100,#f3f4f6); font-size:.9rem; }
|
||
.ck-yes { color:#16a34a; font-weight:700; } .ck-no { color:#9ca3af; }
|
||
.savehint { font-size:.78rem; color:var(--gray-400,#9ca3af); min-height:16px; }
|
||
/* Allinea l'icona sprite BI nel bottone Esporta col testo */
|
||
.content-header-actions .btn .icon { vertical-align:text-bottom; margin-right:4px; }
|
||
</style>
|
||
<!-- PWA:start -->
|
||
<link rel="manifest" href="/manifest.webmanifest">
|
||
<meta name="theme-color" content="#0066CC">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||
<meta name="mobile-web-app-capable" content="yes">
|
||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||
<meta name="application-name" content="NIS2 Agile">
|
||
<script src="/js/pwa.js?v=20260614" defer></script>
|
||
<!-- PWA:end -->
|
||
</head>
|
||
<body>
|
||
<div class="app-layout">
|
||
<aside class="sidebar" id="sidebar"></aside>
|
||
<main class="main-content">
|
||
<header class="content-header">
|
||
<h2 data-i18n="isms.title">Modello Organizzativo SGSI (ISO 27001)</h2>
|
||
<div class="content-header-actions">
|
||
<span class="savehint" id="isms-savehint" role="status" aria-live="polite"></span>
|
||
<button class="btn btn-outline btn-sm" id="nis2-isms-btn-export" onclick="ismsExportView()" data-i18n="isms.export">
|
||
<svg class="icon icon-sm" aria-hidden="true"><use href="/vendor/bootstrap-italia/dist/svg/sprites.svg#it-file"></use></svg>
|
||
<span>Esporta SGSI</span>
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="content-body">
|
||
<div class="isms-intro" id="nis2-isms-intro">
|
||
<strong data-i18n="isms.intro.title">Costruisci il tuo Sistema di Gestione della Sicurezza delle Informazioni.</strong>
|
||
<span data-i18n="isms.intro.body">Procedura guidata ISO/IEC 27001:2022 (clausole 4-10 + Statement of Applicability). Lo Statement of Applicability viene pre-popolato dalle tue risposte alla Gap Analysis NIS2. Attiva le estensioni cloud ISO 27017/27018 dove pertinenti.</span>
|
||
</div>
|
||
<div class="isms-disclaimer" id="nis2-isms-disclaimer" data-i18n="isms.disclaimer">Strumento di supporto e pre-audit: non costituisce una certificazione ISO 27001 né un parere professionale vincolante. Gli obblighi normativi in Italia derivano da NIS2 / D.Lgs. 138/2024 / Determinazioni ACN; ISO 27001/27017/27018 sono best practice.</div>
|
||
|
||
<div class="isms-steps" id="isms-steps"></div>
|
||
|
||
<!-- STEP 1 - Contesto & Ambito (cl.4) -->
|
||
<div class="isms-panel" id="panel-0">
|
||
<div class="card"><div class="card-body">
|
||
<h3 data-i18n="isms.s1.title">1. Contesto e Ambito (cl. 4)</h3>
|
||
<div class="isms-field"><label for="f-scope" data-i18n="isms.s1.scope">Ambito del SGSI (scope statement)</label><textarea id="f-scope" rows="3" placeholder="Es. Tutti i sistemi e processi a supporto dei servizi ICT erogati dalla sede di..."></textarea></div>
|
||
<div class="isms-field"><label for="f-ctx-int" data-i18n="isms.s1.ctx_int">Contesto interno</label><textarea id="f-ctx-int" rows="2"></textarea></div>
|
||
<div class="isms-field"><label for="f-ctx-ext" data-i18n="isms.s1.ctx_ext">Contesto esterno</label><textarea id="f-ctx-ext" rows="2"></textarea></div>
|
||
<div class="isms-field"><label for="f-parties" data-i18n="isms.s1.parties">Parti interessate (una per riga)</label><textarea id="f-parties" rows="3" placeholder="Clienti Autorità (ACN/CSIRT) Fornitori ICT"></textarea></div>
|
||
<div class="isms-field"><label for="f-boundaries" data-i18n="isms.s1.boundaries">Confini del SGSI</label><textarea id="f-boundaries" rows="2"></textarea></div>
|
||
<div class="isms-field"><label for="f-exclusions" data-i18n="isms.s1.exclusions">Esclusioni motivate</label><textarea id="f-exclusions" rows="2"></textarea></div>
|
||
<div class="isms-flags">
|
||
<strong data-i18n="isms.s1.cloud">Estensioni cloud (attivano i controlli condizionali nel SoA)</strong>
|
||
<label><input type="checkbox" id="f-uses-cloud"> <span data-i18n="isms.s1.uses_cloud">Usiamo servizi cloud pubblici (Microsoft 365, AWS, Google...) → ISO 27017</span></label>
|
||
<label><input type="checkbox" id="f-cloud-provider"> <span data-i18n="isms.s1.cloud_provider">Siamo fornitori di servizi cloud → ISO 27017 (lato provider)</span></label>
|
||
<label><input type="checkbox" id="f-pii-cloud"> <span data-i18n="isms.s1.pii_cloud">Trattiamo dati personali (PII) in cloud pubblico come responsabili → ISO 27018</span></label>
|
||
</div>
|
||
<button class="btn btn-primary" id="nis2-isms-btn-save-step1" onclick="saveStep1()" data-i18n="isms.save_next">Salva e continua</button>
|
||
</div></div>
|
||
</div>
|
||
|
||
<!-- STEP 2 - Leadership (cl.5) -->
|
||
<div class="isms-panel" id="panel-1">
|
||
<div class="card"><div class="card-body">
|
||
<h3 data-i18n="isms.s2.title">2. Leadership: ruoli e responsabilità (cl. 5)</h3>
|
||
<p class="text-muted" data-i18n="isms.s2.hint">Definisci i ruoli del SGSI con la matrice RACI (Responsible, Accountable, Consulted, Informed).</p>
|
||
<div id="roles-list"></div>
|
||
<div class="raci-row" style="border-top:2px solid var(--gray-200,#e5e7eb); margin-top:10px;">
|
||
<input id="r-name" placeholder="Ruolo (es. CISO)" aria-label="Ruolo" style="flex:1 1 160px;">
|
||
<input id="r-resp" placeholder="Responsabilità" aria-label="Responsabilità" style="flex:2 1 220px;">
|
||
<select id="r-raci" aria-label="RACI"><option value="">RACI</option><option>R</option><option>A</option><option>C</option><option>I</option></select>
|
||
<button class="btn btn-sm btn-primary" id="nis2-isms-btn-add-role" onclick="addRole()" data-i18n="isms.s2.add">Aggiungi ruolo</button>
|
||
</div>
|
||
<button class="btn btn-outline" id="nis2-isms-btn-next-step2" style="margin-top:14px;" onclick="goStep(2)" data-i18n="isms.next">Continua</button>
|
||
</div></div>
|
||
</div>
|
||
|
||
<!-- STEP 3 - Risk (cl.6) -->
|
||
<div class="isms-panel" id="panel-2">
|
||
<div class="card"><div class="card-body">
|
||
<h3 data-i18n="isms.s3.title">3. Risk: metodologia e obiettivi (cl. 6)</h3>
|
||
<div class="isms-field"><label for="f-method" data-i18n="isms.s3.method">Metodologia di risk assessment</label><textarea id="f-method" rows="3" placeholder="Es. ISO 27005 / NIST SP 800-30; scala probabilità×impatto 5×5 (già usata nel modulo Rischi)."></textarea></div>
|
||
<div class="isms-field"><label for="f-objectives" data-i18n="isms.s3.objectives">Obiettivi del SGSI (uno per riga)</label><textarea id="f-objectives" rows="3"></textarea></div>
|
||
<p class="text-muted" data-i18n="isms.s3.link">Il registro dei rischi vive nel modulo <a href="risks.html">Rischi</a>: questo passo ne dichiara la metodologia.</p>
|
||
<button class="btn btn-primary" id="nis2-isms-btn-save-step3" onclick="saveStep3()" data-i18n="isms.save_next">Salva e continua</button>
|
||
</div></div>
|
||
</div>
|
||
|
||
<!-- STEP 4 - SoA -->
|
||
<div class="isms-panel" id="panel-3">
|
||
<div class="card"><div class="card-body">
|
||
<h3 data-i18n="isms.s4.title">4. Statement of Applicability</h3>
|
||
<p class="text-muted" data-i18n="isms.s4.hint">I controlli sono pre-popolati dalle risposte NIS2 dove esiste corrispondenza (badge "da NIS2"). Conferma applicabilità, stato e motivazione per ciascuno.</p>
|
||
<div style="margin:10px 0;">
|
||
<button class="btn btn-sm btn-outline" id="nis2-isms-btn-derive-soa" onclick="deriveSoa()" data-i18n="isms.s4.derive">Ri-deriva dal NIS2</button>
|
||
<span id="soa-stats" class="text-muted" style="margin-left:12px; font-size:.85rem;"></span>
|
||
</div>
|
||
<div id="soa-groups"></div>
|
||
<button class="btn btn-outline" id="nis2-isms-btn-next-step4" style="margin-top:14px;" onclick="goStep(4)" data-i18n="isms.next">Continua</button>
|
||
</div></div>
|
||
</div>
|
||
|
||
<!-- STEP 5 - Documented information (cl.7-8) -->
|
||
<div class="isms-panel" id="panel-4">
|
||
<div class="card"><div class="card-body">
|
||
<h3 data-i18n="isms.s5.title">5. Documented Information (cl. 7-8)</h3>
|
||
<div class="raci-row" style="border:none;">
|
||
<label for="d-type" class="sr-only" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);">Tipo di documento</label>
|
||
<select id="d-type" style="flex:1 1 200px;" aria-label="Tipo di documento">
|
||
<option value="policy_sgsi">Policy SGSI</option>
|
||
<option value="dichiarazione_applicabilita">Dichiarazione di Applicabilità</option>
|
||
<option value="politica_controllo_accessi">Politica controllo accessi</option>
|
||
<option value="procedura_incident">Procedura gestione incidenti</option>
|
||
<option value="procedura_continuita">Procedura continuità operativa</option>
|
||
<option value="politica_fornitori">Politica sicurezza fornitori</option>
|
||
</select>
|
||
<button class="btn btn-sm btn-primary" onclick="aiGenDoc()" id="btn-aigen" data-i18n="isms.s5.aigen">Genera bozza con AI</button>
|
||
</div>
|
||
<div class="savehint" id="aigen-hint" role="status" aria-live="polite"></div>
|
||
<div id="docs-list" style="margin-top:14px;"></div>
|
||
<button class="btn btn-outline" id="nis2-isms-btn-next-step5" style="margin-top:14px;" onclick="goStep(5)" data-i18n="isms.next">Continua</button>
|
||
</div></div>
|
||
</div>
|
||
|
||
<!-- STEP 6 - Monitoring & Readiness (cl.9-10) -->
|
||
<div class="isms-panel" id="panel-5">
|
||
<div class="card"><div class="card-body">
|
||
<h3 data-i18n="isms.s6.title">6. Monitoraggio e Miglioramento (cl. 9-10)</h3>
|
||
<p class="text-muted" data-i18n="isms.s6.hint">Gli audit interni e le non conformità si gestiscono nei moduli esistenti: <a href="reports.html">Audit & Report</a> e NCR/CAPA.</p>
|
||
<h4 data-i18n="isms.s6.readiness">Completamento del SGSI</h4>
|
||
<div style="text-align:center; margin:14px 0;">
|
||
<div style="font-size:2.6rem; font-weight:800;" id="readiness-pct">0%</div>
|
||
</div>
|
||
<div id="readiness-checklist"></div>
|
||
</div></div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
|
||
<script src="/js/api.js?v=20260624"></script>
|
||
<script src="/js/common.js?v=20260624"></script>
|
||
<!-- Bootstrap Italia bundle (componenti) + override sidebar BI (common-bi.js).
|
||
common-bi.js va DOPO common.js: ridefinisce solo loadSidebar() con markup BI,
|
||
riusando tutti gli helper di common.js (zero backend). -->
|
||
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
|
||
<script>
|
||
if (window.bootstrap && bootstrap.loadFonts) {
|
||
bootstrap.loadFonts('/vendor/bootstrap-italia/dist/fonts');
|
||
}
|
||
</script>
|
||
<script src="/js/common-bi.js?v=20260618"></script>
|
||
<script src="/js/i18n.js?v=20260624"></script>
|
||
<script src="/js/help.js?v=20260624"></script>
|
||
<script src="/js/isms.js"></script>
|
||
</body>
|
||
</html>
|