BastionGuard/webui/includes/footer.php
specialworld83 f0f913a209 Release 2.0
2026-07-15 10:52:22 +02:00

904 lines
51 KiB
PHP

</div>
</main>
</div>
<div id="bg-alert-toast-container" class="bg-toast-container" aria-live="polite" aria-atomic="true"></div>
<script src="assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script>
(function(){
if(document.documentElement.getAttribute('data-theme') !== 'system') return;
var mq=window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
function apply(){ document.documentElement.setAttribute('data-bs-theme', mq && mq.matches ? 'dark' : 'light'); }
apply(); if(mq && mq.addEventListener) mq.addEventListener('change', apply);
})();
(function(){
var sidebar=document.getElementById('bgSidebar');
var openBtn=document.getElementById('bgMobileMenuOpen');
var closeBtn=document.getElementById('bgMobileMenuClose');
var scrim=document.getElementById('bgSidebarScrim');
if(!sidebar || !openBtn || !scrim) return;
function setOpen(open){
document.body.classList.toggle('sidebar-open', open);
sidebar.classList.toggle('is-open', open);
openBtn.setAttribute('aria-expanded', open ? 'true' : 'false');
scrim.hidden=!open;
if(open){ setTimeout(function(){ scrim.classList.add('is-visible'); }, 10); }
else { scrim.classList.remove('is-visible'); }
}
openBtn.addEventListener('click', function(){ setOpen(true); });
if(closeBtn) closeBtn.addEventListener('click', function(){ setOpen(false); });
scrim.addEventListener('click', function(){ setOpen(false); });
document.addEventListener('keydown', function(e){ if(e.key==='Escape') setOpen(false); });
sidebar.querySelectorAll('a.nav-link').forEach(function(a){ a.addEventListener('click', function(){ if(window.matchMedia && window.matchMedia('(max-width: 980px)').matches) setOpen(false); }); });
if(window.matchMedia){
var mq=window.matchMedia('(min-width: 981px)');
function sync(){ if(mq.matches) setOpen(false); }
if(mq.addEventListener) mq.addEventListener('change', sync); else if(mq.addListener) mq.addListener(sync);
}
})();
document.querySelectorAll('[data-confirm]').forEach(function(btn){btn.addEventListener('click',function(e){if(!confirm(btn.getAttribute('data-confirm'))){e.preventDefault();}})});
(function(){
function activateHashTab(){
if(!location.hash) return;
var trigger=document.querySelector('[data-bs-toggle="tab"][data-bs-target="'+CSS.escape(location.hash)+'"]');
if(trigger) bootstrap.Tab.getOrCreateInstance(trigger).show();
}
activateHashTab();
window.addEventListener('hashchange', activateHashTab);
document.querySelectorAll('[data-bs-toggle="tab"]').forEach(function(tab){
tab.addEventListener('shown.bs.tab', function(e){
var target=e.target.getAttribute('data-bs-target');
if(target && history.replaceState) history.replaceState(null,'',target);
});
});
})();
(function(){
document.querySelectorAll('.nav-group-collapse').forEach(function(el){
var key='bg-sidebar-'+el.getAttribute('data-group-id');
var stored=localStorage.getItem(key);
var hasActive=!!el.querySelector('.nav-link.active');
if(stored==='open' || hasActive){ bootstrap.Collapse.getOrCreateInstance(el,{toggle:false}).show(); }
if(stored==='closed' && !hasActive){ bootstrap.Collapse.getOrCreateInstance(el,{toggle:false}).hide(); }
el.addEventListener('shown.bs.collapse', function(){ localStorage.setItem(key,'open'); });
el.addEventListener('hidden.bs.collapse', function(){ localStorage.setItem(key,'closed'); });
});
})();
(function(){
var lang = document.documentElement.lang || 'en';
var baseTranslations={
"Protezione": "Protection",
"Sicurezza": "Security",
"Sistema": "System",
"Dashboard": "Dashboard",
"Scansione realtime": "Realtime scan",
"Scansione in tempo reale": "Realtime scan",
"Anti-Ransomware": "Anti-Ransomware",
"Banche sicure": "Safe banking",
"Desktop privacy module": "Desktop privacy module",
"Modulo USB desktop": "Desktop USB module",
"Log": "Logs",
"Quarantena": "Quarantine",
"Violazioni identità": "Identity leaks",
"Password manager": "Password manager",
"Aggiornamenti": "Updates",
"Configurazioni": "Configurations",
"Previsione": "Prediction",
"Impostazioni": "Settings",
"Informazioni": "About",
"Donazioni": "Donations",
"Logout": "Logout",
"WebUI completa": "Complete WebUI",
"Tema rapido": "Quick theme",
"Lingua rapida": "Quick language",
"Avvia": "Start",
"Ferma": "Stop",
"Riavvia": "Restart",
"Avvia monitor": "Start monitor",
"Ferma monitor": "Stop monitor",
"Riavvia monitor": "Restart monitor",
"Azione solo desktop": "Desktop-only action",
"Sblocca dispositivi": "Unblock devices",
"Salva": "Save",
"Aggiungi": "Add",
"Elimina": "Delete",
"Ripristina": "Restore",
"Scansiona": "Scan",
"Aggiorna": "Refresh",
"Aggiorna lista": "Refresh list",
"Salva configurazione": "Save configuration",
"Salva impostazioni": "Save settings",
"Output": "Output",
"Log operazioni": "Operation log",
"Azioni rapide": "Quick actions",
"Result": "Result",
"Result scansione": "Scan result",
"Result analisi": "Analysis result",
"Analizza": "Analyze",
"Check": "Check",
"Check password": "Check password",
"Mostra": "Show",
"Nascondi": "Hide",
"Sblocca vault": "Unlock vault",
"Avviato": "Started",
"Fermo": "Stopped",
"Errore": "Error",
"Avvio": "Starting",
"Arresto": "Stopping",
"Non letto": "Not read",
"Attivo": "Active",
"Non attivo": "Inactive",
"presente": "present",
"manca": "missing",
"non leggibile": "not readable",
"letto": "read",
"": "yes",
"no": "no",
"installata": "installed",
"non installata": "not installed",
"non trovato": "not found",
"mancante": "missing",
"abilitato": "enabled",
"disabilitato": "disabled",
"unità non caricata o non accessibile": "unit not loaded or not accessible",
"Nessun database trovato.": "No database found.",
"No database found in /var/lib/clamav.": "No database found in /var/lib/clamav.",
"No OnAccess path detected in known clamd.conf locations.": "No OnAccess path detected in known clamd.conf locations.",
"Stato generale di antivirus, protezioni realtime, moduli privacy, banca sicura e servizi collegati.": "Overall antivirus, realtime protections, privacy modules, safe banking and related service status.",
"Aggiorna stato": "Refresh status",
"Apri log": "Open log",
"Servizi utente": "User services",
"utente target": "target user",
"Utente desktop per i servizi": "Desktop user for services",
"non rilevato. Impostalo in": "not detected. Set it in",
"Impostazioni → Opzioni Web": "Settings → Web Options",
"Per leggere/gestire sempre i servizi": "To always read/manage services",
"da Apache/PHP-FPM installa": "from Apache/PHP-FPM install",
"La WebUI prova prima systemd, poi l'helper sicuro e infine il rilevamento processo per i servizi": "The WebUI tries systemd first, then the secure helper, and finally process detection for services",
"Servizi rilevati da systemd": "Services detected by systemd",
"Gestisci servizi": "Manage services",
"Modulo": "Module",
"Unità": "Unit",
"Unità rilevata": "Detected unit",
"Stato": "Status",
"Lettura": "Read method",
"Azioni": "Actions",
"Servizio": "Service",
"PHP gira come:": "PHP runs as:",
"Utente desktop:": "Desktop user:",
"non impostato": "not set",
"DBus user:": "User DBus:",
"Helper WebUI:": "WebUI helper:",
"I servizi di sistema sono letti da": "System services are read from",
"I servizi utente usano DBus utente, helper sudoers sicuro o fallback su processo.": "User services use user DBus, the secure sudoers helper, or process fallback.",
"Per lettura e gestione affidabile dei servizi": "For reliable service reading and management",
"Installa l'helper incluso per permettere alla WebUI di gestire systemd --user:": "Install the included helper to let the WebUI manage systemd --user:",
"Base": "Base",
"Servizi": "Services",
"Safe Payments": "Safe Payments",
"Email": "Email",
"DB ClamAV": "ClamAV DB",
"Opzioni Web": "Web Options",
"Riepilogo impostazioni operative": "Operational settings summary",
"Le impostazioni specifiche dei moduli sono disponibili nelle rispettive pagine: Anti-Ransomware, Phishing, Banche sicure, Privacy, USB, Samba, Quarantena e Scansione realtime.": "Module-specific settings are available in their pages: Anti-Ransomware, Phishing, Safe banking, Privacy, USB, Samba, Quarantine and Realtime scan.",
"Servizi sistema e utente": "System and user services",
"Pagamenti/Banche": "Payments/Banks",
"Safe payments salvati.": "Safe payments saved.",
"Configurazione email salvata.": "Email configuration saved.",
"Opzioni interfaccia salvate.": "Interface options saved.",
"Abilita pagamenti sicuri": "Enable safe payments",
"Payment domains/URLs": "Payment domains/URLs",
"Bypass proxy": "Proxy bypass",
"Protezione Email": "Email protection",
"Abilita proxy email": "Enable email proxy",
"Scansiona allegati": "Scan attachments",
"Aggiungi firma sicurezza": "Add security signature",
"Listener TLS implicito": "Implicit TLS listener",
"Nome visualizzato": "Display name",
"Ruolo": "Role",
"Azienda": "Company",
"Telefono": "Phone",
"Sito web": "Website",
"Salva configurazione email": "Save email configuration",
"Percorso predefinito:": "Default path:",
"Versione": "Version",
"Dimensione": "Size",
"Modificato": "Modified",
"Aggiorna DB": "Update DB",
"Porta HTTP": "HTTP port",
"Porta HTTPS": "HTTPS port",
"Questo utente viene usato per leggere": "This user is used to read",
"ad esempio": "for example",
"Raccolta journalctl dei servizi BastionGuard e ClamAV.": "journalctl collection for BastionGuard and ClamAV services.",
"Scansione manuale tramite helper sudoers NOPASSWD e configurazione BastionGuard reale.": "Manual scan through the NOPASSWD sudoers helper and real BastionGuard configuration.",
"Sudoers:": "Sudoers:",
"installa/aggiorna gli helper con": "install/update the helpers with",
"non chiede password via browser.": "it does not ask for a password through the browser.",
"Scansione manuale": "Manual scan",
"Percorso locale da scansionare": "Local path to scan",
"oppure": "or",
"Avvia scansione": "Start scan",
"Percorsi consentiti dal helper:": "Paths allowed by the helper:",
"Scansione automatica": "Automatic scan",
"Abilita scan automatico per eventi monitorati": "Enable automatic scan for monitored events",
"VirusTotal API key": "VirusTotal API key",
"opzionale": "optional",
"Config:": "Config:",
"Percorsi OnAccess rilevati": "Detected OnAccess paths",
"Nessun percorso OnAccess in clamd.conf.": "No OnAccess path in clamd.conf.",
"Stato:": "Status:",
"Percorsi da monitorare, uno per riga": "Watch paths, one per line",
"Richiede": "Requires",
"Gli eventi vengono scansionati immediatamente con ClamAV e il rilevamento ransomware BastionGuard: la WebUI importa alert da": "Events are scanned immediately with ClamAV and BastionGuard ransomware detection: the WebUI imports alerts from",
"ed esegue anche lo scanner anti-ransomware per-file quando disponibile.": "and also runs the per-file anti-ransomware scanner when available.",
"Root consigliate per il monitoraggio includono": "Recommended monitored roots include",
"radici web utente sotto": "user web roots under",
"e radici del webserver come": "and web-server roots such as",
"Le rilevazioni malware e ransomware creano toast WebPanel e alert email quando configurati.": "Malware and ransomware detections create WebPanel toasts and email alerts when configured.",
"Per mantenere il monitor attivo dopo il logout, abilita": "To keep the monitor active after logout, enable",
"auto refresh": "auto refresh",
"Nessun evento realtime ancora.": "No realtime events yet.",
"Risultato scansione": "Scan result",
"Aggiorna firme ClamAV, database Sanesecurity e controlla le versioni locali.": "Update ClamAV signatures, Sanesecurity database and check local versions.",
"Aggiorna firme ClamAV ora": "Update ClamAV signatures now",
"Aggiorna Sanesecurity DB": "Update Sanesecurity DB",
"Riavvia Freshclam": "Restart Freshclam",
"Richiede sudoers non interattivo per l'utente web.": "Requires non-interactive sudoers for the web user.",
"Database presenti": "Available databases",
"Nessun database locale rilevato.": "No local database detected.",
"Scansione euristica, regole YARA, DB Sanesecurity e servizio realtime.": "Heuristic scan, YARA rules, Sanesecurity DB and realtime service.",
"Servizio realtime": "Realtime service",
"Aggiorna YARA": "Update YARA",
"File o cartella da analizzare": "File or folder to analyze",
"Configurazione scanner": "Scanner configuration",
"Usa regole YARA": "Use YARA rules",
"Usa DB Sanesecurity": "Use Sanesecurity DB",
"Intervallo scansione minuti": "Scan interval in minutes",
"Cartelle da scansionare": "Folders to scan",
"Percorsi da ignorare": "Paths to ignore",
"Estensioni ignorate": "Ignored extensions",
"Estensioni sospette": "Suspicious extensions",
"Log Anti-Ransomware": "Anti-Ransomware log",
"Modulo privacy desktop": "Desktop privacy module",
"Monitoraggio privacy, blocco/sblocco dispositivi e processi che usano audio/video.": "Privacy monitoring, device blocking/unblocking and processes that use audio/video.",
"Controlli": "Controls",
"Aggiornamento automatico ogni 5 minuti": "Automatic refresh every 5 minutes",
"Processi audio/video": "Audio/video processes",
"Output comando": "Command output",
"Log privacy": "Privacy log",
"Rilevazione unità USB, autoscan e scansione manuale dei mountpoint.": "USB drive detection, autoscan and manual mountpoint scan.",
"Daemon attivo": "Daemon active",
"Daemon fermo": "Daemon stopped",
"Daemon USB": "USB daemon",
"Auto scan ogni 3 minuti": "Auto-scan every 3 minutes",
"Dispositivi rilevati": "Detected devices",
"Nome": "Name",
"Modello": "Model",
"Mountpoint": "Mountpoint",
"Output scansione": "Scan output",
"Log giornaliero USB": "Daily USB log",
"Nessuna periferica USB montata rilevata.": "No mounted USB device detected.",
"Zona Sicura – Banche": "Safe Zone – Banks",
"Gestione lista MISP e whitelist locale. Da WebUI non viene aperta la sandbox desktop: il browser isolato resta una funzione del client grafico/servizio locale.": "MISP list and local whitelist management. The desktop sandbox is not opened from the WebUI: the isolated browser remains a function of the graphical client/local service.",
"Lista banche": "Bank list",
"URL lista JSON": "JSON list URL",
"Aggiornamento automatico ogni 6 ore": "Automatic update every 6 hours",
"elementi caricati nella cache WebUI.": "items loaded in the WebUI cache.",
"Whitelist BastionGuard": "BastionGuard whitelist",
"Letta da": "Read from",
"via": "via",
"Sandbox desktop": "Desktop sandbox",
"Rimossa da questa pagina: una WebUI non deve avviare finestre grafiche o sandbox CEF nel desktop dell'utente. Usa il client BastionGuard GTK per l'apertura sicura.": "Removed from this page: a WebUI must not launch graphical windows or CEF sandboxes in the user desktop. Use the BastionGuard GTK client for safe opening.",
"Gestione sicura dei file isolati, con ripristino controllato e cancellazione solo via POST CSRF.": "Safe management of isolated files, with controlled restore and deletion only through POST CSRF.",
"Cartella quarantena": "Quarantine folder",
"Cartella ripristino": "Restore folder",
"File isolati": "Isolated files",
"Eliminare definitivamente il file?": "Permanently delete this file?",
"Nessun file in quarantena.": "No files in quarantine.",
"Samba": "Samba",
"Legge e salva il file reale della UI desktop:": "Reads and saves the real desktop UI file:",
"Configurazione share": "Share configuration",
"Stato file:": "File status:",
"Abilita scansione Samba": "Enable Samba scan",
"Percorsi/share, uno per riga": "Paths/shares, one per line",
"Scansione immediata": "Immediate scan",
"Share": "Share",
"Credenziali": "Credentials",
"nessuna": "none",
"Scansiona ora": "Scan now",
"Nessuna share configurata nel file Samba.": "No share configured in the Samba file.",
"Credenziali SMB rilevate": "Detected SMB credentials",
"Le password non vengono mostrate.": "Passwords are not displayed.",
"utente:": "user:",
"password:": "password:",
"Nessuna credenziale SMB nel file cred.conf.": "No SMB credentials in cred.conf.",
"Phishing Scanner": "Phishing Scanner",
"Usa la stessa logica della pagina sorgente: interrogazione di BastionGuard Security Intelligence e parsing del risultato HTML.": "Uses the same logic as the source page: BastionGuard Security Intelligence query and HTML result parsing.",
"Analizza URL": "Analyze URL",
"Endpoint:": "Endpoint:",
"come in": "as in",
"Servizio anti-phishing locale": "Local anti-phishing service",
"Stato analisi": "Analysis status",
"La whitelist/blacklist operativa viene gestita dai servizi e dai file configurazione BastionGuard. Questa pagina replica la funzione “Phishing Search” del client desktop.": "The operational whitelist/blacklist is managed by BastionGuard services and configuration files. This page replicates the desktop client “Phishing Search” function.",
"Controllo violazioni identità": "Identity breach check",
"Check email su HIBP, controllo password con k-anonymity e configurazione LeakCheck.": "Check email on HIBP, check passwords with k-anonymity and configure LeakCheck.",
"Check violazioni": "Check breaches",
"Password da controllare": "Password to check",
"La password non viene inviata intera a HIBP: si usa il prefisso SHA-1.": "The full password is not sent to HIBP: the SHA-1 prefix is used.",
"API e monitor": "API and monitor",
"Monitor automatico ogni 24h": "Automatic monitor every 24h",
"Wizard BastionGuard": "BastionGuard Wizard",
"Legge": "Reads",
"dell’utente target e replica il primo wizard servizi della UI desktop.": "for the target user and replicates the first services wizard of the desktop UI.",
"Apri configurazioni": "Open configurations",
"File realmente presenti in .config/BastionGuard": "Files actually present in .config/BastionGuard",
"La directory non esiste ancora per l’utente target.": "The directory does not exist yet for the target user.",
"Directory presente ma vuota.": "Directory exists but is empty.",
"Tipo": "Type",
"Letto": "Read",
"Wizard già eseguito": "Wizard already completed",
"Il file": "The file",
"è presente, valido e contiene": "is present, valid and contains",
"con la mappa servizi. Per sicurezza la WebUI non modifica nulla.": "with the service map. For safety, the WebUI does not modify anything.",
"Primo wizard servizi": "First services wizard",
"Questo passaggio crea/aggiorna solo": "This step creates/updates only",
"se manca o è incomplete. Il formato generato è quello della UI:": "if it is missing or incomplete. The generated format is the UI format:",
"Utente desktop": "Desktop user",
"Dopo aver scritto config.json, abilita/avvia i servizi selezionati": "After writing config.json, enable/start the selected services",
"Crea config.json wizard": "Create wizard config.json",
"Log wizard": "Wizard log",
"Configurazioni BastionGuard": "BastionGuard configurations",
"Legge i file realmente usati dal sorgente e può creare automaticamente quelli mancanti quando la WebUI è installata lato server.": "Reads the files actually used by the source and can automatically create missing ones when the WebUI is installed server-side.",
"Crea configurazioni mancanti": "Create missing configurations",
"Utente target:": "Target user:",
"Directory .config/BastionGuard non presente.": "Directory .config/BastionGuard not present.",
"Directory vuota.": "Empty directory.",
"File presenti": "Present files",
"File mancante: verrà mostrato il contenuto default.": "Missing file: default content will be shown.",
"Questa voce è una directory. La WebUI la legge e la mostra, ma non la modifica.": "This item is a directory. The WebUI reads and displays it, but does not modify it.",
"Ripristina default": "Restore default",
"Previsione e diagnostica": "Prediction and diagnostics",
"Controllo preventivo di configurazioni, servizi, permessi WebUI e componenti BastionGuard.": "Preventive check of configurations, services, WebUI permissions and BastionGuard components.",
"Apri wizard": "Open wizard",
"Critici": "Critical",
"Avvisi": "Warnings",
"Da verificare": "To check",
"OK": "OK",
"Esito controlli": "Check results",
"Correzione": "Fix",
"Compatibile con il vault desktop in": "Compatible with the desktop vault in",
"File rilevati": "Detected files",
"Formato sorgente": "Source format",
"Lettura tramite": "Read through",
"La WebUI legge": "The WebUI reads",
"verifica": "checks",
"con PBKDF2-SHA256 e decifra": "with PBKDF2-SHA256 and decrypts",
"con AES-256-GCM, come": "with AES-256-GCM, as in",
"Le password restano nascoste finché non premi": "Passwords remain hidden until you press",
"sulla singola riga.": "on the individual row.",
"La cartella password_manager non contiene ancora un master.json valido.": "The password_manager folder does not yet contain a valid master.json.",
"Le credenziali metadata vengono lette automaticamente; la password master serve solo per decifrare i segreti.": "Credential metadata is read automatically; the master password is only needed to decrypt secrets.",
"Nuova credenziale": "New credential",
"Importa credenziali da browser": "Import browser credentials",
"CSV esportato da Chrome, Edge, Firefox o Safari.": "CSV exported from Chrome, Edge, Firefox or Safari.",
"Scegli file CSV": "Choose CSV file",
"Anteprima": "Preview",
"Browser": "Browser",
"Credenziali trovate": "Credentials found",
"Tutte verranno importate": "All entries will be imported",
"Conferma importazione": "Confirm import",
"Annulla": "Cancel",
"altre.": "more.",
"Eliminare questa credenziale?": "Delete this credential?",
"Contenuto allineato a": "Content aligned with",
"Programma": "Program",
"Terze Parti": "Third Parties",
"Licenza": "License",
"Visita CodeLinSoft": "Visit CodeLinSoft",
"Questa applicazione utilizza:": "This application uses:",
"Sostieni BastionGuard": "Support BastionGuard",
"Grazie al tuo contributo possiamo migliorare BastionGuard, basta un piccolo gesto. Il contributo è prettamente volontario, vi chiediamo solo di sostenerci a portare avanti qualcosa del tutto gratuito per voi.": "Thanks to your contribution we can improve BastionGuard. A small gesture is enough. The contribution is entirely voluntary; we only ask you to support us in carrying forward something completely free for you.",
"Vai alla donazione": "Go to donation",
"Snapshot desktop": "Desktop snapshots",
"Voce GRUB": "GRUB entry",
"SquashFS:": "SquashFS:",
"Kernel:": "Kernel:",
"Spazio /boot": "/boot space",
"Build filesystem squashfs": "Build squashfs filesystem",
"Installa voce GRUB": "Install GRUB entry",
"Rimuovi voce GRUB": "Remove GRUB entry",
"Rimuovere la voce GRUB?": "Remove the GRUB entry?",
"Tema": "Theme",
"Lingua": "Language",
"Chiaro": "Light",
"Scuro": "Dark",
"Italiano": "Italian",
"English": "English",
"Master password": "Master password",
"Nuova master password": "New master password",
"Conferma": "Confirm",
"Username": "Username",
"Password": "Password",
"URL": "URL",
"Note": "Notes",
"Cerca": "Search",
"Nessuna entry nel vault.": "No entries in the vault.",
"password nascosta": "password hidden",
"General GUI/wizard config": "General GUI/wizard config",
"Stato wizard e servizi iniziali letti dalla UI desktop. La WebUI non lo sovrascrive se è già completato.": "Wizard status and initial services read from the desktop UI. The WebUI does not overwrite it if it is already completed.",
"VirusTotal API key read by ScanPage/cloud scanner.": "VirusTotal API key read by ScanPage/cloud scanner.",
"Credenziali / segreti locali": "Credentials / local secrets",
"Local credentials file if used by installed modules.": "Local credentials file if used by installed modules.",
"Firewall preferences read by firewall modules.": "Firewall preferences read by firewall modules.",
"Configurazione controllo identità/email violate.": "Identity/email breach check configuration.",
"UI language": "UI language",
"Lingua letta da più componenti desktop.": "Language read by multiple desktop components.",
"Safe payments": "Safe payments",
"Payment domain list read by desktop SecureBrowser.": "Payment domain list read by desktop SecureBrowser.",
"Desktop privacy module": "Modulo privacy desktop",
"Domains/exclusions used by desktop proxy/browser components.": "Domains/exclusions used by desktop proxy/browser components.",
"Samba configuration compatible with Backend::saveSambaConfig: first line enabled=true/false, then one path/share per line.": "Samba configuration compatible with Backend::saveSambaConfig: first line enabled=true/false, then one path/share per line.",
"Settings generali": "General settings",
"Preferenze generali della UI BastionGuard.": "General BastionGuard UI preferences.",
"UI theme": "UI theme",
"Tema letto dalla UI desktop.": "Theme read by the desktop UI.",
"Whitelist usata da backend e secure browser.": "Whitelist used by backend and secure browser.",
"Flag creato dal wizard servizi della UI.": "Flag created by the UI services wizard.",
"Directory password manager": "Password manager directory",
"Directory dati del password manager desktop.": "Desktop password manager data directory.",
"Porte Web BastionGuard": "BastionGuard web ports",
"Porte HTTP/HTTPS usate dal wizard e dalla configurazione NGINX.": "HTTP/HTTPS ports used by the wizard and NGINX configuration.",
"Local DNS config compatible with the GTK wizard.": "Local DNS config compatible with the GTK wizard.",
"Scansione manuale/realtime": "Manual/realtime scan",
"Configuration used by ScanPage.cpp for auto-scan.": "Configuration used by ScanPage.cpp for auto-scan.",
"Unifica le chiavi lette da SettingsPage.cpp e dallo scanner ransomware.": "Unifies the keys read by SettingsPage.cpp and the ransomware scanner.",
"Sorgenti aggiornamenti": "Update sources",
"Sorgenti UpdatePage per firme e feed.": "UpdatePage sources for signatures and feeds."
};
var t={};
if(lang === 'en') {
t = baseTranslations;
} else if(lang === 'it') {
Object.keys(baseTranslations).forEach(function(k){
var v = baseTranslations[k];
if(v && v !== k) t[v] = k;
});
Object.assign(t, {
'About': 'Informazioni',
'Content aligned with': 'Contenuto allineato a',
'Program': 'Programma',
'Third Parties': 'Terze Parti',
'License': 'Licenza',
'This application uses:': 'Questa applicazione utilizza:',
'Visit CodeLinSoft': 'Visita CodeLinSoft',
'Heuristic scanning, YARA rules, Sanesecurity DB and realtime service.': 'Scansione euristica, regole YARA, DB Sanesecurity e servizio realtime.',
'Realtime service': 'Servizio realtime',
'Start': 'Avvia',
'Stop': 'Ferma',
'Restart': 'Riavvia',
'Update YARA': 'Aggiorna YARA',
'File or folder to analyze': 'File o cartella da analizzare',
'Scanner configuration': 'Configurazione scanner',
'Use YARA rules': 'Usa regole YARA',
'Use Sanesecurity DB': 'Usa DB Sanesecurity',
'Scan interval in minutes': 'Intervallo scansione minuti',
'Folders to scan': 'Cartelle da scansionare',
'Paths to ignore': 'Percorsi da ignorare',
'Ignored extensions': 'Estensioni ignorate',
'Suspicious extensions': 'Estensioni sospette',
'Save configuration': 'Salva configurazione',
'Anti-Ransomware log': 'Log Anti-Ransomware',
'Desktop snapshots': 'Snapshot desktop',
'GRUB entry': 'Voce GRUB',
'/boot space': 'Spazio /boot',
'Install GRUB entry': 'Installa voce GRUB',
'Remove GRUB entry': 'Rimuovi voce GRUB',
'Operation log': 'Log operazioni',
'Safe Zone – Banks': 'Zona Sicura – Banche',
'MISP list and local whitelist management. The desktop sandbox is not opened from the WebUI: the isolated browser remains a function of the graphical client/local service.': 'Gestione lista MISP e whitelist locale. Da WebUI non viene aperta la sandbox desktop: il browser isolato resta una funzione del client grafico/servizio locale.',
'Bank list': 'Lista banche',
'JSON list URL': 'URL lista JSON',
'Automatic update every 6 hours': 'Aggiornamento automatico ogni 6 ore',
'Refresh list': 'Aggiorna lista',
'items loaded in the WebUI cache.': 'elementi caricati nella cache WebUI.',
'Read from': 'Letta da',
'Desktop sandbox': 'Sandbox desktop',
'Removed from this page: a WebUI must not launch graphical windows or CEF sandboxes in the user desktop. Use the BastionGuard GTK client for safe opening.': 'Rimossa da questa pagina: una WebUI non deve avviare finestre grafiche o sandbox CEF nel desktop dell\'utente. Usa il client BastionGuard GTK per l\'apertura sicura.',
'BastionGuard configurations': 'Configurazioni BastionGuard',
'Reads the files actually used by the source and can automatically create missing ones when the WebUI is installed server-side.': 'Legge i file realmente usati dal sorgente e può creare automaticamente quelli mancanti quando la WebUI è installata lato server.',
'Create missing configurations': 'Crea configurazioni mancanti',
'Target user:': 'Utente target:',
'Present files': 'File presenti',
'Missing file: the default content will be shown.': 'File mancante: verrà mostrato il contenuto default.',
'Restore default': 'Ripristina default',
'Identity breach check': 'Controllo violazioni identità',
'Check email on HIBP, check passwords with k-anonymity and configure LeakCheck.': 'Check email su HIBP, controllo password con k-anonymity e configurazione LeakCheck.',
'Check breaches': 'Check violazioni',
'Password to check': 'Password da controllare',
'The full password is not sent to HIBP: the SHA-1 prefix is used.': 'La password non viene inviata intera a HIBP: si usa il prefisso SHA-1.',
'API and monitor': 'API e monitor',
'Automatic monitor every 24h': 'Monitor automatico ogni 24h',
'Logs': 'Log',
'journalctl collection for BastionGuard and ClamAV services.': 'Raccolta journalctl dei servizi BastionGuard e ClamAV.',
'Update ClamAV signatures, Sanesecurity database and check local versions.': 'Aggiorna firme ClamAV, database Sanesecurity e controlla le versioni locali.',
'Quick actions': 'Azioni rapide',
'Update ClamAV signatures now': 'Aggiorna firme ClamAV ora',
'Update Sanesecurity DB': 'Aggiorna Sanesecurity DB',
'Restart Freshclam': 'Riavvia Freshclam',
'Available databases': 'Database presenti',
'No local database detected.': 'Nessun database locale rilevato.',
'BastionGuard Wizard': 'Wizard BastionGuard',
'Files actually present in .config/BastionGuard': 'File realmente presenti in .config/BastionGuard',
'Wizard already completed': 'Wizard già eseguito',
'First services wizard': 'Primo wizard servizi',
'Desktop user': 'Utente desktop',
'Run diagnostics first': 'Esegui prima la diagnostica',
'Wizard log': 'Log wizard',
'Desktop arbitration': 'Arbitraggio desktop',
'Like GTK: none selected': 'Come GTK: nessuno selezionato',
'Recommended preset': 'Preset consigliato',
'CEF/PAC excluded from the WebUI: use the GTK UI.': 'CEF/PAC esclusi dalla WebUI: usa la GUI GTK.',
'BastionGuard setup like the GTK/src wizard': 'Setup BastionGuard come wizard GTK/src',
'BastionGuard WebUI Health': 'Diagnostica BastionGuard WebUI',
'BastionGuard WebUI - diagnostics': 'Diagnostica BastionGuard WebUI',
'This page helps diagnose blank pages or PHP issues.': 'Questa pagina aiuta a diagnosticare pagine bianche o problemi PHP.',
'Back to WebUI': 'Torna alla WebUI',
'Latest WebUI errors': 'Ultimi errori WebUI',
'Disabled PHP functions': 'Funzioni PHP disabilitate',
'Value': 'Valore',
'Issue': 'Problema',
'Close': 'Chiudi',
'Open navigation': 'Apri navigazione',
'Close navigation': 'Chiudi navigazione',
'BastionGuard navigation': 'Navigazione BastionGuard',
'BastionGuard sidebar': 'Barra laterale BastionGuard',
'BastionGuard interface preferences': 'Preferenze interfaccia BastionGuard',
'Manual scan, ClamAV OnAccess status and root WebPanel realtime monitor for malware and ransomware.': 'Scansione manuale, stato ClamAV OnAccess e monitor realtime root del WebPanel per malware e ransomware.',
'Enable automatic scanning for monitored events': 'Abilita scansione automatica per gli eventi monitorati',
'Read method:': 'Metodo di lettura:',
'Status:': 'Stato:',
'File:': 'File:',
'Lines': 'Righe',
'Scope': 'Ambito',
'Enabled': 'Abilitato',
'SubState': 'Sotto-stato',
'PID': 'PID',
'Unit': 'Unità',
'Service': 'Servizio',
'Module': 'Modulo',
'State': 'Stato',
'Reading': 'Lettura',
'Read method': 'Metodo di lettura',
'unit not loaded or not accessible': 'unità non caricata o non accessibile',
'Desktop user for': 'Utente desktop per',
'services was not detected. Set it in': 'servizi non rilevato. Impostalo in',
'read:': 'lettura:',
'scope:': 'ambito:',
'enabled:': 'abilitato:',
'helper': 'helper',
'missing': 'mancante',
'present': 'presente',
'none': 'nessuno',
'unknown': 'sconosciuto',
'ok': 'ok',
'error': 'errore',
'Search': 'Cerca',
'Safe banking': 'Banche sicure',
'Safe Zone – Banks': 'Zona Sicura – Banche',
'Desktop privacy module': 'Desktop privacy module / microfono',
'Desktop USB module': 'Modulo USB desktop',
'Desktop-only USB module.': 'Modulo USB solo desktop.',
'USB daemon': 'Daemon USB',
'Auto scan every 3 minutes': 'Autoscan ogni 3 minuti',
'Detected devices': 'Dispositivi rilevati',
'No mounted USB device detected.': 'Nessuna periferica USB montata rilevata.',
'Scan output': 'Output scansione',
'Daily USB log': 'Log giornaliero USB',
'Name': 'Nome',
'Model': 'Modello',
'Mountpoint': 'Punto di mount',
'Controls': 'Controlli',
'Automatic refresh every 5 minutes': 'Aggiornamento automatico ogni 5 minuti',
'Audio/video processes': 'Processi audio/video',
'Command output': 'Output comando',
'Privacy log': 'Log privacy',
'Desktop-only action': 'Azione solo desktop',
'Unblock devices': 'Sblocca dispositivi',
'BastionGuard configurations': 'Configurazioni BastionGuard',
'Real folder read:': 'Cartella reale letta:',
'To write to': 'Per scrivere in',
'or to the user home from Apache/PHP-FPM, install the helpers:': 'o nella home utente da Apache/PHP-FPM, installa gli helper:',
'Directory .config/BastionGuard not present.': 'Directory .config/BastionGuard non presente.',
'Empty directory.': 'Directory vuota.',
'This item is a directory. The WebUI reads and displays it, but does not modify it.': 'Questa voce è una directory. La WebUI la legge e la mostra, ma non la modifica.',
'File status:': 'Stato file:',
'File': 'File',
'Version': 'Versione',
'Modified': 'Modificato',
'Default path:': 'Percorso predefinito:',
'No database found.': 'Nessun database trovato.',
'No database found in /var/lib/clamav.': 'Nessun database trovato in /var/lib/clamav.',
'No local database detected.': 'Nessun database locale rilevato.',
'No YARA rules found.': 'Nessuna regola YARA trovata.',
'Available databases': 'Database disponibili',
'Updates': 'Aggiornamenti',
'Quick actions': 'Azioni rapide',
'Requires non-interactive sudoers for the web user.': 'Richiede sudoers non interattivo per l’utente web.',
'Update ClamAV signatures, Sanesecurity database and check local versions.': 'Aggiorna firme ClamAV, database Sanesecurity e controlla le versioni locali.',
'Update ClamAV signatures now': 'Aggiorna firme ClamAV ora',
'Update Sanesecurity DB': 'Aggiorna Sanesecurity DB',
'Restart Freshclam': 'Riavvia Freshclam',
'Output': 'Output',
'Anti-Ransomware log': 'Log Anti-Ransomware',
'Realtime service': 'Servizio realtime',
'Heuristic scanning, YARA rules, Sanesecurity DB and realtime service.': 'Scansione euristica, regole YARA, DB Sanesecurity e servizio realtime.',
'File or folder to analyze': 'File o cartella da analizzare',
'Scanner configuration': 'Configurazione scanner',
'Use YARA rules': 'Usa regole YARA',
'Use Sanesecurity DB': 'Usa DB Sanesecurity',
'Scan interval in minutes': 'Intervallo scansione in minuti',
'Folders to scan': 'Cartelle da scansionare',
'Paths to ignore': 'Percorsi da ignorare',
'Ignored extensions': 'Estensioni ignorate',
'Suspicious extensions': 'Estensioni sospette',
'Save configuration': 'Salva configurazione',
'Local path to scan': 'Percorso locale da scansionare',
'Paths allowed by the helper:': 'Percorsi consentiti dall’helper:',
'Automatic scan': 'Scansione automatica',
'VirusTotal API key': 'API key VirusTotal',
'optional': 'opzionale',
'Detected OnAccess paths': 'Percorsi OnAccess rilevati',
'No OnAccess path detected in known clamd.conf locations.': 'Nessun percorso OnAccess rilevato nei clamd.conf conosciuti.',
'No OnAccess path in clamd.conf.': 'Nessun percorso OnAccess in clamd.conf.',
'Watch paths, one per line': 'Percorsi da monitorare, uno per riga',
'Start monitor': 'Avvia monitor',
'Stop monitor': 'Ferma monitor',
'Restart monitor': 'Riavvia monitor',
'Start scan': 'Avvia scansione',
'Scan result': 'Risultato scansione',
'Phishing Scanner': 'Scanner phishing',
'Analyze URL': 'Analizza URL',
'Endpoint:': 'Endpoint:',
'Local anti-phishing service': 'Servizio anti-phishing locale',
'Analysis status': 'Stato analisi',
'Identity breach check': 'Controllo violazioni identità',
'Check email on HIBP, check passwords with k-anonymity and configure LeakCheck.': 'Controllo email su HIBP, password con k-anonymity e configurazione LeakCheck.',
'Check breaches': 'Controlla violazioni',
'Password to check': 'Password da controllare',
'The full password is not sent to HIBP: the SHA-1 prefix is used.': 'La password non viene inviata intera a HIBP: viene usato il prefisso SHA-1.',
'API and monitor': 'API e monitor',
'Automatic monitor every 24h': 'Monitor automatico ogni 24 ore',
'Share configuration': 'Configurazione share',
'Enable Samba scan': 'Abilita scansione Samba',
'Paths/shares, one per line': 'Percorsi/share, uno per riga',
'Immediate scan': 'Scansione immediata',
'Scan now': 'Scansiona ora',
'No share configured in the Samba file.': 'Nessuna share configurata nel file Samba.',
'Detected SMB credentials': 'Credenziali SMB rilevate',
'No SMB credentials in cred.conf.': 'Nessuna credenziale SMB in cred.conf.',
'user:': 'utente:',
'password:': 'password:',
'Prediction and diagnostics': 'Previsione e diagnostica',
'Preventive check of configurations, services, WebUI permissions and BastionGuard components.': 'Controllo preventivo di configurazioni, servizi, permessi WebUI e componenti BastionGuard.',
'Check results': 'Esito controlli',
'Critical': 'Critici',
'Warnings': 'Avvisi',
'To check': 'Da verificare',
'Fix': 'Correzione',
'Run diagnostics first': 'Esegui prima la diagnostica',
'Open wizard': 'Apri wizard',
'About': 'Informazioni',
'Content aligned with': 'Contenuto allineato a',
'Program': 'Programma',
'Third Parties': 'Terze Parti',
'License': 'Licenza',
'Visit CodeLinSoft': 'Visita CodeLinSoft',
'Support BastionGuard': 'Sostieni BastionGuard',
'Go to donation': 'Vai alla donazione',
'Thanks to your contribution we can improve BastionGuard. A small gesture is enough. The contribution is completely voluntary; we only ask you to support us in carrying forward something that is entirely free for you.': 'Grazie al tuo contributo possiamo migliorare BastionGuard. Basta un piccolo gesto. Il contributo è completamente volontario; chiediamo solo supporto per portare avanti qualcosa che per te resta totalmente gratuito.',
'Desktop snapshots': 'Snapshot desktop',
'Installs a GRUB entry to boot an isolated minimal Linux system and restore snapshots safely.': 'Installa una voce GRUB per avviare un sistema Linux minimale isolato e ripristinare snapshot in sicurezza.',
'Free space on': 'Spazio libero su',
'minimum 2 GB required': 'minimo 2 GB richiesti',
'Build filesystem squashfs': 'Crea filesystem squashfs',
'Install GRUB entry': 'Installa voce GRUB',
'Remove GRUB entry': 'Rimuovi voce GRUB',
'Remove the BastionGuard Recovery GRUB entry?': 'Rimuovere la voce GRUB BastionGuard Recovery?',
'Operation log': 'Log operazione',
'None': 'Nessuno',
'From': 'Da',
'Website': 'Sito web',
'Profile label': 'Etichetta profilo',
'Port': 'Porta',
'Username': 'Nome utente',
'Match From': 'Corrispondenza mittente',
'Match From Domain': 'Corrispondenza dominio mittente',
'sendmail / PHP mail() fallback': 'fallback sendmail / PHP mail()',
'Desktop user': 'Utente desktop',
'OS / distro': 'OS / distribuzione',
'Web server': 'Server web',
'Detected': 'Rilevato',
'Apply web configuration': 'Applica configurazione web',
'Light': 'Chiaro',
'Dark': 'Scuro',
'System': 'Sistema',
'English': 'Inglese',
'Italiano': 'Italiano',
'Password': 'Password',
'Size': 'Dimensione',
'Action': 'Azione',
'Password manager': 'Gestore password',
'Logout': 'Esci',
'Result': 'Risultato',
'Check': 'Controlla',
'Check password': 'Controlla password',
'Payment domains/URLs': 'Domini/URL pagamento',
'VirusTotal API key': 'API key VirusTotal',
'auto refresh': 'aggiornamento automatico',
'Mountpoint': 'Punto di mount',
'Share': 'Condivisione',
'Phishing Scanner': 'Scanner phishing',
'Master password': 'Password principale',
'Username': 'Nome utente',
'No database found in /var/lib/clamav.': 'Nessun database trovato in /var/lib/clamav.',
'No OnAccess path detected in known clamd.conf locations.': 'Nessun percorso OnAccess rilevato nei clamd.conf conosciuti.',
'VirusTotal API key read by ScanPage/cloud scanner.': 'API key VirusTotal letta da ScanPage/scanner cloud.',
'General GUI/wizard config': 'Configurazione generale GUI/wizard',
'Local credentials file if used by installed modules.': 'File credenziali locali se usato dai moduli installati.',
'Firewall preferences read by firewall modules.': 'Preferenze firewall lette dai moduli firewall.',
'UI language': 'Lingua interfaccia',
'Safe payments': 'Pagamenti sicuri',
'Payment domain list read by desktop SecureBrowser.': 'Lista domini pagamento letta dal SecureBrowser desktop.',
'Desktop privacy module': 'Modulo privacy desktop',
'Domains/exclusions used by desktop proxy/browser components.': 'Domini/esclusioni usati dai componenti proxy/browser desktop.',
'UI theme': 'Tema interfaccia',
'Local DNS config compatible with the GTK wizard.': 'Configurazione DNS locale compatibile con il wizard GTK.',
'Configuration used by ScanPage.cpp for auto-scan.': 'Configurazione usata da ScanPage.cpp per la scansione automatica.',
'Samba configuration compatible with Backend::saveSambaConfig: first line enabled=true/false, then one path/share per line.': 'Configurazione Samba compatibile con Backend::saveSambaConfig: prima riga enabled=true/false, poi un percorso/share per riga.',
'Actions': 'Azioni'
});
} else { return; }
var tKeys=Object.keys(t).sort(function(a,b){return b.length-a.length;});
function reEscape(s){ return String(s).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
function translateString(value){
var raw=String(value);
var leading=(raw.match(/^\s*/) || [''])[0];
var trailing=(raw.match(/\s*$/) || [''])[0];
var core=raw.trim();
if(Object.prototype.hasOwnProperty.call(t, core)) return leading + t[core] + trailing;
var out=raw;
tKeys.forEach(function(k){
if(!k || out.indexOf(k)<0) return;
var replacement=t[k];
// Short words like "Log" and "or" must not be replaced inside Logout, Password, administrator, etc.
if(/^[A-Za--ÿ]+$/.test(k) && k.length <= 4){
var re=new RegExp('(^|[^A-Za-zÀ-ÿ0-9_])(' + reEscape(k) + ')(?=$|[^A-Za-zÀ-ÿ0-9_])','g');
out=out.replace(re, function(m,p1){ return p1 + replacement; });
} else {
out=out.split(k).join(replacement);
}
});
return out;
}
function replaceTextNode(n){
var raw=n.nodeValue;
if(!raw || !raw.trim()) return;
var translated=translateString(raw);
if(translated!==raw) n.nodeValue=translated;
}
function walk(node){
if(!node) return;
if(node.nodeType===3){replaceTextNode(node);return;}
if(node.nodeType!==1) return;
var tag=node.tagName.toLowerCase();
if(['script','style','pre','code','textarea'].indexOf(tag)>=0) return;
['placeholder','title','aria-label','data-confirm'].forEach(function(attr){var v=node.getAttribute&&node.getAttribute(attr); if(v){var tv=translateString(v); if(tv!==v) node.setAttribute(attr,tv);}});
Array.prototype.forEach.call(node.childNodes,walk);
}
walk(document.body);
})();
(function(){
var container=document.getElementById('bg-alert-toast-container');
if(!container) return;
// Native WebPanel toast engine: do not depend on Bootstrap Toast utilities.
// The local Bootstrap subset intentionally does not include Toast, so this keeps
// malware/ransomware notifications pinned at the top-right on every page.
var seen={};
var csrf='<?= bg_e(csrf_token()) ?>';
function esc(s){return String(s||'').replace(/[&<>"']/g,function(c){return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[c];});}
function ensureTop(){
container.style.position='fixed';
container.style.top='16px';
container.style.right='16px';
container.style.bottom='auto';
container.style.left='auto';
container.style.zIndex='2147483000';
container.style.width='min(440px, calc(100vw - 32px))';
container.style.maxWidth='440px';
container.style.display='flex';
container.style.flexDirection='column';
container.style.gap='12px';
container.style.pointerEvents='none';
}
ensureTop();
window.addEventListener('resize', ensureTop);
function removeToast(el){
if(!el) return;
el.classList.add('bg-toast-leaving');
window.setTimeout(function(){ if(el.parentNode) el.parentNode.removeChild(el); }, 180);
}
function limitToasts(){
var items=container.querySelectorAll('.bg-alert-toast');
for(var i=5;i<items.length;i++) removeToast(items[i]);
}
function action(alert, act, el){
var body=new URLSearchParams();
body.set('csrf_token', csrf);
body.set('id', alert.id);
body.set('path', alert.path||'');
body.set('action', act);
fetch('notification_action.php',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:body.toString(),credentials:'same-origin'})
.then(function(r){return r.json().catch(function(){return {ok:false,error:'Invalid response'};});})
.then(function(j){
if(j.ok){ removeToast(el); }
else { alertBox(j.error || 'Action failed'); }
})
.catch(function(){ alertBox('Action failed'); });
}
function alertBox(msg){
var el=document.createElement('div');
el.className='bg-alert-toast bg-alert-toast-warning';
el.setAttribute('role','alert');
el.innerHTML='<div class="bg-alert-toast-header"><div class="bg-alert-toast-title"><i class="bi bi-exclamation-triangle"></i><span>'+esc(msg)+'</span></div><button type="button" class="bg-toast-close" aria-label="Close">&times;</button></div>';
el.querySelector('.bg-toast-close').addEventListener('click',function(){removeToast(el);});
container.prepend(el); limitToasts();
window.setTimeout(function(){removeToast(el);}, 7000);
}
function showToast(a){
if(!a || !a.id || seen[a.id]) return;
seen[a.id]=true;
var isRansomware=(a.type==='ransomware');
var title=(isRansomware ? <?= json_encode(bg_t('ransomware_detected')) ?> : <?= json_encode(bg_t('malware_detected')) ?>);
var icon=isRansomware ? 'bi-radioactive' : 'bi-shield-exclamation';
var el=document.createElement('div');
el.className='bg-alert-toast ' + (isRansomware ? 'bg-alert-toast-ransomware' : 'bg-alert-toast-malware');
el.setAttribute('role','alert');
el.innerHTML=''
+ '<div class="bg-alert-toast-header">'
+ ' <div class="bg-alert-toast-title"><i class="bi '+icon+'"></i><span>'+esc(title)+'</span></div>'
+ ' <div class="bg-alert-toast-meta"><small>'+esc(a.time||'')+'</small><button type="button" class="bg-toast-close" aria-label="Close">&times;</button></div>'
+ '</div>'
+ '<div class="bg-alert-toast-body">'
+ ' <div class="bg-alert-toast-family">'+esc(a.family||'Malware')+'</div>'
+ ' <div class="bg-alert-toast-path">'+esc(a.path||'')+'</div>'
+ ' <div class="bg-alert-toast-actions">'
+ ' <button type="button" class="btn btn-sm btn-danger" data-act="quarantine"><i class="bi bi-archive"></i> <?= bg_e(bg_t('quarantine_action')) ?></button>'
+ ' <button type="button" class="btn btn-sm btn-outline-secondary" data-act="ignore"><?= bg_e(bg_t('ignore_action')) ?></button>'
+ ' </div>'
+ '</div>';
el.querySelector('.bg-toast-close').addEventListener('click',function(){removeToast(el);});
el.querySelector('[data-act="quarantine"]').addEventListener('click',function(){action(a,'quarantine',el);});
el.querySelector('[data-act="ignore"]').addEventListener('click',function(){action(a,'ignore',el);});
container.prepend(el); limitToasts(); ensureTop();
}
function poll(){
fetch('notifications_feed.php',{credentials:'same-origin'})
.then(function(r){return r.json();})
.then(function(j){(j.alerts||[]).forEach(showToast);})
.catch(function(){});
}
poll();
setInterval(poll,4000);
})();
</script>
</body>
</html>