2 Commits
Author SHA1 Message Date
Thomas Vincent ca2e4f07c2 Build releases from managed dependencies (#7888)
* 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>
2026-09-01 23:11:49 -07:00
Thomas Vincent 964c1fb1f4 Harden RRDtool execution and data handoff (#7615)
* fix(rrdtool): quote RRDfile paths passed to the command line

__rrd_execute() hands the assembled line to shell_exec(), and its docblock
already required callers to quote each variable argument.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(tests): widen bare RRD path sweep

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(rrdtool): quote binary path as one argument

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(rrd): preserve caller logging context

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Make RRD XML mutations transactional

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Harden RRDtool proxy transport handling

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(rrdproxy): reject invalid command argument lists

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(rrdproxy): preserve binary graph payloads

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Keep RRDtool proxy sessions encrypted

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Harden local RRDtool command and output handoff

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Eliminate graph rendering metadata lookups

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Batch DSStats metadata and last-value reads

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Batch interface speed metadata reads

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Update architectural hotspot baseline for RRD execution

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Batch RRD resolution profile lookups

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Batch DSStats summary aggregates

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Narrow phpseclib key types for the proxy encrypt and decrypt calls

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(rrd): bound the forked proxy peers so a stall cannot hang the suite

The children accepted and read with no deadline while the parent used a 2s
socket timeout, so any mismatch left the child blocked in read and the parent
blocked in a bare pcntl_waitpid(). Note that accept() ignores SO_RCVTIMEO, so
readiness has to be waited on with socket_select() rather than a socket option.
Also corrects the array-command expectation, which still assumed develop's
escape-everything behaviour rather than rrdtool_build_command() leaving the
operation unquoted.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(rrd): seed proxy settings where the real read_config_option looks

UnitStubs only declares its stub when lib/functions.php has not been loaded
yet, so during a full run the real database-backed function is the one in
effect and $unit_config_options was being ignored. The parent then dialled an
address the child was not listening on, which is what stalled the handshake.
Seeding the option cache keeps the settings visible to either implementation.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(rrd): assert the shell-free RRDtool launch instead of the old quoting

__rrd_init now hands proc_open an argv array with bypass_shell, so escaping the
binary path would put the quotes inside the filename. The assertion still
expected the pre-argv line and had been failing unnoticed behind the suite hang.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(dsstats): derive the expected stamps instead of assuming UTC

dsstats_poller_output() formats with date(), so the hardcoded UTC strings only
matched on a UTC runner. The failure was masked by the suite hang.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(rrd): keep RRDtool control codes intact in stdin commands

Escaping the backslash when converting a shell-quoted argument to an RRDtool
token left legends such as "  IO Wait\:" ending in a dangling control code, so
RRDtool refused every graph carrying an escaped colon. Verified against RRDtool
1.7.2 in pipe mode; values with no unambiguous quoted form are now refused
rather than mangled.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: use Cacti test bootstrap and config

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: resolve includes through Cacti path constants

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: match the escaping helpers by token, not by text

lib/rrd.php documents its escaping behaviour in a comment, and the regex
over raw source counted that as a call site.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci: refresh sink inventory after develop rebase

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(rrd): prove argv isolation and concurrent pipe draining

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test(security): refresh sink inventory baseline after rebase onto develop

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-08-31 16:49:44 -04:00