[FIX] Epic C / C5 open-items — upload ripristinato + fonti ACN aggiornate + UI

- UPLOAD ALLEGATI RIPRISTINATO in prod (causa: il sito è servito da php-fpm HOST e
  public/uploads era git:git senza ACL per www-data → move_uploaded_file falliva;
  fix host: setfacl -R -m u:www-data:rwx -m d:u:www-data:rwx public/uploads). Collaudato:
  upload interno+portale .pdf 201, .html→422. Risolve anche evidence_files/visure.
- nis2_sources.php (fonti-certe): Determina 333017/2025 datata 22 settembre 2025 e marcata
  STORICA/superata; aggiunta entry VIGENTE 379887/2025 (efficace dal 31/12/2025); URL ACN
  autorevoli (date-giorno marcate [da confermare sul testo ufficiale], verifica nis2-expert).
- UI attività: create+assign non lascia più attività orfane su errore (no duplicati su retry,
  messaggio chiaro) + assegnazione individuale richiede almeno un destinatario; blocco PWA di
  stakeholder-activities allineato (favicon-16/status-bar/application-name). v1.21.2.

ESCALATION (decisione di Simon, non modificata): nis2_sources.php riga 79 riporta "37 misure /
92 requisiti" per gli importanti (dato file Simon), ma la pagina UFFICIALE ACN indica "37/87".
Da riconciliare con Simon (open item #2). NON cambiato per rispettare la decisione bloccata.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-06-16 23:11:40 +02:00
co-authored by Claude Opus 4.8
parent f065d70dda
commit 3051983003
4 changed files with 29 additions and 14 deletions
+14 -5
View File
@@ -52,16 +52,25 @@ return [
'full' => 'Determinazione del Direttore generale dell\'Agenzia per la Cybersicurezza Nazionale n. 164179 del 14 aprile 2025, in attuazione del D.Lgs. 138/2024, che stabilisce modalita e specifiche di base per gli obblighi di cui agli articoli 23, 24, 25, 29 e 32 (incluse classificazione e notifica degli incidenti significativi: Allegato 3 = soggetti IMPORTANTI, Allegato 4 = soggetti ESSENZIALI).',
'file' => 'docs/nis2/Determina164179_apr2025.pdf',
'authority' => 'Agenzia per la Cybersicurezza Nazionale (ACN)',
'url' => 'https://www.acn.gov.it/',
'url' => 'https://www.acn.gov.it/portale/w/nis-avviata-la-seconda-fase',
],
'determina_333017_2025' => [
'key' => 'determina_333017_2025',
'short' => 'Determina ACN 333017/2025',
'citation' => 'Determinazione ACN n. 333017 del settembre 2025',
'full' => 'Determinazione del Direttore generale ACN n. 333017 (settembre 2025): termini, modalita e procedimenti di utilizzo e accesso alla piattaforma digitale ACN, ulteriori informazioni che i soggetti devono fornire e designazione dei rappresentanti NIS sul territorio nazionale.',
'short' => 'Determina ACN 333017/2025 (storica, superata)',
'citation' => 'Determinazione ACN n. 333017 del 22 settembre 2025 (SUPERATA dalla n. 379887/2025)',
'full' => 'Determinazione del Direttore generale ACN n. 333017 del 22 settembre 2025 [data-giorno da confermare sul testo ufficiale]: termini, modalita e procedimenti di utilizzo e accesso alla piattaforma digitale ACN, ulteriori informazioni che i soggetti devono fornire e designazione dei rappresentanti NIS sul territorio nazionale. NOTA: citazione STORICA, SUPERATA dalla Determinazione ACN n. 379887/2025 (efficace dal 31 dicembre 2025); per piattaforma/registrazione/designazioni fare riferimento alla 379887.',
'file' => 'docs/nis2/Determina333017_sett2025.pdf',
'authority' => 'Agenzia per la Cybersicurezza Nazionale (ACN)',
'url' => 'https://www.acn.gov.it/',
'url' => 'https://www.acn.gov.it/portale/w/nis-avviata-la-seconda-fase',
],
'determina_379887_2025' => [
'key' => 'determina_379887_2025',
'short' => 'Determina ACN 379887/2025 (vigente)',
'citation' => 'Determinazione ACN n. 379887/2025, efficace dal 31 dicembre 2025',
'full' => 'Determinazione del Direttore generale ACN n. 379887/2025 (adozione 19 dicembre 2025 [da confermare sul testo ufficiale], efficacia dal 31 dicembre 2025) che SOSTITUISCE la n. 333017/2025: disciplina il Portale ACN e i Servizi NIS per il ciclo di registrazione 2026 (registrazione, aggiornamento dei dati entro 10 giorni dalla presentazione, designazioni incluso il referente CSIRT). Fonte VIGENTE per piattaforma/registrazione/designazioni.',
'file' => null,
'authority' => 'Agenzia per la Cybersicurezza Nazionale (ACN)',
'url' => 'https://www.acn.gov.it/portale/w/nis-avviata-la-seconda-fase',
],
'ambiti_nis2' => [
'key' => 'ambiti_nis2',
+13 -7
View File
@@ -61,10 +61,13 @@
<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>
@@ -417,17 +420,20 @@
planned_date: el('act-planned').value || null, due_date: el('act-due').value || null,
policy_ids: getMulti('act-proc'),
};
const indIds = mode === 'individual' ? getMulti('act-stakeholders') : [];
if (mode === 'individual' && !indIds.length) { el('act-err').textContent = 'Seleziona almeno uno stakeholder.'; return; }
const btn = el('act-save'); btn.disabled = true;
try {
let actId;
if (id) { await api.stkActUpdate(parseInt(id, 10), payload); actId = parseInt(id, 10); }
else { const r = await api.stkActCreate(payload); actId = r.id; }
// assegnazione immediata
if (mode === 'individual') {
const ids = getMulti('act-stakeholders');
if (ids.length) await api.stkActAssign(actId, { stakeholder_ids: ids });
} else {
await api.stkActAssign(actId, {});
else { const r = await api.stkActCreate(payload); actId = r.id; el('act-id').value = actId; } // evita create duplicati su retry
// assegnazione immediata; se fallisce, l'attività esiste già: NON ricreare
try {
await api.stkActAssign(actId, mode === 'individual' ? { stakeholder_ids: indIds } : {});
} catch (assignErr) {
await saLoadAll();
el('act-err').textContent = 'Attività salvata, ma assegnazione destinatari non riuscita: ' + (assignErr.message || '') + ' — riprova o assegna dal dettaglio.';
return;
}
showNotification(id ? 'Attività aggiornata.' : 'Attività creata e destinatari assegnati.', 'success');
actClose(); await saLoadAll();
+1 -1
View File
@@ -13,7 +13,7 @@
* Il nome cache include la release: va BUMPATO ad ogni rilascio (vedi version.json),
* cosi' activate elimina automaticamente la shell vecchia.
*/
const CACHE = 'nis2-shell-v1.21.1';
const CACHE = 'nis2-shell-v1.21.2';
const PRECACHE = [
'/offline.html',
+1 -1
View File
@@ -1 +1 @@
{"version": "1.21.1", "build": "2026-06-16-v1.21.1", "date": "2026-06-16", "changelog": "Epic C / C5 hardening (post-verifica flotta): upload allegati con ALLOWLIST estensioni (no html/svg/js same-origin) + nome file random; scadenza magic-link (mig.054 token_expires_at, 410 TOKEN_EXPIRED) + rate-limit endpoint portale + guard scritture su attivita' chiuse; send() non azzera piu' i destinatari gia' responded/acknowledged; assign individuale con semantica replace + guard lista vuota; update conserva assign_mode esistente; editor opzioni per domande a scelta singola/multipla; etichette stato localizzate; risposte mostrate inline (no alert); ARIA su modali/tab; escAttr nel portale; voce sidebar in common.js. Additivo."}
{"version": "1.21.2", "build": "2026-06-16-v1.21.2", "date": "2026-06-16", "changelog": "Epic C / C5 — fix open-item post-verifica: upload allegati RIPRISTINATO in prod (ACL host www-data su public/uploads; risolve anche evidence/visure) — collaudato. UI: create+assign attività non lascia più attività orfane su errore (no duplicati, messaggio chiaro) e richiede destinatari per assegnazione individuale; blocco PWA di stakeholder-activities allineato (favicon-16, status-bar, application-name). Additivo."}