Skip to content

OF-3025: Refactor System Properties UI to remove inline scripts and improve table layout#3237

Open
MilanTyagi2004 wants to merge 4 commits intoigniterealtime:mainfrom
MilanTyagi2004:OF-3025-Replace-Inline-style
Open

OF-3025: Refactor System Properties UI to remove inline scripts and improve table layout#3237
MilanTyagi2004 wants to merge 4 commits intoigniterealtime:mainfrom
MilanTyagi2004:OF-3025-Replace-Inline-style

Conversation

@MilanTyagi2004
Copy link
Copy Markdown
Collaborator

This PR refactors the System Properties administrative page to ensure better Content Security Policy (CSP) compliance and fixes several UI rendering issues.

Changes included:

  • Removed Inline JavaScript: Extracted inline JS from system-properties.jsp into external files (system-properties.js and list-pager.js) to comply with strict CSP directives without requiring 'unsafe-inline'.
  • Fixed Data Layout Bugs: Corrected an issue where invisible whitespaces and line-breaks broke the edit/delete buttons, and moved dialog confirmation properties away from the <body> tag so they are no longer stripped out by SiteMesh.
  • Improved Table UX & CSS: Added overflow-wrap to property names to prevent horizontal scrolling on small screens. For excessively long property values (like complex CSP headers), added text-overflow: ellipsis to restrict the height to a single line, combined with title attributes so users can view the full un-truncated values on hover.

@MilanTyagi2004
Copy link
Copy Markdown
Collaborator Author

hi @guusdk , this is pr is for OF-3025
please review this and tell me if there is any change

thanku!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the admin “System Properties” page to improve CSP compliance by removing inline JavaScript, while also addressing table/layout issues for long property names/values and improving pagination plumbing.

Changes:

  • Extracts inline JS from system-properties.jsp into new external scripts (system-properties.js, list-pager.js) and adds a mechanism in ListPager to disable inline JS generation.
  • Adjusts System Properties table rendering (wrapping/ellipsis, tooltips for truncated values) and fixes action icon handling via data-* attributes.
  • Tweaks a flaky test timeout for outgoing server session initialization.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
xmppserver/src/test/java/org/jivesoftware/openfire/session/LocalOutgoingServerSessionTest.java Increases session initialize-timeout to reduce test flakiness.
xmppserver/src/main/webapp/system-properties.jsp Removes inline handlers, adds external scripts, adjusts table CSS/markup, and refactors pagination form.
xmppserver/src/main/webapp/js/system-properties.js Implements click handling for edit/encrypt/delete/search and edit form submit actions.
xmppserver/src/main/webapp/js/list-pager.js Adds CSP-friendly ListPager navigation logic (pagination + page size + form submission).
xmppserver/src/main/java/org/jivesoftware/util/ListPager.java Adds inlineJsDisabled flag and alters generated HTML/JS to support CSP-friendly operation.
Comments suppressed due to low confidence (1)

xmppserver/src/main/webapp/system-properties.jsp:137

  • The filter <select> controls (e.g. searchDefaultValue) no longer auto-submit when their value changes (previously done via onchange="submitForm();"). list-pager.js currently only auto-submits on Enter and when an input becomes empty, so changing a select to a non-empty value won’t refresh results unless the user clicks the search icon. Add a JS change handler for these selects (either in system-properties.js or generically in list-pager.js) that calls ListPager.submitForm().
                <select id="searchDefaultValue">
                    <option value="" <c:if test="${search.defaultValue == ''}">selected</c:if>><fmt:message key="server.properties.search_all"/></option>
                    <option value="unchanged" <c:if test="${search.defaultValue == 'unchanged'}">selected</c:if>><fmt:message key="server.properties.default.search_unchanged"/></option>
                    <option value="changed" <c:if test="${search.defaultValue == 'changed'}">selected</c:if>><fmt:message key="server.properties.default.search_changed"/></option>
                    <option value="unknown" <c:if test="${search.defaultValue == 'unknown'}">selected</c:if>><fmt:message key="server.properties.default.unknown"/></option>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +380 to +381
<%-- Refactor; disable inline JS in ListPager and use list-pager.js --%>
<% listPager.setInlineJsDisabled(true); %>
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listPager.setInlineJsDisabled(true) is executed after ${listPager.pageSizeSelection} / ${listPager.pageLinks} have already been rendered. As a result, those HTML fragments will still include inline onchange/onclick handlers, which strict CSP will block, and which also prevents list-pager.js from taking over (it skips elements that already have onchange/onclick). Move the setInlineJsDisabled(true) call to before any use of pageSizeSelection/pageLinks (or set this flag in the servlet before forwarding) so that generated markup contains no inline handlers.

