feat: support dynamic REST context path in UI#153
Closed
Conversation
- ResourceServlet.java: inject window.__openidm_context into index.html - Constants.js: read context path from window.__openidm_context - Replace all hardcoded /openidm/ in UI JS delegates and views - Update Swagger index.html to use dynamic context path - Update e2e tests to use OPENIDM_CONTEXT_PATH env var - Add CI workflow step for /myidm context path smoke tests Agent-Logs-Url: https://github.com/OpenIdentityPlatform/OpenIDM/sessions/ad48882e-aaca-4f2f-be44-fe435d797784 Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
…legate type property Agent-Logs-Url: https://github.com/OpenIdentityPlatform/OpenIDM/sessions/ad48882e-aaca-4f2f-be44-fe435d797784 Co-authored-by: vharseko <6818498+vharseko@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix hardcoded context path for OpenIDM UI REST calls
feat: support dynamic REST context path in UI
Apr 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When OpenIDM starts with
-Dopenidm.context.path=/myidm, the UI sends all REST calls to/openidm/…(hardcoded), getting 404s and rendering a blank page. The fix threads the actual context path from the server into the client at page load.Server-side: inject context path into
index.htmlResourceServlet.copyIndexHtml()readsopenidm.context.pathfromIdentityServer, sanitizes it, and injects a script tag before</head>:Client-side: consume injected context path
Constants.jsnow reads the injected value with a safe fallback:Replace all hardcoded
/openidm/in UI JavaScriptAll 30+ delegate and view files that had
"/openidm/"strings now use"/" + constants.context + "/". Files affected:ConfigDelegate,InfoDelegate,PolicyDelegate,ResourceDelegate,SocialDelegate,SystemHealthDelegate,InternalUserDelegate,NotificationDelegate,WorkflowDelegateSyncDelegate,ReconDelegate,AuditDelegate,MaintenanceDelegate,WorkflowDelegate,SecurityDelegate,SchedulerDelegate,ConnectorDelegate,ScriptDelegate,ExternalAccessDelegateMappingUtils,EditUserView,DataAssociationManagementView, all workflow views (ProcessInstanceView,TaskInstanceView,ProcessListView,TaskListView,ActiveProcessesView,ProcessDefinitionView,ProcessDefinitionsView,ProcessHistoryView)Swagger UI
openidm-ui-api/src/main/resources/index.htmldefault API URL updated:E2E tests & CI
ui-smoke-test.spec.mjs: REST API test URLs useOPENIDM_CONTEXT_PATHenv var (defaults to/openidm, no regression)build.yml: added a second Playwright test run that restarts OpenIDM with-Dopenidm.context.path=/myidmand executes the full test suite against itWarning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
central.sonatype.com/usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.14/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.14/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.14 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.14/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenIDM/OpenIDM org.codehaus.plexus.classworlds.launcher.Launcher -f pom.xml -B -V -e -Dfindbugs.skip -Dcheckstyle.skip -Dpmd.skip=true -Dspotbugs.skip -Denforcer.skip -Dmaven.javadoc.skip(dns block)maven.alfresco.com/usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.14/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.14/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.14 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.14/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenIDM/OpenIDM org.codehaus.plexus.classworlds.launcher.Launcher -f pom.xml -B -V -e -Dfindbugs.skip -Dcheckstyle.skip -Dpmd.skip=true -Dspotbugs.skip -Denforcer.skip -Dmaven.javadoc.skip(dns block)repository.jboss.org/usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.14/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.14/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.14 -Dlibrary.jansi.path=/usr/share/apache-maven-3.9.14/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/REDACTED/work/OpenIDM/OpenIDM org.codehaus.plexus.classworlds.launcher.Launcher -f pom.xml -B -V -e -Dfindbugs.skip -Dcheckstyle.skip -Dpmd.skip=true -Dspotbugs.skip -Denforcer.skip -Dmaven.javadoc.skip(dns block)www.eclipse.org/opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/tools/linux64/java/bin/java /opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/tools/linux64/java/bin/java -jar /opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/xml/tools/xml-extractor.jar --fileList=/tmp/codeql-scratch-dd852eba2a5d9229/dbs/java/working/files-to-index2768345561981740654.list --sourceArchiveDir=/tmp/codeql-scratch-dd852eba2a5d9229/dbs/java/src --outputDir=/tmp/codeql-scratch-dd852eba2a5d9229/dbs/java/trap/java --global t(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
Problem
When OpenIDM is started with a custom REST context path (
-Dopenidm.context.path=/myidm), the UI fails to load becauseConstants.contextis hardcoded as"openidm"in the JavaScript code. All REST calls from the UI are formed via"/" + Constants.context + "/...", so they go to/openidm/...instead of/myidm/..., resulting in 404 errors and a blank page (the#loginelement never appears).This causes all Playwright UI smoke tests to fail with:
See PR #152 for the failing CI workflow.
Root Cause
openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/util/Constants.jshascommonConstants.context = "openidm";hardcoded.Multiple UI delegate files have hardcoded
"/openidm/"strings instead of usingConstants.context:openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/SyncDelegate.js—serviceUrl: constants.host + "/openidm/repo/link"andserviceUrl: "/openidm/endpoint/mappingDetails"openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/delegates/ReconDelegate.js—serviceUrl: "/openidm/recon/"andserviceUrl: "/openidm/audit/recon"openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/resource/RelationshipArrayView.js— usesconstants.contextalready (good)openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/mapping/util/MappingUtils.js—serviceUrl: "/openidm/repo/links"openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/user/EditUserView.js—serviceUrl: "/openidm/managed/user"openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/delegates/ResourceDelegate.js—serviceUrl: constants.host + "/openidm/endpoint/linkedView/"openidm-ui/openidm-ui-api/src/main/resources/index.html(Swagger UI) —url = "/openidm/?_api";The server-side
ResourceServlet(openidm-servlet/src/main/java/org/forgerock/openidm/ui/internal/service/ResourceServlet.java) servesindex.htmlbut does not inject the actual context path into the page.Required Changes
1. Server-side: Inject context path into
index.htmlIn
ResourceServlet.java, when servingindex.html, read the actual context path fromIdentityServer.getInstance().getProperty("openidm.context.path", "/openidm")and inject it into the HTML response. The cleanest approach is:/index.html, read the file contents as a string<script>tag in the<head>section:<script>window.__openidm_context = "myidm";</script>(without leading slash)Look at the existing
doGetmethod around line 120-170 to see howindex.htmlis already treated specially (no-cache headers). The injection should happen there, before writing the response.The property name to read is
openidm.context.path. Strip the leading/before injecting sinceConstants.contextis used without it (e.g.,"openidm"not"/openidm").2. Client-side: Make
Constants.contextdynamicIn
openidm-ui/openidm-ui-common/src/main/js/org/forgerock/openidm/ui/common/util/Constants.js, change:to:
3. Replace all hardcoded
/openidm/in UI JavaScriptSearch for all occurrences of hardcoded
"/openidm/"in JavaScript files underopenidm-ui/and replace them with"/" + constants.context + "/"(using the appropriate variable name for the Constants module in that file). Known locations:SyncDelegate.js:constants.host + "/openidm/repo/link"→constants.host + "/" + constants.context + "/repo/link"and"/openidm/endpoint/mappingDetails"→"/" + constants.context + "/endpoint/mappingDetails"ReconDelegate.js:"/openidm/recon/"→"/" + constants.context + "/recon/"and"/openidm/audit/recon"→"/" + constants.context + "/audit/recon"MappingUtils.js:"/openidm/repo/links"→"/" + constants.context + "/repo/links"EditUserView.js:"/openidm/managed/user"→"/" + constants.context + "/managed/user"(make sure Constants is imported)ResourceDelegate.js:constants.host + "/openidm/endpoint/linkedView/"→constants.host + "/" + constants.context + "/endpoint/linkedView/"openidm-ui-api/src/main/resources/index.html(Swagger):url = "/openidm/?_api";→ read fromwindow.__openidm_contextor default to"openidm"4. Fix the CI workflow in
.github/workflows/build.ymlThe current "UI Smoke Tests with /myidm context path" step runs ALL tests. Once the UI supports the dynamic context path, these tests should pass. No changes needed to the workflow if the above fixes are correct. However, if some tests still rely o...
This pull request was created from Copilot chat.