[DOCS+I18N] Guida aggiornata, i18n idle timeout, 3 documenti commerciali

- help.js: aggiornate sezioni per idle timeout, banner AI dismissible, matrice rischi real-time
- i18n.js: aggiunte 5 chiavi session.* per idle timeout (IT/EN)
- common.js: _showIdleWarning() usa I18n.t() per testi IT/EN
- docs/commercial/scheda-commerciale.html: scheda A4 stampabile (problema/soluzione, moduli, AI, target)
- docs/commercial/scheda-tecnica.html: specifiche stack, architettura, API, DB, sicurezza, deploy
- docs/commercial/presentazione.html: presentazione 10 slide completa (contesto, moduli, AI, compliance, ROI, roadmap)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile 2026-02-20 12:43:17 +01:00
parent 59fad22c0e
commit 1bfca3fbe3
6 changed files with 2323 additions and 10 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,499 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NIS2 Agile — Scheda Commerciale</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Arial, sans-serif;
background: #fff;
color: #1a1a2e;
font-size: 13px;
line-height: 1.5;
}
/* ── Layout A4 ── */
.page {
width: 210mm;
min-height: 297mm;
margin: 0 auto;
padding: 0;
background: #fff;
position: relative;
overflow: hidden;
}
/* ── Header ── */
.header {
background: linear-gradient(135deg, #1a73e8 0%, #0d47a1 60%, #1565c0 100%);
padding: 32px 40px 28px;
position: relative;
overflow: hidden;
}
.header::before {
content: '';
position: absolute;
right: -60px; top: -60px;
width: 200px; height: 200px;
border-radius: 50%;
background: rgba(255,255,255,0.06);
}
.header::after {
content: '';
position: absolute;
right: 40px; bottom: -40px;
width: 140px; height: 140px;
border-radius: 50%;
background: rgba(255,255,255,0.04);
}
.logo-row {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 20px;
}
.logo-icon {
width: 42px; height: 42px;
background: rgba(255,255,255,0.15);
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
}
.logo-icon svg { width: 26px; height: 26px; fill: #fff; }
.logo-text h1 { font-size: 22px; font-weight: 800; color: #fff; letter-spacing: -0.5px; }
.logo-text span { font-size: 10px; color: rgba(255,255,255,0.7); letter-spacing: 1px; text-transform: uppercase; }
.tagline {
font-size: 19px;
font-weight: 700;
color: #fff;
line-height: 1.3;
max-width: 420px;
margin-bottom: 10px;
}
.sub-tagline {
font-size: 12px;
color: rgba(255,255,255,0.8);
max-width: 400px;
}
.badge-row {
display: flex;
gap: 8px;
margin-top: 16px;
flex-wrap: wrap;
}
.badge {
background: rgba(255,255,255,0.15);
color: #fff;
font-size: 10px;
font-weight: 700;
padding: 4px 10px;
border-radius: 20px;
border: 1px solid rgba(255,255,255,0.25);
letter-spacing: 0.3px;
}
/* ── Problema / Soluzione ── */
.problem-solution {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
border-bottom: 1px solid #e8edf3;
}
.problem {
background: #fef2f2;
padding: 20px 24px;
border-right: 1px solid #fecaca;
}
.solution {
background: #f0fdf4;
padding: 20px 24px;
}
.ps-label {
font-size: 9px;
font-weight: 800;
letter-spacing: 1.2px;
text-transform: uppercase;
margin-bottom: 8px;
}
.problem .ps-label { color: #dc2626; }
.solution .ps-label { color: #16a34a; }
.ps-title {
font-size: 13px;
font-weight: 700;
margin-bottom: 10px;
}
.problem .ps-title { color: #991b1b; }
.solution .ps-title { color: #14532d; }
.ps-list { list-style: none; padding: 0; }
.ps-list li {
font-size: 11.5px;
padding: 3px 0 3px 16px;
position: relative;
color: #374151;
}
.ps-list li::before {
content: '';
position: absolute;
left: 0; top: 9px;
width: 5px; height: 5px;
border-radius: 50%;
}
.problem .ps-list li::before { background: #dc2626; }
.solution .ps-list li::before { background: #16a34a; }
/* ── Funzionalità ── */
.features-section {
padding: 22px 40px;
}
.section-title {
font-size: 11px;
font-weight: 800;
letter-spacing: 1.2px;
text-transform: uppercase;
color: #1a73e8;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 2px solid #e8edf3;
}
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 14px;
}
.feature-card {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 8px;
padding: 14px;
}
.feature-icon {
width: 32px; height: 32px;
background: #1a73e8;
border-radius: 7px;
display: flex; align-items: center; justify-content: center;
margin-bottom: 8px;
}
.feature-icon svg { width: 17px; height: 17px; fill: #fff; }
.feature-name {
font-size: 11px;
font-weight: 700;
color: #0d47a1;
margin-bottom: 4px;
}
.feature-desc {
font-size: 10.5px;
color: #4b5563;
line-height: 1.5;
}
.feature-tag {
display: inline-block;
background: #dbeafe;
color: #1d4ed8;
font-size: 9px;
font-weight: 700;
padding: 2px 7px;
border-radius: 10px;
margin-top: 6px;
text-transform: uppercase;
letter-spacing: 0.3px;
}
/* ── Target ── */
.target-section {
background: #f8faff;
border-top: 1px solid #e0eaff;
padding: 18px 40px;
}
.target-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
margin-top: 12px;
}
.target-card {
background: #fff;
border: 1px solid #e0eaff;
border-radius: 8px;
padding: 12px 14px;
display: flex;
gap: 10px;
align-items: flex-start;
}
.target-num {
width: 26px; height: 26px;
background: linear-gradient(135deg, #1a73e8, #0d47a1);
color: #fff;
border-radius: 6px;
display: flex; align-items: center; justify-content: center;
font-size: 12px;
font-weight: 800;
flex-shrink: 0;
}
.target-name { font-size: 11px; font-weight: 700; color: #1a1a2e; margin-bottom: 2px; }
.target-desc { font-size: 10px; color: #6b7280; }
/* ── AI Section ── */
.ai-section {
border-top: 1px solid #e8edf3;
padding: 18px 40px;
background: linear-gradient(135deg, #fdf4ff 0%, #f0f9ff 100%);
display: flex;
gap: 20px;
align-items: center;
}
.ai-icon-wrap {
width: 52px; height: 52px;
background: linear-gradient(135deg, #7c3aed, #2563eb);
border-radius: 12px;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.ai-icon-wrap svg { width: 28px; height: 28px; fill: #fff; }
.ai-title { font-size: 14px; font-weight: 800; color: #4c1d95; margin-bottom: 4px; }
.ai-desc { font-size: 11px; color: #5b21b6; line-height: 1.5; }
.ai-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.ai-chip {
background: rgba(124,58,237,0.1);
color: #6d28d9;
font-size: 9.5px;
font-weight: 600;
padding: 3px 8px;
border-radius: 10px;
border: 1px solid rgba(124,58,237,0.2);
}
/* ── Stats ── */
.stats-bar {
background: #0d47a1;
padding: 14px 40px;
display: flex;
justify-content: space-around;
align-items: center;
}
.stat-item { text-align: center; }
.stat-num { font-size: 20px; font-weight: 800; color: #fff; }
.stat-label { font-size: 9px; color: rgba(255,255,255,0.7); text-transform: uppercase; letter-spacing: 0.5px; }
.stat-sep { width: 1px; height: 32px; background: rgba(255,255,255,0.2); }
/* ── Footer ── */
.footer {
border-top: 1px solid #e8edf3;
padding: 14px 40px;
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
}
.footer-brand { font-size: 12px; font-weight: 800; color: #1a73e8; }
.footer-url { font-size: 11px; color: #6b7280; }
.footer-compliance {
font-size: 9px;
color: #9ca3af;
text-align: right;
line-height: 1.4;
}
@media print {
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.page { width: 100%; margin: 0; }
}
</style>
</head>
<body>
<div class="page">
<!-- HEADER -->
<div class="header">
<div class="logo-row">
<div class="logo-icon">
<svg viewBox="0 0 24 24"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 2.18l7 3.12v4.7c0 4.83-3.23 9.36-7 10.57C8.23 20.36 5 15.83 5 11V6.3l7-3.12zM10 12.5l-2-2-1.41 1.41L10 15.32l5.41-5.41L14 8.5l-4 4z"/></svg>
</div>
<div class="logo-text">
<h1>NIS2 Agile</h1>
<span>Compliance Platform</span>
</div>
</div>
<div class="tagline">La piattaforma SaaS che rende semplice la conformità alla Direttiva NIS2</div>
<div class="sub-tagline">Gestione integrata di rischi, incidenti, policy e audit — con AI integrata — per soggetti essenziali e importanti ai sensi del D.Lgs. 138/2024</div>
<div class="badge-row">
<span class="badge">D.Lgs. 138/2024</span>
<span class="badge">Direttiva UE 2022/2555</span>
<span class="badge">AI Powered</span>
<span class="badge">Multi-Tenant SaaS</span>
<span class="badge">ISO 27001 Aligned</span>
</div>
</div>
<!-- PROBLEMA / SOLUZIONE -->
<div class="problem-solution">
<div class="problem">
<div class="ps-label">Il Problema</div>
<div class="ps-title">La NIS2 è obbligatoria. La compliance è complessa.</div>
<ul class="ps-list">
<li>Sanzioni fino a €10M o 2% fatturato globale</li>
<li>Responsabilità personale dei dirigenti</li>
<li>Obblighi stringenti su notifiche, rischi, policy, formazione</li>
<li>Processi dispersi tra Excel, email e documenti non strutturati</li>
<li>Assenza di visibilità real-time sul livello di compliance</li>
</ul>
</div>
<div class="solution">
<div class="ps-label">La Soluzione</div>
<div class="ps-title">NIS2 Agile centralizza e automatizza tutto.</div>
<ul class="ps-list">
<li>Gap analysis automatica sui 10 requisiti Art. 21</li>
<li>Gestione incidenti con timeline Art. 23 (24h/72h/30gg)</li>
<li>Risk register con matrice ISO 27005</li>
<li>Policy generate dall'AI e approvabili con un clic</li>
<li>Dashboard di compliance con score aggiornato in real-time</li>
</ul>
</div>
</div>
<!-- FUNZIONALITÀ CHIAVE -->
<div class="features-section">
<div class="section-title">Moduli Inclusi</div>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"/><path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm9.707 5.707a1 1 0 00-1.414-1.414L9 12.586l-1.293-1.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Gap Analysis NIS2</div>
<div class="feature-desc">Wizard di assessment con 80 domande sui 10 requisiti Art. 21. Punteggio automatico e report di priorità.</div>
<span class="feature-tag">Art. 21</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zM11 14a1 1 0 11-2 0 1 1 0 012 0zm0-7a1 1 0 10-2 0v3a1 1 0 102 0V7z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Gestione Rischi</div>
<div class="feature-desc">Risk register completo con matrice 5×5, trattamenti e ownership. Conforme ISO 27005.</div>
<span class="feature-tag">ISO 27005</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z"/></svg>
</div>
<div class="feature-name">Gestione Incidenti</div>
<div class="feature-desc">Timeline automatica 24h/72h/30gg con notifiche CSIRT. Decision tree per incidenti significativi.</div>
<span class="feature-tag">Art. 23</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Policy Management</div>
<div class="feature-desc">Ciclo di vita completo con approvazione. Template per tutte le categorie NIS2.</div>
<span class="feature-tag">Art. 21</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Supply Chain Security</div>
<div class="feature-desc">Valutazione fornitori critici con scoring automatico e monitoraggio scadenze contrattuali.</div>
<span class="feature-tag">Art. 21(d)</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zm6-4a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zm6-3a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z"/></svg>
</div>
<div class="feature-name">Audit & Report</div>
<div class="feature-desc">Audit log immutabile, evidenze allegabili, report esecutivo e export CSV multi-modulo.</div>
<span class="feature-tag">Art. 32-33</span>
</div>
</div>
</div>
<!-- AI SECTION -->
<div class="ai-section">
<div class="ai-icon-wrap">
<svg viewBox="0 0 20 20"><path d="M5 2a1 1 0 011 1v1h1a1 1 0 010 2H6v1a1 1 0 01-2 0V6H3a1 1 0 010-2h1V3a1 1 0 011-1zm0 10a1 1 0 011 1v1h1a1 1 0 110 2H6v1a1 1 0 11-2 0v-1H3a1 1 0 110-2h1v-1a1 1 0 011-1zm7-10a1 1 0 01.967.744L14.146 7.2 17.5 8.512a1 1 0 010 1.836l-3.354 1.311-1.18 4.456a1 1 0 01-1.932 0L9.854 11.66 6.5 10.348a1 1 0 010-1.836l3.354-1.311 1.18-4.456A1 1 0 0112 2z"/></svg>
</div>
<div>
<div class="ai-title">AI Integrata con Claude (Anthropic)</div>
<div class="ai-desc">NIS2 Agile integra l'AI generativa per ridurre drasticamente il tempo dedicato alla compliance. L'AI analizza i gap, suggerisce rischi specifici per settore, genera policy complete e classifica automaticamente la gravità degli incidenti.</div>
<div class="ai-chips">
<span class="ai-chip">Gap Analysis AI</span>
<span class="ai-chip">Risk Suggest AI</span>
<span class="ai-chip">Policy Generate AI</span>
<span class="ai-chip">Incident Classify AI</span>
<span class="ai-chip">Dati anonimizzati</span>
</div>
</div>
</div>
<!-- STATS BAR -->
<div class="stats-bar">
<div class="stat-item">
<div class="stat-num">15</div>
<div class="stat-label">Moduli Integrati</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">80</div>
<div class="stat-label">Domande Assessment</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">22</div>
<div class="stat-label">Tabelle DB / 7 Ruoli</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">100%</div>
<div class="stat-label">Art. 21 Copertura</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">SaaS</div>
<div class="stat-label">Multi-Tenant</div>
</div>
</div>
<!-- TARGET -->
<div class="target-section">
<div class="section-title">A chi è destinato</div>
<div class="target-grid">
<div class="target-card">
<div class="target-num">1</div>
<div>
<div class="target-name">PMI — Soggetti Importanti</div>
<div class="target-desc">Medie imprese nei settori Allegato I e II che necessitano di compliance NIS2 strutturata senza un team IT dedicato.</div>
</div>
</div>
<div class="target-card">
<div class="target-num">2</div>
<div>
<div class="target-name">Enterprise — Soggetti Essenziali</div>
<div class="target-desc">Grandi organizzazioni in settori critici (energia, trasporti, sanità, finanza, ICT) soggette a vigilanza proattiva AGID/ACN.</div>
</div>
</div>
<div class="target-card">
<div class="target-num">3</div>
<div>
<div class="target-name">Consulenti & CISO</div>
<div class="target-desc">Consulenti di sicurezza e CISO che gestiscono la compliance NIS2 per conto di più organizzazioni clienti da un'unica piattaforma.</div>
</div>
</div>
</div>
</div>
<!-- FOOTER -->
<div class="footer">
<div>
<div class="footer-brand">NIS2 Agile</div>
<div class="footer-url">nis2.certisource.it</div>
</div>
<div class="footer-compliance">
Conforme a D.Lgs. 138/2024 (recepimento Direttiva UE 2022/2555)<br>
Allineato ISO 27001 · GDPR · ACN Framework
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,660 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NIS2 Agile — Scheda Tecnica</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Arial, sans-serif;
background: #f8faff;
color: #1a1a2e;
font-size: 12.5px;
line-height: 1.6;
}
.page {
width: 210mm;
margin: 0 auto;
background: #fff;
}
/* ── Header ── */
.header {
background: #0d2137;
padding: 24px 36px 20px;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.header-left h1 { font-size: 18px; font-weight: 800; color: #fff; margin-bottom: 4px; }
.header-left p { font-size: 10px; color: #7ea8c4; text-transform: uppercase; letter-spacing: 1px; }
.header-right {
text-align: right;
}
.version-badge {
display: inline-block;
background: #1a73e8;
color: #fff;
font-size: 9px;
font-weight: 700;
padding: 4px 10px;
border-radius: 4px;
margin-bottom: 4px;
}
.header-right p { font-size: 9px; color: #7ea8c4; }
/* ── Content ── */
.content { padding: 0 36px 24px; }
/* ── Section ── */
.section { margin-top: 22px; }
.section-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
padding-bottom: 6px;
border-bottom: 2px solid #e0eaff;
}
.section-num {
width: 22px; height: 22px;
background: #1a73e8;
color: #fff;
border-radius: 5px;
display: flex; align-items: center; justify-content: center;
font-size: 11px;
font-weight: 800;
flex-shrink: 0;
}
.section-title {
font-size: 12px;
font-weight: 800;
color: #0d2137;
text-transform: uppercase;
letter-spacing: 0.8px;
}
/* ── Stack grid ── */
.stack-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.stack-item {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 6px;
padding: 10px 14px;
display: flex;
gap: 10px;
align-items: flex-start;
}
.stack-label {
font-size: 9px;
font-weight: 800;
color: #1a73e8;
text-transform: uppercase;
letter-spacing: 0.5px;
min-width: 80px;
flex-shrink: 0;
padding-top: 1px;
}
.stack-value {
font-size: 11px;
color: #374151;
line-height: 1.5;
}
.stack-value strong { color: #0d2137; font-weight: 700; }
/* ── Architettura ── */
.arch-diagram {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 8px;
padding: 16px;
font-size: 11px;
}
.arch-layers {
display: flex;
flex-direction: column;
gap: 8px;
}
.arch-layer {
display: flex;
gap: 8px;
align-items: center;
}
.arch-layer-label {
font-size: 8.5px;
font-weight: 800;
color: #6b7280;
text-transform: uppercase;
letter-spacing: 0.5px;
min-width: 68px;
text-align: right;
}
.arch-layer-boxes {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.arch-box {
background: #1a73e8;
color: #fff;
font-size: 9.5px;
font-weight: 600;
padding: 4px 10px;
border-radius: 4px;
white-space: nowrap;
}
.arch-box.alt { background: #0d47a1; }
.arch-box.gray { background: #4b5563; }
.arch-box.green { background: #059669; }
.arch-box.purple { background: #7c3aed; }
.arch-arrow {
font-size: 16px;
color: #9ca3af;
text-align: center;
padding-left: 68px;
margin: -4px 0;
}
/* ── API table ── */
.api-table {
width: 100%;
border-collapse: collapse;
font-size: 10.5px;
}
.api-table th {
background: #0d2137;
color: #fff;
padding: 6px 10px;
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
text-align: left;
}
.api-table td {
padding: 5px 10px;
border-bottom: 1px solid #e8edf3;
vertical-align: top;
}
.api-table tr:nth-child(even) td { background: #f8faff; }
.method {
display: inline-block;
font-size: 8.5px;
font-weight: 700;
padding: 1px 5px;
border-radius: 3px;
color: #fff;
}
.get { background: #059669; }
.post { background: #1a73e8; }
.put { background: #d97706; }
.del { background: #dc2626; }
/* ── DB table ── */
.db-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 6px;
}
.db-table-item {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 5px;
padding: 7px 10px;
font-size: 10px;
}
.db-table-name { font-weight: 700; color: #0d2137; margin-bottom: 2px; }
.db-table-desc { font-size: 9px; color: #6b7280; }
/* ── Security ── */
.security-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.sec-item {
background: #f0fdf4;
border: 1px solid #bbf7d0;
border-radius: 6px;
padding: 10px 12px;
}
.sec-item.warn { background: #fff7ed; border-color: #fed7aa; }
.sec-icon { font-size: 15px; margin-bottom: 4px; }
.sec-name { font-size: 10.5px; font-weight: 700; color: #14532d; margin-bottom: 3px; }
.sec-item.warn .sec-name { color: #92400e; }
.sec-desc { font-size: 9.5px; color: #166534; line-height: 1.5; }
.sec-item.warn .sec-desc { color: #78350f; }
/* ── Performance ── */
.perf-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.perf-item {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 6px;
padding: 10px;
text-align: center;
}
.perf-num { font-size: 18px; font-weight: 800; color: #1a73e8; }
.perf-unit { font-size: 9px; color: #6b7280; }
.perf-label { font-size: 9px; color: #4b5563; margin-top: 3px; }
/* ── Deploy ── */
.deploy-options {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.deploy-card {
border: 1px solid #e0eaff;
border-radius: 6px;
padding: 12px;
}
.deploy-type {
font-size: 10px;
font-weight: 800;
color: #0d47a1;
margin-bottom: 6px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.deploy-specs { list-style: none; }
.deploy-specs li {
font-size: 9.5px;
color: #4b5563;
padding: 1px 0 1px 12px;
position: relative;
}
.deploy-specs li::before {
content: '✓';
position: absolute;
left: 0;
color: #1a73e8;
font-size: 8px;
top: 2px;
}
/* ── Compliance map ── */
.compliance-map {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.cm-item {
display: flex;
gap: 8px;
align-items: center;
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 5px;
padding: 7px 10px;
}
.cm-art {
font-size: 9px;
font-weight: 800;
color: #fff;
background: #1a73e8;
padding: 2px 6px;
border-radius: 4px;
white-space: nowrap;
}
.cm-desc { font-size: 10px; color: #374151; }
/* ── Footer ── */
.footer {
background: #0d2137;
padding: 12px 36px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
}
.footer-left { font-size: 10px; color: #7ea8c4; }
.footer-left strong { color: #fff; font-size: 12px; }
.footer-right { font-size: 9px; color: #7ea8c4; text-align: right; }
@media print {
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.page { width: 100%; margin: 0; }
}
</style>
</head>
<body>
<div class="page">
<!-- HEADER -->
<div class="header">
<div class="header-left">
<h1>NIS2 Agile — Scheda Tecnica</h1>
<p>Specifiche di architettura, stack tecnologico e integrazione</p>
</div>
<div class="header-right">
<div class="version-badge">v1.0 — Febbraio 2026</div>
<p>nis2.certisource.it</p>
</div>
</div>
<div class="content">
<!-- 1. STACK TECNOLOGICO -->
<div class="section">
<div class="section-header">
<div class="section-num">1</div>
<div class="section-title">Stack Tecnologico</div>
</div>
<div class="stack-grid">
<div class="stack-item">
<div class="stack-label">Backend</div>
<div class="stack-value"><strong>PHP 8.4</strong> — vanilla, Front Controller pattern, zero dipendenze framework. Router personalizzato con pattern matching per URI gerarchici.</div>
</div>
<div class="stack-item">
<div class="stack-label">Database</div>
<div class="stack-value"><strong>MySQL 8.0</strong> — 22 tabelle, indici ottimizzati, soft delete, trigger immutabili su audit_log. PDO con prepared statements.</div>
</div>
<div class="stack-item">
<div class="stack-label">Frontend</div>
<div class="stack-value"><strong>HTML5 / CSS3 / JavaScript</strong> — vanilla, nessun framework JS. 17 pagine HTML + 3 admin. CSS custom ~1.600 righe. i18n IT/EN integrato.</div>
</div>
<div class="stack-item">
<div class="stack-label">Autenticazione</div>
<div class="stack-value"><strong>JWT HS256</strong> — access token 2h, refresh token 7d. Refresh atomico con SELECT FOR UPDATE. Idle timeout 30min con avviso.</div>
</div>
<div class="stack-item">
<div class="stack-label">AI Integration</div>
<div class="stack-value"><strong>Anthropic Claude</strong> — modello <em>claude-sonnet-4-5</em>. Prompt anonimizzati (no ragione sociale, no fatturato). 4 funzionalità AI.</div>
</div>
<div class="stack-item">
<div class="stack-label">Infrastruttura</div>
<div class="stack-value"><strong>Hetzner CPX31</strong> — Ubuntu, Apache 2.4, subdomain dedicato. Docker-ready (Dockerfile + nginx.conf inclusi).</div>
</div>
</div>
</div>
<!-- 2. ARCHITETTURA -->
<div class="section">
<div class="section-header">
<div class="section-num">2</div>
<div class="section-title">Architettura Sistema</div>
</div>
<div class="arch-diagram">
<div class="arch-layers">
<div class="arch-layer">
<div class="arch-layer-label">Browser</div>
<div class="arch-layer-boxes">
<span class="arch-box">HTML5 Pages</span>
<span class="arch-box alt">api.js Client</span>
<span class="arch-box alt">i18n.js IT/EN</span>
<span class="arch-box alt">common.js Utils</span>
<span class="arch-box alt">help.js</span>
</div>
</div>
<div class="arch-arrow">↓ HTTPS / JWT Bearer</div>
<div class="arch-layer">
<div class="arch-layer-label">Router</div>
<div class="arch-layer-boxes">
<span class="arch-box green">public/index.php — Front Controller</span>
<span class="arch-box gray">.htaccess Rewrite</span>
</div>
</div>
<div class="arch-arrow">↓ /api/{controller}/{action}/{id?}</div>
<div class="arch-layer">
<div class="arch-layer-label">Controllers</div>
<div class="arch-layer-boxes">
<span class="arch-box">Auth</span>
<span class="arch-box">Assessment</span>
<span class="arch-box">Risk</span>
<span class="arch-box">Incident</span>
<span class="arch-box">Policy</span>
<span class="arch-box">SupplyChain</span>
<span class="arch-box">Audit</span>
<span class="arch-box alt">+ 8 altri</span>
</div>
</div>
<div class="arch-arrow">↓ PDO / Services</div>
<div class="arch-layer">
<div class="arch-layer-label">Services</div>
<div class="arch-layer-boxes">
<span class="arch-box purple">AIService (Claude)</span>
<span class="arch-box gray">EmailService</span>
<span class="arch-box gray">ReportService</span>
<span class="arch-box gray">RateLimitService</span>
<span class="arch-box gray">VisuraService</span>
</div>
</div>
<div class="arch-arrow">↓ PDO Singleton</div>
<div class="arch-layer">
<div class="arch-layer-label">Database</div>
<div class="arch-layer-boxes">
<span class="arch-box green">MySQL 8.0 — nis2_agile_db — 22 tabelle</span>
</div>
</div>
</div>
</div>
</div>
<!-- 3. API ENDPOINTS -->
<div class="section">
<div class="section-header">
<div class="section-num">3</div>
<div class="section-title">API REST — Endpoint Principali</div>
</div>
<p style="font-size:10px;color:#6b7280;margin-bottom:8px;">Base URL: <code style="background:#f8faff;padding:1px 5px;border-radius:3px;font-size:10px;">https://nis2.certisource.it/api/{controller}/{action}/{id?}</code> — Auth: Bearer JWT + X-Organization-Id header</p>
<table class="api-table">
<thead>
<tr>
<th style="width:16%">Modulo</th>
<th style="width:12%">Metodo</th>
<th style="width:35%">Endpoint</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody>
<tr><td>Auth</td><td><span class="method post">POST</span></td><td>/auth/login, /register, /refresh</td><td>Login, registrazione, rinnovo token JWT</td></tr>
<tr><td>Auth</td><td><span class="method get">GET</span></td><td>/auth/me</td><td>Dati utente autenticato e organizzazioni</td></tr>
<tr><td>Organizations</td><td><span class="method post">POST</span></td><td>/organizations/create, /classify</td><td>Crea org, classifica soggetto NIS2</td></tr>
<tr><td>Assessment</td><td><span class="method get">GET</span></td><td>/assessments/{id}/questions</td><td>80 domande gap analysis (10 categorie Art.21)</td></tr>
<tr><td>Assessment</td><td><span class="method post">POST</span></td><td>/assessments/{id}/ai-analyze</td><td>Analisi AI dei gap con raccomandazioni</td></tr>
<tr><td>Risks</td><td><span class="method get">GET</span></td><td>/risks/matrix</td><td>Matrice rischi 5×5 aggregata</td></tr>
<tr><td>Risks</td><td><span class="method post">POST</span></td><td>/risks/ai-suggest</td><td>Suggerimenti rischi AI per settore/asset</td></tr>
<tr><td>Incidents</td><td><span class="method post">POST</span></td><td>/incidents/{id}/early-warning</td><td>Early warning CSIRT entro 24h (Art.23)</td></tr>
<tr><td>Incidents</td><td><span class="method post">POST</span></td><td>/incidents/{id}/final-report</td><td>Report finale CSIRT entro 30gg (Art.23)</td></tr>
<tr><td>Policies</td><td><span class="method post">POST</span></td><td>/policies/ai-generate</td><td>Genera policy NIS2 con AI (per categoria)</td></tr>
<tr><td>Audit</td><td><span class="method get">GET</span></td><td>/audit/executive-report</td><td>Report esecutivo HTML stampabile</td></tr>
<tr><td>Audit</td><td><span class="method get">GET</span></td><td>/audit/export?type=risks</td><td>Export CSV (rischi/incidenti/controlli/asset)</td></tr>
<tr><td>NCR/CAPA</td><td><span class="method post">POST</span></td><td>/ncr/from-assessment</td><td>Genera NCR automatiche dai gap assessment</td></tr>
<tr><td>Onboarding</td><td><span class="method post">POST</span></td><td>/onboarding/upload-visura</td><td>Estrazione AI da PDF visura camerale</td></tr>
</tbody>
</table>
</div>
<!-- 4. DATABASE -->
<div class="section">
<div class="section-header">
<div class="section-num">4</div>
<div class="section-title">Schema Database — 22 Tabelle</div>
</div>
<div class="db-grid">
<div class="db-table-item"><div class="db-table-name">organizations</div><div class="db-table-desc">Tenant principale + classificazione NIS2</div></div>
<div class="db-table-item"><div class="db-table-name">users</div><div class="db-table-desc">Utenti (7 ruoli, multi-org)</div></div>
<div class="db-table-item"><div class="db-table-name">user_organizations</div><div class="db-table-desc">Mapping utente↔org + ruolo</div></div>
<div class="db-table-item"><div class="db-table-name">refresh_tokens</div><div class="db-table-desc">Token refresh JWT indicizzati</div></div>
<div class="db-table-item"><div class="db-table-name">assessments</div><div class="db-table-desc">Sessioni gap analysis</div></div>
<div class="db-table-item"><div class="db-table-name">assessment_responses</div><div class="db-table-desc">Risposte singole domande</div></div>
<div class="db-table-item"><div class="db-table-name">risks</div><div class="db-table-desc">Register rischi (soft delete)</div></div>
<div class="db-table-item"><div class="db-table-name">risk_treatments</div><div class="db-table-desc">Piani di trattamento</div></div>
<div class="db-table-item"><div class="db-table-name">incidents</div><div class="db-table-desc">Incidenti + flag significativo</div></div>
<div class="db-table-item"><div class="db-table-name">incident_timeline</div><div class="db-table-desc">Aggiornamenti e notifiche</div></div>
<div class="db-table-item"><div class="db-table-name">policies</div><div class="db-table-desc">Policy (soft delete, versioning)</div></div>
<div class="db-table-item"><div class="db-table-name">suppliers</div><div class="db-table-desc">Fornitori catena approvv.</div></div>
<div class="db-table-item"><div class="db-table-name">training_courses</div><div class="db-table-desc">Catalogo corsi formazione</div></div>
<div class="db-table-item"><div class="db-table-name">training_assignments</div><div class="db-table-desc">Assegnazioni e completamenti</div></div>
<div class="db-table-item"><div class="db-table-name">assets</div><div class="db-table-desc">Inventario ICT (4 tipi)</div></div>
<div class="db-table-item"><div class="db-table-name">compliance_controls</div><div class="db-table-desc">Controlli NIS2 per org</div></div>
<div class="db-table-item"><div class="db-table-name">evidence_files</div><div class="db-table-desc">Allegati e documenti audit</div></div>
<div class="db-table-item"><div class="db-table-name">audit_logs</div><div class="db-table-desc">Log immutabili (trigger MySQL)</div></div>
<div class="db-table-item"><div class="db-table-name">ai_interactions</div><div class="db-table-desc">Storico chiamate API AI</div></div>
<div class="db-table-item"><div class="db-table-name">email_log</div><div class="db-table-desc">Log notifiche email CSIRT</div></div>
<div class="db-table-item"><div class="db-table-name">non_conformities</div><div class="db-table-desc">NCR — Non Conformity Reports</div></div>
<div class="db-table-item"><div class="db-table-name">corrective_actions</div><div class="db-table-desc">CAPA — Azioni correttive</div></div>
</div>
</div>
<!-- 5. SICUREZZA -->
<div class="section">
<div class="section-header">
<div class="section-num">5</div>
<div class="section-title">Sicurezza Applicativa</div>
</div>
<div class="security-grid">
<div class="sec-item">
<div class="sec-name">JWT + Refresh Token Atomico</div>
<div class="sec-desc">Access token 2h, refresh 7d. Rinnovo con SELECT FOR UPDATE (no race conditions). Revoca token al logout.</div>
</div>
<div class="sec-item">
<div class="sec-name">CORS Configurato</div>
<div class="sec-desc">No wildcard. Origin verificata contro lista bianca configurabile. Header personalizzati sicuri.</div>
</div>
<div class="sec-item">
<div class="sec-name">Rate Limiting</div>
<div class="sec-desc">File-based per IP (proxy-aware, X-Forwarded-For). Login: 5/min, 20/h. Register: 3/10min. AI: 10/min.</div>
</div>
<div class="sec-item">
<div class="sec-name">SQL Injection Prevention</div>
<div class="sec-desc">PDO esclusivo con prepared statements. Nessuna concatenazione di query. Input validato lato server.</div>
</div>
<div class="sec-item">
<div class="sec-name">XSS Prevention</div>
<div class="sec-desc">escapeHtml() su ogni output frontend. Content-Security-Policy header configurato.</div>
</div>
<div class="sec-item">
<div class="sec-name">Audit Log Immutabile</div>
<div class="sec-desc">Trigger MySQL prevent_update + prevent_delete su audit_logs. Ogni operazione registrata con utente, azione e timestamp.</div>
</div>
<div class="sec-item">
<div class="sec-name">AI Data Privacy</div>
<div class="sec-desc">Prompt anonimizzati: ragione sociale e fatturato mai inviati ad Anthropic. Dipendenti convertiti in range (micro/piccola/media/grande).</div>
</div>
<div class="sec-item warn">
<div class="sec-name">Idle Session Timeout</div>
<div class="sec-desc">Logout automatico dopo 30 min di inattività. Avviso con countdown 5 min. Monitoraggio eventi mouse/keyboard/scroll.</div>
</div>
</div>
</div>
<!-- 6. PERFORMANCE -->
<div class="section">
<div class="section-header">
<div class="section-num">6</div>
<div class="section-title">Performance Target</div>
</div>
<div class="perf-grid">
<div class="perf-item">
<div class="perf-num">&lt;1s</div>
<div class="perf-unit">secondi</div>
<div class="perf-label">Caricamento Dashboard</div>
</div>
<div class="perf-item">
<div class="perf-num">&lt;2s</div>
<div class="perf-unit">secondi</div>
<div class="perf-label">Report Compliance</div>
</div>
<div class="perf-item">
<div class="perf-num">100+</div>
<div class="perf-unit">rischi</div>
<div class="perf-label">Matrice Fluida</div>
</div>
<div class="perf-item">
<div class="perf-num"></div>
<div class="perf-unit">tenant</div>
<div class="perf-label">Multi-Tenant Isolati</div>
</div>
</div>
</div>
<!-- 7. DEPLOY -->
<div class="section">
<div class="section-header">
<div class="section-num">7</div>
<div class="section-title">Opzioni di Deploy</div>
</div>
<div class="deploy-options">
<div class="deploy-card">
<div class="deploy-type">Cloud SaaS</div>
<ul class="deploy-specs">
<li>Hosting su nis2.certisource.it</li>
<li>Zero configurazione client</li>
<li>Aggiornamenti automatici</li>
<li>Backup giornaliero incluso</li>
<li>SSL/TLS incluso</li>
</ul>
</div>
<div class="deploy-card">
<div class="deploy-type">On-Premise / VPS</div>
<ul class="deploy-specs">
<li>PHP 8.4 + MySQL 8.0 + Apache/Nginx</li>
<li>Deploy via git pull + .env config</li>
<li>Supporto subdomain dedicato</li>
<li>Documentazione SQL migrations</li>
<li>Chiave SSH per accesso sicuro</li>
</ul>
</div>
<div class="deploy-card">
<div class="deploy-type">Docker / Container</div>
<ul class="deploy-specs">
<li>Dockerfile ottimizzato incluso</li>
<li>docker-compose.yml pronto</li>
<li>nginx.conf + php.ini configurati</li>
<li>Compatibile Kubernetes</li>
<li>Multi-stage build support</li>
</ul>
</div>
</div>
</div>
<!-- 8. COMPLIANCE MAP -->
<div class="section">
<div class="section-header">
<div class="section-num">8</div>
<div class="section-title">Copertura Normativa NIS2</div>
</div>
<div class="compliance-map">
<div class="cm-item"><span class="cm-art">Art. 20</span><div class="cm-desc">Governance — Formazione obbligatoria management, responsabilità organi</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.1</span><div class="cm-desc">Risk-based approach — Risk register, matrice rischi, trattamenti</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(a)</span><div class="cm-desc">Politiche sicurezza — Gap analysis 80 domande, policy management</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(b)</span><div class="cm-desc">Gestione incidenti — Ciclo di vita, classificazione AI, timeline</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(c)</span><div class="cm-desc">Business continuity — Asset inventory, dipendenze, backup</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(d)</span><div class="cm-desc">Supply chain — Registro fornitori, valutazione rischio, scoring</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(g)</span><div class="cm-desc">Formazione — Training management, compliance tracking, report</div></div>
<div class="cm-item"><span class="cm-art">Art. 23</span><div class="cm-desc">Notifica incidenti — Early warning 24h, notifica 72h, report 30gg</div></div>
<div class="cm-item"><span class="cm-art">Art. 32-33</span><div class="cm-desc">Vigilanza — Audit log immutabili, evidenze, controlli compliance</div></div>
<div class="cm-item"><span class="cm-art">D.Lgs. 138/2024</span><div class="cm-desc">Recepimento italiano NIS2 — Classificazione soggetti, settori</div></div>
</div>
</div>
</div><!-- /content -->
<!-- FOOTER -->
<div class="footer">
<div class="footer-left">
<strong>NIS2 Agile</strong><br>
Piattaforma SaaS compliance NIS2 per PMI e Enterprise
</div>
<div class="footer-right">
nis2.certisource.it<br>
Versione 1.0 · Febbraio 2026<br>
24.000+ righe di codice · 50+ file sorgente
</div>
</div>
</div>
</body>
</html>

View File

@ -510,25 +510,26 @@ function _showIdleWarning() {
'background:rgba(0,0,0,0.55)', 'display:flex', 'align-items:center', 'justify-content:center'
].join(';');
const _t = (key, fallback) => (typeof I18n !== 'undefined' ? I18n.t(key) : fallback);
overlay.innerHTML = `
<div style="background:var(--card-bg,#fff);border-radius:12px;padding:32px;max-width:400px;width:90%;text-align:center;box-shadow:0 20px 60px rgba(0,0,0,0.3);">
<div style="width:56px;height:56px;background:#fff7ed;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">
<svg width="28" height="28" viewBox="0 0 20 20" fill="#c2410c"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/></svg>
</div>
<h3 style="font-size:1.1rem;font-weight:700;color:var(--gray-800,#1f2937);margin-bottom:8px;">Sessione in scadenza</h3>
<h3 style="font-size:1.1rem;font-weight:700;color:var(--gray-800,#1f2937);margin-bottom:8px;">${_t('session.expiring_title', 'Sessione in scadenza')}</h3>
<p style="font-size:0.875rem;color:var(--gray-500,#6b7280);margin-bottom:20px;">
Per motivi di sicurezza, verrai disconnesso tra<br>
${_t('session.expiring_msg', 'Per motivi di sicurezza, verrai disconnesso tra')}<br>
<strong id="idle-countdown" style="font-size:1.5rem;color:#c2410c;display:block;margin:8px 0;">5:00</strong>
a causa di inattivita'.
${_t('session.idle_reason', "a causa di inattivita'.")}
</p>
<div style="display:flex;gap:12px;justify-content:center;">
<button id="idle-stay-btn"
style="padding:10px 24px;background:var(--primary,#2563eb);color:#fff;border:none;border-radius:8px;font-weight:600;cursor:pointer;font-size:0.875rem;">
Rimani connesso
${_t('session.stay', 'Rimani connesso')}
</button>
<button onclick="api.logout();"
style="padding:10px 24px;background:var(--gray-100,#f3f4f6);color:var(--gray-700,#374151);border:none;border-radius:8px;font-weight:600;cursor:pointer;font-size:0.875rem;">
Disconnetti
${_t('session.logout_now', 'Disconnetti')}
</button>
</div>
</div>

View File

@ -151,7 +151,8 @@ const HelpSystem = (function () {
items: [
'Ogni rischio registrato include: descrizione, categoria, asset coinvolti, owner e piano di trattamento.',
'Lo stato di ogni rischio e\' tracciato nel tempo con lo storico delle modifiche.',
'I rischi possono essere collegati ad asset, incidenti e controlli di compliance.'
'I rischi possono essere collegati ad asset, incidenti e controlli di compliance.',
'La <strong>Matrice Rischi</strong> si aggiorna in tempo reale: eliminando un rischio dalla vista dettaglio, la matrice si ricalcola automaticamente senza richiedere un refresh manuale.'
]
}
],
@ -234,7 +235,7 @@ const HelpSystem = (function () {
'La funzione <strong>Genera con AI</strong> crea automaticamente bozze di policy conformi NIS2.',
'L\'AI utilizza il contesto della tua organizzazione (settore, dimensione, classificazione) per personalizzare il contenuto.',
'Le policy generate includono: obiettivo, ambito di applicazione, responsabilita\', procedure e riferimenti normativi.',
'Le bozze generate devono essere revisionate e personalizzate prima dell\'approvazione.'
'Le bozze AI sono contrassegnate da un <strong>banner arancione di avviso</strong> che ricorda l\'obbligo di revisione prima dell\'approvazione. Il banner puo\' essere chiuso premendo la X.'
]
},
{
@ -485,10 +486,11 @@ const HelpSystem = (function () {
]
},
{
heading: 'Sicurezza',
heading: 'Sicurezza Account',
items: [
'Modifica la password del tuo account.',
'Visualizza le sessioni attive e disconnetti dispositivi remoti.',
'Modifica la password del tuo account in qualsiasi momento.',
'La piattaforma applica un <strong>timeout di sessione automatico</strong> dopo 30 minuti di inattivita\'. Un avviso con countdown appare 5 minuti prima del logout per permetterti di rimanere connesso.',
'Il logout automatico protegge le informazioni sensibili in caso di postazione incustodita.',
'Configura le impostazioni di notifica per scadenze e alert.'
]
}

View File

@ -168,6 +168,13 @@ const I18n = (function () {
'msg.error_connection': { it: 'Errore di connessione al server.', en: 'Server connection error.' },
'msg.no_data': { it: 'Nessun dato disponibile.', en: 'No data available.' },
// ── Sessione / Idle timeout ─────────────────────
'session.expiring_title': { it: 'Sessione in scadenza', en: 'Session expiring' },
'session.expiring_msg': { it: 'Per motivi di sicurezza, verrai disconnesso tra', en: 'For security reasons, you will be logged out in' },
'session.idle_reason': { it: 'a causa di inattivita\'.', en: 'due to inactivity.' },
'session.stay': { it: 'Rimani connesso', en: 'Stay connected' },
'session.logout_now': { it: 'Disconnetti', en: 'Log out' },
// ── Tempo relativo ─────────────────────────────
'time.now': { it: 'Adesso', en: 'Just now' },
'time.min_ago': { it: 'min fa', en: 'min ago' },