Conversation
There was a problem hiding this comment.
Pull request overview
Adds an experimental React/Vite-based “OpenAM UI JS SDK” module to the OpenAM UI build, packages it as distributable ZIP artifacts (app + library), and wires the app bundle into the openam-server-only WAR under extui/ (with a small CORS schema update to allow Accept-API-Version).
Changes:
- Introduce new
openam-ui-js-sdkMaven module with Vite/Vitest/TypeScript project (app + library builds, plus assemblies). - Package and embed the generated app ZIP into
openam-server-onlyWAR underextui/. - Bump frontend build toolchain versions (frontend-maven-plugin, Node, npm) and update CORS allowed headers.
Reviewed changes
Copilot reviewed 48 out of 50 changed files in this pull request and generated 23 comments.
Show a summary per file
| File | Description |
|---|---|
pom.xml |
Adds openam-ui-js-sdk app ZIP as a dependency in the root build. |
openam-ui/pom.xml |
Registers new UI module and bumps frontend-maven-plugin/Node/npm versions. |
openam-ui/openam-ui-js-sdk/vitest.config.js |
Vitest configuration (jsdom + setup file). |
openam-ui/openam-ui-js-sdk/vite.lib.config.ts |
Vite config for library build + DTS generation. |
openam-ui/openam-ui-js-sdk/vite.config.ts |
Vite config for app build output to target/app. |
openam-ui/openam-ui-js-sdk/tsconfig.node.json |
TS config for Vite config files. |
openam-ui/openam-ui-js-sdk/tsconfig.lib.json |
TS config for library build typings/source scope. |
openam-ui/openam-ui-js-sdk/tsconfig.json |
Project references for TS build mode. |
openam-ui/openam-ui-js-sdk/tsconfig.app.json |
TS config for app compilation scope. |
openam-ui/openam-ui-js-sdk/src/main.tsx |
App entry point rendering OpenAMUI. |
openam-ui/openam-ui-js-sdk/src/lib/userService.ts |
Client-side calls for user/session/profile/password operations. |
openam-ui/openam-ui-js-sdk/src/lib/types.ts |
SDK response/data type definitions. |
openam-ui/openam-ui-js-sdk/src/lib/setupTests.ts |
Test environment setup for RTL matchers. |
openam-ui/openam-ui-js-sdk/src/lib/router.tsx |
Hash router definition + service instantiation. |
openam-ui/openam-ui-js-sdk/src/lib/loginService.ts |
Client-side authentication request/callback submission helpers. |
openam-ui/openam-ui-js-sdk/src/lib/index.ts |
Library public exports (components + config/types). |
openam-ui/openam-ui-js-sdk/src/lib/env.d.ts |
Vite env typings for OpenAM URL configuration variables. |
openam-ui/openam-ui-js-sdk/src/lib/config.ts |
Global mutable config + default component implementations. |
openam-ui/openam-ui-js-sdk/src/lib/components/types.ts |
Pluggable UI component type contracts. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultUserForm.tsx |
Default user profile + change password modal UI. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultUserForm.test.tsx |
Tests for default user form behavior. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultLoginForm.tsx |
Default login form rendering callbacks + actions. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultLoginForm.test.tsx |
Tests for default login form integration with config. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultErrorForm.tsx |
Default error UI component. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultErrorForm.test.tsx |
Tests for default error UI. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultCallbackElement.tsx |
Default rendering for OpenAM callback types. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultCallbackElement.test.tsx |
Tests for callback element rendering/value updates. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultActionElements.tsx |
Default submit/action button rendering for callbacks. |
openam-ui/openam-ui-js-sdk/src/lib/components/DefaultActionElements.test.tsx |
Tests for action element behavior. |
openam-ui/openam-ui-js-sdk/src/lib/__tests__/mocks.ts |
Mock auth/user payloads for component tests. |
openam-ui/openam-ui-js-sdk/src/lib/User.tsx |
User route: session check, profile load/save, password update. |
openam-ui/openam-ui-js-sdk/src/lib/OpenAMUI.tsx |
SDK root component mounting the router provider. |
openam-ui/openam-ui-js-sdk/src/lib/NotFoundPage.tsx |
404 page component. |
openam-ui/openam-ui-js-sdk/src/lib/Login.tsx |
Login route: init, submit callbacks, redirect or route change. |
openam-ui/openam-ui-js-sdk/src/lib/Home.tsx |
Home route: redirect to login or user based on session. |
openam-ui/openam-ui-js-sdk/src/index.scss |
Basic styling for forms/modals. |
openam-ui/openam-ui-js-sdk/pom.xml |
Maven build for npm test/build + assembly ZIPs (app + lib). |
openam-ui/openam-ui-js-sdk/package.json |
React/React Router/Vite/Vitest/TS toolchain definitions and scripts. |
openam-ui/openam-ui-js-sdk/index.html |
Vite HTML entry document. |
openam-ui/openam-ui-js-sdk/eslint.config.js |
ESLint config for TS/React hooks/refresh. |
openam-ui/openam-ui-js-sdk/assembly/lib-zip.xml |
Assembly descriptor for library ZIP artifact. |
openam-ui/openam-ui-js-sdk/assembly/app-zip.xml |
Assembly descriptor for app ZIP artifact. |
openam-ui/openam-ui-js-sdk/README.md |
Usage/customization docs for app and SDK consumption. |
openam-ui/openam-ui-js-sdk/.gitignore |
Ignores for node/vite outputs and zips. |
openam-ui/openam-ui-js-sdk/.env.development |
Dev env defaults for OpenAM server/context path. |
openam-ui/openam-ui-js-sdk/.env |
Sample env variables (commented). |
openam-server-only/src/main/resources/services/amCORS.xml |
Allows Accept-API-Version header; bumps revisionNumber. |
openam-server-only/pom.xml |
Downloads app ZIP, stages under extui/, and includes it in WAR resources; adds ZIP dependency. |
.github/workflows/deploy.yml |
Excludes openam-ui-js-sdk from javadoc aggregate build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <resources> | ||
| <resource> | ||
| <directory>${project.basedir}/target/app</directory> | ||
| <filtering>true</filtering> | ||
| <includes> | ||
| <include>**</include> | ||
| <include>*</include> | ||
| </includes> | ||
| </resource> | ||
| </resources> |
There was a problem hiding this comment.
The Vite build output under target/app is configured with Maven resource filtering enabled. Filtering can corrupt bundled JS/CSS (e.g., sequences like ${...} in minified output). openam-ui-api’s analogous resource configuration uses <filtering>false</filtering>; consider doing the same here and only filter explicit template files if needed.
| import type { ErrorForm } from "./types"; | ||
|
|
||
| const DefaultErrorForm: ErrorForm = ({ error, resetError }) => { |
There was a problem hiding this comment.
This file is missing the standard CDDL header block that is present in the other new JS SDK source files. Please add the project’s license header here as well for consistency/compliance.
| const response = await fetch(userUrl, { | ||
| method: "GET", | ||
| mode: "cors", | ||
| credentials: "include", | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| }) | ||
| return await response.json(); | ||
| } catch (e) { |
There was a problem hiding this comment.
getUserData returns response.json() without checking response.ok. For non-2xx responses, this can silently propagate error payloads as UserData and break callers. Handle non-OK responses (e.g., parse an error shape and throw) before returning data.
| const response = await fetch(userUrl, { | ||
| method: "PUT", | ||
| mode: "cors", | ||
| credentials: "include", | ||
| headers: { | ||
| "Accept-API-Version": "resource=2.0, protocol=1.0", | ||
| "Content-Type": "application/json" | ||
| }, | ||
| body: JSON.stringify(dataToUpdate), | ||
| } | ||
| ) | ||
| return await response.json(); | ||
| } |
There was a problem hiding this comment.
saveUserData returns response.json() even when the server responds with a non-2xx status. This can make the UI treat error payloads as successful updates. Add a response.ok check and surface a useful error (similar to savePassword).
| - **Ease of Use**: Pre-configured React components ready for integration. | ||
| - **Modular & Flexible**: Easily swap components and customize the SDK to suit your needs. | ||
| - **TypeScript Support**: Enhance development experience with type safety and better code completion. | ||
| - **Seamless Integration**: Easily integrate OpenAM with minimal configura |
There was a problem hiding this comment.
Typo/incomplete word: "minimal configura" should be "minimal configuration".
| - **Seamless Integration**: Easily integrate OpenAM with minimal configura | |
| - **Seamless Integration**: Easily integrate OpenAM with minimal configuration. |
| import { setConfig } from 'openam-js-sdk' | ||
|
|
||
| setConfig({ | ||
| openamServer: 'https://openam.example.org:443', | ||
| openamContextPath: '/am', | ||
| errorForm: ({ error, resetError }) => { | ||
| return <div> | ||
| <h1>An error occurred</h1> | ||
| <p>{error?.message}</p> | ||
| <input type="button" value="Retry" onClick={() => resetError()} /> | ||
| </div> | ||
| }) | ||
|
|
There was a problem hiding this comment.
The customization example uses errorForm, but the config interface property is ErrorForm (capital E) and the default config also uses ErrorForm. As written, the example won’t override the error UI. Update the README example to match the actual config API shape.
| setConfig({ | ||
| CallbackElement: mockCallbackElement, | ||
| ActionElements: mockActionElements, | ||
| }) | ||
|
|
There was a problem hiding this comment.
This test mutates the global singleton config via setConfig at module initialization time, which can leak state into other test files depending on execution order. Prefer setting config in beforeEach/beforeAll and restoring the previous config in afterEach/afterAll to keep tests isolated.
|
|
||
| ### As an Application | ||
|
|
||
| Copy the contents of the `dist/app` folder into your OpenAM WAR file (or the extracted WAR contents in your web container), e.g., into a directory like `extui`, so it could be accessible in your OpenAM context path, for example, http://openam.example.org:8080/openam/extui |
There was a problem hiding this comment.
The README refers to copying dist/app, but this project’s build output is configured to go to target/app (see vite.config.ts and the Maven assembly descriptors). Update the documentation to point to the correct output path/artifact so the instructions work.
| Copy the contents of the `dist/app` folder into your OpenAM WAR file (or the extracted WAR contents in your web container), e.g., into a directory like `extui`, so it could be accessible in your OpenAM context path, for example, http://openam.example.org:8080/openam/extui | |
| Copy the contents of the `target/app` folder into your OpenAM WAR file (or the extracted WAR contents in your web container), e.g., into a directory like `extui`, so it could be accessible in your OpenAM context path, for example, http://openam.example.org:8080/openam/extui |
| //update the default configuration | ||
| import { setConfig } from 'openam-js-sdk' | ||
|
|
||
| setConfig({ | ||
| openamServer: 'https://openam.example.org:443', | ||
| openamContextPath: '/am', | ||
| errorForm: ({ error, resetError }) => { | ||
| return <div> | ||
| <h1>An error occurred</h1> | ||
| <p>{error?.message}</p> | ||
| <input type="button" value="Retry" onClick={() => resetError()} /> | ||
| </div> | ||
| }) | ||
|
|
||
| createRoot(document.getElementById('root')!).render( | ||
| <StrictMode> | ||
| <OpenAMUI /> | ||
| </StrictMode>, | ||
| ) |
There was a problem hiding this comment.
The configuration override example has multiple copy/paste issues: it uses errorForm instead of ErrorForm, and the snippet as written is not valid TSX/TS (unbalanced braces/parentheses and missing imports like createRoot, StrictMode, OpenAMUI). Please fix the snippet so it compiles and matches the actual exported API.
| //update the default configuration | |
| import { setConfig } from 'openam-js-sdk' | |
| setConfig({ | |
| openamServer: 'https://openam.example.org:443', | |
| openamContextPath: '/am', | |
| errorForm: ({ error, resetError }) => { | |
| return <div> | |
| <h1>An error occurred</h1> | |
| <p>{error?.message}</p> | |
| <input type="button" value="Retry" onClick={() => resetError()} /> | |
| </div> | |
| }) | |
| createRoot(document.getElementById('root')!).render( | |
| <StrictMode> | |
| <OpenAMUI /> | |
| </StrictMode>, | |
| ) | |
| // update the default configuration | |
| import React, { StrictMode } from 'react'; | |
| import { createRoot } from 'react-dom/client'; | |
| import { OpenAMUI, setConfig } from 'openam-js-sdk'; | |
| setConfig({ | |
| openamServer: 'https://openam.example.org:443', | |
| openamContextPath: '/am', | |
| ErrorForm: ({ error, resetError }) => { | |
| return ( | |
| <div> | |
| <h1>An error occurred</h1> | |
| <p>{error?.message}</p> | |
| <input | |
| type="button" | |
| value="Retry" | |
| onClick={() => resetError()} | |
| /> | |
| </div> | |
| ); | |
| }, | |
| }); | |
| createRoot(document.getElementById('root')!).render( | |
| <StrictMode> | |
| <OpenAMUI /> | |
| </StrictMode>, | |
| ); |
| const config = getConfig(); | ||
| const userService = new UserService(config.getOpenAmUrl()); | ||
| const loginService = new LoginService(config.getOpenAmUrl()); | ||
|
|
||
| const router = createHashRouter([ |
There was a problem hiding this comment.
config, userService, loginService, and the router are instantiated at module load time. Since consumers are expected to call setConfig(...) to customize openamServer/openamContextPath, importing OpenAMUI (via src/lib/index.ts) will run this file before setConfig is called, so the services/router can be locked to the default URL. Consider creating the router/services lazily (e.g., factory function or inside OpenAMUI with useMemo) so updates via setConfig take effect.
Experimental UI based on React JS library.
Allows to develop a custom OpenAM UI using pluggable components, see the README.md file