Copilot uses AI. Check for mistakes.
Comment on lines +370 to +372
<form method="post" id="actionForm"
data-encrypt-confirm="<fmt:message key="server.properties.encrypt_confirm"/>"
data-delete-confirm="<fmt:message key="server.properties.delete_confirm"/>">
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The confirmation messages are injected into HTML attributes using <fmt:message .../> without escaping. If a translation ever contains characters like " or &, it can break the attribute value (or, depending on content, create injection risk). Prefer storing the message in a variable and outputting it with XML/HTML escaping (e.g., via <c:out>).

Copilot uses AI. Check for mistakes.
final StringBuilder sb = new StringBuilder();
sb.append(String.format("<select name='%s' onchange='return setPageSize(this.value);'>", REQUEST_PARAMETER_KEY_PAGE_SIZE));
sb.append(String.format("<select name='%s'%s>", REQUEST_PARAMETER_KEY_PAGE_SIZE, inlineJsDisabled ? ""
: String.format(" onchange='return setPageSize(this.value);'", REQUEST_PARAMETER_KEY_PAGE_SIZE)));
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This String.format call passes an extra argument that is never used (the format string has no placeholders). It’s harmless but confusing; remove the unused argument to make it clear what is being formatted.

Suggested change
: String.format(" onchange='return setPageSize(this.value);'", REQUEST_PARAMETER_KEY_PAGE_SIZE)));
: " onchange='return setPageSize(this.value);'"));

Copilot uses AI. Check for mistakes.
Comment on lines +144 to +158

// Global keydown for Enter on search inputs
const searchInputs = ["searchName", "searchValue", "searchDescription"];
searchInputs.forEach(id => {
const input = document.getElementById(id);
if (input) {
input.addEventListener('keydown', function(e) {
if (e.keyCode === 13) {
if (typeof ListPager !== 'undefined') {
ListPager.submitForm();
}
}
});
}
});
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list-pager.js already binds Enter-to-submit behavior for all data-additional-form-fields (including searchName, searchValue, searchDescription). Adding another keydown listener here duplicates submissions and can trigger multiple form.submit() calls for a single Enter key press. Consider removing this block and relying on list-pager.js, or call e.preventDefault()/e.stopPropagation() to ensure only one submit is triggered.

Suggested change
// Global keydown for Enter on search inputs
const searchInputs = ["searchName", "searchValue", "searchDescription"];
searchInputs.forEach(id => {
const input = document.getElementById(id);
if (input) {
input.addEventListener('keydown', function(e) {
if (e.keyCode === 13) {
if (typeof ListPager !== 'undefined') {
ListPager.submitForm();
}
}
});
}
});

Copilot uses AI. Check for mistakes.
@guusdk
Copy link
Copy Markdown
Member

guusdk commented Apr 3, 2026

Oof, this is a very large change set. That makes it hard to review this one.

@MilanTyagi2004
Copy link
Copy Markdown
Collaborator Author

MilanTyagi2004 commented Apr 3, 2026

Oof, this is a very large change set. That makes it hard to review this one.

sorry Guus, i know that large changes are headache to review, as you know UI changes are generally large.

guusdk

This comment was marked as outdated.

Copy link
Copy Markdown
Member

@guusdk guusdk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the effort, but I am still going to ask you to split this in separate PRs. The PR description now says that this is fixing three different issues. Please make those three different PRs, so that they can be evaluated one-by-one.

This PR is making changes to ListPager. That is used on many different pages, not just the one that is being changed in this PR. Have you verified that these changes do not break other pages?

I'm not sure why the change in LocalOutgoingServerSessionTest is included. Does that relate to this PR?

The PR contains a couple of commits that need to be fixed - they are not very concise. Perhaps you should squash some of them (but also split things up over different PR's, as suggested above).

The current PR can no longer be merged, probably because other PRs got merged that change the base of Openfire that this was created on. Please re-base on the latest HEAD of the Main branch and address any merge conflicts!

@MilanTyagi2004
Copy link
Copy Markdown
Collaborator Author

okay Guus,
i will do the changes.

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.

3 participants