* security: move filter inline onChange/onClick handlers into ready() for CSP
The threshold, notification list, notification queue, template and
device/log status filter forms still carried inline onChange/onClick
attributes on their selects and Clear/Go/Import/Export controls. Under
Cacti's Content-Security-Policy these trip the script-src-attr directive
(inline event handlers). Bind them in each view's existing
$(function(){...}) ready block instead.
Scope: thold.php, notify_queue.php, thold_templates.php, notify_lists.php,
thold_graph.php (all gate-allowlisted UI files; no measured source changed).
The cactiReturnTo() cancel buttons on the bulk-action confirmation pages are
left as-is (shared Cacti-core pattern). Regenerated locales/po/cacti.pot for
the shifted source line references.
* security: convert cactiReturnTo cancel buttons to the CSP-safe class
The confirmation pages' Cancel buttons used an inline
onClick='cactiReturnTo()' handler, which trips Cacti's Content-Security-Policy
script-src-attr directive. Switch them to the CSP-safe cactiReturnTo CSS
class (class='cactiReturnTo', plus an optional data-url when a target is
passed).
Cacti 1.2.31 and later bind this class automatically. The README documents a
one-time include/layout.js applySkin() snippet for operators still on an
earlier release - no shim is baked into the core or the plugin.
* fix: give Thresholds/Devices filter Clear buttons the id the ready() handler binds
The hosts() and tholds() filter views used name='clear' on the Clear button, but the ready() handler binds to #clear, so Clear was a no-op on those two views. Switch them to id='clear' to match the other views and the handler.
---------
Co-authored-by: TheWitness <larry@thewitness.org>
* INFO: set compat to 1.2.32
* docs: update Copilot instructions Cacti baseline to 1.2.32 (matches INFO compat)
* INFO: back off compat to 1.2.29
* Add manifest.json + upgrade-time file pruning
* Prune phpunit.xml on upgrade and ignore markdown-lint configs
phpunit.xml ships in the repo for CI but is a dev-only test artifact, so it
is removed from manifest.json 'expected', pruned from installs on upgrade
(like tests/), and excluded from the manifest drift check.
The retired markdown-lint configs (.mdlrc, .md_style.rb) are deleted, and
.md* is now ignored like .git*: protected from pruning and excluded from
drift if it reappears.
* Move thold_functions.php and thold_webapi.php into includes/; flatten css
The main threshold library becomes includes/functions.php and the web API
helper becomes includes/webapi.php; every caller (setup.php, includes/*, the
CLI/poller/notify entry points and the test suite) loads them from includes/.
Each per-theme stylesheet css/<theme>/main.css becomes css/<theme>.css so users
can drop their own css/<theme>.css into the css base, and the page_head hook
looks there. Old paths are tombstoned so existing installs drop the stale
copies on upgrade.
* Regenerate cacti.pot for the includes/ file relocations
Moving the plugin's library files into includes/ changed the source-reference
lines in the translation template; regenerate it so the 'Verify translation
template' CI check passes.
* Harden the hook-include test and make RPN integer ops explicit
The HookFunctionsIncludeTest invokes real hooks with placeholder input purely
to execute their relocated include_once lines; it now swallows engine
notices/warnings/deprecations during those calls (and restores the error
handler and config afterward) so it cannot trip the suite's failOnDeprecation
or leak state into other tests. The RPN % and ^ operators now cast their
operands to int explicitly, matching their long-standing integer-truncation
behaviour while silencing the implicit float-to-int conversion deprecation.
* Harden prune against tampered-manifest path traversal
The upgrade-time prune now rejects any tombstone containing '.'/'..' segments
(which could escape the plugin directory or resolve to its root) and treats
ancestors of whitelist entries as protected, so a tombstone on a parent
directory can no longer delete a whitelisted file beneath it.
* docs: update and align the Project Structure block
Point the structure tree at the relocated files (libraries now under
includes/, data files under docs/, stylesheets under css/) and align the
trailing '# ...' comments to a single column so they no longer drift right.
* docs/tests: standardize test header and correct manifest-contract notes
- Use the full license header (from the plugin's own setup.php) in
tests/Unit/PruneFilesTest.php instead of the abbreviated copyright banner.
- Document that the manifest drift check and the upgrade-time prune also
handle phpunit.xml and .md* files, matching the implemented behavior.
* refactor: rename prune helpers to the plugin-slug function prefix
The repository naming contract reserves the plugin_<name>_ prefix for plugin
lifecycle / hook-registration functions; all other functions use the plain
<name>_ prefix. Rename the internal upgrade helpers accordingly:
plugin_<name>_prune_files() -> <name>_prune_files()
plugin_<name>_rmtree() -> <name>_rmtree()
The call site, unit tests, and the copilot-instructions.md references are
updated to match. No behavioral change.
* chore: set the Cacti compatibility floor to 1.2.29
Align the compat metadata (and the contributor-guide references) with the
team decision to standardize the minimum supported Cacti version at 1.2.29;
the previously proposed 1.2.32 floor was not adopted.
---------
Co-authored-by: Copilot <copilot@users.noreply.github.com>
* Add PHPDoc blocks: small files batch (cli_import, poller_thold, includes/tab, includes/database, cli_thresholds, thold_notify, notify_queue)
* Add PHPDoc blocks: includes/polling.php, includes/settings.php (WIP checkpoint)
* Add PHPDoc blocks: thold_process.php, thold_daemon.php (WIP checkpoint)
* Add PHPDoc blocks: thold_webapi.php (WIP checkpoint)
* Add PHPDoc blocks: thold.php (WIP checkpoint)
* Add PHPDoc blocks: thold_graph.php (WIP checkpoint)
* Add PHPDoc blocks: notify_lists.php (WIP checkpoint)
* Add PHPDoc blocks: thold_templates.php (WIP checkpoint)
* Add PHPDoc blocks: setup.php batch 1-2 (WIP checkpoint)
* Add PHPDoc blocks: setup.php batch 3-4 (WIP checkpoint)
* Add PHPDoc blocks: setup.php batch 5 (WIP checkpoint)
* Add PHPDoc blocks: setup.php batch 6-7 (WIP checkpoint)
* Add PHPDoc blocks: setup.php complete
* Address review feedback and refresh translation template
- Fix thold_update_host_status() return type (int|null, since it
falls through with no explicit return in the normal case)
- Fix @global $device_change_fields description in
thold_config_arrays() (appends this plugin's fields, not unused)
- Fix @global $config description in thold_graph_button() (used to
build the Create Threshold link's URL)
- Fix thold_data_source_action_prepare()/thold_graphs_action_prepare()
return types (array|void; only the non-plugin_thold_create branch
returns $save)
- Fix @global $timearray description in list_tholds() (used to render
each baseline threshold's reference time range)
- Fix @global $thold_types description in thold_show_log() (used to
render each log row's type column)
- Regenerate locales/po/cacti.pot (source line references only)
- Fix .gitignore pattern for compiled .mo files (locales/LC_MESSAGES/, not locales/po/)
* test(coverage): allowlist untestable entry points touched by PHPDoc pass
This PR only adds PHPDoc blocks (no functional changes), but touching every file in the plugin newly triggers the 'Enforce coverage of changed lines' CI gate for files that were never require()'d by any test before now:
- cli_import.php, cli_thresholds.php: CLI entry points (include cli_check.php / chdir + execute at the top level).
- poller_thold.php: poller entry point, same category.
- thold.php, thold_graph.php, thold_templates.php, notify_lists.php: authenticated web entry points (chdir + include(auth.php) at the top level), like notify_queue.php/thold_notify.php already allowlisted above.
- thold_daemon.php: daemon entry point, same category as thold_process.php already allowlisted above.
- includes/settings.php, includes/tab.php: Settings-page/header-tab-bar hook callbacks, only meaningful inside a live Cacti page render.
- thold_webapi.php: web-page action handlers that read \ and the database directly.
None of these can be require()'d into the isolated unit test process, matching the existing allowlist entries' precedent exactly. Verified locally: running patch-coverage.php against the PR's actual base ref confirms all 11 files are no longer reported as unexpected-unmeasured.
* docs: add PHPDoc blocks to remaining thold_functions.php functions
* chore: refresh translation template after PHPDoc line-number shifts
* fix: recover unfinished notification claims
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover notification claim recovery branches
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: harden notification worker recovery
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: heartbeat notification queue loops
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: fail closed on notification worker recovery
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: bound notification worker recovery
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style: format notification CLI validation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: prove notification claim ownership at completion
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: bound notification completion failures
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: recover unverifiable stale workers
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: keep disabled exec path measurable
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: verify stale worker age without wall clocks
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: fail closed on unverifiable live workers
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover portable process age fallback
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: reject invalid process age output
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Retry failed queued email notifications (#811)
* Retry failed queued email notifications
* test: cover queued delivery retry paths
* style: document notification fixture parameters
* fix: batch grouped notification delivery updates
* fix: align notification retry status output
* refactor: centralize notification retry updates
* fix: retain retry queue ownership
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* issue#673: Device up/down notification emails don't appear to be sent if the notification queue is enabled
* issue#674: Thold Current Value is incorrect in 1.8.1
* issue#678: Unable to remove suspended notifications one by one
* feature#677: Allow the Administrator to create a default Single Email Notification Subject
* Make notification list devices tab sortable
* Prepared SQL for Device Notification list
* Remove some warnings when host notification delay is disabled
* Debounce Notification Suspend messages
- Revert thold_mail() calling parameters to more sane defaults
- Continue conversion of 'type' to 'topic'
- Add hostname and notification list to Queue GUI
* Todo: Make suspension/resumption work
* Todo: Delete individual events
* Todo: Add Object Name as a column
* Todo: Add event_processing_time double to table
* Todo: Sort on name and filter by type Event Type, and Processed