Commit 8471 bumped dompurify from 3.4.16 to 3.4.17 in package.json but left
the JavaScript contract test and the vendored include/js/purify.js at 3.4.16,
breaking the "JavaScript contracts" CI job on develop (test "DOMPurify is
pinned and generated from the matching npm release").
- Update tests/js/sync_js.test.mjs to expect dompurify 3.4.17 in both the
package.json pin assertion and the purify.js license-header match.
- Regenerate include/js/purify.js and include/js/purify.js.map from the
dompurify 3.4.17 npm release via build/sync-js.mjs (npm install postinstall).
All 78 JavaScript contract tests pass locally.
Co-authored-by: TheWitness <copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: Restore base javascript files for testing
* fix: screenfull 6.0.2 is missing screenfull.js
* fix: Restoring screenful after discovering how the files are managed
* fix: Remove node modules directory after installing modules
* fix: Change in screenfull.js behavior affects cacti
* fix: Restore jQuery 4 compatibility in the tablesorter pager plugin
$.isArray()/$.trim() were removed in jQuery 4.0, which this PR pins in
package.json. The restored jquery.tablesorter.pager.js still called
E.isArray(...)/E.trim(...), so any Ajax pager response threw before
rendering. Also fix a TypeError in the countChildRows branch, which
indexed into `a` while it was still an undeclared var.
Add patches/tablesorter+2.32.0.patch so the fix survives the next
`npm run build:js` sync from node_modules, following the existing
pace-js patch-package precedent.
* fix: Rewrite screenfull's ESM export during sync-js instead of downgrading
screenfull 6+ ships ESM-only (`export default screenfull;` in
node_modules/screenfull/index.js), which throws "export declarations
may only appear at top level of a module" when the copied file is
loaded as a classic <script>.
Add a post-copy transform step to build/sync-js.mjs that rewrites that
line to `window.screenfull = screenfull;` for include/js/screenfull.js,
so the 6.0.2 pin in package.json can be kept instead of reverting to
5.2.0. Throws if the expected export line isn't found, so a future
screenfull release changing its export shape fails the build loudly
rather than silently shipping a broken asset.
Updates tests/js/sync_js.test.mjs to cover the transform and its
failure mode.
* chore: manage front-end JavaScript libraries with npm and Dependabot
Move all third-party front-end JavaScript to npm so Dependabot tracks it, and
drop the committed copies in favour of a build. package.json pins jquery,
jquery-ui, jstree (3.3.12 -> 3.3.17), billboard.js, pace-js, tablesorter and
jquery-validation; build/sync-js.mjs copies their dist files into include/js/
and runs on npm install via postinstall.
pace-js carries a one-line local fix (a stray regex alternation that made it
match the empty string) applied through patch-package
(patches/pace-js+1.2.4.patch); the fix should be sent upstream so the patch can
be dropped. Only Cacti's own themed jquery-ui/jstree CSS stays committed.
An npm ecosystem is added to dependabot.yml for develop. The release pipeline
and any workflow that serves Cacti pages must run 'npm ci' (which builds via
postinstall) before use, since the generated files are no longer in the tree.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* hardening: remove vendored development artifacts
* feat(release): attach the built artifact to the release
The workflow already builds an attested, checksummed archive carrying the
Composer dependencies, then discards it after thirty days.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: fail the publish step when the bundle is empty
An unmatched glob would otherwise reach gh as a literal path.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: treat the maintenance lock notice as expected log output
The line records the lock working, so a second maintenance run overlapping
in CI failed unrelated pull requests.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: consolidate release dependency changelog
* ci: build managed JavaScript in release artifacts
* test: cover managed JavaScript build end to end
* deps: complete phpseclib 4 migration
* deps: update patch-package to audited release
* ci: satisfy workflow shell policy
* chore: source DOMPurify from npm and update it to 3.4.14
Add dompurify to the npm-managed set (was committed at 3.4.7) and bump to 3.4.14.
DOMPurify is the client-side XSS sanitizer used on tree labels, device tooltips
and plugin messages; keeping it current with upstream bypass fixes matters more
than for the UI libraries.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: preserve release changelog ordering
* test: preserve DOMPurify source map in npm build
* chore: source htmx, d3, big.js, lzjs and screenfull from npm
Add the remaining unmodified third-party libraries to the npm-managed build:
htmx.org 2.0.6, d3 7.8.2, big.js 6.2.2, lzjs 1.3.1 and screenfull 3.3.3. Each
was verified byte-identical (lzjs differs only in a JSDoc comment) to the copies
being removed. htmx in particular moves from a hand-tracked SHA pin to npm with
lockfile integrity.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover phpseclib 4 integration
* ci: build managed assets before htmx tests
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(security): align develop with advisory hardening
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(security): harden remote agent auth compatibility
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(security): reorder remote auth checks
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(security): harden remote_agent auth order and query scope
Move whitelist check before the single-poller guard so single-poller
installs relying on the whitelist are not incorrectly rejected.
Narrow SELECT * to SELECT hostname; the loop only reads hostname.
Drop function_exists guards around md5/hash; both are PHP core and the
raw $cache_seed fallback is unsafe as an APCu key.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(theme): cast read_config_option result to string in cacti_validate_theme
read_config_option can return false or null when the setting is absent.
Without the cast, a strict comparison to '' would not match, leaving
$default unset and risking a null-typed value flowing into callers.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(reports): skip invalid IDs in bulk action without aborting the loop
Replace input_validate_input_number (which calls die_html_input_error
on bad input, aborting the entire bulk action) with an inline guard.
Cast $report_id to int at call sites where the signature requires int.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* feat(security): comprehensive UI hardening and 7.4 normalization
- Refactored poller_spikekill.php to use array-based execution and sanitized SQL IN clauses.
- Refactored script_server.php Windows process check to use cacti_exec.
- Hardened snmpagent background process lifecycles.
- Standardized version checks in support.php and utilities.php.
- Replaced short array syntax [] with array() and verified 7.4 compatibility.
- Synchronized all hardened files to primary developer path.
* fix(snmpagent): replace undefined cacti_process_execute() with exec_background()
cacti_process_execute() was called but never defined, causing a PHP fatal.
Replaced with exec_background() from lib/poller.php. Also fix pre-existing
parse error in snmpagent_persist.php ([ closed with ) instead of ]).
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style: convert new code to short array syntax
php-cs-fixer (array_syntax/list_syntax short) flagged array() introduced
on this branch; convert to [] so the coding-standards gate passes.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* revert off-topic exec changes to match develop
poller_spikekill, script_server, snmpagent_persist/mibcache and support
had been switched to 1.2.x-style cacti_exec(), which is undefined on
develop and failed phpstan. Restore develop's native exec() idiom; these
files are outside this PR's scope (report actions and theme handling).
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* build: pin phpstan to 2.2.1
phpstan 2.2.2 added a stricter is_numeric() always-true inference that
fails on pre-existing develop code (lib/data_query.php); pin until that
is addressed upstream so CI is reproducible.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(reports): deserialize type-prefixed bulk items so actions run
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: ignore phpstan function.alreadyNarrowedType identifier
Clears the level 6 alreadyNarrowedType error on lib/data_query.php:2591 that
develop currently emits, matching the sibling narrowing identifiers already ignored.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: add missing PCRE delimiters to graph_template_id regexp filter
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(reports): parse the confirm list identically to the action branch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* refactor(remote_agent): drop the APCu auth cache (uncertain dependency, cross-request only)
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Enhance security checks for remote agent access
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>