* fix(forms): preserve action URLs in HTML and JavaScript
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs(changelog): record form action URL fix for issue 8438
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(forms): encode configured form name and enctype attributes
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
* fix: Update the deepness favicon
(cherry picked from commit 3a59295162)
* QA: If the SVG is present, it's all we need.
(cherry picked from commit ee0b4c84ed)
* fix: Update such that the modern svg favicon can render
* data_sources: render RRDtool Tune Info as balanced div boxes
rrdtool_tune() emitted an unbalanced mix of html_header() and
html_end_box() calls wrapped around raw table rows inside the single
box opened by data_sources.php. The premature and extra closing tags
corrupted the DOM, which (depending on theme) clipped the Save button
at the bottom of the Data Source edit page while in Data Source Info
mode.
- Separate the execute, CLI and HTML code paths in rrdtool_tune() and,
for HTML, render each section as a self contained, balanced div box.
- Extract and rename the helper print_leaves() to the standalone
rrdtool_tune_print_leaves(), matching the rrdtool_tune_* naming
convention, and emit div rows instead of table rows.
- Switch the data_sources.php wrapper box to div mode to match.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* data_debug: require POST for the Data Source repair actions
Applying RRDfile repairs and rerunning the debugger are state changing
operations, so they should not be reachable with a GET. Driving them
through a GET also meant the follow up redirect was pulled into the
content area as a full page, losing the theme and navigation on
rerender.
Register data_debug.php run_repair and run_debug in the
cactiIsPostActionUrl() allowlist so loadUrl() upgrades them to a
token-bearing POST, and add the matching csrf_require_post() guard so
the browser transport and server side guard stay in sync.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* rrd: split rrdtool_tune into testable render and execute helpers
Break rrdtool_tune() into small single-purpose helpers so each path can
be exercised directly by unit tests (the web display path is otherwise
unreachable under CACTI_CLI):
- rrdtool_tune_print_leaves() takes an explicit $html flag instead of
branching on CACTI_CLI, so both the div and plain-text branches are
testable.
- rrdtool_tune_execute() applies the tune/resize commands for a repair.
- rrdtool_tune_print_cli() prints the source commands as plain text.
- rrdtool_tune_print_html() renders the balanced div boxes.
- rrdtool_tune() becomes a thin dispatcher over the three.
Add tests/Unit/RrdTuneRenderTest.php covering the leaf printer, the HTML
and CLI printers, the execute path and the dispatcher, asserting the
output is balanced div markup with no table rows.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* review: post Data Source Troubleshooter actions via cactiPostAction
Address PR review feedback:
- Switch the Apply Suggested Fixes and Rerun Analysis links to the
existing cactiPostAction/data-url idiom (as data_sources.php already
does for ds_repair) instead of upgrading a loadUrl() GET through the
cactiIsPostActionUrl allowlist. The allowlist path replayed the
query-free mutation URL into browser history, so a refresh reopened
the list instead of the selected Data Source; a full cactiPostAction
submission follows the server redirect to the read-only view URL and
records that in history. The run_repair / run_debug csrf_require_post
guards are retained, and the data_debug.php allowlist entry (and its
now redundant click handlers) are removed.
- Add a callable $executor test seam to rrdtool_tune_execute() (matching
rrdtool_dump_document) so the unit tests assert the tune and resize
commands are actually executed, with resize.rrd produced only when the
resize command runs, rather than passing on the rename alone.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* review: move RrdTuneRenderTest into the Unit/Core/Rrd category folder
Per AGENTS.md, new unit tests belong in a category subfolder rather than
directly under tests/Unit. Move RrdTuneRenderTest there and update the
UnitStubs include depth accordingly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: TheWitness <copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
.cactiConsoleContentArea scrolls vertically, and with no right padding the
scrollbar sat flush against the right-aligned cells (for example the Data
Source Info values on data_sources.php), hiding the last digits. Give it a
15px right gutter in every legacy theme (cacti, carrot, dark, deepness,
hollyberry, modern, paper-plane, paw, raspberry, sunrise). midwinter already
reserves a scrollbar gutter and is unchanged.
Cover each changed rule with a develop-theme-correctness targeted test.
The page_filter_format setting is meant to be either/or: Modern shows the
Layouts selector with its Edit dialog, Legacy shows the classic inline
filter. Legacy also rendered the Layouts selector row (and its JavaScript),
so the new and the classic filters appeared together.
Stop rendering the Layouts selector in Legacy mode: create_filter() no
longer appends create_layouts(), and create_javascript() only emits the
layouts script in modern mode. The now-unused create_layouts() and
create_layouts_javascript() helpers are removed, and the setting help text
is updated to say the Layouts selector is available in Modern only.
* Add one-click RRDfile repair to Data Source Info mode
The Data Source Info mode already compares the RRDfile against the Cacti
definition and prints the rrdtool tune recommendations (add a missing Data
Source with DS:name:type:heartbeat:min:max, remove an extra one with DEL:name,
and correct the type, heartbeat, minimum and maximum). It did not, however,
offer a way to apply them from the page the way data_debug.php does.
- Add an "Apply Suggested Fixes" link to the "RRDtool Tune Info" box header when
the web server can write the RRDfile; when it cannot, the header falls back to
"Run Fix from Command Line" and the commands remain listed for manual use.
- Add a ds_repair action that runs the same tune recommendations server-side
(gated on data_source_authorized() and on the RRDfile being writable, and
skipping any recommendation carrying control characters), logs each command to
DSDEBUG, then reloads the Data Source so the result is visible. This mirrors
data_debug.php's run_repair / "Apply Suggested Fixes".
- Harden the Info-mode guard so a missing/unreadable RRDfile (rrdtool info
returning false) no longer triggers an array-offset warning.
* Address review: POST-guard ds_repair and harden repair result check
- Route the "Apply Suggested Fixes" action through a CSRF-protected POST: the
link now uses the cactiPostAction handler (href="#", data-url) instead of a
GET navigation, and ds_repair is added to the $bad_actions guard in
include/global.php so a tokenless request fails closed with 405. ds_repair is
added to the curated CSRF action test for regression coverage.
- Use a strict comparison on the rrdtool_execute() result: it can return null
on a failed exec/proxy connection, and null == '' would have reported a failed
repair as "All RRDfile repairs succeeded."
- Refresh the sink inventory baseline for the new header redirects in ds_repair.
* Add request-coverage probe for the ds_repair RRDfile repair handler
The Data Source Info mode repair handler ds_repair() is a POST action that the
page-level e2e suites do not drive (it needs a Data Source whose RRDfile
mismatches its Cacti definition). Add a request-coverage fixture that loads the
handler in isolation via cacti_fixture_source_function(), stubs its I/O
boundaries, and drives every branch (unauthorized, unreadable RRDfile, no RRA,
nothing to tune, not writable, a control-character recommendation that is
skipped, and both tune success and failure). Register it in
run_request_coverage.sh for data_sources.php changes so the changed-line
coverage gate sees the handler exercised.
* Address review: use defined helpers and boolean repair result
- Replace the undefined cacti_has_control_chars() check with a comparison
against rrd_strip_control_chars() (loaded from lib/rrd.php) to skip any
tune recommendation that carries control characters.
- Execute each tune with RRDTOOL_OUTPUT_BOOLEAN and treat a strict true as
success so proxy storage (which returns the raw 'OK u:...' status under
RRDTOOL_OUTPUT_RETURN_STDERR) is not misreported as a failure.
- Add the new translatable strings to locales/po/cacti.pot and reuse the
existing failure msgid.
- Update the request-coverage fixture to the new boundary contract.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(graphs): clear empty query fields in rendered text
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci(coverage): enforce changed PHP statement coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: share changed-code coverage contracts and enforce shell policy
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ci): run request coverage with portable path matching
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: retain bootstrap coverage and validate request dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
report_changed_coverage.py failed closed on an empty report: a pull request
that changes no files of the gated language produced {} and the redundant
'report and all(...)' guard made that falsy, so the gate returned 1. This
failed the chromium 'changed CSS lines' step (and the equivalent PHP/JS
gates) for any PR that does not touch that language.
Drop the 'report and' guard. all() over no rows is already True, so an empty
report is complete and passes via the existing total == 0 clause, while a
genuinely changed but uninstrumented file still fails closed through all().
Restoring a plugin from an archive, or installing one downloaded from
GitHub into the database, extracts the tgz to a temp file and writes each
entry under plugins/<name>/. validate_relative_path_within() anchored a
not-yet-created entry on its immediate parent directory, so every entry in
a subdirectory the restore had not created yet (includes/, css/, tests/,
docs/, ...) resolved against a missing path, failed the containment check
and was skipped. The plugin was left with only its top-level files and
setup.php then fatally required the missing includes/database.php.
Judge a not-yet-created entry by its deepest existing ancestor instead,
mirroring data_source_path_within_rra(). Every path segment is already a
validated plain name and no walked segment may be a symlink, so the full
candidate still stays within the base; traversal, absolute, drive-letter,
null-byte and symlink entries remain rejected.
* deepness: make search-result highlight readable and on-theme
The .filteredValue search highlight set a neon yellow (#F8D93D) background
with no text color, so the emerald link text (--dp-link) rendered on bright
yellow was effectively unreadable and clashed with the dark emerald theme.
Use a warm gold background that complements the emerald palette and a
near-black (--dp-page) text color for high-contrast, readable matches.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* tests: cover deepness .filteredValue highlight computed styles
Assert the deepness search-highlight background and text colors in the
theme-correctness suite so the changed .filteredValue CSS lines are
exercised and meet the changed-CSS coverage gate.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The install, enable, remote enable, load and dialog-confirmed actions on
plugins.php are guarded by csrf_require_post() on the server. The anchors
were still activated by the generic GET anchor handler, so clicking them
returned a 405 on the develop branch. Submit these actions over POST:
- The dialog Continue button and the Check Latest control now post.
- A capture-phase document click listener intercepts the install, enable,
remote enable and load icons before the bubble-phase generic handler, so
they post, keep working after Ajax table refreshes, and bind only once.
Tabler (i.ti) icons rendered smaller than the FontAwesome glyphs used on
the 1.2.x branch, so give them an explicit 16px rule matching the fa
layout in each bundled theme, and cover the new rule with
develop-theme-correctness targeted tests.
* fix(plugins): honor version range boundaries and compatibility status
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): preserve null hook diagnostics and enforce dependency versions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): report config failures and confine error attribution
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): guard entrypoint frames and bind realm filenames
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): propagate install hook failures on develop
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(plugins): match realm filenames literally
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs(changelog): defer release entries to final backlog PR
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(plugins): add standard GPL headers
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci(coverage): require 80 percent of changed PHP statements
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: share changed-code coverage contracts and enforce shell policy
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ci): run request coverage with portable path matching
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: retain bootstrap coverage and validate request dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* security(ci): constrain dependency installs and container build boundaries
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(docker): retain shipped runtime libraries in build context
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(tooling): quote gettext paths and honor Docker base selection
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(auth): use certificate expiry truth in rendering assertions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(tooling): finish Docker layer and regex scan findings
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ci): preserve documentation badge anchors without alternation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(ci): preserve contributor badges and enforce Python coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: share changed-code coverage contracts and enforce shell policy
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ci): enforce private review files and run path regressions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure changed gettext shell coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: pin coverage to the reviewed PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(themes): correct CSS cascade, font fallbacks and responsive selectors
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(themes): remove validated empty and redundant CSS rules
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style(css): remove reviewed inactive rules and redundant separators
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style(themes): consolidate two reviewed duplicate selectors
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(themes): remove identical whitespace declaration after consolidation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(theme): keep context menu fallbacks in Cacti overrides
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(theme): measure native CSS and header coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: retain bootstrap coverage and validate request dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover Midwinter and graph heading CSS repairs in Chromium
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: take the theme coverage base from the merge commit parent
- github.event.pull_request.base.sha can predate the develop tip the checkout was merged onto, which counted develop's own CSS lines as the PR's.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* log user action (create, delete, locked, ..)
* change log
* update changelog
* style(auth): apply coding standards to user action logging
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Audit password changes only after successful account saves
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(auth): sanitize audit fields and confirm account removals
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover native account audit state transitions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
* perf: reuse bootstrapped graph option arrays and document validation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: record the installed RRDtool version in profiles
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: record final validation scope and profiling runtime limits
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: clarify the scope of changed-code coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: repair relocated PHPUnit configs and the deletion-only coverage gate
- Point the five relocated configs that still carried a contributor's local
autoload path (#8376) at ../include/vendor/autoload.php.
- Pass --configuration=tests/phpunit.xml to the CSV window workflow and the
README example now that phpunit.xml no longer lives in the repository root.
- Let the changed-lines gate pass deletion-only PHP changes. Without added
lines the generated config has no source filter, PHPUnit writes no clover
report, and the gate failed on the missing file instead of reporting zero
executable changed lines.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: TheWitness <thewitness@cacti.net>
* ci: keep the missing request-report check for deletion-only changes
Only short-circuit the changed-lines gate when there are no added PHP lines
and PHPUnit wrote no clover report, so an empty request-coverage directory
is still rejected.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: TheWitness <thewitness@cacti.net>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: TheWitness <thewitness@cacti.net>
Co-authored-by: TheWitness <thewitness@cacti.net>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- The job ran pest with no --configuration after the configs moved under tests/, so it found no config and exited 2.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: drop backslash and line breaks in sanitize_uri
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: add changelog entry for sanitize_uri fix
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: reject dangling symlinks in validate_relative_path_within
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: add changelog entry for dangling symlink fix
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(boost): never re-stage poller output when boost_redirect is on
#8332 gated the boost_redirect bypass in boost_poller_on_demand() on the
caller not passing $staged. process_poller_output() always passes it, so
the bypass never fired and the main poller re-inserted every row spine or
cmd.php had already written to poller_output_boost, flooding the log with
"Boost staging ignored N of N duplicate sample keys" warnings.
When boost_redirect is enabled the poller now never inserts into
poller_output_boost and reports the rows as staged so they are cleared
from poller_output. poller_recovery.php writes recovered remote rows via
boost_flush_output_batch() directly and is unaffected.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: TheWitness <thewitness@cacti.net>
* chore(changelog): use changelog.d fragment for #8374
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: TheWitness <thewitness@cacti.net>
* fix(boost): log failed poller_output_boost staging as an ERROR
boost_flush_output_batch() returned false silently when the database did
not acknowledge a chunk. cmd.php's boost_redirect staging ignores that
return, so a failed collector-side write left no trace. Log a BOOST ERROR
with the sample count from the helper so every caller's failure is visible.
Adds in-process coverage for the failure log and for boost_poller_on_demand()
never re-staging rows when boost_redirect is on.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: TheWitness <thewitness@cacti.net>
---------
Signed-off-by: TheWitness <thewitness@cacti.net>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Scope the tree Graph Templates filter to the drilled Device Template
When drilling a Site Branch into a Device Template (host_id=-1, host_template_id set), create_tree_filter() fell through to listing every Graph Template. Scope the dropdown to the Graph Templates present on that Device Template's devices (within the drilled Site when set), matching the graphs the branch actually shows.
* docs(CHANGELOG): add issue#8370 entry
* test: cover the tree Device Template graph-template scope; fix CHANGELOG ordering
Add an isolated source-slice probe that drives create_tree_filter()'s new host_template_id branch so the changed lines meet the >=80% changed-line coverage gate, wired into run_request_coverage.sh. Move the issue#8370 CHANGELOG entry into the issue block so it no longer precedes the security entries.
* docs(CHANGELOG): append issue#8370 at the end of the issue block
* Detect and repair RRDfile Data Source count mismatches via RRDtune
Report when a Graph requires more or fewer Data Sources than its RRDfile
contains, generate the rrdtool tune DS:/DEL: command to correct it, and run
it when the RRDfile is writable. Applies to data_debug (rrdtool_cacti_compare)
and the RRDchecker batch process (do_rrdcheck). The decision logic lives in
pure helpers (rrdtool_cacti_compare_ds, rrdcheck_ds_findings) with unit tests.
Resolves#8366
* rrdcheck: only probe local writability for local storage
Under the storage proxy the RRDfile is remote, so is_resource_writable()
checks the wrong filesystem. Skip the local probe when using the proxy and
let it enforce remote permissions and report failures via its response.
* rrdcheck: validate tune args, enforce RRA containment, fix failure detection
Validate every tune specification against RRDtool's documented DS grammar
(ds-name 1-19 [a-zA-Z0-9_], known DST, integer heartbeat, numeric-or-U min/max)
and escape it before use. For local storage require the RRDfile to resolve
inside the RRA directory via data_source_path_within_rra(). Detect failures
from the real return value (false/null/empty or missing OK) instead of casting
to string, so a failed tune is no longer logged as success.
* rrd: normalize a 0/0 data source range to 0:U when building a tune add spec
rrdtool_function_info_from_ds() passes min/max through unchanged, so a source
stored as 0/0 produced DS:name:type:hb:0:0 which RRDtool rejects. Mirror RRD
creation and emit 0:U so the repair paths can restore those sources.
* ci: copy pinned CI images to GHCR
- Service containers pull before any step runs, so the registry mirror cannot help them; a digest-preserving copy under ghcr.io/cacti/ci-images lets jobs pull with GITHUB_TOKEN.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: pull database and Rocky Linux images from GHCR
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(graphs): reveal graph content area after tree branch loads
The jstree select_node handler hides .cactiGraphContentArea (#navigation_right) before loading a branch's graphs via AJAX to avoid flashing the previous branch, but the only re-show was coupled to a window resize event that does not fire after the AJAX load. On themes that hide .cactiGraphContentArea by default (e.g. Deepness) the content area stayed display:none and the graphs/filters were invisible. Re-show it on loadUrl completion.
* fix(filter): keep the Edit Filter dialog columns from collapsing
The modern filter Edit dialog is created with jQuery UI width:'auto'. Its body is a table-based label/field grid, which jQuery UI measures at min-content, collapsing the dialog content to a sliver and pushing the fields off to the right. Floor the content min-width so the columns lay out. Validated in Deepness and Dark.
* fix(graphs): centre single-column graphs in the graph view
graphWrapperOuter > div:first-child is width:fit-content inside a (full-width for one column) flex wrapper, so the graph rendered flush-left. Add auto horizontal margins so it centres; the absolutely-positioned drilldown toggle continues to track the graph.
* fix(graphs): don't re-show content area on aborted branch load
A superseding tree branch click aborts the in-flight loadUrl; its .always() must not re-show the content area the new selection just hid, or stale graphs flash while the new branch loads. Skip completions whose textStatus is 'abort'.
* Cross-filter Device and Graph Template on Preview and List views
Forward the selected Graph Template(s) to the ajax_hosts Device callback and filter the device list accordingly, so choosing a Graph Template narrows the Device list. Device-to-template narrowing already exists on these views.
* Use line comment style to satisfy php-cs-fixer
* fix(graph_view): validate raw graph_template_id against filter allowlist in html_make_device_where
The ajax_hosts endpoint calls html_make_device_where() before the graph filter is sanitized, so gnrv('graph_template_id') is raw request data. An array value such as graph_template_id[]=cg_1 reached html_transform_graph_template_ids()'s str_contains() and raised a TypeError (HTTP 500). Reject non-string input and validate against the same regexp allowlist the filter uses before transforming.
* test(graph_view): add request-coverage probe for the device/template cross-filter
The pr-php-coverage gate requires >=80 percent of changed executable PHP lines to be exercised. The new html_make_device_where() graph_template_id branch and the request_vars changes in create_graphs_preview_filter()/create_listview_filter() are only reached when a graph_template_id filter is present, which the page-level e2e suites do not drive. Add an isolated source-slice probe that runs those production functions with stubbed I/O boundaries and wire it into run_request_coverage.sh so the changed lines are covered.
* feat: expose RRDtool 1.11 graph axis controls
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: constrain axis template inheritance checkboxes
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): exercise native aggregate validation and enforce coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: share changed-code coverage contracts and enforce shell policy
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ci): run request coverage with portable path matching
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: retain bootstrap coverage and validate request dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* log user action (create, delete, locked, ..)
* change log
* update changelog
* style(auth): apply coding standards to user action logging
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Audit password changes only after successful account saves
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(auth): sanitize audit fields and confirm account removals
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover native account audit state transitions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(auth): audit only confirmed account persistence
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Petr Macek <petr.macek@kostax.cz>
* perf: add disposable browser and SQL/RRD profiling
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: record profiling harness in the changelog
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>