Skip to content

NMS-20180: Fix various menu-related issues after NMS-20174 Review - #8792

Open
synqotik wants to merge 3 commits into
release-36.xfrom
jira/NMS-20180-more-menu-issues
Open

NMS-20180: Fix various menu-related issues after NMS-20174 Review#8792
synqotik wants to merge 3 commits into
release-36.xfrom
jira/NMS-20180-more-menu-issues

Conversation

@synqotik

Copy link
Copy Markdown
Contributor

Fix various issues found in PR review for NMS-20174 (PR #8758) ("Fix Menubar/SideMenu issues in Firefox and Safari on JSP pages").

There were 9 different items. 5 are fixed here. 4 have been deferred as they represent more work or tradeoffs.

Fixed Items

Fix 1 — narrowed anonymous rule: applicationContext-spring-security.xml now grants /ui-components/assets/** instead of /ui-components/**, with a comment explaining why (due to the stray index.html in the dist-menu artifact, NMS-20180). /ui-components/index.html now falls through to the /** → ROLE_USER catch-all, so it 302s to login like any other page.

Fix 3 — comment only: extended the bootstrap.jsp head comment to mark the login-page stylesheet + modulepreload as deliberate cache-warming, cross-referencing the anonymous rule it depends on.

Fix 4 — test gap: added expect(event.defaultPrevented).toBe(false) to the "does not cancel navigation for regular items" test.

FIx 7WebappIT smoke tests (three new tests): anonymous GET of the menu JS/CSS returns 200 with the right content types; ui-components/index.html requires auth (302, pinning fix 1's narrowing); and login.jsp contains no <script> tag for the menu bundle — with a positive control asserting the preload link is present so the negative assertion stays meaningful.

Fix 9 — locale-safe URL matching (LoginModuleUtils.java:163): toLowerCase()toLowerCase(Locale.ROOT), with a comment explaining the Turkish dotless-ı problem and added tests.

Deferred Items

These four items were identified while reviewing the NMS-20174 fixes (PR #8758) but deliberately not fixed in NMS-20180. I will open separate tickets to follow up.

1. Vue menu disappeared from nine popup JSPs (documentation / QA spot-check)

What happened. NMS-20174 fix #2 made bootstrap.jsp honor both quiet
mechanisms (the param.quiet include parameter and the Bootstrap.flags("quiet")
request attribute). The PR description only mentions login.jsp, but nine other JSPs
also set the quiet flag and therefore silently lost the Vue menu with that change:

  • admin/discovery/add-er.jsp
  • admin/discovery/add-ex-url.jsp
  • admin/discovery/add-ir.jsp
  • admin/discovery/add-specific.jsp
  • admin/discovery/add-url.jsp
  • admin/userGroupView/users/newPassword.jsp
  • graph/forecast.jsp
  • graph/nrtg.jsp
  • includes/legendInfo-box.jsp

Why it is probably fine. Every one of these is opened via window.open as a
popup/utility window. Losing the menu there is almost certainly the intended
rendering — and the pre-fix behavior (menu app executing in a popup that had asked
for quiet mode) is a plausible source of the original "menus overlapping content"
symptom.


2. Cache-buster stats the menu bundle files on every legacy page render

What happens today. includes/bootstrap.jsp computes the ?v= cache-buster for
the menu bundle by calling application.getRealPath(...) + File.lastModified()
for both index.js and index.css on every JSP page render (two filesystem
stats per request). The load-assets.jsp precedent it mirrors reads a cached
AssetLocator.lastModified() instead.

Suggested fix. Memoize the computed version in a ServletContext attribute,
keyed on (or invalidated by) the files' mtimes, or re-checked on a short TTL.

Tradeoffs / why it was deferred.

  • Two stats per render is noise next to JSP rendering cost; the OS caches the inode.
    There is no observed performance problem.
  • A naive memoization (compute once, cache forever) breaks the hot-copy developer
    workflow (build-and-copy.sh, ui/CLAUDE.md instructions): newly copied bundles
    would keep serving the stale ?v= until a webapp restart. A correct fix needs
    mtime-keyed or TTL-based invalidation — more code for marginal benefit.
  • If item 3 below (content-hashed filenames) is done, this entire code block is
    deleted anyway.
    Fixing this separately is only worthwhile if content-hashing is
    rejected or slips.

Action: will consider folding it into the content-hashing work if/when we proceed with that./


3. Content-hashed filenames for the menu bundle (replace ?v=<mtime>)

What happens today. The menu bundle is built with fixed filenames
(ui/vite.config.menu.tsassets/index.js, assets/index.css) because
bootstrap.jsp hardcodes the URLs. Cache correctness relies on a ?v=<deployed file mtime> query parameter appended by bootstrap.jsp (added in NMS-20174 fix #6).

Why ?v= is not durable.

  1. In-place overwrite skew (the core problem).
  2. Per-node divergence.
  3. Second-class caching.

Suggested fix.

Leaving out details, but adding a content hash to all filenames.

Costs / risks.

  • JSP + Java + Vite config + assembly all change together; needs its own Playwright
    re-verification
  • Manifest resolution becomes a runtime dependency of every legacy page: a missing
    or unreadable manifest must fail loudly with a sane fallback, or the menu breaks.
  • Dev hot-copy workflow changes: stale hashed files accumulate in the target
    directory (already true for the main SPA — ui/CLAUDE.md documents the occasional
    rm assets/*.*), and the manifest must be copied along with the assets.
  • Aligns the menu app with the main SPA, which already uses Vite's default hashed
    filenames.

Action: Will open a separate ticket to do the full content-hash + manifest change, targeted at the next
major release (Horizon 37).

4. Root fix for REST/API requests polluting the Spring Security request cache

Omitting details, but this is a larger effort as part of fixing OpenNMSAuthSuccessHandler and HttpSessionRequestCache to not saved assets in the cache, and to more properly handle redirects.

Action: Will open a separate ticket to do a comprehensive fix in Horizon 37.

External References

…s/**

The unpacked dist-menu artifact also ships an index.html (the Vite build
input) at /ui-components/, which nothing links to and which should not be
anonymously reachable; only assets/** needs the ROLE_ANONYMOUS rule from
NMS-20174. Document the deliberate login-page preload in bootstrap.jsp,
and pin the NMS-20174 access/quiet fixes with WebappIT smoke tests:
anonymous asset access with correct content types, index.html requiring
authentication, and login.jsp never executing the menu bundle.
… locale

Under a Turkish default locale, locale-sensitive toLowerCase() turns "I"
into a dotless ı, so a saved "/API" request would slip past the "/api"
prefix check added in NMS-20174. Use Locale.ROOT and cover it with a test
that runs the matcher under tr-TR.
The "does not cancel navigation for regular items" test only checked that
performLogout was not called, so an unconditional preventDefault() (breaking
navigation for every self-service item) would still pass. Assert
event.defaultPrevented is false so the test covers what its name claims.
@synqotik
synqotik marked this pull request as ready for review August 13, 2026 19:56
@synqotik synqotik changed the title NMS-20180: Fix various menu-related issue after NMS-20174 Review NMS-20180: Fix various menu-related issues after NMS-20174 Review Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant