mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-27 15:17:05 +09:00
develop
36
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ff31e051dd |
fix(a11y): [develop] correct labels, document semantics and duplicate IDs (#8295)
* fix(a11y): [develop] correct labels, document semantics and duplicate IDs Associates form controls with their labels, replaces obsolete tt markup, removes duplicate element IDs, and adds a native accessibility browser suite with its database fixture. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(a11y): validate label IDs and recognize attribute escaping Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
41780277d3 |
fix(docker): restrict development permissions and start the poller (#8453)
* fix(docker): restrict the dev stack to localhost and make the poller run The web port bound to every interface, named volumes hid the shipped .htaccess denies, and the cron job could neither find php nor write to PID 1's output, so the poller never ran. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(docker): keep harnesses polling and restore the developer's config.php check_docker.sh deleted an existing include/config.php on exit, health polling aborted under pipefail before the container reported, the MariaDB wait had no bound, and the BSD mktemp template left its Xs literal. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): add fragment for #8453 Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(e2e): move the pointer off the Deepness multiselect button Deepness sets a zero body margin, so the unhovered #ms-button sits at the viewport origin and headless Chromium on Linux intermittently applies :hover to it. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: pull pinned integration database from authenticated mirror Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
b430f5b1ec |
fix(tests): make hooks, CI helpers and the i18n audit fail closed (#8457)
* fix(hooks): check staged blobs and fail closed in the changelog tools The pre-commit hooks read working-tree files while claiming to check staged content, check-changelog.py passed when its base diff failed, and fold-changelog.py deleted fragments it had not validated. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(tests): make CI helper scripts fail when they check nothing check_all_pages.sh passed without logging in or crawling, the sink inventory accepted ripgrep errors, install_packages.sh and copyright_year.sh lost their failures, and the LDAP spec asserted before navigation finished. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(i18n): audit only changed .po entries and keep contributor badges separate audit_po.py failed every translation PR on pre-existing errors and matched non-printf text as conversions; update-contributors.py leaked badges between aliased contributors. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): add fragment for #8457 Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(e2e): move the pointer off the Deepness multiselect button Deepness sets a zero body margin, so the unhovered #ms-button sits at the viewport origin and headless Chromium on Linux intermittently applies :hover to it. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: pull pinned integration database from authenticated mirror Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
a9c73cfc42 |
fix(themes): skin jQuery multiselect in Deepness and fix 3.x markup in four themes (develop) (#8443)
* fix(themes): skin jQuery multiselect in Deepness and the 3.x markup in four themes Deepness: main.css repainted select2 onto its --dp-* palette but never the jQuery multiselect button or popup menu, so those fell through to the jquery-ui.css textured surfaces and the generic uppercase button rule and looked like the Dark theme. Repaint them to match the select2 controls. Cacti, Carrot, Hollyberry, Raspberry: these themes ship the old 1.x jquery.multiselect.css while include/js/jquery.multiselect.js is 3.x, so optgroup menus showed list bullets, a nested indent, compounded 0.9em option text and an unstyled group label. Add the missing 3.x rules. All changes extend each theme's main.css; the stock jquery.multiselect.css files are left untouched. Reported in Cacti/plugin_flowview#298. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(themes): satisfy the develop CHANGELOG and theme coverage gates - Move the CHANGELOG entries into changelog.d/8443.issue, as develop expects fragments rather than direct CHANGELOG edits. - Drop the Deepness multiselect border-radius; .ui-corner-all forces border-radius with !important in this theme, so it never applied. - Add Chromium computed-style tests for the new multiselect rules in Deepness, Cacti, Carrot, Hollyberry and Raspberry so the changed CSS lines are exercised by the theme correctness suite. 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> |
||
|
|
281e8e28f2 |
deps(deps-dev): bump @playwright/test in /tests/e2e in the npm-e2e group (#8435)
Bumps the npm-e2e group in /tests/e2e with 1 update: [@playwright/test](https://github.com/microsoft/playwright). Updates `@playwright/test` from 1.63.0 to 1.64.0 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.63.0...v1.64.0) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-version: 1.64.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-e2e ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: TheWitness <thewitness@cacti.net> |
||
|
|
c226f2a1a5 |
Add a right scrollbar gutter to the console content area in legacy themes (#8403)
.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. |
||
|
|
4e09327660 |
deepness: fix unreadable search-result highlight color (#8396)
* 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> |
||
|
|
5c1577a382 |
Force plugins.php action icons over POST and enlarge Tabler icons (#8394)
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. |
||
|
|
62063a29e0 |
fix(theme): [develop] correct CSS cascade, invalid values and responsive selectors (#8293)
* 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> |
||
|
|
8221a941a7 |
test(performance): [develop] add disposable browser and SQL/RRD profiling (#8336)
* 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> |
||
|
|
8acc5ec916 |
feature: theme-aware graph drilldown action menu (per-theme CSS palette) (#8355)
Label the open graph drilldown strip (layout.js labelGraphDrilldownIcons), shorten the action titles, and restyle the strip as a table menu. Each theme's main.css declares the --cacti-dd-* custom properties (foreground, hamburger/panel backgrounds, hairline border, hover accent) that include/css/graph_drilldown.css consumes via var() with a dark fallback, so each theme gets an appropriate light or dark look with its own accent and the hamburger reads correctly on light themes. Themes without a block (e.g. midwinter) use the dark fallback. Regenerates the affected locales/po/cacti.pot entries for the shortened titles. Co-authored-by: TheWitness <1439914+TheWitness@users.noreply.github.com> |
||
|
|
ce6ab6e0b3 |
fix(auth): [develop] preserve SAML POST callback sessions (#8333)
* fix(auth): preserve SAML POST callback sessions Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(auth): filter SAML inputs before bootstrap Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
49c95bef63 |
fix(deps): track legacy browser assets and remove patch-package (#8330)
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
ac50e0e0d0 |
fix(csrf): restrict XHR tokens to same-origin requests (#8329)
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
9a3a7dfce0 |
fix(graphs): [develop] correct opacity, redraw and realtime retries (#8328)
* fix(theme): enable graph opacity without selectmenu Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): describe theme fix Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(graph): restore redraw URLs and retry realtime failures Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
6e5078c929 |
fix(theme): [develop] restore Midwinter navigation, search and filter controls (#8327)
* fix(theme): restore Midwinter navigation and kiosk controls Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): describe theme fix Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(navigation): preserve filters and restore search and keyboard controls Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
f28071eb67 |
fix(theme): [develop] restore Midwinter login controls, form state and notifications (#8326)
* fix(theme): preserve Midwinter authentication controls Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): describe theme fix Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(ui): preserve form state and notification lifecycles Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix: replace the blinking timer during skin setup Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
f39e74c65c |
Graph drilldown: keep hamburger fixed, icons reachable, hide on graph leave (#8315)
* Graph drilldown: keep hamburger fixed, icons reachable, hide on graph leave The action-icon strip now slides down below the hamburger (flex column) instead of the hamburger dropping to the bottom of the icons. Closing is driven by leaving the whole graph rather than the small icon strip, so the mouse can move from the hamburger onto the icons without the strip closing. Leaving the graph also blurs the hamburger so it no longer lingers after interacting with it. * changelog: graph drilldown interaction fixes (#8315) * Graph drilldown: tolerate tooltip-induced mouseleave, drop hamburger title A native tooltip appearing over a drilldown icon fires a spurious mouseleave on the graph (relatedTarget null), which closed the strip. Defer the close and re-check the graph is genuinely not hovered first, so the icon tooltips no longer destabilize it. Also drop the hamburger's redundant title (its aria-label stays). * Graph drilldown: widen the close grace period to 500ms * Graph drilldown: tie hamburger visibility to the graph image Reveal the hamburger while the pointer is over the graph image (or the toggle overlaid on it) rather than anywhere in the graph cell, so moving off the image hides it after the grace period. Entering a different graph now immediately hides and closes any other graph's open strip. * Graph drilldown: lift the open graph so its strip clears thumbnails below With thumbnails a short graph's open icon strip overflows onto the graph below; sibling graphs paint in DOM order, so that graph rendered on top of the strip, making the icons unclickable and stealing the hover (which closed the strip). Raise the open graph (.graphDrillActive, position:relative; z-index) so its overflowing strip stays on top and the graph beneath is not hovered. * Graph drilldown: reveal via :focus-visible and stop blurring to preserve keyboard focus * fix(ui): preserve graph action focus during pointer navigation Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(ui): cover graph drilldown interactions and gate PR coverage Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: measure committed PR changes on a policy-compliant runner Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
49e14c9785 |
Filter dialog: theme-aware close glyph, titlebar height matches table header, Deepness input theming (#8312)
* Filter dialog: theme-aware close glyph, titlebar height matches tableHeader, Deepness input theming - Replace the non-theme-aware inverted sprite close icon with a theme-coloured x glyph (color: inherit) across all 10 themes that style cactiFilterDialog. - Set the titlebar height/line-height to match each theme's cactiTableTitleRow height instead of 10px padding that made the dialog header taller than table headers. - Deepness: re-apply theme field colours to dialog inputs/selects/textareas with higher specificity so jQuery UI .ui-widget-content .ui-state-default no longer overrides them. * changelog: filter dialog theme consistency (#8312) * Filter dialog: theme select focus border; raspberry titlebar 28px to match table header box * test(ui): cover filter dialogs across all changed themes Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: measure committed PR changes on a policy-compliant runner Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
97e67c6777 |
security: harden browser rendering and review CodeQL boundaries (#8298)
* security: harden browser history and dependency option merging Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs: record CodeQL triage decisions and follow-up scope Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: wait for history reload before inspecting browser storage Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * security: isolate HTMX history from the legacy navigation handler Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: build CodeQL assets through controlled dependency installs Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * security: render form validation messages as plain text Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: verify drag rows and color input security boundaries Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: verify tree navigation rename and datetime input boundaries Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * security: harden menu rendering and complete CodeQL caller review Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * security: centralize menu rendering and stabilize certificate CI Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: align certificate expectation with parallel web PR Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> |
||
|
|
08d0f94f24 |
Fix develop client behavior, popup isolation and PHP method visibility (#8292)
* fix(core): correct client state and declare public method contracts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(security): isolate Midwinter external homepage popup Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(client): isolate menu state and simplify validated JavaScript guards 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> * refactor(js): remove unused local storage while retaining initializer calls Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(js): encode inline translated values through the shared JSON boundary Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * style(js): wrap encoded translation literals without changing messages Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(client): remove unused checkbox reads from graph resizing Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * refactor(client): declare repeated function locals once Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(ui): run column width regression in browser CI Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
9899fdf221 |
fix(installer): allow forced replays after LDAP migration (#8317)
* fix(installer): preserve forced replay on already upgraded schemas Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): record forced upgrade replay repair Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
06c32ab13f |
fix(installer): preserve upgrade state and propagate failures (#8266)
* fix(installer): preserve upgrade state and propagate failures Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(changelog): record installer recovery fixes for #8266 Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(security): refresh installer sink inventories Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(installer): retain merge precedence for browser parameters Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(installer): defer debug settings until the process lock is held Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(installer): enforce table conversion failures and postconditions Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(installer): refresh SQL audit baseline after clause refactor Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
8ebc7e8a1a |
test(e2e): resolve browser smoke assets from the configured base URL (#8260)
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
bcb4aaf4ae |
fix(auth): render password reset links outside login error text (#8289)
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
0821439917 |
deps(deps-dev): bump @playwright/test in /tests/e2e in the npm-e2e group (#8251)
Bumps the npm-e2e group in /tests/e2e with 1 update: [@playwright/test](https://github.com/microsoft/playwright). Updates `@playwright/test` from 1.62.1 to 1.63.0 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.62.1...v1.63.0) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-version: 1.63.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-e2e ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
a52368125e |
feat(auth): rename User Domains to Login Providers, add SAML2 and OpenID Connect (#8066)
* feat(auth): rename User Domains to Login Providers Collapses user_domains/user_domains_ldap into a single login_providers table with a JSON parameters column, migrated in place during the 1.3.0 upgrade. Renames the admin page, menu, breadcrumbs, and help links to match. * feat(auth): rework login providers as Cacti\Auth classes Introduces LoginProviderInterface with credential (LDAP/AD) and redirect (SAML2/OpenID) flavors, replacing the procedural domains_login_process()/domains_ldap_*() functions. Adds blank-field group membership gating shared by every provider type. * feat(auth): add SAML2 and OpenID Connect login providers Adds onelogin/php-saml and firebase/php-jwt, a new cacti_http() SSRF-hardened outbound request helper for every OpenID discovery/token/JWKS call, and login_sso.php to handle the redirect-based SSO flow. Login page now shows a button per enabled SAML2/OpenID provider, and per-provider auth cookie opt-out is enforced on both the password and SSO login paths. * chore(i18n): regenerate cacti.pot * feat(auth): add Local and Basic auth as Cacti\Auth providers LocalAuthLoginProvider (CredentialLoginProviderInterface) and BasicAuthLoginProvider (new PreAuthenticatedLoginProviderInterface, since Basic Auth has no password for Cacti to check) are thin adapters over the existing local_auth_login_process()/basic_auth_login_process() functions, which are left untouched to avoid disturbing their regression-tested lockout/timing/rehash behavior. * feat(auth): move local password verification into LocalAuthLoginProvider secpass_login_process() and local_auth_login_process() are retired; their lockout, constant-time verification, forced-password-change, and rehash-on-login logic now live end to end in the class (verifyCredential/enforcePasswordPolicy/rehashIfNeeded). secpass_check_pass() stays a shared lib/auth.php function since password change/reset/user_admin also call it outside any login flow. Local auth still has no login_providers row: isEnabled() is always true and it cannot be disabled or deleted. * feat(auth): move Login Provider CRUD into Cacti\Auth classes AbstractLoginProvider gains static deleteById()/enableById()/disableById()/makeDefaultById()/persist(); each concrete provider owns its own collectParameters(), dispatched via LoginProviderFactory. login_providers.php's form_save()/form_actions() call these instead of doing raw SQL, and the retired provider_remove()/provider_disable()/provider_enable()/provider_default()/provider_collect_parameters() procedural functions are gone. Local/Basic auth are unaffected: they never extend AbstractLoginProvider, so they structurally cannot expose delete/disable. * fix(auth): address Copilot review findings on SSO/SAML/OIDC security Fixes callback/ACS/SLS/metadata URLs that used the raw provider id instead of the login realm (broke every SSO login), adds InResponseTo correlation for SAML and sub/azp validation for OIDC, requires HTTPS for OIDC discovery/endpoints, pins cacti_http() connections against DNS rebinding via CURLOPT_RESOLVE, exempts login_sso.php from the authenticated-page redirect guard and gates it on auth_method, wraps provider dispatch in a exception boundary, adds a dedicated SAML SLO path instead of routing it through login completion, makes remember-me an explicit opt-in for SSO, fixes disabled/deleted providers not revoking existing auth cookies, restricts the default-realm action to LDAP/AD, and fixes the 1.3.0 migration silently enabling group enforcement for installs that had it off. Also updates the E2E seed script for the login_providers schema. * chore(auth): refresh CI security baselines and document no-op validation Regenerate the sink inventory baseline for the new/renamed lib/Auth/* and login_providers.php files, and add '// no-validation:' comments on the intentionally-unconstrained admin/free-text/secret fields (LDAP DNs/filters, SAML certs/keys, OIDC client credentials, provider display fields) flagged by the validator constraint ratchet. Refreshes the validator baseline to drop the deleted user_domains.php entries. * refactor(ldap): remove dead DB-lookup path from Ldap::__construct The domain_id>0 branch duplicated the JSON-parameter-to-property mapping already owned by LdapLoginProvider::buildLdap(), and nothing constructs Ldap with a real id anymore (all call sites pass 0). Drop the parameter and the branch so Ldap stays a pure connection/protocol class with no DB coupling. Also fixes a latent bug: group_require is a typed bool property, but LdapLoginProvider::authenticate() assigned it an int (1/0) from a strict_types=1 file, which throws a TypeError on every LDAP/AD login attempt. Assign a real bool instead. * fix(auth): fix LDAP login, upgrade ordering, and hardening guard failures LdapLoginProvider compared LdapError::GetErrorDetails()'s int error_num against the string '0' with strict equality, so it never matched and every LDAP/AD login was rejected regardless of valid credentials. Compare against int 0 instead. install/upgrades/1_3_0.php called login_providers_convert_1_3_0() (which reads and then drops user_domains/user_domains_ldap) before the pre-existing legacy ALTER TABLE statements that add the debug/network_timeout/bind_timeout columns those reads depend on, so upgrades failed once the tables were already gone. Moved the call to run after those ALTERs. OpenIdLoginProvider::complete() read state/code from raw \ instead of gnrv(), tripping the hardening pattern guard; switched to the request helper. * style(auth): apply php-cs-fixer formatting and normalize line endings to LF Runs php-cs-fixer across the new lib/Auth/* classes, login_providers.php, login_sso.php, and the other touched files, fixing indentation/alignment/docblock style to match project convention. Also normalizes several files that had picked up CRLF line endings back to the LF the project's .php-cs-fixer.php config (setLineEnding) and the rest of the tracked tree actually use. * fix(auth): address second Copilot review round (9 high/medium findings) - Make login_providers_convert_1_3_0() resumable: CREATE TABLE IF NOT EXISTS and INSERT ... ON DUPLICATE KEY UPDATE so an interrupted upgrade can be re-run instead of leaving a half-migrated, unrecoverable table. - SamlLoginProvider::complete() now fails closed when no saved AuthnRequest ID exists instead of passing null to processResponse(), which skipped InResponseTo validation and accepted unsolicited IdP-initiated assertions. - LoginResult gains an isCredentialFailure flag; only a genuine wrong-password LDAP bind (LdapError::Failure) counts toward the lockout counter now, not connection errors or group-membership denials. - Fixed button_label/debug being read from the JSON parameters column in OpenIdLoginProvider/SamlLoginProvider/LdapLoginProvider when they are actually top-level login_providers columns; AbstractLoginProvider now hydrates and exposes both. - Removed SamlLoginProvider's wantMessagesSigned, which silently required the outer SAML message (not just the assertion) to be signed, rejecting IdPs that only sign the assertion as the UI promises. - Added getTemplateUserId() to CredentialLoginProviderInterface and implemented it on LocalAuthLoginProvider so the contract (not just incidental AbstractLoginProvider inheritance) guarantees the method lib/auth.php calls. - cacti_http()'s CURLOPT_RESOLVE entries now bracket IPv6 literals correctly, and safe-IP validation strips parse_url()'s brackets before checking, fixing IPv6 target pinning. - login_providers.php's type dropdown now swaps the Full Name attribute default (cn/displayName) on an actual user-driven type change, not on page load, so a new Active Directory provider does not silently save the LDAP default. - Extracted auth_apply_group_login_opts() and call it from both auth_login.php and login_sso.php, so SSO logins honor a user's group-derived login_opts the same way password logins already do. * fix(auth): fix PHPStan level 8 errors and pest harness stub drift Test harness fix: the LoginProvidersLoginRealmValidationTest stub LoginResult class was missing the isCredentialFailure property added to the real class, causing 'Undefined property' warnings that broke the harness's JSON output. Added the property and set it on the simulated bad-password failure. PHPStan (48+ errors, all newly introduced by this branch's rewrite, never actually verified until now): narrowed db_fetch_row_prepared()/db_fetch_assoc()'s array|bool (including bare true, which survives a '?: []' short-circuit - fixed with explicit is_array() checks instead) at every call site across auth_login.php, login_sso.php, lib/auth.php, lib/Auth/LocalAuthLoginProvider.php, lib/Auth/LoginProviderFactory.php, and install/upgrades/1_3_0.php. Fixed OpenIdLoginProvider::discover()'s return shape to match its declared docblock instead of returning the raw decoded JSON. Fixed lib/functions.php's cacti_http() to narrow curl_exec()'s string|bool result with is_string() (not ===false, which still leaves 'true' as a residual type) and guard / as non-empty for curl_setopt_array()'s stubs. Fixed a real bug in SamlLoginProvider::processLogout(): processSLO(true) was passing 'true' as \ (the first parameter) instead of \ (the fifth), so it always redirected/exited internally with the default \=false, making Cacti's own logout.php never regain control. Now calls processSLO(keepLocalSession: true, stay: true) and is typed ': never' to match; login_sso.php's now-genuinely-unreachable break statements after processLogout()/initiate() are removed. Fixed login_providers.php passing a expression (not a variable) to inject_form_variables()'s by-reference parameter. Verified: PHPStan analyse clean (0 errors), full Pest Unit/Security suite passes (128 tests), hardening guard/sink inventory/validator ratchet all still clean. * fix(auth): fix ambiguous column and array+bool crash in user_log filter The user filter dropdown query selected a bare 'id' column after joining user_auth and login_providers, which is ambiguous now that login_providers also has an id column (unlike the old user_domains.domain_id) - MySQL rejected the query outright. Qualified as ua.id. Also narrow db_fetch_assoc()'s array|bool result before the \ + \ + \ merge, which was throwing a TypeError whenever the query failed instead of surfacing the real SQL error. * fix(auth): address third Copilot review round (5 findings + tests) - AbstractLoginProvider::persist() now disables the template account for every provider type; SAML2/OpenID also copy it via user_copy() in login_sso_complete() and were left directly usable as a local login. - cacti_http_resolve_safe_ips() now detects IPv4-mapped IPv6 literals (::ffff:0:0/96) via inet_pton() and validates the embedded IPv4 address, closing an SSRF bypass via e.g. ::ffff:169.254.169.254. - login_providers_convert_1_3_0() now tracks db_install_execute()'s status for every row and only drops the legacy user_domains/user_domains_ldap tables once every row (and the final row count) is confirmed migrated. - Ldap::Getcn() now looks up ldap_get_entries()'s always-lowercased attribute keys case-insensitively while still storing the result under the originally-requested key, fixing AD's displayName (and any other mixed-case configured attribute) always resolving to a blank full name. - SamlLoginProvider::processLogout() now redirects to the LogoutResponse URL processSLO() returns for a LogoutRequest (stay:true), instead of discarding it and always redirecting to Cacti's own logout page - federated logout was never actually acknowledged to the IdP. - Added tests/Unit/Security/Auth/OpenIdLoginProviderTest.php (13 tests) covering verifyIdToken() signature/issuer/audience/azp/nonce validation, discover()'s HTTPS enforcement, and complete()'s callback-state and UserInfo-subject-matching checks, against a locally-generated RSA keypair/JWKS. - Regenerated the sink inventory baseline for the new header_redirect call in SamlLoginProvider::processLogout(). Verified: PHPStan clean, full Pest Security/Auth suite passes (830 tests including the 13 new ones), php-cs-fixer/hardening-guard/sink-inventory/validator-ratchet all clean. |
||
|
|
055c5ef5fa |
security: reject LDAP logins that skip a domain bind (#8009)
* hardening: validate the login realm and escape the LDAP username per context domains_login_process() now rejects a realm get_auth_realms() does not list and fails closed on one that is listed but has no domain behind it, and the Ldap class escapes the username for the DN and the search filter separately rather than relying on a filter-only blocklist. - an unlisted realm sent with a non-empty password used to match no branch at all and returned an empty user with no error, which auth_login.php reads as an authenticated user and provisions from the template account Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * security: reject LDAP logins that skip a domain bind Posted realms outside user_domains no longer fall through to template or guest login. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(ldap): align escaping contract with username lookup Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover LDAP domain login through OpenLDAP The e2e stack now binds a real directory user and checks that a forged realm cannot skip that bind. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(ldap): address Copilot review feedback Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix: substitute LDAP filter placeholders in one pass LDAP_ESCAPE_FILTER leaves angle brackets intact, so a looped str_replace can rescan one value as another key. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Change realm retrieval function from gnrv to gfrv * tests: add gfrv() stub to harnesses that exercise gfrv()-calling code domains_login_process() and api_aggregate_convert_template() call gfrv() for realm/aggregate_template_id, but their test harnesses only stubbed gnrv(), so Pest failed with 'Call to undefined function gfrv()'. --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> |
||
|
|
79a9ae0351 |
build: raise the 1.3 floor to PHP 8.3 (#7939)
* build: raise the 1.3 floor to PHP 8.3 RHEL 10 ships 8.3 in AppStream and dropped modularity, so an 8.4 floor would put every RHEL, Alma and Rocky 10 install on Remi. Ubuntu 24.04 is 8.3 as well, which makes it the lowest common denominator of the current LTS fleet. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs: raise the documented PHP floor to 8.3 The 1.2.x column keeps 8.1, which still matches that branch's composer constraint. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: run process lock coverage on PHP 8.3 * fix: finish PHP 8.3 floor cleanup Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
ead882172e |
Make installer completion fail closed and add test coverage (#7626)
* Make installer completion fail closed Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Add installer unit and Docker integration gates Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Require installer coverage evidence Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Stabilize installer failure scenarios Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Address installer review feedback Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Reject incomplete installer selection payloads Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Match table validation to rendered controls Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Protect long-running installer migrations Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Load installer table metadata in one query Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Optimize installer completion queries Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Batch installer default settings writes Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Batch installer color upserts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Batch installer template and poller lookups Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Refresh SQL interpolation baseline after develop rebase Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: use Cacti Composer test setup Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: resolve includes through Cacti path constants Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: align installer workflows with policy Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines after develop rebase Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: reuse TCP database credentials for installer checks 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> * ci: run installer coverage on PHP 8.2 The 8.1 pin is below the ^8.2 composer requirement, so pest died in platform_check before any test ran. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> |
||
|
|
37d7e85506 |
ci(deps): bump playwright (#7830)
Bumps the npm_and_yarn group with 1 update in the /tests/e2e directory: [playwright](https://github.com/microsoft/playwright). Updates `playwright` from 1.49.0 to 1.62.1 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.49.0...v1.62.1) --- updated-dependencies: - dependency-name: playwright dependency-version: 1.62.1 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
a75bf823bb |
feat: consolidate htmx loader and renderer abstraction global.php includes (#7517)
* feat(rendering): add view renderer abstraction Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * isolate renderer traversal test file * Standardize renderer headers and endpoint guard * style(renderer): use standard unit-test header in CactiRendererTest Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(renderer): reject null-byte paths before realpath Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh sink and hotspot baselines for line shifts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(renderer): guard root base path and template-dir redirect Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(renderer): canonicalize both paths in index.php direct-access guard Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * hardening: normalize renderer base path to one separator Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(renderer): reject filesystem root as template path A /-rooted renderer collapsed the containment prefix to /, which str_starts_with() matches for every absolute path, so any file was includable. Fail closed by refusing a root template path. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * hardening: reject windows drive-root template path Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * refactor: adopt PHP 8.4 idioms in view renderer Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover renderer abstraction to full coverage Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * hardening(renderer): reject UNC template names and fix sink baselines Refuse a leading-backslash (UNC) template name the same way absolute POSIX paths are refused, skip the direct-request redirect when SCRIPT_FILENAME carries a null byte, and correct the renderer include and views redirect line numbers in the security baselines. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * style: apply php-cs-fixer Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(renderer): use PHP 8.1-compatible readonly property in CactiRenderer Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * hardening(rendering): drop template context array before include Unset the internal context array after extract so an included template only sees the extracted variables, not the full context. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines for renderer line shift Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(renderer): simplify containment check and drain nested output buffers The redundant real_path !== template_path comparison in validateTemplateFile() can never be false once is_file()/is_dir() have run, so drop it and keep the str_starts_with() prefix check as the actual containment guard. renderFile() also only unwound a single output buffer, so a template that opens (and leaves) its own buffer could leak an ob level or drop its content; unwind every buffer opened during rendering and reassemble them in the order they were written. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines for renderer buffer/containment fix The dynamic_include line for lib/renderer.php's include shifted again after adding drainOutputBuffers(). Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * feat(htmx): vendor htmx 2.0.6 and add opt-in filter loader Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover htmx filter loader Add missing-vendored-file case for htmx_script_tag and mark the pre-bootstrap read_config_option guard as uncoverable. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: harden htmx loader harness and tighten enable check Skip anything but an exact 'on' for htmx_enabled, reject 4xx/5xx fixture responses, fail fast when the fixture base path is unresolved, pin setup-php to a commit SHA, and reindent the e2e specs to tabs. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * style: apply php-cs-fixer to htmx test files Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(htmx): drop duplicate script-tag src assertion The subdir-install test repeated the preceding assertion; CACTI_PATH_URL is fixed at bootstrap so it could not exercise a distinct scenario. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(e2e): drop sqlite3 from docker-php-ext-install php:8.2-apache already ships sqlite3 built in, and its ext/sqlite3 source only carries config0.m4 (not config.m4), so building it standalone always fails with "Cannot find config.m4", breaking the e2e image build before Playwright ever runs. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(htmx): clear stat cache around version-file rename Earlier tests already stat the version file via file_exists()/ file_get_contents(), so PHP's stat cache can report it present right after these tests rename it away, making the assertions flaky. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(htmx): recompute script-tag cache-buster per call The md5 cache-buster was cached in a static, so FPM/script_server processes kept serving a stale ?v=... hash after an htmx.min.js upgrade. Recompute it per call, matching get_md5_include_js() and get_theme_paths() in lib/functions.php, and drop the 'v=' parameter name to match their path + '?' + hash shape. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(e2e): drop obsolete MariaDB options * ci(htmx): run the htmx integration test by path instead of a testsuite filter Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * build: vendor htmx unminified Debian rejects minified sources. The file is the htmx 2.0.6 dist source; its minified sibling hashes identically to what was committed, and the pinned SRI is recomputed over the unminified file. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix: address htmx review feedback * test(e2e): resolve Cacti version through PHP * test(htmx): harden portable server cleanup * ci(actions): update checkout action pins --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> |
||
|
|
7c5e4c102a |
feat(support): consolidate diagnostics, lockout CSRF, process-table hook, and safe-triage (#7514)
* feat(support): add redaction toggle and recent-log panel Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover support safe triage Unit-test the redaction helper, severity log tail and environment table, and add a Docker probe that the redacted report masks the RSA fingerprint and hides the database host and password. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): escape rsa fingerprint and default unknown poller type Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): redact compressed IPv6 addresses Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: skip tests tree in hardening pattern guard Test fixtures assign request superglobals to exercise product code; the guard only protects product code. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): drop redundant isset flagged by phpstan Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * feat(support): guard snmpget path before executing Reject a null byte and require a regular executable file for path_snmpget so a misconfigured path cannot throw a ValueError or match a directory. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines for snmpget path guard Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): redact FQDNs before the node name and stop truncating tool output Masking the node name first could leave a domain suffix unmasked when the name was a prefix of an FQDN, and strip_tags() on installed SNMP output dropped legitimate angle-bracket content instead of just masking it. Also tighten the redact toggle to a strict '1' match, carry it through page-refresh URLs, and correct the diagnostics report comment to describe what actually gets masked. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): guard poller type lookup, log stats, and binary path checks Fall back to an "Unknown" label when poller_type doesn't match a known poller instead of an undefined-index warning, suppress warnings from filesize()/fopen() if the log file disappears between the caller's check and the open, and require is_file() plus a null-byte guard on the required-binaries version check (matches the snmpget check next to it). Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs(tests): align triage probe comments with actual assertions The header comments claimed the unredacted report exposes the DB host and password, but the probe only ever asserts the RSA fingerprint; DB credentials are checked for absence when present, not required to appear unmasked. Correct the wording in both files. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): require POST + CSRF token for maintenance lockout, compare-and-set Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): require a valid expected state for lockout compare-and-set Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(security): refresh sink/hotspot baselines for upstream line shifts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): clamp page offset, quote SQL literals, suppress lockout URL state Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover support lockout csrf guard Exercise the POST-only guard and compare-and-set branches, and add a Docker probe that a GET or tokenless POST cannot change the lockout state. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): guard lockout probe extraction and correct probe scope note Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: skip tests tree in hardening pattern guard Test fixtures assign request superglobals to exercise product code; the guard only protects product code. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): keep lockout e2e health poll alive under pipefail Tolerate grep returning non-zero before the Health field appears so the poll loop waits instead of exiting the script. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): add integration coverage for the lockout compare-and-set The Unit test cannot reach the "currently locked" branch (forced reads return the PHP_TESTING default) and the e2e probe deliberately never locks the system, so the real read/write round trip against cacti_lockout_status has no coverage. Add a fast integration test that drives the lock, a stale-expected rejection, and the unlock against a real database, skipping gracefully when none is reachable. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): match the page-clamp assertion whitespace-tolerantly Whitespace-exact substr_count() breaks on reformatting; the regex enforces the same guard without depending on exact spacing. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): harden the lockout e2e probe's auth and cookie-jar handling Assert a CSRF token was extracted and the session actually authenticated before running the lockout checks, otherwise a failed login still passes. Also handle tempnam() failure and clean up the cookie jar on every exit path via a shutdown handler. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * feat(support): add diagnostics export and environment checks Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover support diagnostics export Unit-test the environment table and report redaction, and add a Docker probe that checks the report never leaks the database host, password or full RSA fingerprint. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): guard null snmp version and copy-status styling Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): keep diagnostics textarea visible on copy failure and report real extension load state Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): verify PHP extensions in both cli and web contexts show_tech_environment() only checked utility_php_verify_extensions()'s web flag, which seeds CLI-only extensions like pcntl as satisfied without checking whether they're actually loaded. Shell out to cli_check.php for the real CLI state and combine it with the web state the same way lib/installer.php does, so status reflects reality in both directions. Also guard the source-extraction helpers in SupportDiagnosticsTest and the e2e probe against a moved/unreadable support.php instead of letting strpos(false, ...)/eval() fail confusingly. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): require POST + CSRF token for maintenance lockout, compare-and-set Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * refactor(support): register process tables via support_process_tables hook Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): guard non-array hook result and empty process-table set Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): cast poller_interval to int in SQL and validate hook entry types Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(security): refresh sink/hotspot baselines for upstream line shifts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): reuse forced admin lookup and coerce expected state Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover support process-table hook Verify the hook drops malformed plugin definitions and keeps valid ones, and add a Docker probe that the hook returns well-formed tables against a real database. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): guard hook extraction and tolerate empty health probe Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): escape plugin-contributed process-table cells Plugins can now supply the process-table SELECT fragments via the support_process_tables hook, so escape the rendered cell values, and install the e2e cleanup trap before backing up config.php. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * ci: refresh security baselines for support.php line shift Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): use form_selectable_ecell for process rows and cast pid in row id Plugin-contributed process-table values were only escaped via manual html_escape() calls, and the row id was built from an unsanitized pid; switch to the file's existing form_selectable_ecell() helper and cast pid to int before it goes into the id attribute. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): harden hook-call rewrite and narrow validation comment Replace the exact-string str_replace() with a regex plus a match-count assertion so the probe fails loudly instead of silently no-op'ing if support_process_tables() formatting drifts, and correct the header comment's claim that malformed definitions can't corrupt the UNION -- the validation only checks types, not SQL validity. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): make e2e hook extraction regex whitespace-tolerant The extraction pattern required exact spacing around the function signature; match flexible whitespace instead and fail loudly if preg_match doesn't return exactly one match. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): add integration coverage for the process tables SQL path Unit tests eval() support_process_tables() with the plugin hook stubbed and never touch a database; the e2e Docker probe calls the same function directly but never builds or executes the UNION show_cacti_processes() runs. Add a fast, DB-only integration test that executes the real query against a live schema, skipping gracefully when no database is reachable. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(support): harden process table hook contracts * docs: add changelog entry * style: satisfy support hook fixer rules * fix(support): reconcile escaping contract and diagnostics test after merge tech_env_status() now escapes its $text argument (safe-triage's design, tested by SupportSafeTriageTest); strip the now-redundant html_escape() calls at its call sites in show_tech_environment() to avoid double encoding. Update SupportDiagnosticsTest's source-extraction marker and eval() inputs to match the merged, redact-toggle-aware report block from safe-triage. Refresh the sink inventory baseline for the resulting line shift. * fix(support): escape the PHP uname value on both redact paths Hostnames and kernel strings can carry markup, and support_redact() itself substitutes <host>, so redact first and escape the result either way. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(support): locate the diagnostics report block by regex, not literal The $snmp_line assignment became a conditional and the literal start marker stopped matching, aborting the probe before it built a report. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs: append the process tables entry to the feature block Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> |
||
|
|
c65f56d7e1 |
fix(graph): correct graph subsystem bugs (#7186)
* fix(graph): correct graph subsystem bugs * Address graph PR review findings * style: convert new code to short array syntax php-cs-fixer flagged array() in graph_realtime.php; convert to [] for the coding-standards gate. 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(rrd): key GPRINT CF cache per data source instance Two local data sources from the same data template shared a cache key, so a GPRINT could print another instance's consolidation function. 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> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> |
||
|
|
255667b49d |
chore(assets): update jQuery UI and theme assets (#7082)
* chore(assets): update jQuery UI and theme assets Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(codex): restore jQuery UI compatibility and fix PHPStan issues * fix(midwinter): restore full-width multiselect button rules dropped in jquery-ui rebuild 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> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: TheWitness <thewitness@cacti.net> |
||
|
|
d5a070f7ef |
fix(ui): tooltip pin behavior and jQuery compatibility cleanup (#7040)
* fix(ui): pin explanation tooltips on click * fix(ui): avoid duplicate tooltip pin handlers * fix(js): replace deprecated jQuery APIs with modern equivalents * fix(ui): restore decimal-safe numeric parsing in zoom deserialize * chore(vendor): bump tablesorter and jquery-validation assets * test(e2e): add jquery vendor smoke coverage with playwright |