mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-29 16:17:14 +09:00
* fix: correct grammar and possessive errors in English source strings (batch 2) (#1) * fix: correct grammar and possessive errors in English source strings (batch 2) Seven errors found via cacti.pot audit: - automation_networks.php: "senders name" → "sender\'s name" (line 839) - automation_networks.php: "senders Email" → "sender\'s Email" (line 848) - automation_templates.php: "devices sysDescr" → "device\'s sysDescr" (line 1060) - automation_templates.php: "devices sysName" → "device\'s sysName" (line 1067) - automation_templates.php: "devices sysOid" → "device\'s sysOid" (line 1074) - data_templates.php: garbled "it either it value...critical data Data Query" → "its value...Data Query" (line 903) - package_repos.php: "Package Repositorites" → "Package Repositories" (line 436) All changes are to UI description strings inside __() / __esc() calls. cacti.pot should be regenerated via build_gettext.sh after merge. * fix: correct grammar and possessive errors in English source strings (batch 2) Seven errors found via cacti.pot audit: - automation_networks.php: "senders name" → "sender\'s name" (line 839) - automation_networks.php: "senders Email" → "sender\'s Email" (line 848) - automation_templates.php: "devices sysDescr" → "device\'s sysDescr" (line 1060) - automation_templates.php: "devices sysName" → "device\'s sysName" (line 1067) - automation_templates.php: "devices sysOid" → "device\'s sysOid" (line 1074) - data_templates.php: garbled string → "its value...Data Query" (line 903) - package_repos.php: "Package Repositorites" → "Package Repositories" (line 436) All changes are to UI description strings inside __() / __esc() calls. cacti.pot should be regenerated via build_gettext.sh after merge. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: add dependabot config with npm and github-actions * ci: add CodeQL (JS/TS, excludes PHP) with workflow_dispatch * ci: update CodeQL for javascript-typescript, python * fix(ci): use specific runner labels, fix codeql concurrency * Improve IPv6 support in RRDtool proxy and ping utilities (#2) * Improve IPv6 support in RRDtool proxy and ping utilities - Fix RRDtool proxy to dynamically detect IPv6 addresses and use AF_INET6 sockets instead of hardcoded AF_INET (IPv4-only), enabling connections to IPv6 RRDtool proxy servers including backup servers - Strip brackets from IPv6 addresses before passing to socket_connect - Properly close failed sockets before creating new ones for failover - Replace fragile str_contains(':') IPv6 detection in ping with filter_var(FILTER_FLAG_IPV6) for more robust address validation https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Fix JS code quality: implicit globals, deprecated APIs, loose equality - Add var declarations to prevent implicit globals in install.js (element, enabled, button, buttonCheck) - Remove console.log debug output left in production (install.js) - Replace deprecated jQuery .unbind() with .off() (layout.js) - Fix "depreciated" typo to "deprecated" in deprecation warnings - Convert == / != to === / !== for null, boolean, string, typeof, and numeric comparisons across install.js and realtime.js https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Replace deprecated jQuery shorthand event methods in layout.js Replace .click(), .keyup(), .keydown(), .mousedown(), .mouseenter(), .mouseleave(), .submit(), .resize() with .on() equivalents. Replace .focus(), .change() trigger calls with .trigger(). These shorthands were deprecated in jQuery 3.5. https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Replace deprecated jQuery methods in realtime.js Replace .bind() with .on() and .change() trigger calls with .trigger('change'). .bind() was deprecated in jQuery 3.0 and shorthand triggers in jQuery 3.5. https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Replace deprecated jQuery methods in install.js and fix ===/!== errors Replace .click(), .change(), .focus() with .on()/.trigger() equivalents. Also fix !=== and ==== operators that were incorrectly introduced by a prior replace-all of == to === within existing !== and === expressions. https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Restore == null where needed to catch both null and undefined In JavaScript, == null matches both null and undefined, which is an intentional idiom. The prior === null conversion broke cases where values come from jQuery .val(), .data(), $.urlParam(), or object property access that may return undefined rather than null. Revert those specific cases while keeping === null where variables are explicitly initialized to null. https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Replace deprecated jQuery methods in all theme main.js files Replace .unbind().click() with .off('click').on('click'), convert .hover() to .on('mouseenter').on('mouseleave'), replace .change(), .scroll(), .click() shorthands with .on() equivalents, and .blur() with .trigger('blur') across all 10 theme files. https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Convert string concatenation to template literals Replace 'str' + var + 'str' patterns with ES6 template literals in realtime.js and install.js. Improves readability especially for URL construction and HTML building. Also replace $.parseJSON() with native JSON.parse() in realtime.js. https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo * Convert var to const for single-assignment variables Replace var with const where the variable is assigned once and never reassigned within its scope, in install.js and realtime.js. Keeps var for variables that are conditionally reassigned (e.g. size, url). https://claude.ai/code/session_01SbuDigvAkYvPKvdcougsdo --------- Co-authored-by: Claude <noreply@anthropic.com> * fix(sqli): sanitize sort_column and enforce sort_direction in ORDER BY clauses Closes GHSA-q9xg-p762-9jm3 and GHSA-72vr-jr4v-55vf. - Add sanitize_sql_column() to lib/functions.php stripping all chars outside [a-zA-Z0-9_().] from user-supplied column names - Apply sanitize_sql_column() at every ORDER BY concatenation in api_automation.php and html_reports.php - Enforce direction to literal ASC/DESC in html_reports.php, api_automation.php, and html_utility.php (update_order_string, get_order_string) - Add tests/Unit/SafeSortTest.php with 22 stub-based regression tests Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(docs): move sanitize_sql_column above sanitize_search_string docblock The sanitize_search_string docblock was orphaned after sanitize_sql_column was inserted between it and the function body. Reorder so each function follows its own docblock directly. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(sqli): escape apostrophes in automation_templates and harden sort_direction in display_matching_hosts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(sqli): restore allowlist guard, sanitize session keys, add sanitize_sql_column default Restore the preg_match allowlist guard in get_order_string() that was removed by the PR, re-opening the ORDER BY injection surface. When the request var is empty after sanitization, return '' rather than building a malformed ORDER BY clause. Sanitize sort_column before storing as SESSION array key in update_order_string() and add read-time guard in the inplace loop that rebuilds ORDER BY from stored keys. Add $default parameter to sanitize_sql_column() so callers get a safe fallback instead of an empty string that produces 'ORDER BY ASC'. Fix inconsistent INET_ATON substitution in display_matching_hosts(). Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Improve sanitize_sql_column function Fix regex to sanitize SQL column names properly. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: TheWitness <thewitness@cacti.net> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
184 lines
7.9 KiB
JavaScript
184 lines
7.9 KiB
JavaScript
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2026 The Cacti Group |
|
|
| |
|
|
| This program is free software; you can redistribute it and/or |
|
|
| modify it under the terms of the GNU General Public License |
|
|
| as published by the Free Software Foundation; either version 2 |
|
|
| of the License, or (at your option) any later version. |
|
|
| |
|
|
| This program is distributed in the hope that it will be useful, |
|
|
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
| GNU General Public License for more details. |
|
|
+-------------------------------------------------------------------------+
|
|
| Cacti: The Complete RRDTool-based Graphing Solution |
|
|
+-------------------------------------------------------------------------+
|
|
| This code is designed, written, and maintained by the Cacti Group. See |
|
|
| about.php and/or the AUTHORS file for specific developer information. |
|
|
+-------------------------------------------------------------------------+
|
|
| http://www.cacti.net/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
function themeReady() {
|
|
if ($('#cactiPageBottom').length == 0) {
|
|
$('<div id="cactiPageBottom" class="cactiPageBottom"></a></div>').insertAfter('#cactiContent');
|
|
}
|
|
|
|
// Setup the navigation menu
|
|
setMenuVisibility();
|
|
|
|
// Add nice search filter to filters
|
|
if ($('input[id="filter"]').length > 0 && $('input[id="filter"]').next('i[class="ti ti-search filter"]').length < 1) {
|
|
$('input[id="filter"]').after("<i class='ti ti-search filter'/>").attr('autocomplete', 'off').attr('placeholder', searchFilter).parent('td').css('white-space', 'nowrap');
|
|
}
|
|
|
|
if ($('input[id="filterd"]').length > 0 && $('input[id="filterd"]').next('i[class="ti ti-search filter"]').length < 1) {
|
|
$('input[id="filterd"]').after("<i class='ti ti-search filter'/>").attr('autocomplete', 'off').attr('placeholder', searchFilter).parent('td').css('white-space', 'nowrap');
|
|
}
|
|
|
|
if ($('input[id="rfilter"]').length > 0 && $('input[id="rfilter"]').next('i[class="ti ti-search filter"]').length < 1) {
|
|
$('input[id="rfilter"]').after("<i class='ti ti-search filter'/>").attr('autocomplete', 'off').attr('placeholder', searchRFilter).parent('td').css('white-space', 'nowrap');
|
|
}
|
|
|
|
$('input#filter, input#rfilter').addClass('ui-state-default ui-corner-all');
|
|
|
|
$('input[type="text"], input[type="password"], input[type="checkbox"], textarea').not('image').addClass('ui-state-default ui-corner-all');
|
|
|
|
/* Start clean up */
|
|
|
|
//login page
|
|
$('.cactiLoginLogo').html("<i class='ti ti-paw'/>").css('font-size: 20px');
|
|
|
|
/* clean up the navigation menu */
|
|
$('.cactiConsoleNavigationArea').find('#menu').appendTo($('.cactiConsoleNavigationArea').find('#navigation'));
|
|
$('.cactiConsoleNavigationArea').find('#navigation > table').remove();
|
|
|
|
$('.maintabs nav ul li a.lefttab').each( function() {
|
|
id = $(this).attr('id');
|
|
|
|
if (id == 'tab-graphs' && $(this).parent().hasClass('maintabs-has-submenu') == 0 ) {
|
|
$(this).parent().addClass('maintabs-has-submenu');
|
|
$('<div class="dropdownMenu">'
|
|
+'<ul id="submenu-tab-graphs" class="submenuoptions" style="display:none;">'
|
|
+'<li><a href="'+urlPath+'graph_view.php?action=tree">'+treeView+'</a></li>'
|
|
+'<li><a href="'+urlPath+'graph_view.php?action=list">'+listView+'</a></li>'
|
|
+'<li><a href="'+urlPath+'graph_view.php?action=preview">'+previewView+'</a></li>'
|
|
+'</ul>'
|
|
+'</div>').appendTo('body');
|
|
}
|
|
});
|
|
|
|
/* user menu on the right ... */
|
|
if ($('.usertabs').length == 0) {
|
|
$('#userDocumentation').remove();
|
|
$('#userCommunity').remove();
|
|
$('.menuHr').remove();
|
|
$('<div class="maintabs usertabs">'
|
|
+'<nav><ul>'
|
|
+'<li><a id="menu-user-help" class="usertabs-submenu" href="#"><i class="ti ti-question-mark"></i></a></li>'
|
|
+'<li class="action-icon-user"><a class="pic" href="#"><i class="ti ti-user"></i></a></li>'
|
|
+'</ul></nav>'
|
|
+'</div>').insertAfter('.maintabs');
|
|
|
|
$('<div class="dropdownMenu">'
|
|
+'<ul id="submenu-user-help" class="submenuoptions right" style="display:none;">'
|
|
+'<li><a href="https://www.cacti.net" target="_blank"><span>'+cactiHome+'</span></a></li>'
|
|
+'<li><a href="https://github.com/cacti" target="_blank"><span>'+cactiProjectPage+'</span></a></li>'
|
|
+'<li><hr class="menu"></li>'
|
|
+'<li><a href="https://forums.cacti.net/" target="_blank"><span>'+cactiCommunityForum+'</span></a></li>'
|
|
+'<li><a href="https://github.com/Cacti/documentation/blob/develop/README.md" target="_blank"><span>'+cactiDocumentation+'</span></a></li>'
|
|
+'<li><hr class="menu"></li>'
|
|
+'<li><a href="https://github.com/Cacti/cacti/issues/new" target="_blank"><span>'+reportABug+'</span></a></li>'
|
|
+'<li><a href="'+urlPath+'about.php"><span>'+aboutCacti+'</span></a></li>'
|
|
+'</ul>'
|
|
+'</div>').appendTo('body');
|
|
}
|
|
|
|
ajaxAnchors();
|
|
|
|
/* User Menu */
|
|
$('.menuoptions').parent().appendTo('body');
|
|
|
|
$(window).trigger('resize');
|
|
|
|
$('.action-icon-user').off('click').on('click', function(event) {
|
|
event.preventDefault();
|
|
|
|
if ($('.menuoptions').is(':visible') === false) {
|
|
$('.submenuoptions').slideUp(120);
|
|
$('.menuoptions').slideDown(120);
|
|
} else {
|
|
$('.menuoptions').slideUp(120);
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
/* Highlight sortable table columns */
|
|
$('.tableHeader th').has('i.fa-sort').removeClass('tableHeaderColumnHover tableHeaderColumnSelected');
|
|
$('.tableHeader th').has('i.fa-sort-up').addClass('tableHeaderColumnSelected');
|
|
$('.tableHeader th').has('i.fa-sort-down').addClass('tableHeaderColumnSelected');
|
|
$('.tableHeader th').has('i.fa-sort').on('mouseenter', function() {
|
|
$(this).addClass('tableHeaderColumnHover');
|
|
}).on('mouseleave', function() {
|
|
$(this).removeClass('tableHeaderColumnHover');
|
|
});
|
|
|
|
$('input#filter, input#rfilter').addClass('ui-state-default ui-corner-all');
|
|
|
|
$('input[type="text"], input[type="password"], input[type="checkbox"], textarea').not('image').addClass('ui-state-default ui-corner-all');
|
|
|
|
setNavigationScroll();
|
|
}
|
|
|
|
function setMenuVisibility() {
|
|
storage=Storages.sessionStorage;
|
|
|
|
// Initialize the navigation settings
|
|
$('#navigation').hide();
|
|
$('li.menuitem').each(function() {
|
|
active = storage.get($(this).attr('id'));
|
|
if (active != null && active == 'active') {
|
|
$(this).find('ul').attr('aria-hidden', 'false').attr('aria-expanded', 'true').show();
|
|
$(this).next('a').show();
|
|
} else {
|
|
$(this).find('ul').attr('aria-hidden', 'true').attr('aria-expanded', 'false').hide();
|
|
$(this).next('a').hide();
|
|
}
|
|
});
|
|
|
|
$('#navigation').show();
|
|
|
|
// Functon to give life to the Navigation pane
|
|
$('#nav li:has(ul) a.active').off('click').on('click', function(event) {
|
|
event.preventDefault();
|
|
|
|
id = $(this).closest('.menuitem').attr('id');
|
|
|
|
if ($(this).next().is(':visible')){
|
|
$(this).next('ul').attr('aria-hidden', 'true').attr('aria-expanded', 'false');
|
|
$(this).next().slideUp( { duration: 200, easing: 'swing' } );
|
|
storage.set($(this).closest('.menuitem').attr('id'), 'collapsed');
|
|
} else {
|
|
$(this).next('ul').attr('aria-hidden', 'false').attr('aria-expanded', 'true');
|
|
$(this).next().slideToggle( { duration: 200, easing: 'swing' } );
|
|
if ($(this).next().is(':visible')) {
|
|
storage.set($(this).closest('.menuitem').attr('id'), 'active');
|
|
} else {
|
|
storage.set($(this).closest('.menuitem').attr('id'), 'collapsed');
|
|
}
|
|
}
|
|
|
|
$('li.menuitem').not('#'+id).each(function() {
|
|
text = $(this).attr('id');
|
|
id = $(this).attr('id');
|
|
|
|
$(this).find('ul').attr('aria-hidden', 'true').attr('aria-expanded', 'false');
|
|
$(this).find('ul').slideUp( { duration: 200, easing: 'swing' } );
|
|
storage.set($(this).attr('id'), 'collapsed');
|
|
});
|
|
});
|
|
}
|