diff --git a/README.md b/README.md index c1b9f918..4e48d348 100755 --- a/README.md +++ b/README.md @@ -157,6 +157,8 @@ Check the [GitHub Issues](https://github.com/netalertx/NetAlertX/issues) for the ## Everything else +jokob-sk%2FNetAlertX | Trendshift + ### 📧 Get notified what's new Get notified about a new release, what new functionality you can use and about breaking changes. @@ -219,7 +221,7 @@ Proudly using [Weblate](https://hosted.weblate.org/projects/pialert/). Help out [sync_hub]: ./docs/img/sync_hub.png "Screen 8" [notification_center]: ./docs/img/notification_center.png "Screen 8" [sent_reports_text]: ./docs/img/sent_reports_text.png "Screen 8" -[device_nmap]: ./docs/img/device_nmap.png "Screen 9" +[device_nmap]: ./docs/img/device_tools.png "Screen 9" [report1]: ./docs/img/report_sample.png "Report sample 1" [main_dark]: /docs/img/1_devices_dark.jpg "Main screen dark" [maintain_dark]: /docs/img/5_maintain.jpg "Maintain screen dark" diff --git a/docs/API.md b/docs/API.md index bca932cf..3135b9d9 100755 --- a/docs/API.md +++ b/docs/API.md @@ -59,6 +59,10 @@ http://:/ ## Endpoints +> [!NOTE] +> You can explore the API endpoints by using the interactive API docs at `http://:/docs`. +> ![API docs](./img/API/API_docs.png) + > [!TIP] > When retrieving devices or settings try using the GraphQL API endpoint first as it is read-optimized. diff --git a/docs/API_MCP.md b/docs/API_MCP.md index 6ab19c4b..344f163a 100644 --- a/docs/API_MCP.md +++ b/docs/API_MCP.md @@ -31,11 +31,6 @@ graph TB D -->|Response Data| C C -->|JSON Response| B B -->|Stream Events| A - - style A fill:#e1f5fe - style B fill:#f3e5f5 - style C fill:#fff3e0 - style D fill:#e8f5e8 ``` ### MCP Tool Integration @@ -98,15 +93,6 @@ graph LR F --> I G --> J H --> I - - style A fill:#e1f5fe - style B fill:#e1f5fe - style C fill:#f3e5f5 - style D fill:#f3e5f5 - style E fill:#f3e5f5 - style F fill:#fff3e0 - style G fill:#fff3e0 - style H fill:#fff3e0 ``` --- diff --git a/docs/FEATURES.md b/docs/FEATURES.md index aca49ed9..6eeb3520 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -6,7 +6,7 @@ NetAlertX is a lightweight, flexible platform for monitoring networks, tracking ## Network Discovery & Device Tracking -[Network Discovery & Device Tracking](./img/FEATURES/Network_Discovery_Device_Tracking.png) +![Network Discovery & Device Tracking](./img/FEATURES/Network_Discovery_Device_Tracking.png) - **Automatic Device Detection**: Continuously scans your local network to detect all connected devices via ARP, DHCP, SNMP, and compatible controllers. - **Presence Monitoring**: Track when devices appear, disappear, or reconnect on the network. diff --git a/docs/img/API/API_docs.png b/docs/img/API/API_docs.png new file mode 100644 index 00000000..03db08fc Binary files /dev/null and b/docs/img/API/API_docs.png differ diff --git a/docs/img/FEATURES/MCP_Server.png b/docs/img/FEATURES/MCP_Server.png index bac50d4c..4eb7a40c 100644 Binary files a/docs/img/FEATURES/MCP_Server.png and b/docs/img/FEATURES/MCP_Server.png differ diff --git a/docs/img/device_nmap.png b/docs/img/device_nmap.png deleted file mode 100755 index c1208edb..00000000 Binary files a/docs/img/device_nmap.png and /dev/null differ diff --git a/docs/img/device_tools.png b/docs/img/device_tools.png new file mode 100644 index 00000000..0e3b6612 Binary files /dev/null and b/docs/img/device_tools.png differ diff --git a/docs/img/devices_split.png b/docs/img/devices_split.png index 4a27a1bb..4f044aeb 100755 Binary files a/docs/img/devices_split.png and b/docs/img/devices_split.png differ diff --git a/docs/img/maintenance.png b/docs/img/maintenance.png index 93958686..989af00d 100755 Binary files a/docs/img/maintenance.png and b/docs/img/maintenance.png differ diff --git a/docs/img/network.png b/docs/img/network.png index b87d42f5..19231586 100755 Binary files a/docs/img/network.png and b/docs/img/network.png differ diff --git a/docs/img/report_sample.png b/docs/img/report_sample.png index 7b688864..988267cf 100755 Binary files a/docs/img/report_sample.png and b/docs/img/report_sample.png differ diff --git a/docs/img/sync_hub.png b/docs/img/sync_hub.png index dc452e2d..af42a944 100755 Binary files a/docs/img/sync_hub.png and b/docs/img/sync_hub.png differ diff --git a/docs/index.md b/docs/index.md index bc0b0ce9..720842a2 100755 --- a/docs/index.md +++ b/docs/index.md @@ -4,10 +4,21 @@ hide: - toc --- -# NetAlertX Documentation - -Guides and resources to help you set up, configure, and troubleshoot NetAlertX. +
+
+

NetAlertX

+

+ Centralized network visibility and continuous asset discovery. +

+

+ NetAlertx delivers a scalable and secure solution for comprehensive network monitoring, supporting security awareness and operational efficiency. +

+
+
+ Hero image for NetAlertx +
+
@@ -43,48 +54,6 @@ Guides and resources to help you set up, configure, and troubleshoot NetAlertX.
-![Preview](./img/devices_split.png) - -## In-App Help - -NetAlertX provides contextual help within the application: - -- **Hover over settings, fields, or labels** to see additional tooltips and guidance. -- **Click ? (question-mark) icons** next to various elements to view detailed information. - ---- - -## Installation Guides - -The app can be installed different ways, with the best support of the docker-based deployments. This includes the Home Assistant and Unraid installation approaches. See details below. - -### Docker (Fully Supported) - -NetAlertX is fully supported in Docker environments, allowing for easy setup and configuration. Follow the official guide to get started: - -- [Docker Installation Guide](./DOCKER_INSTALLATION.md) - -This guide will take you through the process of setting up NetAlertX using Docker Compose or standalone Docker commands. - -### Home Assistant (Fully Supported) - -You can install NetAlertX also as a Home Assistant addon [![Home Assistant](https://img.shields.io/badge/Repo-blue?logo=home-assistant&style=for-the-badge&color=0aa8d2&logoColor=fff&label=Add)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons) via the [alexbelgium/hassio-addons](https://github.com/alexbelgium/hassio-addons/) repository. This is only possible if you run a supervised instance of Home Assistant. If not, you can still run NetAlertX in a separate Docker container and follow this guide to configure MQTT. - -- [[Installation] Home Assistant](https://github.com/alexbelgium/hassio-addons/tree/master/netalertx) - -### Unraid (Partial Support) - -The Unraid template was created by the community, so it's only partially supported. Alternatively, here is [another version of the Unraid template](https://github.com/jokob-sk/NetAlertX-unraid). - -- [[Installation] Unraid App](https://unraid.net/community/apps) - -### Bare-Metal Installation (Experimental) - -If you prefer to run NetAlertX on your own hardware, you can try the experimental bare-metal installation. Please note that this method is still under development, and are looking for maintainers to help improve it. - -- [Bare-Metal Installation Guide](./HW_INSTALL.md) - - --- ## Help and Support @@ -93,14 +62,16 @@ If you need help or run into issues, here are some resources to guide you: **Before opening an issue, please:** + - **Hover over settings, fields, or labels** to see additional tooltips and guidance. + - **Click ? (question-mark) icons** next to various elements to view detailed information. - [Check common issues](./DEBUG_TIPS.md#common-issues) to see if your problem has already been reported. - - [Look at closed issues](https://github.com/jokob-sk/NetAlertX/issues?q=is%3Aissue+is%3Aclosed) for possible solutions to past problems. + - [Look at closed issues](https://github.com/netalertx/NetAlertX/issues?q=is%3Aissue+is%3Aclosed) for possible solutions to past problems. - **Enable debugging** to gather more information: [Debug Guide](./DEBUG_TIPS.md). **Need more help?** Join the community discussions or submit a support request: - - Visit the [GitHub Discussions](https://github.com/jokob-sk/NetAlertX/discussions) for community support. - - If you are experiencing issues that require immediate attention, consider opening an issue on our [GitHub Issues page](https://github.com/jokob-sk/NetAlertX/issues). + - Visit the [GitHub Discussions](https://github.com/netalertx/NetAlertX/discussions) for community support. + - If you are experiencing issues that require immediate attention, consider opening an issue on our [GitHub Issues page](https://github.com/netalertx/NetAlertX/issues). --- @@ -119,15 +90,15 @@ For more information on contributing, check out our [Dev Guide](./DEV_ENV_SETUP. To keep up with the latest changes and updates to NetAlertX, please refer to the following resources: -- [Releases](https://github.com/jokob-sk/NetAlertX/releases) +- [Releases](https://github.com/netalertx/NetAlertX/releases) Make sure to follow the project on GitHub to get notifications for new releases and important updates. --- ## Additional info -- **Documentation Index**: Check out the full [documentation index](https://github.com/jokob-sk/NetAlertX/tree/main/docs) for all the guides available. +- **Documentation Index**: Check out the full [documentation index](https://github.com/netalertx/NetAlertX/tree/main/docs) for all the guides available. If you have any suggestions or improvements, please don’t hesitate to contribute! -NetAlertX is actively maintained. You can find the source code, report bugs, or request new features on our [GitHub page](https://github.com/jokob-sk/NetAlertX). +NetAlertX is actively maintained. You can find the source code, report bugs, or request new features on our [GitHub page](https://github.com/netalertx/NetAlertX). diff --git a/docs/stylesheets/custom.css b/docs/stylesheets/custom.css index bf526cb5..4407decd 100644 --- a/docs/stylesheets/custom.css +++ b/docs/stylesheets/custom.css @@ -14,6 +14,53 @@ * limitations under the License. */ + +/* --- HERO SECTION --- */ +.hero-wrapper { + display: flex; + align-items: flex-start; + justify-content: space-between; + max-width: 1200px; + margin: 0 auto; +} + +.hero-content { + flex: 1; + max-width: 26.8rem; +} + +.hero-content h1 { + font-size: 3rem; + line-height: 1.12; + font-weight: 450; + margin-bottom: 0.5rem; + letter-spacing: -0.02em; +} + +p.hero-subheading { + font-size: 1.5rem; + line-height: 1.28; + margin: 0 0 1rem; +} + +p.hero-description { + line-height: 1.4; + margin: 0; +} + +.hero-image { + display: flex; + justify-content: center; + margin-top: 15px; + max-width: 45%; +} + +.hero-logo-crisp { + width: 100%; + height: auto; + object-fit: contain; +} + /* --- PROMO CARDS --- */ .promo-card-wrapper { display: flex; diff --git a/front/css/app.css b/front/css/app.css index ecafc508..a3183087 100755 --- a/front/css/app.css +++ b/front/css/app.css @@ -508,6 +508,41 @@ body color: #a0a0a0; } +.small-box { + margin-bottom: 15px !important; + float: left; + width: 100%; +} +#TopSmallBoxes .small-box { + height: 3em; +} + +.small-box .icon +{ + font-size: 2.2em !important; + float: right; + top: 0; +} +.small-box .small-box-text +{ + float:left; + font-size: x-large; + margin-top: -0.3em; +} + +.small-box .infobox_label +{ + font-size: larger; + float: right; + text-align: center; +} + +hr +{ + margin-top: 5px; + margin-bottom: 10px; +} + /* ----------------------------------------------------------------------------- Customized Box Borders ----------------------------------------------------------------------------- */ @@ -901,10 +936,6 @@ height: 50px; background-color: #b2b6be !important; } -.infobox_label { - font-size: 16px !important; -} - .deviceSelector { display: block; @@ -1667,6 +1698,10 @@ textarea[readonly], min-height: 42px; } +.form-group { + margin-bottom: 5px !important; +} + /* Remove the default Select2 chevron (the down arrow) */ .select2-container .select2-selection__arrow b { display: none !important; diff --git a/front/deviceDetailsEdit.php b/front/deviceDetailsEdit.php index d2689866..55dd73e5 100755 --- a/front/deviceDetailsEdit.php +++ b/front/deviceDetailsEdit.php @@ -172,6 +172,15 @@ function getDeviceData() { labelClasses: "col-sm-4 col-xs-12 control-label", inputClasses: "col-sm-8 col-xs-12 input-group" }, + // Group for Custom properties. + DevDetail_CustomProperties_Title: { + data: ["devCustomProps"], + docs: "https://docs.netalertx.com/CUSTOM_PROPERTIES", + iconClass: "fa fa-list", + inputGroupClasses: "field-group cutprop-group col-lg-6 col-sm-12 col-xs-12", + labelClasses: "col-sm-12 col-xs-12 control-label", + inputClasses: "col-sm-12 col-xs-12 input-group" + }, // Group for Children. DevDetail_Children_Title: { data: ["devChildrenDynamic"], @@ -181,15 +190,6 @@ function getDeviceData() { labelClasses: "col-sm-12 col-xs-12 control-label", inputClasses: "col-sm-12 col-xs-12 input-group" }, - // Group for Custom properties. - DevDetail_CustomProperties_Title: { - data: ["devCustomProps"], - docs: "https://docs.netalertx.com/CUSTOM_PROPERTIES", - iconClass: "fa fa-list", - inputGroupClasses: "field-group cutprop-group col-lg-6 col-sm-12 col-xs-12", - labelClasses: "col-sm-12 col-xs-12 control-label", - inputClasses: "col-sm-12 col-xs-12 input-group" - } }; // Filter settings data to get relevant settings diff --git a/front/js/common.js b/front/js/common.js index da0f2cb8..ceeb82a5 100755 --- a/front/js/common.js +++ b/front/js/common.js @@ -450,10 +450,18 @@ function localizeTimestamp(input) { const date = new Date(str); if (!isFinite(date)) { console.error(`ERROR: Couldn't parse date: '${str}' with TIMEZONE ${tz}`); - return 'Failed conversion - Check browser console'; + return 'Failed conversion'; } + + // CHECK: Does the input string have an offset (e.g., +11:00 or Z)? + // If it does, and we apply a 'tz' again, we double-shift. + const hasOffset = /[Z|[+-]\d{2}:?\d{2}]$/.test(str.trim()); + return new Intl.DateTimeFormat(LOCALE, { - timeZone: tz, + // If it has an offset, we display it as-is (UTC mode in Intl + // effectively means "don't add more hours"). + // If no offset, apply your variable 'tz'. + timeZone: hasOffset ? 'UTC' : tz, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false diff --git a/front/js/sse_manager.js b/front/js/sse_manager.js index 3afda1c6..2c53d31d 100644 --- a/front/js/sse_manager.js +++ b/front/js/sse_manager.js @@ -23,10 +23,19 @@ class NetAlertXStateManager { */ init() { if (this.initialized) return; + // waiting until cache ready + const waitForInit = () => { + if (!isAppInitialized()) { + setTimeout(waitForInit, 300); + return; + } - console.log("[NetAlertX State] Initializing state manager..."); - this.trySSE(); - this.initialized = true; + console.log("[NetAlertX State] App initialized, starting state manager"); + this.trySSE(); + this.initialized = true; + }; + + waitForInit(); } /** diff --git a/front/maintenance.php b/front/maintenance.php index fbf2fd04..553ca391 100755 --- a/front/maintenance.php +++ b/front/maintenance.php @@ -478,9 +478,14 @@ function deleteEvents30() function askUnlockFields () { // Ask showModalWarning('', '', - '', '', 'unlockFields'); + '', '', () => unlockFields(true)); } -function unlockFields() { +function unlockFields(clearAllFields) { + + + console.log("clearAllFields"); + console.log(clearAllFields); + const apiBase = getApiBase(); const apiToken = getSetting("API_TOKEN"); const url = `${apiBase}/devices/fields/unlock`; @@ -489,7 +494,7 @@ function unlockFields() { const payload = { mac: null, // null = all devices fields: null, // null = all tracked fields - clearAll: true // clear all source values + clearAll: clearAllFields // clear all source values }; $.ajax({ diff --git a/front/multiEditCore.php b/front/multiEditCore.php index 6006b6db..e3f4c5e3 100755 --- a/front/multiEditCore.php +++ b/front/multiEditCore.php @@ -70,6 +70,12 @@
+
+
+ +
+
+
@@ -436,6 +442,18 @@ function askUnlockFieldsSelected () { 'unlockFieldsSelected'); } +// ----------------------------------------------------------------------------- +// Ask to unlock fields of selected devices +function askClearSourceFields () { + // Ask + showModalWarning( + getString('Maintenance_Tool_clearSourceFields_selected_noti'), + getString('Gen_AreYouSure'), + getString('Gen_Cancel'), + getString('Gen_Okay'), + ()=>unlockFieldsSelected(null, true)); +} + // ----------------------------------------------------------------------------- // Unlock fields for selected devices function unlockFieldsSelected(fields = null, clearAll = false) { @@ -443,6 +461,7 @@ function unlockFieldsSelected(fields = null, clearAll = false) { const macs_tmp = selectorMacs(); // returns array of MACs console.log(macs_tmp); + console.log(clearAll); if (!macs_tmp || macs_tmp == "" || macs_tmp.length === 0) { @@ -461,7 +480,7 @@ function unlockFieldsSelected(fields = null, clearAll = false) { const payload = { mac: macsArray, // array of MACs for backend fields: fields, // null for all tracked fields - clear_all: clearAll // true to clear all sources, false to clear only LOCKED/USER + clearAll: clearAll // true to clear all sources, false to clear only LOCKED/USER }; $.ajax({ diff --git a/front/php/components/device_cards.php b/front/php/components/device_cards.php index e131b7e1..0ca24e44 100755 --- a/front/php/components/device_cards.php +++ b/front/php/components/device_cards.php @@ -21,8 +21,10 @@ function renderSmallBox($params) {
-

' . htmlspecialchars($dataValue) . '

-

' . lang(htmlspecialchars($labelLang)) . '

+
+
' . htmlspecialchars($dataValue) . '
+
+
' . lang(htmlspecialchars($labelLang)) . '
diff --git a/front/php/templates/language/ar_ar.json b/front/php/templates/language/ar_ar.json index 9fb0111e..e5ec5c6a 100644 --- a/front/php/templates/language/ar_ar.json +++ b/front/php/templates/language/ar_ar.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "جاري إنشاء نسخة احتياطية...", "Maintenance_Tool_backup_text": "إنشاء نسخة احتياطية من قاعدة البيانات", "Maintenance_Tool_check_visible": "فحص المرئي", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "الوضع الداكن", "Maintenance_Tool_darkmode_noti": "الوضع الداكن", "Maintenance_Tool_darkmode_noti_text": "تم تغيير الوضع الداكن", @@ -786,4 +789,4 @@ "settings_system_label": "نظام", "settings_update_item_warning": "قم بتحديث القيمة أدناه. احرص على اتباع التنسيق السابق. لم يتم إجراء التحقق.", "test_event_tooltip": "احفظ التغييرات أولاً قبل اختبار الإعدادات." -} +} \ No newline at end of file diff --git a/front/php/templates/language/ca_ca.json b/front/php/templates/language/ca_ca.json index a02d4e10..943f239e 100644 --- a/front/php/templates/language/ca_ca.json +++ b/front/php/templates/language/ca_ca.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Estàs segur que vols executar el Backup DB? Assegura't que no hi ha exploració en funcionament.", "Maintenance_Tool_backup_text": "Les còpies de seguretat de la base de dades es troben al directori de bases de dades com a arxiu zip, anomenat amb la data de creació. No hi ha un nombre màxim de còpies de seguretat.", "Maintenance_Tool_check_visible": "Desmarqueu-ho per amagar la columna.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Canvia Modes (Fosc/Clar)", "Maintenance_Tool_darkmode_noti": "Canvia Modes", "Maintenance_Tool_darkmode_noti_text": "Després del canvi de tema, la pàgina intenta recarregar-se per activar el canvi. Si és necessari, s'ha de netejar la memòria cau.", diff --git a/front/php/templates/language/cs_cz.json b/front/php/templates/language/cs_cz.json index 18609abe..61324a97 100644 --- a/front/php/templates/language/cs_cz.json +++ b/front/php/templates/language/cs_cz.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "", "Maintenance_Tool_backup_text": "", "Maintenance_Tool_check_visible": "", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "", "Maintenance_Tool_darkmode_noti": "", "Maintenance_Tool_darkmode_noti_text": "", diff --git a/front/php/templates/language/de_de.json b/front/php/templates/language/de_de.json index fdbf364a..57f55df0 100644 --- a/front/php/templates/language/de_de.json +++ b/front/php/templates/language/de_de.json @@ -84,12 +84,12 @@ "DevDetail_EveandAl_NewDevice": "Neues Gerät", "DevDetail_EveandAl_NewDevice_Tooltip": "Zeigt den Status „Neu“ für das Gerät an und nimmt es in Listen auf, wenn der Filter „Neue Geräte“ aktiv ist. Hat keine Auswirkungen auf Benachrichtigungen.", "DevDetail_EveandAl_RandomMAC": "Zufällige MAC", - "DevDetail_EveandAl_ScanCycle": "Scan Abstand", + "DevDetail_EveandAl_ScanCycle": "Gerät scannen", "DevDetail_EveandAl_ScanCycle_a": "Gerät scannen", "DevDetail_EveandAl_ScanCycle_z": "Gerät nicht scannen", - "DevDetail_EveandAl_Skip": "pausiere wiederhol. Meldungen für", + "DevDetail_EveandAl_Skip": "Keine wiederholten Benachrichtigungen für", "DevDetail_EveandAl_Title": "Konfiguration der Benachrichtigungen", - "DevDetail_Events_CheckBox": "Blende Verbindungs-Ereignisse aus", + "DevDetail_Events_CheckBox": "Verbindungsereignisse ausblenden", "DevDetail_GoToNetworkNode": "Zur Netzwerkseite des angegebenen Knotens navigieren.", "DevDetail_Icon": "Icon", "DevDetail_Icon_Descr": "Geben Sie einen Font Awesome Icon-Namen ohne das Präfix „fa-“ ein oder die vollständige Klasse, z. B.: fa fa-brands fa-apple.", @@ -102,10 +102,10 @@ "DevDetail_MainInfo_Network": " Knoten (MAC)", "DevDetail_MainInfo_Network_Port": " Port", "DevDetail_MainInfo_Network_Site": "Seite", - "DevDetail_MainInfo_Network_Title": "Network", + "DevDetail_MainInfo_Network_Title": "Netzwerkdetails", "DevDetail_MainInfo_Owner": "Eigen­tümer", "DevDetail_MainInfo_SSID": "SSID", - "DevDetail_MainInfo_Title": "Hauptinformation", + "DevDetail_MainInfo_Title": "Geräteinformationen", "DevDetail_MainInfo_Type": "Typ", "DevDetail_MainInfo_Vendor": "Hersteller", "DevDetail_MainInfo_mac": "MAC", @@ -209,7 +209,7 @@ "Device_MultiEdit_Tooltip": "Achtung! Beim Drücken werden alle Werte auf die oben ausgewählten Geräte übertragen.", "Device_Save_Failed": "", "Device_Save_Unauthorized": "", - "Device_Saved_Success": "", + "Device_Saved_Success": "Gerät erfolgreich gespeichert", "Device_Saved_Unexpected": "", "Device_Searchbox": "Suche", "Device_Shortcut_AllDevices": "Meine Geräte", @@ -255,7 +255,7 @@ "Device_TableHead_SyncHubNodeName": "Synchronisationsknoten", "Device_TableHead_Type": "Typ", "Device_TableHead_Vendor": "Hersteller", - "Device_TableHead_Vlan": "", + "Device_TableHead_Vlan": "VLAN", "Device_Table_Not_Network_Device": "Nicht konfiguriert als Netzwerkgerät", "Device_Table_info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen", "Device_Table_nav_next": "Nächste", @@ -445,6 +445,9 @@ "Maintenance_Tool_backup_noti_text": "Sind Sie sicher, dass Sie die Datenbank jetzt sichern möchten. Prüfen Sie, dass gerade keine Scans stattfinden.", "Maintenance_Tool_backup_text": "Die Datenbank-Sicher­ungen befinden sich im Datenbank-Ver­zeich­nis, gepackt als zip-Archive, benannt mit dem Erstellungs­datum. Es gibt keine maximale Anzahl von Backups.", "Maintenance_Tool_check_visible": "Abwählen um die Spalte auszublenden.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Darstellungswechsel (Dunkel/Hell)", "Maintenance_Tool_darkmode_noti": "Darstellungswechsel", "Maintenance_Tool_darkmode_noti_text": "Wechselt zwischen der hellen und der dunklen Darstellung. Wenn die Umschaltung nicht ordentlich funktionieren sollte, versuchen Sie den Browsercache zu löschen.", diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json index ba88789f..a58c4af8 100755 --- a/front/php/templates/language/en_us.json +++ b/front/php/templates/language/en_us.json @@ -414,8 +414,8 @@ "Maintenance_Tool_ImportPastedConfig": "Settings Import (paste)", "Maintenance_Tool_ImportPastedConfig_noti_text": "Are you sure you want to import the pasted config settings? This will completely overwrite the app.conf file.", "Maintenance_Tool_ImportPastedConfig_text": "Imports the app.conf file containing all the application Settings. You might want to download the current app.conf file first with the Settings Export.", - "Maintenance_Tool_UnlockFields": "Clear All Device Sources", - "Maintenance_Tool_UnlockFields_noti": "Clear All Device Sources", + "Maintenance_Tool_UnlockFields": "Unlock Device Fields", + "Maintenance_Tool_UnlockFields_noti": "Unlock Device Fields", "Maintenance_Tool_UnlockFields_noti_text": "Are you sure you want to clear all source values (LOCKED/USER) for all device fields on all devices? This action cannot be undone.", "Maintenance_Tool_UnlockFields_text": "This tool will remove all source values from every tracked field for all devices, effectively unlocking all fields for plugins and users. Use this with caution, as it will affect your entire device inventory.", "Maintenance_Tool_arpscansw": "Toggle arp-Scan (on/off)", @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Are you sure you want to execute the DB Backup? Be sure that no scan is currently running.", "Maintenance_Tool_backup_text": "The database backups are located in the database directory as a zip-archive, named with the creation date. There is no maximum number of backups.", "Maintenance_Tool_check_visible": "Uncheck to hide column.", + "Maintenance_Tool_clearSourceFields_selected": "Clear source fields", + "Maintenance_Tool_clearSourceFields_selected_noti": "Clear sources", + "Maintenance_Tool_clearSourceFields_selected_text": "This will clear all source fields of the selected devices. This action cannot be undone.", "Maintenance_Tool_darkmode": "Toggle Modes (Dark/Light)", "Maintenance_Tool_darkmode_noti": "Toggle Modes", "Maintenance_Tool_darkmode_noti_text": "After the theme switch, the page tries to reload itself to activate the change. If necessary, the cache must be cleared.", diff --git a/front/php/templates/language/es_es.json b/front/php/templates/language/es_es.json index e7e9bf03..aff4832c 100644 --- a/front/php/templates/language/es_es.json +++ b/front/php/templates/language/es_es.json @@ -443,6 +443,9 @@ "Maintenance_Tool_backup_noti_text": "¿Estás seguro de que quieres exactos la copia de seguridad de DB? Asegúrese de que ningún escaneo se esté ejecutando actualmente.", "Maintenance_Tool_backup_text": "Las copias de seguridad de la base de datos se encuentran en el directorio de la base de datos como una Zip-Archive, nombrada con la fecha de creación. No hay un número máximo de copias de seguridad.", "Maintenance_Tool_check_visible": "Desactivar para ocultar columna.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Cambiar Modo (Dark/Light)", "Maintenance_Tool_darkmode_noti": "Cambiar Modo", "Maintenance_Tool_darkmode_noti_text": "Después del cambio de tema, la página intenta volver a cargar para activar el cambio. Si es necesario, el caché debe ser eliminado.", diff --git a/front/php/templates/language/fa_fa.json b/front/php/templates/language/fa_fa.json index 3ed24919..772ef8df 100644 --- a/front/php/templates/language/fa_fa.json +++ b/front/php/templates/language/fa_fa.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "", "Maintenance_Tool_backup_text": "", "Maintenance_Tool_check_visible": "", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "", "Maintenance_Tool_darkmode_noti": "", "Maintenance_Tool_darkmode_noti_text": "", diff --git a/front/php/templates/language/fr_fr.json b/front/php/templates/language/fr_fr.json index 38500544..56ce651b 100644 --- a/front/php/templates/language/fr_fr.json +++ b/front/php/templates/language/fr_fr.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Êtes-vous sûr de vouloir lancer la sauvegarde de la base de données ? Assurez-vous de ne pas avoir de scan en cours.", "Maintenance_Tool_backup_text": "Les sauvegardes de base de données sont situées dans le répertoire de la base de données, soir forme d'archive ZIP, nommé selon la date de création. Il n'y a pas de limite de nombre de sauvegarde.", "Maintenance_Tool_check_visible": "Décocher pour masquer la colonne.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Basculer de mode (clair/sombre)", "Maintenance_Tool_darkmode_noti": "Basculer de mode", "Maintenance_Tool_darkmode_noti_text": "Après le changement de thème, la page tente de se rafraîchir pour activer le changement. Si besoin, le cache doit être supprimé.", @@ -786,4 +789,4 @@ "settings_system_label": "Système", "settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. Il n'y a pas de pas de contrôle.", "test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage." -} +} \ No newline at end of file diff --git a/front/php/templates/language/it_it.json b/front/php/templates/language/it_it.json index ce37850e..c3edccb7 100644 --- a/front/php/templates/language/it_it.json +++ b/front/php/templates/language/it_it.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Sei sicuro di voler eseguire il backup del DB? Assicurati che nessuna scansione sia attualmente in esecuzione.", "Maintenance_Tool_backup_text": "I backup del database si trovano nella directory del database come archivio zip, denominato con la data di creazione. Non esiste un numero massimo di backup.", "Maintenance_Tool_check_visible": "Deseleziona per nascondere la colonna.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Alterna modalità (Scuro/Chiaro)", "Maintenance_Tool_darkmode_noti": "Alterna modalità", "Maintenance_Tool_darkmode_noti_text": "Dopo il cambio di tema, la pagina tenta di ricaricarsi per attivare la modifica. Potrebbe essere necessaria la cancellazione della cache.", @@ -786,4 +789,4 @@ "settings_system_label": "Sistema", "settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. La convalida non viene eseguita.", "test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni." -} +} \ No newline at end of file diff --git a/front/php/templates/language/ja_jp.json b/front/php/templates/language/ja_jp.json index e5dece69..2c00ce59 100644 --- a/front/php/templates/language/ja_jp.json +++ b/front/php/templates/language/ja_jp.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "データベースのバックアップを実行してもよろしいですか? 現在スキャンが実行されていないことを確認してください。", "Maintenance_Tool_backup_text": "データベースのバックアップは、作成日をファイル名としたzipアーカイブとしてデータベースディレクトリ内に配置されます。バックアップの最大数は存在しません。", "Maintenance_Tool_check_visible": "チェックを外すと列を非表示にします。", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "モード切替(ダーク/ライト)", "Maintenance_Tool_darkmode_noti": "モード切替", "Maintenance_Tool_darkmode_noti_text": "テーマ変更後、変更を有効化するためにページを再読み込みします。必要に応じて、キャッシュをクリアする必要があります。", diff --git a/front/php/templates/language/nb_no.json b/front/php/templates/language/nb_no.json index 7b1d40aa..e86b9200 100644 --- a/front/php/templates/language/nb_no.json +++ b/front/php/templates/language/nb_no.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Er du sikker på at du vil kjøre Database Sikkerhetskopiering? Pass på at ingen skanning kjører for øyeblikket.", "Maintenance_Tool_backup_text": "Databasesikkerhetskopiene er plassert i databasekatalogen som et zip-arkiv, navngitt med opprettelsesdatoen. Det er ikke noe maksimalt antall sikkerhetskopier.", "Maintenance_Tool_check_visible": "Fjern merket for å skjule kolonne.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Bytt Modus (mørk/lys)", "Maintenance_Tool_darkmode_noti": "Bytt Modus", "Maintenance_Tool_darkmode_noti_text": "Etter tema bytte, prøver siden å laste seg inn på nytt for å aktivere endringen. Om nødvendig må hurtigbufferen tømmes.", diff --git a/front/php/templates/language/pl_pl.json b/front/php/templates/language/pl_pl.json index 14d8fbe5..877376bd 100644 --- a/front/php/templates/language/pl_pl.json +++ b/front/php/templates/language/pl_pl.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Czy na pewno chcesz wykonać kopię zapasową bazy danych? Upewnij się, że żadne skanowanie nie jest obecnie uruchomione.", "Maintenance_Tool_backup_text": "Kopie zapasowe bazy danych są zapisywane w katalogu bazy danych jako archiwum ZIP, nazwane zgodnie z datą utworzenia. Nie ma ustalonego limitu liczby kopii zapasowych.", "Maintenance_Tool_check_visible": "Usuń zaznaczenie, aby ukryć kolumnę.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Przełącz tryb (Ciemny/Jasny)", "Maintenance_Tool_darkmode_noti": "Przełącz tryb", "Maintenance_Tool_darkmode_noti_text": "Po zmianie motywu strona próbuje przeładować się, aby zastosować zmiany. W razie potrzeby należy wyczyścić pamięć podręczną (cache).", diff --git a/front/php/templates/language/pt_br.json b/front/php/templates/language/pt_br.json index 02244aea..5adbb5cd 100644 --- a/front/php/templates/language/pt_br.json +++ b/front/php/templates/language/pt_br.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Tem a certeza de que pretende executar a cópia de segurança da BD? Certifique-se de que não está a ser executada nenhuma verificação.", "Maintenance_Tool_backup_text": "Os backups do banco de dados estão localizados no diretório do banco de dados como um zip-archive, nomeado com a data de criação. Não há nenhum número máximo de backups.", "Maintenance_Tool_check_visible": "Desmarque para esconder a coluna.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Modos de alternância (escuro/claro)", "Maintenance_Tool_darkmode_noti": "Modos de alternância", "Maintenance_Tool_darkmode_noti_text": "Após a mudança de tema, a página tenta recarregar-se para ativar a alteração. Se necessário, a cache deve ser limpa.", diff --git a/front/php/templates/language/pt_pt.json b/front/php/templates/language/pt_pt.json index 687a9009..c44b0545 100644 --- a/front/php/templates/language/pt_pt.json +++ b/front/php/templates/language/pt_pt.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Tem a certeza de que pretende executar a cópia de segurança da BD? Certifique-se de que não está a ser executada nenhuma verificação.", "Maintenance_Tool_backup_text": "Os backups da base de dados estão localizadas no diretório da base de dados como um arquivo zip, nomeado com a data de criação. Não há nenhum número máximo de backups.", "Maintenance_Tool_check_visible": "Desmarque para esconder a coluna.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Modos de alternância (escuro/claro)", "Maintenance_Tool_darkmode_noti": "Modos de alternância", "Maintenance_Tool_darkmode_noti_text": "Após a mudança de tema, a página tenta recarregar-se para ativar a alteração. Se necessário, a cache deve ser limpa.", diff --git a/front/php/templates/language/ru_ru.json b/front/php/templates/language/ru_ru.json index dd868dbe..493c55ca 100644 --- a/front/php/templates/language/ru_ru.json +++ b/front/php/templates/language/ru_ru.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Вы уверены, что хотите выполнить резервное копирование БД? Убедитесь, что в данный момент сканирование не выполняется.", "Maintenance_Tool_backup_text": "Резервные копии базы данных располагаются в каталоге базы данных в виде zip-архива, имя которого соответствует дате создания. Максимального количества резервных копий не существует.", "Maintenance_Tool_check_visible": "Снимите флажок, чтобы скрыть столбец.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Тема (Темная/Светлая)", "Maintenance_Tool_darkmode_noti": "Переключение режимов", "Maintenance_Tool_darkmode_noti_text": "После переключения темы страница пытается перезагрузиться, чтобы активировать изменение. При необходимости кэш необходимо очистить.", diff --git a/front/php/templates/language/sv_sv.json b/front/php/templates/language/sv_sv.json index ae8afffd..74024c1d 100644 --- a/front/php/templates/language/sv_sv.json +++ b/front/php/templates/language/sv_sv.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "", "Maintenance_Tool_backup_text": "", "Maintenance_Tool_check_visible": "", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "", "Maintenance_Tool_darkmode_noti": "", "Maintenance_Tool_darkmode_noti_text": "", diff --git a/front/php/templates/language/tr_tr.json b/front/php/templates/language/tr_tr.json index ad873c21..3d54e46c 100644 --- a/front/php/templates/language/tr_tr.json +++ b/front/php/templates/language/tr_tr.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "DB Yedeklemesini yürütmek istediğinizden emin misiniz? Şu anda hiçbir taramanın çalışmadığından emin olun.", "Maintenance_Tool_backup_text": "Veritabanı yedekleri, veritabanı dizininde, oluşturulma tarihiyle adlandırılan bir zip arşivi olarak bulunur. Maksimum yedekleme sayısı yoktur.", "Maintenance_Tool_check_visible": "Sütunu gizlemek için işareti kaldırın.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Modları Değiştir (Koyu/Açık)", "Maintenance_Tool_darkmode_noti": "Modları Aç/Kapat", "Maintenance_Tool_darkmode_noti_text": "Tema geçişinden sonra sayfa, değişikliği etkinleştirmek için kendini yeniden yüklemeye çalışır. Gerekirse, önbellek temizlenmelidir.", diff --git a/front/php/templates/language/uk_ua.json b/front/php/templates/language/uk_ua.json index 78006829..8c5efe4f 100644 --- a/front/php/templates/language/uk_ua.json +++ b/front/php/templates/language/uk_ua.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "Ви впевнені, що хочете виконати резервне копіювання БД? Переконайтеся, що сканування наразі не виконується.", "Maintenance_Tool_backup_text": "Резервні копії бази даних зберігаються в каталозі бази даних у вигляді zip-архіву з датою створення. Немає максимальної кількості резервних копій.", "Maintenance_Tool_check_visible": "Зніміть прапорець, щоб приховати стовпець.", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "Перемикати режими (темний/світлий)", "Maintenance_Tool_darkmode_noti": "Перемикати режими", "Maintenance_Tool_darkmode_noti_text": "Після перемикання теми сторінка намагається перезавантажитися, щоб активувати зміну. При необхідності необхідно очистити кеш.", diff --git a/front/php/templates/language/zh_cn.json b/front/php/templates/language/zh_cn.json index ab2966b4..0d46621b 100644 --- a/front/php/templates/language/zh_cn.json +++ b/front/php/templates/language/zh_cn.json @@ -427,6 +427,9 @@ "Maintenance_Tool_backup_noti_text": "您确定要执行数据库备份吗?请确保当前没有正在运行的扫描。", "Maintenance_Tool_backup_text": "数据库备份以 zip 存档形式位于数据库目录中,以创建日期命名。备份数量没有上限。", "Maintenance_Tool_check_visible": "取消选择隐藏列。", + "Maintenance_Tool_clearSourceFields_selected": "", + "Maintenance_Tool_clearSourceFields_selected_noti": "", + "Maintenance_Tool_clearSourceFields_selected_text": "", "Maintenance_Tool_darkmode": "切换模式(暗/亮)", "Maintenance_Tool_darkmode_noti": "切换模式", "Maintenance_Tool_darkmode_noti_text": "主题切换后,页面会尝试重新加载以激活更改。如有必要,必须清除缓存。", @@ -760,7 +763,7 @@ "run_event_tooltip": "在运行之前,请先启用设置并保存更改。", "select_icon_event_tooltip": "选择图标", "settings_core_icon": "fa-solid fa-gem", - "settings_core_label": "核心", + "settings_core_label": "主要", "settings_device_scanners": "设备扫描器用于发现写入当前扫描数据库表的设备。", "settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus", "settings_device_scanners_info": "使用 LOADED_PLUGINS 设置加载更多设备扫描仪", @@ -786,4 +789,4 @@ "settings_system_label": "系统", "settings_update_item_warning": "更新下面的值。请注意遵循先前的格式。未执行验证。", "test_event_tooltip": "在测试设置之前,请先保存更改。" -} +} \ No newline at end of file diff --git a/front/plugins/icmp_scan/config.json b/front/plugins/icmp_scan/config.json index ee4b12fa..382b8b7f 100755 --- a/front/plugins/icmp_scan/config.json +++ b/front/plugins/icmp_scan/config.json @@ -418,7 +418,6 @@ }, { "column": "Watched_Value1", - "mapped_to_column": "scanName", "css_classes": "col-sm-2", "show": true, "type": "label", diff --git a/mkdocs.yml b/mkdocs.yml index 4451824b..dd4769de 100755 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,6 @@ -site_name: NetAlertX Documentation +site_name: Documentation site_url: https://docs.netalertx.com -repo_url: https://github.com/jokob-sk/NetAlertX/ +repo_url: https://github.com/netalertx/NetAlertX/ edit_uri: blob/main/docs/ docs_dir: docs use_directory_urls: true @@ -141,7 +141,7 @@ theme: custom_dir: docs/overrides metadata: description: "NetAlertX Documentation - The go-to resource for all things related to NetAlertX." - image: "https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/front/img/netalertx_docs.png" + image: "https://raw.githubusercontent.com/netalertx/NetAlertX/main/front/img/netalertx_docs.png" extra: home_hide_sidebar: true analytics: diff --git a/server/api_server/api_server_start.py b/server/api_server/api_server_start.py index de68c90d..221d57be 100755 --- a/server/api_server/api_server_start.py +++ b/server/api_server/api_server_start.py @@ -4,7 +4,7 @@ import os # flake8: noqa: E402 -from flask import Flask, request, jsonify, Response +from flask import Flask, redirect, request, jsonify, url_for, Response from models.device_instance import DeviceInstance # noqa: E402 from flask_cors import CORS from werkzeug.exceptions import HTTPException @@ -1165,6 +1165,11 @@ def api_docs(): return send_from_directory(openapi_dir, 'swagger.html') +@app.route('/') +def index_redirect(): + """Redirect root to API documentation.""" + return redirect(url_for('api_docs')) + # -------------------------- # DB query # -------------------------- @@ -1401,7 +1406,7 @@ def api_create_event(mac, payload=None): def api_events_by_mac(mac, payload=None): """Delete events for a specific device MAC; string converter keeps this distinct from /events/.""" device_handler = DeviceInstance() - + result = device_handler.deleteDeviceEvents(mac) return jsonify(result) @@ -1740,7 +1745,8 @@ def api_write_notification(payload=None): auth_callable=is_authorized ) def api_get_unread_notifications(payload=None): - return get_unread_notifications() + notifications = get_unread_notifications() + return jsonify(notifications) @app.route("/messaging/in-app/read/all", methods=["POST"]) diff --git a/server/messaging/in_app.py b/server/messaging/in_app.py index ca90962a..ae35c1bd 100755 --- a/server/messaging/in_app.py +++ b/server/messaging/in_app.py @@ -231,7 +231,7 @@ def get_unread_notifications(): notifications = json.load(f) unread = [n for n in notifications if n.get("read", 0) == 0] - return jsonify(unread) + return unread def mark_notification_as_read(guid=None, max_attempts=3): @@ -283,6 +283,13 @@ def mark_notification_as_read(guid=None, max_attempts=3): return {"success": False, "error": error_msg} +def update_unread_notifications_count(): + """ + Re-broadcast unread notifications for the frontend . + """ + broadcast_unread_notifications_count(len(get_unread_notifications())) + + def delete_notification(guid): """ Delete a notification from the notifications file based on its GUID. diff --git a/server/models/device_instance.py b/server/models/device_instance.py index 6037ab7f..4aa1544b 100755 --- a/server/models/device_instance.py +++ b/server/models/device_instance.py @@ -18,7 +18,7 @@ from db.authoritative_handler import ( unlock_fields ) from helper import is_random_mac, get_setting_value -from utils.datetime_utils import timeNowDB, format_date +from utils.datetime_utils import timeNowDB class DeviceInstance: @@ -489,8 +489,8 @@ class DeviceInstance: return None device_data = row_to_json(list(row.keys()), row) - device_data["devFirstConnection"] = format_date(device_data["devFirstConnection"]) - device_data["devLastConnection"] = format_date(device_data["devLastConnection"]) + device_data["devFirstConnection"] = device_data["devFirstConnection"] + device_data["devLastConnection"] = device_data["devLastConnection"] device_data["devIsRandomMAC"] = is_random_mac(device_data["devMac"]) # Fetch children diff --git a/server/plugin.py b/server/plugin.py index 6986b706..998e8df9 100755 --- a/server/plugin.py +++ b/server/plugin.py @@ -212,8 +212,8 @@ class plugin_manager: # Run test self.handle_run(runType) - # Remove sample notification - notificationObj.remove(notificationObj.GUID) + # Save notification + notificationObj.upsert() mylog("minimal", ["[Test] END Test: ", runType]) diff --git a/server/scan/session_events.py b/server/scan/session_events.py index 049ed591..3f9f1022 100755 --- a/server/scan/session_events.py +++ b/server/scan/session_events.py @@ -17,6 +17,7 @@ from db.db_helper import print_table_schema from utils.datetime_utils import timeNowDB from logger import mylog, Logger from messaging.reporting import skip_repeated_notifications +from messaging.in_app import update_unread_notifications_count # Make sure log level is initialized correctly @@ -104,6 +105,9 @@ def process_scan(db): # 🐛 CurrentScan DEBUG: comment out below when debugging to keep the CurrentScan table after restarts/scan finishes db.sql.execute("DELETE FROM CurrentScan") + # re-broadcast unread notifiation count to update FE + update_unread_notifications_count() + # Commit changes db.commitDB() diff --git a/server/utils/datetime_utils.py b/server/utils/datetime_utils.py index 1d513206..3465be49 100644 --- a/server/utils/datetime_utils.py +++ b/server/utils/datetime_utils.py @@ -112,12 +112,29 @@ def normalizeTimeStamp(inputTimeStamp): # ------------------------------------------------------------------------------------------- -def format_date_iso(date1: str) -> Optional[str]: - """Return ISO 8601 string for a date or None if empty""" - if not date1: +def format_date_iso(date_val: str) -> Optional[str]: + """Ensures a date string from DB is returned as a proper ISO string with TZ.""" + if not date_val: return None - dt = datetime.datetime.fromisoformat(date1) if isinstance(date1, str) else date1 - return dt.isoformat() + + try: + # 1. Parse the string from DB (e.g., "2026-01-20 07:58:18") + if isinstance(date_val, str): + # Use a more flexible parser if it's not strict ISO + dt = datetime.datetime.fromisoformat(date_val.replace(" ", "T")) + else: + dt = date_val + + # 2. If it has no timezone, ATTACH (don't convert) your config TZ + if dt.tzinfo is None: + target_tz = conf.tz if isinstance(conf.tz, datetime.tzinfo) else ZoneInfo(conf.tz) + dt = dt.replace(tzinfo=target_tz) + + # 3. Return the string. .isoformat() will now include the +11:00 or +10:00 + return dt.isoformat() + except Exception as e: + print(f"Error formatting date: {e}") + return str(date_val) # ------------------------------------------------------------------------------------------- @@ -156,21 +173,35 @@ def parse_datetime(dt_str): def format_date(date_str: str) -> str: try: - if isinstance(date_str, str): - # collapse all whitespace into single spaces - date_str = re.sub(r"\s+", " ", date_str.strip()) + if not date_str: + return "" + date_str = re.sub(r"\s+", " ", str(date_str).strip()) dt = parse_datetime(date_str) + + if dt.tzinfo is None: + if isinstance(conf.tz, str): + dt = dt.replace(tzinfo=ZoneInfo(conf.tz)) + else: + dt = dt.replace(tzinfo=conf.tz) + if not dt: return f"invalid:{repr(date_str)}" + # If the DB has no timezone, we tell Python what it IS, + # we don't CONVERT it. if dt.tzinfo is None: + # Option A: If the DB time is already AEDT, use AEDT. + # Option B: Use conf.tz if that is your 'source of truth' dt = dt.replace(tzinfo=conf.tz) - return dt.astimezone().isoformat() + # IMPORTANT: Return the ISO format of the object AS IS. + # Calling .astimezone() here triggers a conversion to the + # System Local Time , which is causing your shift. + return dt.isoformat() - except Exception: - return f"invalid:{repr(date_str)}" + except Exception as e: + return f"invalid:{repr(date_str)} e: {e}" def format_date_diff(date1, date2, tz_name): diff --git a/test/api_endpoints/test_docs.py b/test/api_endpoints/test_docs.py new file mode 100644 index 00000000..bc12cecf --- /dev/null +++ b/test/api_endpoints/test_docs.py @@ -0,0 +1,23 @@ +# test/api_endpoints/test_docs.py - Tests for root redirect and API docs endpoints + + +from api_server import api_server_start + + +def test_index_redirect_logic(): + """Test the redirect function logic directly.""" + with api_server_start.app.test_client() as client: + response = client.get("/", follow_redirects=False) + assert response.status_code == 302 + assert response.location == '/docs' + + +def test_api_docs_logic(): + """Test that api_docs attempts to serve the correct file.""" + with api_server_start.app.test_client() as client: + response = client.get("/docs") + assert response.status_code == 200 + assert response.mimetype == "text/html" + response.direct_passthrough = False + data = response.get_data() + assert b"" in data or b"" in data