Skip to content

Conversation

@syntrydy
Copy link
Contributor

@syntrydy syntrydy commented Dec 11, 2025

#2491
Closes #2491

Summary by CodeRabbit

  • New Features

    • Redesigned OpenID Connect client UI with organized sections, add/edit/view flows, commit confirmation, and client secret copy/generate.
  • Active Tokens

    • Token listing with filtering, date-range controls, CSV export, revoke actions and per-token details.
  • Localization

    • Large expansion of translation keys and UI messages across multiple languages.
  • Tests

    • New comprehensive unit tests for client forms, hooks and utilities.
  • Style

    • Theme color adjusted for improved contrast.

✏️ Tip: You can customize this high-level summary in your review settings.

@syntrydy syntrydy self-assigned this Dec 11, 2025
@syntrydy syntrydy requested a review from duttarnab as a code owner December 11, 2025 11:07
@syntrydy syntrydy added comp-admin-ui Component affected by issue or PR comp-docker-admin-ui Component affected by issue or PR labels Dec 11, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

📝 Walkthrough

Walkthrough

Replaces many legacy JS client UI pieces with a new TypeScript-based Clients feature: adds typed pages, modular TSX sections, hooks, utils, validations, constants, tests and translations; removes numerous old JS components/tests; updates routes, plugin metadata, dev-server config and theme color.

Changes

Cohort / File(s) Summary
Localization
admin-ui/app/locales/*/translation.json
Large additive expansion of translation keys across en/es/fr/pt: actions, fields, sections, titles, messages, placeholders and many OIDC/client/token metadata labels.
Routing & Plugin Metadata
admin-ui/app/helpers/navigation.ts, admin-ui/plugins/auth-server/plugin-metadata.js
Added client view route constant and plugin route entry for ClientDetailPage.
Dev config & Theme
admin-ui/config/webpack.config.client.dev.ts, admin-ui/app/context/theme/config.ts
DevServer historyApiFallback index & disableDotRule adjusted; dark theme fontColor tweaked.
Removed legacy JS components & tests
admin-ui/plugins/auth-server/components/Clients/*.js, admin-ui/plugins/auth-server/__tests__/**/*.test.js
Deleted many legacy JS client pages, panels, active-token UI and their JS tests (wizard, panels, tokens, scripts, detail views, etc.).
New TS pages
admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx, .../ClientAddPage.tsx, .../ClientEditPage.tsx, .../ClientDetailPage.tsx
Added typed list/add/edit/view pages with React Query CRUD hooks, permissions, navigation and audit logging.
Form & detail components
.../components/ClientForm.tsx, ClientAddForm.tsx, ClientDetailView.tsx, ActiveTokenDetailPanel.tsx, SectionErrorFallback.tsx
New Formik-driven ClientForm, add-form, client detail view, active-token detail panel, and error-fallback component.
Per-section TSX components
admin-ui/plugins/auth-server/components/Clients/sections/*
Added modular sections: BasicInfo, Authentication, ScopesGrants, Uris, Tokens, Ciba, Scripts, Localization, SystemInfo, ActiveTokens.
Types & constants
.../types/*, .../helper/constants.ts
New strongly-typed client models, form types, EMPTY_CLIENT template and constants (grant/response types, algs, token defaults, routes, UI labels).
Utils & validations
.../helper/utils.ts, .../helper/validations.ts
Added payload builders, transformations, secret generation, download helpers, date/URI helpers and Yup/runtime validators/schemas.
Hooks & helpers
.../hooks/*
New hooks: useClientApi (React Query CRUD wrappers), useClientActions (audit/navigation helpers), useClientScopes (debounced scope search), useDebounce, usePageSize.
Barrels & exports
.../components/Clients/index.ts, .../sections/index.ts, .../types/index.ts, .../hooks/index.ts
Added barrel files consolidating exports for Clients feature.
Tests (new & removed)
admin-ui/plugins/auth-server/__tests__/components/Clients/*
Added new TS test suites for ClientForm, ClientListPage, hooks/utils; removed several legacy JS tests.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant UI as ClientForm / ClientListPage
  participant Hooks as useClientApi (React Query)
  participant API as JansConfigApi / Backend
  participant Audit as AuditLogger/Webhook

  Note over User,UI: User triggers create/update/delete or token revoke
  User->>UI: submit form / click revoke
  UI->>Hooks: call mutation (create/update/delete/revoke)
  Hooks->>API: HTTP request (POST/PUT/DELETE)
  API-->>Hooks: response (success / error)
  Hooks-->>UI: mutation result
  UI->>Audit: log action (logClientCreation/update/deletion) with modifiedFields
  Audit-->>UI: ack (success / fallback)
  UI->>UI: show toast / navigate / open commit dialog
  UI->>Hooks: invalidate queries (clients/tokens)
  Hooks->>API: refetch clients/tokens
  API-->>Hooks: refreshed lists
  Hooks-->>UI: updated data rendered
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested reviewers

  • duttarnab
  • moabu
  • faisalsiddique4400

Poem

"I'm a rabbit, I nibble keys and code,
New sections sprout where the old ones strode,
Types tidy burrows, hooks hop along,
Forms commit changes and toasts sing a song,
Hooray — clients bloom and locales glow!" 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'fix(admin-ui): Use typescript generated Clients pages' is specific and accurately describes the main change: migrating to TypeScript-generated client types.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #2491 objectives: TypeScript-generated types are integrated across new Clients components, Redux-related custom code is absent, and manually-added type definitions are replaced with generated types throughout the codebase.
Out of Scope Changes check ✅ Passed All changes align with PR objectives: translation additions support new UI, old JS components are removed and replaced with new TS equivalents, utilities and validations are introduced for the new architecture, and webpack/routing updates enable the new client pages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch admin-ui-2491

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 60

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
admin-ui/config/webpack.config.client.dev.ts (1)

21-22: Normalize BASE_PATH to avoid malformed index URL in historyApiFallback.

As written, if BASE_PATH does not end with a trailing slash (e.g. '/admin-ui'), the computed index becomes '/admin-uiindex.html', and publicPath will also be slightly off. This will break dev routing for those configurations.

Either enforce that BASE_PATH always includes a trailing slash at the env/config level, or normalize it here before using it in both output.publicPath and historyApiFallback.index.

One way to make this more robust in-code:

-const BASE_PATH: string = process.env.BASE_PATH || '/'
+const RAW_BASE_PATH = process.env.BASE_PATH || '/'
+const BASE_PATH = RAW_BASE_PATH.endsWith('/') ? RAW_BASE_PATH : `${RAW_BASE_PATH}/`

output.publicPath and historyApiFallback.index can then safely rely on BASE_PATH:

   output: {
     filename: '[name].bundle.js',
     chunkFilename: '[name].chunk.js',
     path: config.distDir,
-    publicPath: BASE_PATH,
+    publicPath: BASE_PATH,
   },
   devServer: {
@@
-    historyApiFallback: {
-      disableDotRule: true,
-      index: `${BASE_PATH}index.html`,
-    },
+    historyApiFallback: {
+      disableDotRule: true,
+      index: `${BASE_PATH}index.html`,
+    },

(Last two hunks just keep using the normalized BASE_PATH and are shown for clarity.)

Also applies to: 103-108, 266-268

admin-ui/app/locales/fr/translation.json (1)

652-659: Portuguese text found in French translation file.

These entries appear to be in Portuguese instead of French:

  • "mapping": "Mapeamento" → should be "Mappage" or "Mapping"
  • "source": "Fonte" → should be "Source"
  • "created_date": "Data de Criação" → should be "Date de création"
  • "token_type": "Tipo de Token" → should be "Type de jeton"
  • "token_code": "Código do Token" → should be "Code du jeton"
  • "deleteable": "Deletável" → should be "Supprimable"
  • "grant_Id": "ID de Concessão" → should be "ID d'octroi"
  • "reference_id": "ID de Referência" → should be "ID de référence"
admin-ui/app/locales/pt/translation.json (1)

572-573: Fix duplicated spontaneous_scopes key in fields.

"spontaneous_scopes" is defined twice in fields (once near Line 572 and again around Line 711). Only the last value will be used. Remove one of them and keep a single, correct translation.

Also applies to: 710-712

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04e71bf and e32b12f.

📒 Files selected for processing (62)
  • admin-ui/app/locales/en/translation.json (13 hunks)
  • admin-ui/app/locales/es/translation.json (11 hunks)
  • admin-ui/app/locales/fr/translation.json (10 hunks)
  • admin-ui/app/locales/pt/translation.json (10 hunks)
  • admin-ui/config/webpack.config.client.dev.ts (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientAddPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientDetailPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientEditPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientListPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientWizardForm.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientListPage.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokenDetailPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokens.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientAdvancedPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientBasicPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientCibaParUmaPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEncryptionSigningPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientLogoutPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientScriptPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientShowScopes.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientShowSpontaneousScopes.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientSoftwarePanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientTokensPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientWizardForm.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/SectionErrorFallback.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/plugin-metadata.js (2 hunks)
💤 Files with no reviewable changes (22)
  • admin-ui/plugins/auth-server/tests/components/ClientEditPage.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.js
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js
  • admin-ui/plugins/auth-server/components/Clients/ClientShowSpontaneousScopes.js
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.js
  • admin-ui/plugins/auth-server/components/Clients/ClientShowScopes.js
  • admin-ui/plugins/auth-server/components/Clients/ClientCibaParUmaPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokens.js
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokenDetailPage.js
  • admin-ui/plugins/auth-server/components/Clients/ClientTokensPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientBasicPanel.js
  • admin-ui/plugins/auth-server/tests/components/ClientDetailPage.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientSoftwarePanel.js
  • admin-ui/plugins/auth-server/tests/components/ClientListPage.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientLogoutPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientWizardForm.js
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.js
  • admin-ui/plugins/auth-server/components/Clients/ClientScriptPanel.js
  • admin-ui/plugins/auth-server/tests/components/ClientWizardForm.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientAdvancedPanel.js
  • admin-ui/plugins/auth-server/tests/components/ClientAddPage.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientEncryptionSigningPanel.js
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-12-05T18:24:41.713Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.713Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/components/SectionErrorFallback.tsx
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/config/webpack.config.client.dev.ts
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/config/webpack.config.client.dev.ts
🧬 Code graph analysis (26)
admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • Client (17-17)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • formatScopeDisplay (102-109)
  • formatGrantTypeLabel (111-125)
  • formatResponseTypeLabel (127-134)
admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • BACKCHANNEL_TOKEN_DELIVERY_MODES (41-45)
admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (5)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-98)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (2)
  • useClientById (31-51)
  • useUpdateClient (86-117)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ClientScope (37-43)
  • ModifiedFields (57-59)
admin-ui/app/utils/ApiUtils.ts (1)
  • handleSuccess (51-53)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • filterScriptsByType (145-155)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SCRIPT_TYPES (94-116)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/ClientAddPage.tsx (4)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-98)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1)
  • useCreateClient (53-84)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/services/Components/Configuration/PersistenceDetail.js (1)
  • labelStyle (37-39)
admin-ui/plugins/auth-server/plugin-metadata.js (1)
admin-ui/app/utils/PermChecker.ts (1)
  • CLIENT_READ (11-11)
admin-ui/plugins/auth-server/__tests__/components/Clients/ClientListPage.test.tsx (1)
admin-ui/plugins/auth-server/components/Configuration/JsonPropertyBuilder.js (1)
  • result (9-9)
admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1)
admin-ui/app/utils/Util.ts (1)
  • formatDate (53-64)
admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (2)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (18)
  • buildClientInitialValues (4-16)
  • buildClientPayload (18-82)
  • hasFormChanges (84-89)
  • formatScopeDisplay (102-109)
  • formatGrantTypeLabel (111-125)
  • formatResponseTypeLabel (127-134)
  • extractInumFromDn (136-139)
  • buildScopeDn (141-143)
  • filterScriptsByType (145-155)
  • getScriptNameFromDn (157-163)
  • formatDateForDisplay (165-173)
  • formatDateForInput (175-183)
  • isValidUrl (185-192)
  • isValidUri (194-198)
  • truncateText (220-223)
  • sortByName (225-227)
  • removeDuplicates (229-231)
  • arrayEquals (233-238)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • EMPTY_CLIENT (102-201)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (3)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-98)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1)
  • useClientById (31-51)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ClientScope (37-43)
admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (5)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • uriValidation (20-24)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (3)
  • DEFAULT_SCOPE_SEARCH_LIMIT (136-136)
  • SECRET_GENERATION (176-179)
  • GRANT_TYPES (1-12)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ClientScope (37-43)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • buildClientPayload (18-82)
admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (2)
admin-ui/app/utils/Util.ts (1)
  • formatDate (53-64)
admin-ui/plugins/auth-server/redux/sagas/SsaSaga.js (2)
  • blob (138-138)
  • link (141-141)
admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ClientScope (37-43)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatScopeDisplay (102-109)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (2)
  • GRANT_TYPES (1-12)
  • RESPONSE_TYPES (14-18)
admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (6)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ClientTableRow (61-65)
  • Client (17-17)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-98)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • DEFAULT_PAGE_SIZE (135-135)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (2)
  • formatGrantTypeLabel (111-125)
  • truncateText (220-223)
admin-ui/app/components/Card/Card.tsx (1)
  • Card (27-27)
admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/app/utils/Util.ts (1)
  • formatDate (53-64)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (3)
  • SECRET_GENERATION (176-179)
  • APPLICATION_TYPES (20-23)
  • SUBJECT_TYPES (25-28)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • isValidUri (194-198)
admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (5)
  • useClientList (15-29)
  • useClientById (31-51)
  • useCreateClient (53-84)
  • useUpdateClient (86-117)
  • useDeleteClient (119-146)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • RootState (138-140)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ExtendedClient (31-35)
  • ModifiedFields (57-59)
admin-ui/app/utils/AuditLogger.ts (1)
  • logAuditUserAction (25-66)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • CLIENT_ROUTES (128-133)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ClientListOptions (53-55)
  • Client (17-17)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (4)
  • ExtendedClient (31-35)
  • ModifiedFields (57-59)
  • ClientScope (37-43)
  • ClientScript (45-51)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (3)
  • ExtendedClient (31-35)
  • EMPTY_CLIENT (102-201)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • isValidUri (3-18)
🪛 Biome (2.1.2)
admin-ui/app/locales/en/translation.json

[error] 358-358: The key logout_status_jwt_signed_response_alg was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1094-1094: The key id_token was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1095-1095: The key access_token was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1096-1096: The key userinfo was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1097-1097: The key request_object was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1098-1098: The key introspection was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1099-1099: The key jarm was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1100-1100: The key token_endpoint_auth was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)

admin-ui/plugins/auth-server/components/Clients/helper/validations.ts

[error] 38-38: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 62-62: Do not add then to an object.

(lint/suspicious/noThenProperty)

🔇 Additional comments (49)
admin-ui/plugins/auth-server/components/Clients/types/index.ts (1)

1-2: LGTM!

Clean barrel file that consolidates type exports, enabling cleaner imports throughout the Clients feature.

admin-ui/plugins/auth-server/components/Clients/components/SectionErrorFallback.tsx (1)

11-45: LGTM!

Well-structured error boundary fallback with proper i18n support and accessible UI. The use of MUI's Alert component provides appropriate semantic meaning for the error state.

One optional consideration: You may want to log the error for debugging purposes (e.g., console.error(error) in a useEffect), which can help identify issues in production. Based on learnings from similar components in this codebase, error logging has been useful for debugging.

admin-ui/plugins/auth-server/plugin-metadata.js (2)

9-9: LGTM!

Import follows the existing pattern for client page components.


172-177: LGTM!

Route configuration is well-structured:

  • Path /client/view/:id follows the existing convention alongside /client/edit/:id
  • CLIENT_READ permission is appropriate for a read-only detail view
  • Resource key properly configured for Cedar authorization
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)

1-9: LGTM!

Clean barrel export pattern that properly centralizes hook exports from the Clients feature module.

admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (3)

44-48: SetTitle is called even when id is missing.

The SetTitle hook runs before the early return check for missing id. While this may not cause runtime issues, it sets a title for a page that immediately returns null. Consider moving the early return check before SetTitle or ensuring this is the intended behavior.

Based on learnings, SetTitle should be called at component top level, so this pattern is acceptable if the title should always be set regardless of render output.


50-64: LGTM!

The component properly handles loading states with GluuLoader, conditionally renders ClientForm only when client exists, and correctly configures the form for view-only mode.


23-40: Simplify scope mapping by leveraging the ClientScope type directly.

The inline type assertion duplicates the structure of ClientScope. Since ClientScope is already imported, consider using a simpler cast or type guard to reduce redundancy.

  const scopes = useMemo((): ClientScope[] => {
-   const entries = (scopesResponse?.entries || []) as Array<{
-     dn?: string
-     inum?: string
-     id?: string
-     displayName?: string
-     description?: string
-   }>
+   const entries = (scopesResponse?.entries || []) as ClientScope[]
    return entries.map(
      (scope): ClientScope => ({
        dn: scope.dn || '',
        inum: scope.inum,
        id: scope.id,
        displayName: scope.displayName || scope.id,
        description: scope.description,
      }),
    )
  }, [scopesResponse?.entries])

Likely an incorrect or invalid review comment.

admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1)

67-84: LGTM!

Good separation of concerns with nested try/catch for audit logging that doesn't block the main update flow. The warning toast for audit failures is appropriate UX.

admin-ui/plugins/auth-server/components/Clients/ClientAddPage.tsx (2)

22-39: LGTM!

Consistent error handling pattern with nested try/catch for audit logging. The separation ensures that audit failures don't block user navigation while still providing feedback via warning toast.


43-47: LGTM!

Clean render logic with GluuLoader blocking during pending state and proper props passed to ClientAddForm.

admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (1)

79-96: LGTM!

Clean layout structure with proper theming integration and conditional status badge rendering.

admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (2)

97-133: LGTM!

Good use of useMemo for filtering scripts by type. Each filtered list correctly depends on the scripts prop, preventing unnecessary recalculations.


135-170: LGTM!

Well-structured reusable renderScriptSelector with proper memoization via useCallback. The function correctly uses option.dn as the key for chips.

admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)

89-97: LGTM!

The hook is well-structured with proper memoization of callbacks. The separation of audit logging and navigation concerns is clean, and the return object provides a clear API for consumers.

admin-ui/app/locales/fr/translation.json (1)

1121-1132: LGTM!

The new sections object provides proper French translations for section labels used in the client form UI.

admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (3)

407-443: Duplicate submit buttons in the form.

The submit button appears twice - at the top (lines 424-443) and bottom (lines 507-526) of the form. While this may be intentional for UX on long forms, ensure this is the desired behavior and both buttons maintain identical logic.

Also applies to: 506-527


396-541: LGTM!

The component is well-architected with:

  • Proper error boundaries for section-level error handling
  • Responsive layout with mobile-friendly section navigation
  • Formik integration with validation schema
  • Memoized callbacks and styles for performance
  • Theme-aware styling

214-219: This review comment is incorrect. The operations variable is meaningfully used by GluuCommitDialog. The component checks operations?.length (line 169) and maps over the array to render each operation as a list of changes in the modal body (lines 183–218), displaying both the field path and its new value.

Likely an incorrect or invalid review comment.

admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (2)

97-196: LGTM!

The System Information section is well-structured with proper disabled state for read-only fields and appropriate theme-aware styling.


258-268: Avoid duplicate key prop on Chip component.

The getTagProps({ index }) spread already provides a key prop. Adding key={index} separately creates a duplicate. Use the key from getTagProps instead.

 renderTags={(value, getTagProps) =>
   value.map((option, index) => (
     <Chip
       {...getTagProps({ index })}
-      key={index}
       label={option}
       size="small"
       sx={chipStyle}
     />
   ))
 }

Likely an incorrect or invalid review comment.

admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1)

43-113: LGTM!

The component provides a clean, accessible detail view for tokens with proper responsive grid layout and theme integration.

admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (2)

108-146: Well-structured reusable JSON editor renderer.

The renderJsonEditor callback is cleanly implemented with proper memoization and consistent styling. The dependency array is complete.


148-186: LGTM!

The component correctly renders all five localized JSON editors with consistent styling and proper Formik integration. The theme-aware styling and viewOnly mode handling are implemented correctly.

admin-ui/app/locales/en/translation.json (1)

1236-1247: Good addition of a dedicated sections object.

The new sections object provides a clean namespace for section-related translations, avoiding pollution of the titles namespace.

admin-ui/plugins/auth-server/components/Clients/index.ts (1)

1-11: Clean barrel export structure.

The barrel file properly consolidates exports for the Clients module, enabling clean imports like import { ClientListPage, ClientForm } from '.../Clients'. The organization follows common TypeScript/React patterns.

Note: Wildcard re-exports (export * from) can cause naming conflicts if the source modules have overlapping export names. If conflicts arise, switch to named re-exports.

admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (2)

79-85: Good fallback chain for signing algorithms.

The component correctly falls back to id_token_signing_alg_values_supported when backchannel_authentication_request_signing_alg_values_supported is not available, ensuring the dropdown is populated even with partial OIDC configuration.


9-192: LGTM!

The CibaSection component is well-implemented with:

  • Consistent theming and styling patterns
  • Proper Formik integration via handleFieldChange
  • Correct handling of viewOnly mode
  • Appropriate use of memoization for styles and derived data
admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (2)

31-40: Good separation of field vs attribute handlers.

The handleAttributeChange callback correctly prefixes the field path with attributes. for nested form values, maintaining clean separation from top-level fields handled by handleFieldChange.


78-100: Appropriate deduplication of algorithm options.

Using new Set() to deduplicate algorithm arrays from oidcConfiguration prevents duplicate options in dropdowns. The fallback to signingAlgorithms for access token signing is sensible.

admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (1)

24-276: Good test coverage for utility functions.

The test suite comprehensively covers the utility functions with both happy path and edge case scenarios. The structure follows good testing practices with descriptive test names and proper grouping.

admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (2)

133-138: Good use of cryptographically secure random generation.

Using crypto.getRandomValues for secret generation is the correct approach for security-sensitive random values.


68-81: Validation schema is well-defined.

The Yup validation properly handles required fields and URI validation with a custom test for ensuring at least one valid redirect URI.

admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (2)

74-82: Good search optimization with minimum character threshold.

Triggering the scope search only when input length is >= 2 prevents excessive API calls on initial typing.


33-42: Clean handler pattern for field changes.

The handleFieldChange callback properly updates both formik state and the modified fields tracker in a single operation.

admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (2)

24-44: Well-structured field change handlers.

The separation between handleFieldChange for top-level fields and handleAttributeChange for nested attributes is clean and maintains consistency with the form structure.


102-815: Comprehensive token configuration UI.

The component provides a well-organized interface covering token lifetimes, options, PAR, security, ACR, and advanced token settings. The logical grouping into sections improves usability.

admin-ui/plugins/auth-server/components/Clients/sections/index.ts (1)

1-10: Clean barrel export pattern.

The index file properly consolidates section component exports, enabling cleaner imports for consumers. The export ordering follows a logical UI flow.

admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (1)

38-71: Well-structured hook usage with proper query configuration.

Good use of Orval-generated hooks with appropriate query options (enabled, refetchOnMount, refetchOnWindowFocus). The conditional enabling based on clientInum prevents unnecessary API calls.

admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1)

86-145: Well-organized component with comprehensive permission handling.

The component properly integrates Cedarling-based permissions, memoizes query parameters, and uses appropriate React Query options. The separation of concerns between state management and UI rendering is clean.

admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (2)

15-29: Clean hook design with proper memoization.

Good use of useMemo for query options to prevent unnecessary re-renders. The query configuration follows React Query best practices.


31-51: Consider using a dedicated single-client fetch endpoint if available in the OAuth Config API.

This hook currently fetches a list with pattern: inum and limit: 1, then filters client-side. If the API supports a dedicated endpoint for fetching a client by inum (similar to useGetAttributesByInum, useGetOauthScopesByInum, etc.), using that would be more efficient. Verify whether JansConfigApi exposes such an endpoint for OAuth OpenID clients.

admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1)

45-103: Well-structured memoized style objects.

Good use of useMemo for style objects with proper dependencies. This prevents unnecessary re-renders and style recalculations.

admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (2)

360-381: Good conditional rendering for expiration date picker.

The DateTimePicker is properly guarded by the expirable flag and correctly converts to ISO string format. The use of LocalizationProvider with AdapterDayjs follows MUI best practices.


32-53: Clean component structure with proper TypeScript typing.

The component follows the established SectionProps interface pattern, uses proper callback memoization, and integrates well with the theme context. The separation between field change handlers is well-organized.

admin-ui/app/locales/es/translation.json (1)

642-713: New Clients/OIDC/tokens translations look structurally consistent.

The added keys for client details, token lifetimes/options, PAR/CIBA, localized strings, and the new sections grouping align well with the new client form sections and appear correctly localized. Once other locales are updated to the same key set, this should give good i18n coverage for the new UI.

Please double‑check that all section IDs used in code (e.g., basic, authentication, tokens, activeTokens) map to the correct titles.* or sections.* keys here.

Also applies to: 876-883, 962-974, 1068-1073, 1181-1215, 1216-1226

admin-ui/app/locales/pt/translation.json (1)

335-339: New client/token/section translations are consistent with the expanded Clients UI.

The added keys (section/sort_order, access token / PAR / CIBA / UMA fields, client token messages, new titles, and the sections group) match the structure introduced for the Clients pages and appear correctly localized. Keeping PT in sync with EN/ES/FR for these keys should avoid i18n gaps.

Please verify that all keys used by the new Clients components (especially tokens/CIBA/UMA and localization tabs) are present here with the same identifiers as in the English source.

Also applies to: 673-743, 763-764, 812-819, 828-910, 994-999, 1002-1114, 1115-1125

admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)

1-29: Typed client surface and EMPTY_CLIENT look coherent and usable.

ExtendedClient, ClientScope/ClientScript, UmaResource, TokenEntry, and EMPTY_CLIENT provide a clear, strongly-typed surface for the Clients UI and match how the helpers/form values consume them. Defaults in EMPTY_CLIENT also seem reasonable for initializing new clients.

Please ensure EMPTY_CLIENT stays in sync with the actual Client/ClientAttributes shape from JansConfigApi whenever the backend schema changes, so we don’t silently drop or mis‑type new attributes.

Also applies to: 31-84, 102-200

admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)

84-100: Change‑tracking helpers are simple and effective for this context.

hasFormChanges (JSON stringify comparison), trackFieldChange, truncateText, sortByName, removeDuplicates, and arrayEquals are straightforward and appropriate for the relatively small, flat payloads involved in client forms. No issues spotted here.

Also applies to: 220-238

@mo-auto mo-auto added the kind-bug Issue or PR is a bug in existing functionality label Dec 11, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 30

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-ui/app/locales/es/translation.json (1)

4-4: Fix concatenated translation string.

The value appears to be a copy-paste error where "Aceptar" was concatenated with the intended translation.

-    "add_attribute_mapping": "AceptarAgregar mapeo de atributos",
+    "add_attribute_mapping": "Agregar mapeo de atributos",
admin-ui/app/locales/fr/translation.json (1)

652-659: Portuguese text in French translation file.

Several keys contain Portuguese instead of French translations:

  • Line 652: "mapping": "Mapeamento" should be "Mappage"
  • Line 653: "source": "Fonte" should be "Source"
  • Line 654: "created_date": "Data de Criação" should be "Date de création"
  • Line 655: "token_type": "Tipo de Token" should be "Type de jeton"
  • Line 656: "token_code": "Código do Token" should be "Code du jeton"
  • Line 657: "deleteable": "Deletável" should be "Supprimable"
  • Line 658: "grant_Id": "ID de Concessão" should be "ID d'octroi"
  • Line 659: "reference_id": "ID de Referência" should be "ID de référence"
♻️ Duplicate comments (36)
admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1)

97-106: Silent catch hides JSON validation errors from users.

The empty catch {} block silently swallows JSON parse errors. Users editing malformed JSON receive no feedback that their input is invalid.

Consider setting an error state or using Formik's setFieldError to provide visual feedback when JSON is invalid.

admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (2)

240-251: Redundant disabled={viewOnly} prop on Switch.

This Switch is rendered inside a !viewOnly branch (line 236), so viewOnly is always false here. The disabled prop is unnecessary.


277-288: Redundant disabled={viewOnly} prop on Switch (response types).

Same as the grant types Switch - this branch only executes when !viewOnly, making the disabled prop redundant.

admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1)

14-30: DRY up mock client data and consider covering invalidate/callback behavior.

  • The mockClients array is unused and duplicates the inline entries array returned in the JansConfigApi mock. Either remove mockClients or refactor the mock to return mockClients (including entriesCount/totalEntriesCount) to keep test data in one place.
  • The hooks barrel also exports useInvalidateClientQueries, but this file does not exercise it. Adding a small test that calls it and asserts mockInvalidateQueries is invoked would close that gap.
  • For the mutation hooks, you may want to extend tests beyond checking mutate/isPending to verify that mutate actually calls the underlying mocked mutation and that invalidateQueries is triggered on success.

Also applies to: 35-74, 138-163

admin-ui/plugins/auth-server/__tests__/components/Clients/ClientListPage.test.tsx (1)

1-82: Tests only validate mock return values, not ClientListPage behavior.

The suite never imports or renders ClientListPage; it just calls mockUseGetOauthOpenidClients() and inspects the returned object. This doesn’t exercise the component, routing, or table rendering, so it provides little real coverage.

Consider updating the tests to:

  • Import and render ClientListPage using the existing Wrapper.
  • Keep the JansConfigApi mock, but assert on rendered UI (e.g., findByText('Jans Config Api Client'), loading/empty states, row actions).

Also applies to: 84-118

admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1)

1-134: ClientForm tests do not render or exercise the actual component.

All tests operate on mockClient data and mock callbacks; ClientForm itself is never imported or rendered, so validation, layout, and interaction logic are untested.

Consider:

  • Importing ClientForm and rendering it inside Wrapper.
  • Passing mockClient, mockOnSubmit, mockOnCancel, and mockOnScopeSearch.
  • Asserting on rendered fields and user flows (e.g., initial values, submit/cancel behavior, scope search wiring).
admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (2)

130-139: Verify script pagination limit is sufficient.

The script fetch uses limit: 200. If there are more than 200 scripts, some will be missing from selection options.


119-128: Redundant variable assignments.

Lines 119-120 simply alias the props without transformation. Consider using propScopes and propScopesLoading directly.

admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (2)

38-55: Duplicate scope transformation logic across pages.

This scope mapping logic is nearly identical to ClientDetailPage.tsx. Consider extracting into a shared utility.


86-89: Unnecessary useMemo for simple boolean expression.

This simple OR operation doesn't benefit from memoization.

admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (2)

29-41: Add error handling for clipboard operations.

navigator.clipboard.writeText() returns a Promise that can reject. Unhandled rejections may cause silent failures.


43-56: Memoize getScopeNames to avoid recalculating on every render.

This function performs filtering and mapping operations that are recalculated on every render. Wrap it in useMemo with dependencies [client.scopes, scopes].

admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1)

102-816: Component is functional but consider extraction for maintainability.

This component handles 9 distinct sections (~700 lines) with highly repetitive TextField select patterns. While functional, extracting a reusable AlgorithmSelect helper component would significantly reduce duplication.

admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (1)

310-319: Use option value as key instead of index.

For the spontaneous scopes freeSolo Autocomplete, using the string value as the key is more stable than the array index.

  renderTags={(value, getTagProps) =>
    value.map((option, index) => (
      <Chip
        {...getTagProps({ index })}
-       key={index}
+       key={`${option}-${index}`}
        label={option}
        size="small"
        sx={chipStyle}
      />
    ))
  }

Using ${option}-${index} handles potential duplicate scope strings while maintaining key stability.

admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (2)

140-142: Handle clipboard API failures gracefully.

navigator.clipboard.writeText returns a Promise and can fail (e.g., if clipboard permission is denied).

-  const handleCopyToClipboard = useCallback((text: string) => {
-    navigator.clipboard.writeText(text)
+  const handleCopyToClipboard = useCallback((text: string) => {
+    navigator.clipboard.writeText(text).catch(() => {
+      // Silently fail or show toast notification
+    })
   }, [])

196-205: Double type assertions suggest incomplete transformation from form values.

The as unknown as ClientFormValues pattern indicates a type mismatch between AddFormValues and ClientFormValues. Consider extracting the payload construction into a dedicated transformation function.

admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)

17-65: Consider adding error handling for audit log failures.

The logAuditUserAction calls are awaited but failures are silently ignored. If audit logging fails, the calling code won't know.

Based on learnings, console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

 const logClientCreation = useCallback(
   async (client: ExtendedClient, message: string, modifiedFields?: ModifiedFields) => {
+    try {
       await logAuditUserAction({
         token,
         userinfo,
         action: CREATE,
         resource: OIDC,
         message,
         modifiedFields,
         performedOn: client.inum,
         client_id,
         payload: client,
       })
+    } catch (error) {
+      console.error('Failed to log client creation audit:', error)
+    }
   },
   [token, userinfo, client_id],
 )
admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (2)

22-22: Remove unused import.

The clients import is never used in this test file.

-import { clients } from '../../components/clients.test'

184-193: Strengthen the formatDateForDisplay test assertion.

The test only checks that the result is truthy, which doesn't verify the actual formatting behavior.

   describe('formatDateForDisplay', () => {
     it('formats valid date string', () => {
       const result = formatDateForDisplay('2025-01-15T10:30:00')
-      expect(result).toBeTruthy()
+      expect(result).toContain('2025')
+      expect(result).toContain('15')
     })
admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (3)

34-41: Duplicate formatDate function.

This is a duplicate of similar date formatting logic. There's already a formatDate utility in admin-ui/app/utils/Util.ts. Consider using a shared utility.


78-89: Translation key typo: deleteable vs deletable.

Line 79 uses t('fields.deleteable') but the Spanish translation file (line 626) has "deleteable" while other files may use "deletable". Verify which spelling is canonical.

#!/bin/bash
# Check for both spellings across translation files
rg -n "deleteable|deletable" admin-ui/app/locales/ --include="*.json"

91-110: Document what token attributes may contain or add a security notice.

The attributes object is displayed as raw JSON. If token attributes could include sensitive information, consider documenting safe fields or adding a user notice.

admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (1)

164-189: CSV field escaping issue persists.

The CSV conversion still replaces commas with semicolons instead of properly escaping fields per RFC 4180. This was flagged in a previous review.

admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (1)

115-121: Missing radix parameter in parseInt calls.

This was flagged in a previous review. All parseInt calls should specify the radix parameter for clarity and to avoid edge cases with strings starting with 0.

admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (2)

53-117: Duplicate handler patterns in useCreateClient and useUpdateClient.

This was noted in a previous review. The success/error handler logic is nearly identical and could be extracted into a shared factory function.


31-51: useClientById implementation may return incorrect client.

The current implementation searches with pattern: inum and limit: 1, then filters by exact inum match. This has issues:

  1. If the pattern matches multiple clients (e.g., partial match), limit: 1 may return a different client
  2. The subsequent find by exact inum could then return undefined

Consider using a dedicated endpoint if available, or removing the limit: 1 to ensure the target client is in the results.

- const { data, ...rest } = useGetOauthOpenidClients({ pattern: inum, limit: 1 }, queryOptions)
+ const { data, ...rest } = useGetOauthOpenidClients({ pattern: inum }, queryOptions)
admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1)

114-116: React key warning: using index as key in dynamic lists.

Using array index as key for Chips in dynamic lists where items can be added/removed can cause incorrect component recycling and subtle bugs. This applies to both the read-only chips (line 115) and the editable Autocomplete tags (line 141).

Apply this diff to improve key stability:

 {(value || []).map((uri, index) => (
-  <Chip key={index} label={uri} sx={chipStyle} size="small" />
+  <Chip key={`${uri}-${index}`} label={uri} sx={chipStyle} size="small" />
 ))}

And for the Autocomplete:

 renderTags={(value, getTagProps) =>
   value.map((option, index) => (
     <Chip
       {...getTagProps({ index })}
-      key={index}
+      key={`${option}-${index}`}
       label={option}
       size="small"
       sx={chipStyle}
     />
   ))
 }

Also applies to: 137-147

admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (2)

108-111: Unsafe parseInt without radix and no NaN handling.

parseInt(stored) without a radix can produce unexpected results with strings starting with "0". Also, NaN is not handled if the stored value is corrupted.

 const getInitialPageSize = (): number => {
   const stored = localStorage.getItem('paggingSize')
-  return stored ? parseInt(stored) : DEFAULT_PAGE_SIZE
+  if (!stored) return DEFAULT_PAGE_SIZE
+  const parsed = parseInt(stored, 10)
+  return Number.isNaN(parsed) ? DEFAULT_PAGE_SIZE : parsed
 }

158-163: Query invalidation predicate may be fragile.

Casting query.queryKey[0] to string and comparing against the first element of the query key array is brittle. If the query key structure changes, this will silently fail.

Consider using a more robust approach:

 queryClient.invalidateQueries({
-  predicate: (query) => {
-    const queryKey = query.queryKey[0] as string
-    return queryKey === getGetOauthOpenidClientsQueryKey()[0]
-  },
+  queryKey: getGetOauthOpenidClientsQueryKey(),
 })

Also applies to: 324-329

admin-ui/app/locales/en/translation.json (2)

358-358: Duplicate key logout_status_jwt_signed_response_alg in fields object.

This key is defined at line 358 and again at line 722. In JSON, duplicate keys cause only the last definition to take effect, which may lead to unexpected translation values.

Remove one of the duplicate definitions to ensure consistent translations.

Also applies to: 722-722


1093-1101: Multiple duplicate keys in titles object will cause translation conflicts.

Static analysis detected the following duplicate keys that are defined at lines 1094-1101 and again later in the file:

  • id_token (also at line 1179)
  • access_token (also at line 1180)
  • userinfo (also at line 1181)
  • request_object (also at line 1183)
  • introspection (also at line 1205)
  • jarm (also at line 1206)
  • token_endpoint_auth (also at line 1214)

Remove the duplicate definitions. The later definitions use different casing conventions—consolidate to one consistent style.

Also applies to: 1178-1214

admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (2)

59-71: Clipboard API calls lack error handling.

navigator.clipboard.writeText returns a Promise that can reject (e.g., if clipboard access is denied). The code doesn't handle this rejection.

-const handleCopyClientId = useCallback(() => {
+const handleCopyClientId = useCallback(async () => {
   if (formik.values.inum) {
-    navigator.clipboard.writeText(formik.values.inum)
-    dispatch(updateToast(true, 'success', t('messages.client_id_copied')))
+    try {
+      await navigator.clipboard.writeText(formik.values.inum)
+      dispatch(updateToast(true, 'success', t('messages.client_id_copied')))
+    } catch {
+      dispatch(updateToast(true, 'error', t('messages.copy_failed')))
+    }
   }
 }, [formik.values.inum, dispatch, t])

Apply similar changes to handleCopyClientSecret.


415-426: Contacts Autocomplete uses index as key.

Similar to UrisSection, using array index as key for chips in a dynamic list can cause React reconciliation issues.

 renderTags={(value, getTagProps) =>
   value.map((option, index) => (
     <Chip
       {...getTagProps({ index })}
-      key={index}
+      key={`${option}-${index}`}
       label={option}
       size="small"
       sx={{ backgroundColor: themeColors?.background, color: 'white' }}
     />
   ))
 }
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (3)

3-18: Duplicate isValidUri function exists in utils.ts with different implementation.

This file defines isValidUri that returns true for empty/null values (permissive), while utils.ts (lines 193-197) defines a stricter version that returns false for empty values. This inconsistency could cause confusion.

Consider consolidating into a single implementation or renaming to clarify different purposes (e.g., isValidOptionalUri vs isValidRequiredUri).


55-57: Inconsistent terminology: "positive number" but zero is allowed.

The error message states "Must be a positive number" but min(0) allows zero, which is technically non-negative, not positive.

-  accessTokenLifetime: Yup.number().nullable().min(0, 'Must be a positive number'),
-  refreshTokenLifetime: Yup.number().nullable().min(0, 'Must be a positive number'),
-  defaultMaxAge: Yup.number().nullable().min(0, 'Must be a positive number'),
+  accessTokenLifetime: Yup.number().nullable().min(0, 'Must be a non-negative number'),
+  refreshTokenLifetime: Yup.number().nullable().min(0, 'Must be a non-negative number'),
+  defaultMaxAge: Yup.number().nullable().min(0, 'Must be a non-negative number'),

Apply the same fix to validatePositiveNumber (line 90) and validateTokenLifetime (line 119).

Also applies to: 87-92, 114-122


68-79: validateRedirectUri doesn't support custom schemes unlike isValidUri.

isValidUri (lines 12-14) accepts custom schemes like myapp://callback for mobile app redirects, but validateRedirectUri lacks this support.

 export function validateRedirectUri(uri: string): string | null {
   if (!uri) return 'URI is required'
   try {
     new URL(uri)
     return null
   } catch {
     if (uri.startsWith('http://localhost') || uri.startsWith('http://127.0.0.1')) {
       return null
     }
+    const customSchemeRegex = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/.+$/
+    if (customSchemeRegex.test(uri)) {
+      return null
+    }
     return 'Must be a valid URL'
   }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04e71bf and e4bef07.

📒 Files selected for processing (62)
  • admin-ui/app/locales/en/translation.json (15 hunks)
  • admin-ui/app/locales/es/translation.json (13 hunks)
  • admin-ui/app/locales/fr/translation.json (11 hunks)
  • admin-ui/app/locales/pt/translation.json (12 hunks)
  • admin-ui/config/webpack.config.client.dev.ts (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientAddPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientDetailPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientEditPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientListPage.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/ClientWizardForm.test.js (0 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientListPage.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokenDetailPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokens.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientAdvancedPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientBasicPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientCibaParUmaPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEncryptionSigningPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientLogoutPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientScriptPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientShowScopes.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientShowSpontaneousScopes.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientSoftwarePanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientTokensPanel.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientWizardForm.js (0 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/SectionErrorFallback.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/plugin-metadata.js (2 hunks)
💤 Files with no reviewable changes (22)
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokens.js
  • admin-ui/plugins/auth-server/components/Clients/ClientCibaParUmaPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientAdvancedPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientTokensPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientWizardForm.js
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.js
  • admin-ui/plugins/auth-server/components/Clients/ClientShowSpontaneousScopes.js
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js
  • admin-ui/plugins/auth-server/tests/components/ClientWizardForm.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientActiveTokenDetailPage.js
  • admin-ui/plugins/auth-server/tests/components/ClientDetailPage.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientBasicPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientSoftwarePanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientEncryptionSigningPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.js
  • admin-ui/plugins/auth-server/tests/components/ClientListPage.test.js
  • admin-ui/plugins/auth-server/tests/components/ClientAddPage.test.js
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.js
  • admin-ui/plugins/auth-server/components/Clients/ClientScriptPanel.js
  • admin-ui/plugins/auth-server/components/Clients/ClientShowScopes.js
  • admin-ui/plugins/auth-server/components/Clients/ClientLogoutPanel.js
  • admin-ui/plugins/auth-server/tests/components/ClientEditPage.test.js
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-11-26T12:25:34.923Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2475
File: admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js:111-216
Timestamp: 2025-11-26T12:25:34.923Z
Learning: In the admin-ui codebase, avoid suggesting comments for small functionalities or straightforward layout decisions in smaller components. Comments should be reserved for more complex or non-obvious logic.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx
📚 Learning: 2025-12-05T18:24:41.713Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.713Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientAddPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/SectionErrorFallback.tsx
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts
🧬 Code graph analysis (22)
admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (5)
  • useClientList (15-29)
  • useClientById (31-51)
  • useCreateClient (53-84)
  • useUpdateClient (86-117)
  • useDeleteClient (119-146)
admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/auth-server/plugin-metadata.js (1)
admin-ui/app/utils/PermChecker.ts (1)
  • CLIENT_READ (11-11)
admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (3)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-98)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1)
  • useClientById (31-51)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ClientScope (37-43)
admin-ui/plugins/auth-server/components/Clients/ClientAddPage.tsx (6)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-98)
admin-ui/app/utils/ApiUtils.ts (1)
  • handleSuccess (51-53)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • handleSubmit (115-128)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Configuration/JsonPropertyBuilder.js (1)
  • result (9-9)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • RootState (138-140)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ExtendedClient (31-35)
  • ModifiedFields (57-59)
admin-ui/app/utils/AuditLogger.ts (1)
  • logAuditUserAction (25-66)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • CLIENT_ROUTES (128-133)
admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • BACKCHANNEL_TOKEN_DELIVERY_MODES (41-45)
admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/services/Components/Configuration/PersistenceDetail.js (1)
  • labelStyle (37-39)
admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • Client (17-17)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • formatScopeDisplay (102-109)
  • formatGrantTypeLabel (111-125)
  • formatResponseTypeLabel (127-134)
admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • filterScriptsByType (145-155)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SCRIPT_TYPES (94-116)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (4)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (18)
  • buildClientInitialValues (4-16)
  • buildClientPayload (18-82)
  • hasFormChanges (84-89)
  • formatScopeDisplay (102-109)
  • formatGrantTypeLabel (111-125)
  • formatResponseTypeLabel (127-134)
  • extractInumFromDn (136-139)
  • buildScopeDn (141-143)
  • filterScriptsByType (145-155)
  • getScriptNameFromDn (157-163)
  • formatDateForDisplay (165-173)
  • formatDateForInput (175-183)
  • isValidUrl (185-192)
  • isValidUri (194-198)
  • truncateText (220-223)
  • sortByName (225-227)
  • removeDuplicates (229-231)
  • arrayEquals (233-238)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • EMPTY_CLIENT (102-201)
admin-ui/plugins/admin/helper/utils.js (1)
  • current (82-82)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • isValidUri (3-18)
admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (3)
  • SECRET_GENERATION (176-179)
  • APPLICATION_TYPES (20-23)
  • SUBJECT_TYPES (25-28)
admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (3)
  • ClientFormProps (22-31)
  • ClientSection (6-16)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • buildClientInitialValues (4-16)
  • buildClientPayload (18-82)
  • downloadClientAsJson (200-214)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SECTIONS (146-157)
admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/app/utils/Util.ts (1)
  • formatDate (53-64)
admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1)
admin-ui/app/utils/Util.ts (1)
  • formatDate (53-64)
admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (4)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ClientListOptions (53-55)
  • Client (17-17)
admin-ui/app/utils/ApiUtils.ts (2)
  • handleSuccess (51-53)
  • handleError (42-49)
admin-ui/plugins/admin/redux/sagas/WebhookSaga.ts (1)
  • triggerWebhook (279-368)
admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js (1)
  • errorMessage (100-100)
admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (63-72)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ClientScope (37-43)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatScopeDisplay (102-109)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (2)
  • GRANT_TYPES (1-12)
  • RESPONSE_TYPES (14-18)
admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (5)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-98)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (2)
  • useClientById (31-51)
  • useUpdateClient (86-117)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ClientScope (37-43)
  • ModifiedFields (57-59)
admin-ui/app/utils/ApiUtils.ts (1)
  • handleSuccess (51-53)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (2)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • isValidUri (194-198)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • schema (58-58)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (2)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (3)
  • ExtendedClient (31-35)
  • EMPTY_CLIENT (102-201)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
🪛 Biome (2.1.2)
admin-ui/app/locales/en/translation.json

[error] 358-358: The key logout_status_jwt_signed_response_alg was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1095-1095: The key id_token was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1096-1096: The key access_token was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1097-1097: The key userinfo was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1098-1098: The key request_object was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1099-1099: The key introspection was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1100-1100: The key jarm was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1101-1101: The key token_endpoint_auth was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)

admin-ui/plugins/auth-server/components/Clients/helper/validations.ts

[error] 38-38: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 62-62: Do not add then to an object.

(lint/suspicious/noThenProperty)

admin-ui/app/locales/pt/translation.json

[error] 1027-1027: The key jarm was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1028-1028: The key token_endpoint_auth was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-ui/app/locales/fr/translation.json (1)

123-177: Add French translation for actions.generate_secret to match new UI

BasicInfoSection.tsx uses t('actions.generate_secret') for the “Generate Secret” button, but this key is missing in the French actions block, so users will see the fallback language.

Consider adding:

   "copy_to_clipboard": "Copier dans le presse-papier",
-  "refresh": "Actualiser"
+  "refresh": "Actualiser",
+  "generate_secret": "Générer un secret"

to keep the UX consistent for French users.

admin-ui/app/locales/en/translation.json (1)

452-457: Remove duplicate fields.spontaneous_scopes entry

spontaneous_scopes is defined twice in the fields object (once near the existing spontaneous scope settings and again in the new OIDC-related block). Only the last value will be used, and Biome will flag this as noDuplicateObjectKeys.

Recommend keeping a single definition, for example by removing the newer one in the added block:

-    "spontaneous_scope_scripts": "Spontaneous Scope Scripts",
-    "spontaneous_scopes": "Spontaneous Scopes",
+    "spontaneous_scope_scripts": "Spontaneous Scope Scripts",

(or vice versa, but ensure exactly one spontaneous_scopes key remains in fields).

Also applies to: 694-695

♻️ Duplicate comments (17)
admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (2)

57-70: Localize Yup validation messages via t instead of hardcoded English.

The schema uses literal English strings, so error messages won’t be localized. Consider turning validationSchema into a factory that receives t and uses translation keys for all messages, then pass validationSchema(t) into Formik.


115-119: Defensively handle missing navigator.clipboard support.

navigator.clipboard.writeText is accessed directly; in environments without the Clipboard API this will throw before .catch runs. Guard for navigator.clipboard?.writeText (and optionally provide a no-op or legacy fallback) so the handler is safe across environments.

admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (1)

16-49: Consider explicit “client not found” UX when id is present.

When an id exists but client resolves to undefined and loading is false, the loader renders no content. You may want to render a small translated “client not found” message (and perhaps a back-to-list action) in that case to avoid a blank page. SetTitle usage at the top level looks correct.

admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1)

190-221: Preserve ttl value 0 instead of coercing it to empty string.

value={formik.values.ttl || ''} will render a valid ttl of 0 as '', breaking the visual distinction between “0” and “unset”. Prefer nullish coalescing so zero is preserved:

-              value={formik.values.ttl || ''}
+              value={formik.values.ttl ?? ''}

The updated parseInt(e.target.value, 10) looks good.

admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1)

77-79: Consider redirecting when client ID is missing.

Returning null when id is missing provides no user feedback. Consider redirecting to the client list instead.

  if (!id) {
+   navigateToClientList()
    return null
  }
admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (1)

99-135: Optional: Consider consolidating script filtering.

The 10 individual useMemo calls for filtering scripts by type work correctly but add visual noise. Consolidating into a single memoized object would improve readability while maintaining the same dependency handling.

const filteredScripts = useMemo(() => ({
  postAuthn: filterScriptsByType(scripts, SCRIPT_TYPES.POST_AUTHN),
  spontaneousScope: filterScriptsByType(scripts, SCRIPT_TYPES.SPONTANEOUS_SCOPE),
  consent: filterScriptsByType(scripts, SCRIPT_TYPES.CONSENT_GATHERING),
  introspection: filterScriptsByType(scripts, SCRIPT_TYPES.INTROSPECTION),
  ropc: filterScriptsByType(scripts, SCRIPT_TYPES.RESOURCE_OWNER_PASSWORD_CREDENTIALS),
  updateToken: filterScriptsByType(scripts, SCRIPT_TYPES.UPDATE_TOKEN),
  rptClaims: filterScriptsByType(scripts, SCRIPT_TYPES.UMA_RPT_CLAIMS),
  tokenExchange: filterScriptsByType(scripts, SCRIPT_TYPES.TOKEN_EXCHANGE),
  par: filterScriptsByType(scripts, SCRIPT_TYPES.PAR),
  logoutStatusJwt: filterScriptsByType(scripts, SCRIPT_TYPES.LOGOUT_STATUS_JWT),
}), [scripts])
admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1)

102-107: Guard localStorage access to avoid runtime errors in restricted/SSR contexts

localStorage.getItem and setItem can throw (e.g., disabled storage, SSR). Wrap both in try/catch (and optionally gate on typeof window !== 'undefined') so the form still renders and toggles even when storage is unavailable.

-  const [navCollapsed, setNavCollapsed] = useState(() => {
-    const stored = localStorage.getItem(NAV_COLLAPSED_KEY)
-    return stored === 'true'
-  })
+  const [navCollapsed, setNavCollapsed] = useState(() => {
+    try {
+      const stored = typeof window !== 'undefined'
+        ? window.localStorage.getItem(NAV_COLLAPSED_KEY)
+        : null
+      return stored === 'true'
+    } catch {
+      return false
+    }
+  })
@@
   const handleNavCollapse = useCallback(() => {
     setNavCollapsed((prev) => {
       const newValue = !prev
-      localStorage.setItem(NAV_COLLAPSED_KEY, String(newValue))
+      try {
+        if (typeof window !== 'undefined') {
+          window.localStorage.setItem(NAV_COLLAPSED_KEY, String(newValue))
+        }
+      } catch {
+        // ignore storage errors, keep in‑memory state
+      }
       return newValue
     })
   }, [])

Also applies to: 175-181

admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (1)

66-72: Avoid saving empty scope identifiers when dn/inum are missing

handleScopeChange maps scopes to s.dn || s.inum || '', so any scope without dn/inum becomes an empty string in the persisted value, which can be ambiguous or invalid. You already consider id elsewhere; reuse it here and drop empties.

-  const handleScopeChange = useCallback(
-    (newScopes: ClientScope[]) => {
-      const scopeValues = newScopes.map((s) => s.dn || s.inum || '')
-      handleFieldChange('scopes', t('fields.scopes'), scopeValues)
-    },
-    [handleFieldChange, t],
-  )
+  const handleScopeChange = useCallback(
+    (newScopes: ClientScope[]) => {
+      const scopeValues = newScopes
+        .map((s) => s.dn || s.inum || s.id || '')
+        .filter(Boolean)
+      handleFieldChange('scopes', t('fields.scopes'), scopeValues)
+    },
+    [handleFieldChange, t],
+  )
admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (3)

89-96: Reuse shared date formatting utility instead of local formatDate

There is now a shared formatDateTime helper in ../helper/utils. Re-implementing a local formatDate here duplicates logic and still won’t handle invalid dates as robustly as the shared helper.

Consider removing formatDate and using formatDateTime for formattedCreationDate / formattedExpirationDate to keep behavior consistent across views.

-  const formatDate = (dateString?: string): string => {
-    if (!dateString) return '--'
-    try {
-      return dayjs(dateString).format('YYYY/MM/DD HH:mm:ss')
-    } catch {
-      return dateString
-    }
-  }
+  // Prefer shared formatter for consistency
+  const formatDate = (dateString?: string): string =>
+    formatDateTime(dateString, '--')

98-115: Make date range filtering inclusive of boundary dates

The filter uses dayjs(dateField).isAfter(dateAfter) && isBefore(dateBefore), which excludes tokens whose date equals the selected start or end. Users typically expect inclusive ranges.

Switch to inclusive comparisons (either via isSameOrAfter / isSameOrBefore with the appropriate plugin, or by comparing timestamps manually), so tokens on the boundary dates are included.

-      const tokenDate = dayjs(dateField)
-      return tokenDate.isAfter(dateAfter) && tokenDate.isBefore(dateBefore)
+      const tokenDate = dayjs(dateField)
+      return (
+        (tokenDate.isAfter(dateAfter) || tokenDate.isSame(dateAfter, 'day')) &&
+        (tokenDate.isBefore(dateBefore) || tokenDate.isSame(dateBefore, 'day'))
+      )

424-433: Propagate revoke errors to MaterialTable instead of swallowing them

onRowDelete currently calls reject() without an error, so MaterialTable gets no context about what went wrong and can’t surface a meaningful message.

Pass through the actual error to reject so the table can handle/display it appropriately.

-                  onRowDelete: (oldData) =>
-                    new Promise<void>((resolve, reject) => {
-                      handleRevokeToken(oldData)
-                        .then(() => resolve())
-                        .catch(() => reject())
-                    }),
+                  onRowDelete: (oldData) =>
+                    new Promise<void>((resolve, reject) => {
+                      handleRevokeToken(oldData)
+                        .then(() => resolve())
+                        .catch((error) => reject(error))
+                    }),
admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1)

253-259: Optional: align handler choice for attributes.backchannelLogoutUri

Here you pass 'attributes.backchannelLogoutUri' into renderUriList, which delegates to handleFieldChange. This is functionally fine because Formik supports dotted paths, but other attribute fields in this file use handleAttributeChange.

For consistency and easier future maintenance, consider either:

  • switching this call to a variant that uses handleAttributeChange, or
  • documenting that renderUriList expects fully-qualified Formik paths (including for attributes).
admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1)

59-79: Clipboard handling improved; consider guarding API availability

The copy handlers are now async with proper success/error toasts, which resolves the unhandled Promise issue. One optional hardening step would be to guard against environments where navigator.clipboard is unavailable:

-    if (formik.values.inum) {
-      try {
-        await navigator.clipboard.writeText(formik.values.inum)
+    if (formik.values.inum && navigator.clipboard?.writeText) {
+      try {
+        await navigator.clipboard.writeText(formik.values.inum)
...
-    if (formik.values.clientSecret) {
-      try {
-        await navigator.clipboard.writeText(formik.values.clientSecret)
+    if (formik.values.clientSecret && navigator.clipboard?.writeText) {
+      try {
+        await navigator.clipboard.writeText(formik.values.clientSecret)

so you fail gracefully on older/locked-down environments instead of throwing before the try.

Also applies to: 137-189

admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (3)

157-169: Prefer queryKey over a custom predicate for invalidation.

Both handleDeleteSuccess and handleRefresh invalidate queries by inspecting query.queryKey[0], which is brittle if the key structure changes or if multiple variants share the same first element. React Query supports direct key-based invalidation.

You can simplify and harden this:

-  const handleDeleteSuccess = useCallback(
-    (_data: unknown, variables: { inum: string }) => {
+  const handleDeleteSuccess = useCallback(
+    (_data: unknown, variables: { inum: string }) => {
       dispatch(updateToast(true, 'success'))
-      queryClient.invalidateQueries({
-        predicate: (query) => {
-          const queryKey = query.queryKey[0] as string
-          return queryKey === getGetOauthOpenidClientsQueryKey()[0]
-        },
-      })
+      queryClient.invalidateQueries({
+        queryKey: getGetOauthOpenidClientsQueryKey(),
+      })
       dispatch(triggerWebhook({ createdFeatureValue: { inum: variables.inum } }))
     },
     [dispatch, queryClient],
   )
@@
-  const handleRefresh = useCallback((): void => {
+  const handleRefresh = useCallback((): void => {
     setStartIndex(0)
     setPageNumber(0)
-    queryClient.invalidateQueries({
-      predicate: (query) => {
-        const queryKey = query.queryKey[0] as string
-        return queryKey === getGetOauthOpenidClientsQueryKey()[0]
-      },
-    })
+    queryClient.invalidateQueries({
+      queryKey: getGetOauthOpenidClientsQueryKey(),
+    })
   }, [queryClient])

Also applies to: 323-332


453-471: Use a stable key for grant type chips instead of the array index.

Using index as the React key can cause reconciliation glitches if the grant types array changes order. The grant string itself is a good stable identifier.

-        {displayGrants.map((grant, index) => (
+        {displayGrants.map((grant) => (
           <Chip
-            key={index}
+            key={grant}
             label={formatGrantTypeLabel(grant)}
             size="small"
             sx={{ backgroundColor: '#fff3e0', fontSize: '0.7rem' }}
           />
         ))}

601-617: Debounce effect could avoid redundant setPattern calls and extra effect runs.

The debounce useEffect always calls setPattern(searchInput || null), then triggers another run when pattern changes, even if the value is unchanged. You can compute the new pattern once and update only when it really changes, and drop pattern from the deps to avoid re-triggering on that state.

-  useEffect(() => {
-    debounceTimerRef.current = setTimeout(() => {
-      setPattern(searchInput || null)
-      if (searchInput !== (pattern || '')) {
-        setPageNumber(0)
-        setStartIndex(0)
-      }
-      debounceTimerRef.current = null
-    }, 500)
+  useEffect(() => {
+    debounceTimerRef.current = setTimeout(() => {
+      const newPattern = searchInput || null
+      setPattern((prev) => prev === newPattern ? prev : newPattern)
+      if (newPattern !== pattern) {
+        setPageNumber(0)
+        setStartIndex(0)
+      }
+      debounceTimerRef.current = null
+    }, 500)
@@
-  }, [searchInput, pattern])
+  }, [searchInput])

You can also derive pattern for the comparison from state via the setter callback if you want to avoid referencing it in the dependency array entirely.

admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)

165-170: hasFormChanges using JSON.stringify is order‑sensitive.

Comparing form values via JSON.stringify will treat changes in array ordering or key ordering as real changes and can be tripped by non‑primitive differences.

If you expect to ignore ordering or want structural comparison, consider a deep‑equality helper instead:

-import function hasFormChanges(
-  currentValues: ClientFormValues,
-  initialValues: ClientFormValues,
-): boolean {
-  return JSON.stringify(currentValues) !== JSON.stringify(initialValues)
-}
+import isEqual from 'lodash/isEqual' // or a local deepEqual utility
+
+export function hasFormChanges(
+  currentValues: ClientFormValues,
+  initialValues: ClientFormValues,
+): boolean {
+  return !isEqual(currentValues, initialValues)
+}

If ordering differences should count as a change, adding a brief comment documenting that assumption would help future maintainers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e4bef07 and 2cfc58c.

📒 Files selected for processing (29)
  • admin-ui/app/locales/en/translation.json (16 hunks)
  • admin-ui/app/locales/es/translation.json (14 hunks)
  • admin-ui/app/locales/fr/translation.json (11 hunks)
  • admin-ui/app/locales/pt/translation.json (12 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientListPage.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts
  • admin-ui/plugins/auth-server/components/Clients/sections/ActiveTokensSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx
📚 Learning: 2025-12-05T18:24:41.713Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.713Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts
📚 Learning: 2025-11-26T12:25:34.923Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2475
File: admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js:111-216
Timestamp: 2025-11-26T12:25:34.923Z
Learning: In the admin-ui codebase, avoid suggesting comments for small functionalities or straightforward layout decisions in smaller components. Comments should be reserved for more complex or non-obvious logic.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx
🧬 Code graph analysis (17)
admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (4)
  • ClientFormProps (33-42)
  • ClientSection (6-16)
  • ClientFormValues (18-20)
  • SectionProps (74-84)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • buildClientInitialValues (85-97)
  • buildClientPayload (99-163)
  • downloadClientAsJson (297-311)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SECTIONS (146-157)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • clientValidationSchema (30-66)
admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (6)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (2)
  • ClientFormValues (18-20)
  • AddFormValues (22-31)
admin-ui/plugins/auth-server/components/AuthN/AuthNForm.js (1)
  • initialValues (21-42)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • uriValidation (20-24)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (3)
  • DEFAULT_SCOPE_SEARCH_LIMIT (136-136)
  • SECRET_GENERATION (176-179)
  • GRANT_TYPES (1-12)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • transformScopesResponse (18-28)
  • buildAddFormPayload (34-83)
  • buildClientPayload (99-163)
admin-ui/app/components/Card/Card.tsx (1)
  • Card (27-27)
admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (6)
  • useClientList (52-66)
  • useClientById (68-88)
  • useCreateClient (90-112)
  • useUpdateClient (114-136)
  • useDeleteClient (138-161)
  • useInvalidateClientQueries (163-171)
admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (5)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-110)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (2)
  • useClientById (68-88)
  • useUpdateClient (114-136)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • transformScopesResponse (18-28)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (74-84)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (74-84)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (3)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-110)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1)
  • useClientById (68-88)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • transformScopesResponse (18-28)
admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatDateTime (256-265)
admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (1)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • formatScopeDisplay (183-190)
  • formatGrantTypeLabel (192-206)
  • formatResponseTypeLabel (208-215)
admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (74-84)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • filterScriptsByType (226-236)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SCRIPT_TYPES (94-116)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (74-84)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatDateTime (256-265)
admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ClientTableRow (61-65)
  • Client (17-17)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-110)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • DEFAULT_PAGE_SIZE (135-135)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (2)
  • formatGrantTypeLabel (192-206)
  • truncateText (317-320)
admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (2)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (21)
  • transformScopesResponse (18-28)
  • buildAddFormPayload (34-83)
  • buildClientInitialValues (85-97)
  • buildClientPayload (99-163)
  • hasFormChanges (165-170)
  • formatScopeDisplay (183-190)
  • formatGrantTypeLabel (192-206)
  • formatResponseTypeLabel (208-215)
  • extractInumFromDn (217-220)
  • buildScopeDn (222-224)
  • filterScriptsByType (226-236)
  • getScriptNameFromDn (238-244)
  • formatDateForDisplay (246-254)
  • formatDateTime (256-265)
  • formatDateForInput (267-275)
  • isValidUrl (277-284)
  • hasValidUriScheme (291-295)
  • truncateText (317-320)
  • sortByName (322-324)
  • removeDuplicates (326-328)
  • arrayEquals (330-335)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • EMPTY_CLIENT (102-201)
admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (74-84)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ClientScope (37-43)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatScopeDisplay (183-190)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (2)
  • GRANT_TYPES (1-12)
  • RESPONSE_TYPES (14-18)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (3)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • Client (17-17)
  • ClientListOptions (53-55)
admin-ui/app/utils/ApiUtils.ts (2)
  • handleSuccess (51-53)
  • handleError (42-49)
admin-ui/plugins/admin/redux/sagas/WebhookSaga.ts (1)
  • triggerWebhook (279-368)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (4)
  • ExtendedClient (31-35)
  • ModifiedFields (57-59)
  • ClientScope (37-43)
  • ClientScript (45-51)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (2)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (3)
  • ExtendedClient (31-35)
  • EMPTY_CLIENT (102-201)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (2)
  • AddFormValues (22-31)
  • ClientFormValues (18-20)
🪛 Biome (2.1.2)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts

[error] 38-38: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 62-62: Do not add then to an object.

(lint/suspicious/noThenProperty)

admin-ui/app/locales/pt/translation.json

[error] 1052-1052: The key introspection was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1053-1053: The key jarm was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)

🔇 Additional comments (29)
admin-ui/plugins/auth-server/__tests__/components/Clients/utils.test.ts (1)

26-427: Comprehensive and well-aligned utils test coverage.

This suite exercises the major helpers (transformers, payload builders, formatters, comparisons) with realistic cases and edge conditions; it’s a solid fit for the current implementations.

admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1)

16-50: Good abstraction of shared mutation success/error handling.

createMutationHandlers cleanly centralizes toast updates, query invalidation, and optional webhook triggering, reducing duplication between create/update/delete while keeping behavior consistent.

admin-ui/plugins/auth-server/__tests__/components/Clients/ClientListPage.test.tsx (1)

92-221: ClientListPage tests now exercise real UI behavior.

The suite renders ClientListPage with realistic mocks and checks list contents, loading/empty states, navigation to the add page, search, and refresh controls, which is a meaningful improvement over testing only the mocked hook.

admin-ui/plugins/auth-server/__tests__/components/Clients/useClientApi.test.tsx (1)

106-287: Strong coverage of client API hooks and mutation handlers.

These tests verify list/detail selection, that mutations are exposed, and that success/error handlers dispatch toasts, invalidate the correct query key, and invoke callbacks. The added useInvalidateClientQueries tests neatly close the gap in hook coverage.

admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1)

97-244: ClientForm tests provide meaningful behavioral coverage.

The tests now mount ClientForm in a realistic context and verify rendering, basic interactions (cancel, edit, save visibility), and section navigation, which gives solid confidence in the form wiring.

admin-ui/plugins/auth-server/components/Clients/components/ClientDetailView.tsx (2)

1-60: LGTM! Past review feedback addressed.

The clipboard operations now properly handle Promise rejections with .then()/.catch() chains (lines 29-45), and the getScopeNames function has been converted to a memoized scopeNames value (lines 47-60). Both improvements from previous reviews have been implemented correctly.


154-165: Conditional rendering may hide description when both exist.

The conditional at lines 155-165 shows either description or subjectType, never both. If both fields have values, only description is displayed. Verify this is intentional UX behavior, as users might expect to see both fields when available.

admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (3)

9-50: Good extraction of AlgorithmSelect helper component.

The reusable AlgorithmSelect component addresses the previous review feedback about extracting repeated select field patterns. This improves maintainability and reduces duplication throughout the 9 configuration sections.


121-143: LGTM! Algorithm options are appropriately memoized.

The separate useMemo calls for different algorithm types are justified since they derive from different OIDC configuration properties. The accessTokenSigningAlgs correctly falls back to signingAlgorithms when the specific configuration is unavailable.


450-510: LGTM! Consistent pattern for nested attributes.

The introspection, JARM, TX Token, and logout sections correctly use handleAttributeChange for nested attributes.* fields, while top-level fields use handleFieldChange. This maintains a clear distinction between field types throughout the component.

admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (2)

98-110: Good! JSON validation feedback now implemented.

The handleEditorChange function now tracks parse errors via jsonErrors state (line 106), and the UI displays appropriate error feedback (lines 144-148). This addresses the previous review concern about silent error handling.


165-200: LGTM! Clean structure for localized string editors.

The component renders five JSON editors with consistent patterns for client name, logo URI, client URI, policy URI, and TOS URI localization. The renderJsonEditor helper keeps the code DRY while maintaining proper dependency tracking.

admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (2)

39-42: **Good! Scope transformation extracted to shared utility.**The scope transformation now uses the shared transformScopesResponse utility from helper/utils.ts (line 40), addressing the previous review feedback about duplicate code between ClientEditPage and ClientDetailPage.


73-75: LGTM! Simple boolean and correct hook usage.

isLoading is now a simple computed boolean (line 73) instead of unnecessary useMemo, and SetTitle is correctly called at the component's top level (line 75) as per the codebase conventions.

admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (2)

158-168: Good! Proper key usage in renderTags.

The script selector's renderTags correctly uses option.dn as the key (line 162), which is stable and unique for script options. This is better than using array indices.


317-327: Good! Key now uses string value instead of index.

The renderTags for spontaneous scopes correctly uses key={option} (line 321), which is more stable than array indices for freeSolo inputs where items can be dynamically added/removed. This addresses the previous review feedback.

admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)

17-77: Audit logging callbacks now handle failures appropriately

Wrapping logAuditUserAction in try/catch with contextual console.error logging avoids silent failures while keeping caller flows simple. The dependency arrays also look correct.

admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (2)

192-201: Align onSubmit typing with the ExtendedClient payload

handleCommitAccept builds an ExtendedClient via buildClientPayload but then casts it to ClientFormValues to satisfy onSubmit’s signature. This undermines type safety, since expirable is intentionally stripped from the payload.

Consider updating ClientFormProps so onSubmit accepts the actual payload type (e.g., ExtendedClient) instead of ClientFormValues, and drop the cast here.
[uggest_essential_refactor]

-    (message: string) => {
-      if (formValues) {
-        const payload = buildClientPayload(formValues)
-        onSubmit(payload as ClientFormValues, message, modifiedFields)
-      }
+    (message: string) => {
+      if (formValues) {
+        const payload = buildClientPayload(formValues)
+        onSubmit(payload, message, modifiedFields)
+      }

And in ClientFormProps (formTypes), adjust the callback type accordingly:

-  onSubmit: (values: ClientFormValues, message: string, modifiedFields: ModifiedFields) => void
+  onSubmit: (values: ExtendedClient, message: string, modifiedFields: ModifiedFields) => void

211-217: Remove unused buttonStyle memo

buttonStyle is defined but never used, which adds noise and suggests a missing refactor. Either apply it to the relevant buttons or remove the memo entirely.

-  const buttonStyle = useMemo(
-    () => ({
-      ...applicationStyle.buttonStyle,
-      mr: 1,
-    }),
-    [],
-  )

Likely an incorrect or invalid review comment.

admin-ui/plugins/auth-server/components/Clients/components/ActiveTokenDetailPanel.tsx (1)

1-114: Token detail panel implementation looks solid

This component cleanly reuses formatDateTime, fixes the deletable translation key usage, and adds a clear notice around potentially sensitive attributes. Layout and theming are consistent with the rest of the UI.

admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (1)

102-813: Token configuration section is consistent and type-safe

Numeric lifetimes parse with explicit radix, boolean flags and Autocomplete fields correctly feed handleFieldChange / handleAttributeChange, and viewOnly is applied uniformly. This section integrates cleanly with the shared SectionProps/modifiedFields pattern.

admin-ui/app/locales/fr/translation.json (1)

685-757: New OIDC client, token, and section translations look consistent

The added keys for client token fields, active-token messages, placeholders, titles, and the new sections block align well with the corresponding English keys and the new Clients UI sections. No structural or naming issues beyond the duplicate fields keys already noted.

Also applies to: 759-941, 1027-1033, 1035-1168

admin-ui/app/locales/en/translation.json (1)

65-69: New client/section translations and structure look correct

The added action labels, filtering/sorting fields, extensive OIDC client and token configuration fields, messages (copy-to-clipboard, token status, selection-empty hints), placeholders, titles, and the new sections object all line up logically with the new Clients TS components (BasicInfoSection, UrisSection, Tokens, etc.), and key names are consistent and readable.

Aside from the single duplicate spontaneous_scopes entry already noted, the JSON structure here looks clean.

Also applies to: 106-107, 136-137, 356-358, 467-467, 656-735, 828-909, 1108-1117, 1119-1274, 1263-1274

admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1)

17-152: UrisSection wiring and theming look solid

Form state updates, view-only handling, reusable URI list rendering, and theme-based styling are all implemented cleanly. The Autocomplete chips now use stable keys and should avoid reconciliation issues.

Also applies to: 154-438

admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1)

132-437: BasicInfoSection form wiring and theming look correct

Field updates, setModifiedFields tracking, switches, DateTimePicker integration, and the contacts Autocomplete (with stable chip keys) are all consistent and idiomatic. No further functional issues spotted.

admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1)

108-115: Page size initialization and localStorage handling look correct.

getInitialPageSize now safely parses paggingSize with radix 10 and a NaN fallback, which addresses previous robustness concerns. Consider also trimming the stored string if you ever expect whitespace, but current logic is sound.

admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)

68-83: Redirect URI runtime validation is consistent and supports custom schemes.

validateRedirectUri mirrors isValidUri semantics, including localhost exceptions and generic custom schemes. This looks appropriate for redirect URI fields that allow mobile/deeplink schemes.

admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)

18-42: Client form value and props modeling look solid.

ClientFormValues extending ExtendedClient with a required expirable, and ClientFormProps wiring in ModifiedFields and scope search props, gives a clear, type‑safe contract for the form and sections. No issues here.

admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)

34-83: Add‑client payload builder is consistent and well‑scoped.

buildAddFormPayload sensibly normalizes new‑client defaults (application type, auth method, booleans, arrays) and filters out empty redirect URIs. This aligns with EMPTY_CLIENT and keeps the API payload compact. Looks good.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-ui/app/locales/fr/translation.json (1)

756-835: Define messages.secret_generation_failed to match new error handling

BasicInfoSection.tsx uses t('messages.secret_generation_failed') as a fallback error message when client secret generation fails, but this key is not present in the French messages block.

Consider adding a localized message here, for example:

   "invalid_url_error": "URL invalide ou URL non autorisée.",
+  "secret_generation_failed": "Échec de la génération du secret client. Assurez-vous que la page est chargée via HTTPS.",
   "action_commit_question": "Journal d'audit : vous souhaitez appliquer les modifications apportées sur cette page ?",

Repeat for other locales to keep error handling consistent across languages.

admin-ui/app/locales/es/translation.json (1)

351-462: New OIDC client fields and logout JWT alg key look structurally correct; consider scope term consistency.

The added fields.logout_status_jwt_signed_response_alg and the new OIDC‑related field keys (access token, PAR/PKCE, JARM, localization, etc.) align with the new Clients UI and avoid duplicate keys in this object. One minor nit: fields.spontaneous_scopes now uses “Alcances Espontáneos” while nearby keys still use “Ámbitos espontáneos”; if you care about terminology consistency, consider standardizing on one term across fields (e.g., “Ámbitos”).

Also applies to: 648-719

♻️ Duplicate comments (7)
admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (3)

160-165: Query invalidation predicate is still fragile.

This was flagged in a previous review. The casting and index-based comparison will silently fail if the query key structure changes.

Consider using the simpler approach:

 queryClient.invalidateQueries({
-  predicate: (query) => {
-    const queryKey = query.queryKey[0] as string
-    return queryKey === getGetOauthOpenidClientsQueryKey()[0]
-  },
+  queryKey: getGetOauthOpenidClientsQueryKey(),
 })

466-474: Using index as key for grant type chips.

This was flagged in a previous review. Since grant types are unique strings, use the grant value as the key for stable reconciliation.

 {displayGrants.map((grant, index) => (
   <Chip
-    key={index}
+    key={grant}
     label={formatGrantTypeLabel(grant)}
     size="small"
     sx={{ backgroundColor: '#fff3e0', fontSize: '0.7rem' }}
   />
 ))}

607-623: Debounce effect may cause unnecessary state updates.

This was flagged in a previous review. The effect always calls setPattern even when the value hasn't changed, and including pattern in dependencies can cause re-triggering.

 useEffect(() => {
   debounceTimerRef.current = setTimeout(() => {
-    setPattern(searchInput || null)
-    if (searchInput !== (pattern || '')) {
+    const newPattern = searchInput || null
+    if (newPattern !== pattern) {
+      setPattern(newPattern)
       setPageNumber(0)
       setStartIndex(0)
     }
     debounceTimerRef.current = null
   }, 500)

   return () => {
     if (debounceTimerRef.current) {
       clearTimeout(debounceTimerRef.current)
       debounceTimerRef.current = null
     }
   }
-}, [searchInput, pattern])
+}, [searchInput]) // Remove pattern from deps to avoid re-triggering
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)

3-24: Consolidate isValidUri with the existing helper in utils.ts to avoid divergent behavior.

This implementation still duplicates the isValidUri in utils.ts with different empty-value semantics and validation rules. Please centralize URI validation into a single canonical helper (or clearly named pair, e.g., required vs optional) and import it here, so future changes don’t drift between the two versions.

admin-ui/app/locales/fr/translation.json (1)

1033-1151: Add missing titles.client_information and titles.permissions_and_endpoints for FR

ClientAddForm.tsx renders section titles via t('titles.client_information') and t('titles.permissions_and_endpoints'), but these keys are not present in this French locale file. That will cause fallbacks or visible key names for FR users.

Add them alongside the other client-related titles, e.g.:

   "client_basic": "De base",
+  "client_information": "Informations sur le client",
   "client_detail": "Détails du client",
   "saml_management": "SAML",
@@
   "client_encryption_signing": "Cryptage/Signature",
   "client_scripts": "Scripts clients",
@@
   "user_management": "Gestion des utilisateurs",
   "ssa_management": "SSA Gestion",
+  "permissions_and_endpoints": "Permissions et points de terminaison",
   "jans_ink": "Jans Link",

Make sure equivalent keys exist (and are translated) in the other non-English locales as well.

admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1)

62-75: Localize Yup validation messages instead of hardcoded English

The validationSchema currently uses literal English strings ('Client name is required', 'At least one valid redirect URI is required'), which breaks i18n and will not respect the active locale.

Refactor the schema to be built from the translation function and replace these literals with translation keys, for example:

-import * as Yup from 'yup'
+import * as Yup from 'yup'
+import type { TFunction } from 'i18next'

-const validationSchema = Yup.object().shape({
-  clientName: Yup.string().required('Client name is required'),
-  clientSecret: Yup.string().required('Client secret is required'),
+const validationSchema = (t: TFunction) =>
+  Yup.object().shape({
+    clientName: Yup.string().required(t('validations.field_required')),
+    clientSecret: Yup.string().required(t('validations.field_required')),
   description: Yup.string(),
   scopes: Yup.array().of(Yup.string()),
   grantTypes: Yup.array().of(Yup.string()),
   redirectUris: Yup.array()
     .of(uriValidation)
-    .test('has-valid-uri', 'At least one valid redirect URI is required', (value) => {
+    .test('has-valid-uri', t('validations.redirect_uri_required'), (value) => {
       if (!value || value.length === 0) return false
       return value.some((uri) => uri && uri.trim() !== '')
     }),
   postLogoutRedirectUris: Yup.array().of(uriValidation),
-})
+})

And pass the localized schema into Formik:

-        <Formik
-          initialValues={initialValues}
-          validationSchema={validationSchema}
+        <Formik
+          initialValues={initialValues}
+          validationSchema={validationSchema(t)}
           onSubmit={handleFormSubmit}

Adjust the exact translation keys to match your existing locale structure and ensure they are added for all supported languages.

admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)

134-134: Good: RootState is now re-exported from the central Redux types instead of being redefined.

Importing and re-exporting RootState from 'Redux/sagas/types/audit' resolves the earlier concern about a locally fabricated store type drifting from the real store shape. This keeps consumer components aligned with the canonical Redux typing.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2cfc58c and 48fcf39.

📒 Files selected for processing (12)
  • admin-ui/app/locales/en/translation.json (17 hunks)
  • admin-ui/app/locales/es/translation.json (16 hunks)
  • admin-ui/app/locales/fr/translation.json (12 hunks)
  • admin-ui/app/locales/pt/translation.json (13 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-03T08:47:33.943Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.943Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-26T12:25:34.923Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2475
File: admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js:111-216
Timestamp: 2025-11-26T12:25:34.923Z
Learning: In the admin-ui codebase, avoid suggesting comments for small functionalities or straightforward layout decisions in smaller components. Comments should be reserved for more complex or non-obvious logic.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx
🧬 Code graph analysis (5)
admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (2)
  • ClientFormValues (18-20)
  • AddFormValues (22-31)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • uriValidation (20-24)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (2)
  • DEFAULT_SCOPE_SEARCH_LIMIT (136-136)
  • GRANT_TYPES (1-12)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (4)
  • transformScopesResponse (19-29)
  • buildAddFormPayload (35-84)
  • buildClientPayload (100-167)
  • generateClientSecret (330-339)
admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (74-84)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • generateClientSecret (330-339)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (2)
  • APPLICATION_TYPES (20-23)
  • SUBJECT_TYPES (25-28)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (4)
  • ExtendedClient (31-35)
  • ModifiedFields (57-59)
  • ClientScope (37-43)
  • ClientScript (45-51)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • schema (58-58)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (3)
  • ExtendedClient (31-35)
  • EMPTY_CLIENT (102-201)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (2)
  • AddFormValues (22-31)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SECRET_GENERATION (176-179)
🔇 Additional comments (36)
admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (5)

1-55: LGTM!

Imports are well-organized and the style constants are properly extracted with as const for type safety.


108-113: LGTM!

The parseInt now includes radix 10 and handles NaN gracefully with a fallback to DEFAULT_PAGE_SIZE.


286-306: LGTM!

The navigate logic now properly preserves other query parameters while selectively removing only scopeInum. This addresses the previous review feedback.


625-750: LGTM!

The render logic is well-structured with:

  • Proper permission gating via GluuViewWrapper
  • Conditional rendering of delete modal based on permissions and selection
  • ARIA labels on interactive elements for accessibility
  • Theme-aware styling throughout

601-601: SetTitle called in render body.

Side-effectful operations like setting the document title should be in a useEffect to comply with React's render purity guidelines.

-SetTitle(t('titles.openid_connect_clients'))
+useEffect(() => {
+  SetTitle(t('titles.openid_connect_clients'))
+}, [t])
⛔ Skipped due to learnings
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.713Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.
admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1)

87-165: JSON editor behavior and error handling look correct

handleEditorChange only pushes parsed JSON into Formik on successful JSON.parse and tracks per-field errors in jsonErrors, while renderJsonEditor surfaces both border color and helper text based on that state. Combined with getEditorValue and the borderColor refactor, this gives a clear, resilient UX for localized JSON editing.

admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1)

9-31: Reusable AlgorithmSelect and algorithm option derivation are clean and consistent

The SelectOption union plus AlgorithmSelect keep all these select fields DRY, and the memoized signingAlgorithms / encryptionAlgorithms / encryptionEncodings / accessTokenSigningAlgs correctly dedupe and fall back to sensible defaults from oidcConfiguration. The wiring of handleFieldChange vs handleAttributeChange looks coherent across all subsections.

Also applies to: 127-149, 151-645

admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1)

119-155: Payload building and commit dialog integration look sound

handleFormSubmit defers to the commit dialog, and handleCommitAccept correctly composes AddFormValuesClientFormValues via buildAddFormPayload and buildClientPayload, while computing modifiedFields using translated labels from fieldLabelMap. The operations array passed to GluuCommitDialog is filtered with the same non-empty criteria, keeping audit logs and payload generation aligned.

Also applies to: 205-212, 610-627

admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1)

45-96: Core basic-info behavior (copy, secret generation, status/expiration, contacts) is well wired

handleFieldChange consistently updates Formik and setModifiedFields with translated labels; the copy handlers wrap navigator.clipboard.writeText in async try/catch and surface success/error via toasts; handleGenerateSecret correctly uses the shared generateClientSecret helper with a guarded toast fallback; the active/trusted/expirable switches toggle the right booleans and conditionally show the ISO-based expirationDate picker; and the contacts Autocomplete uses stable chip keys and theme-aware styling. Overall this section integrates cleanly with the new client form model.

Also applies to: 136-213, 314-393, 397-438

admin-ui/app/locales/es/translation.json (6)

813-838: Messages for token attributes, section errors, and IdP creation are clear and consistent.

The new token_attributes_notice, generic section_error, and create_identity_provider strings integrate well with the existing tone and provide useful guidance without ambiguity.

Also applies to: 855-855


884-893: Client/token UX messages are comprehensive and align with the new Active Tokens/Details views.

Clipboard feedback, scripts truncation warning, token revoke/fetch errors, and the “no_*” helper messages for claims/grants/response types/scopes all match the expected flows in the new Clients detail and active‑tokens sections; keys and wording are coherent.

Also applies to: 920-927, 973-985


1092-1097: New placeholders for claims/emails/search/localized JSON are appropriately descriptive.

placeholders.more, add_claims, add_email, search_clients, search_scopes, and localized_json_format give clear hints for the new client UI controls and match the JSON formats used elsewhere.


1100-1140: Token/tabs titles cluster looks consistent and previous duplication issues appear resolved.

The added titles for actions, token/id/userinfo/request_object sections, client detail views, OpenID Connect client operations, and the various configuration sub‑tabs (scopes_and_grants, token_settings, acr_security, localization, etc.) line up with the new TS‑driven Clients pages. The earlier duplicate titles.* keys called out in past reviews are no longer present in this object, which should satisfy the linter.

Also applies to: 1206-1235


1242-1253: New top-level sections map matches the Clients UI sectioning.

The sections object mirrors the logical grouping used in the new client detail form (basic_info, authentication, scopes_and_grants, uris, tokens, ciba, scripts, localization, system_info, active_tokens) and should work cleanly as label sources for section configs.


2034-2034: Adding other.retry keeps generic action labels consistent across locales.

The new other.retry key matches usage in other languages and avoids overloading actions.retry when a neutral, non‑button label is needed.

admin-ui/app/locales/pt/translation.json (7)

335-338: Fields additions align with new UI and clean up earlier duplicate-key problems.

The new fields.section, fields.sort_order, and fields.page_size entries, plus the extended OIDC/tokens block (access_token_as_jwt, PAR/PKCE, JARM, localization, etc.), correctly reflect the new Clients/Active Tokens UI. Importantly, keys previously duplicated (logout_status_jwt_signed_response_alg, spontaneous_scopes) are now present only once under "fields", which should unblock JSON linters.

Also applies to: 572-581, 680-749


752-781: Token attributes notice, section error, and IdP creation messages are well phrased.

token_attributes_notice, section_error, and create_identity_provider are accurate and consistent with the rest of the Portuguese locale, giving administrators clear context about sensitive token data and section‑level failures.


820-839: Clipboard and client-token UX messages correctly support the new Active Tokens panel.

The “client_id/secret copied”, copy failure, scripts truncation, token revoked/error, and view_client texts are all appropriate for the revamped Clients detail/Active Tokens flows and should provide clear feedback to users.


921-933: Additional audit/tokens helper messages support better filtering and inspection.

The refined both_dates_required plus the new “no_*” and audit meta fields (dn, ttl, groups, client_id_issued_at, client_secret_expires_at, last_access_time, last_logon_time, registration_access_token) are consistent with the underlying data model and will make the clients/tokens pages more understandable.


1018-1023: Client/scopes search and localized JSON placeholders are clear.

placeholders.more, add_claims, add_email, and the search/localized_json_format hints are concise and match the patterns used in other locales, helping users understand expected input formats.


1026-1062: New titles for tokens, OpenID Connect client flows, and client details are coherent and duplicates are removed.

The token‑area titles (id_token, access_token, userinfo, request_object, introspection, jarm, token_endpoint_auth) and the expanded client‑UI titles (add/edit OpenID Connect client, scopes_and_grants, token_settings, acr_security, localization, etc.) fit the new TypeScript‑driven Clients pages. Earlier duplicate titles.introspection, titles.jarm, and titles.token_endpoint_auth mentioned in past reviews now appear only once, addressing the prior critical linter errors.

Also applies to: 1107-1145


1144-1157: delete_identity_provider title and new sections mapping line up with Clients/IdP detail layouts.

The updated titles.delete_identity_provider plus the new sections object (basic_info, authentication, scopes_and_grants, uris, tokens, ciba, scripts, localization, system_info, active_tokens) match the way the Clients and identity‑provider detail views are segmented in the UI, and provide a clean source for section labels.

admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)

1-121: Client form/tab/section typings are well-structured and map cleanly to the new UI.

The ClientTab/ClientSection unions, ClientFormValues/AddFormValues, and the various *TabProps/SectionProps interfaces form a coherent, strongly typed surface around ExtendedClient and Formik, which should make the new TypeScript-based Clients pages easier to maintain.

admin-ui/app/locales/en/translation.json (5)

65-69: Actions/fields additions for client UI look structurally sound

The new actions and fields entries (add_uri, save_changes, copy, generate_secret, filter_by, section, logout_uris, logout_status_jwt_signed_response_alg, sort_order) are well‑named, non‑duplicated within their objects, and match the domain. No structural JSON issues here.

Also applies to: 106-107, 136-137, 356-358, 467-467


656-733: Cedar/OIDC client policy field keys are consistent and non-duplicated

The large fields block under cedarlingPolicyStoreRetrievalPoint introduces many OIDC/token/PKCE/PAR‑related labels. Key naming is consistent (snake_case keys, human‑readable values), there are no duplicate keys within fields, and the semantics align with typical AS/OIDC config. Looks good.


827-907: New client/token messages improve UX clarity

The additions under messages (token attributes notice, section_error, identity provider/client copy feedback, token management messages, generic load error, and “no_* selected” texts) are clear, specific, and aligned with the new client management flows. No key collisions in messages.

Also applies to: 940-941, 989-992


1106-1114: Placeholders for search/localized JSON are precise and developer-friendly

New placeholders (search_clients, search_scopes, localized_json_format, etc.) are descriptive and accurately reflect expected input formats, which should help both users and implementers. Structure and keys are consistent with existing placeholders.


1117-1157: Titles/sections for OIDC client detail pages are well-organized

The new titles and sections entries for client details (basic_info, scopes_and_grants, token_settings, CIBA/UMA/PAR, localization, system_info, etc.) form a coherent navigation model and no duplicate keys remain in titles. This aligns well with the new TypeScript client pages.

Also applies to: 1221-1255, 1261-1272

admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (8)

86-98: buildClientInitialValues correctly merges defaults and derived expirable

Merging EMPTY_CLIENT with the incoming client and then shallow-merging attributes gives a safe, predictable initial form state, and deriving expirable from expirationDate is a clean UI-only flag. This is a solid pattern for initializing the form model.


100-167: Verify semantics for clearing customAttributes and empty localized fields

buildClientPayload has thoughtful normalization (string→boolean for accessTokenAsJwt/rptAsJwt, shallow copy of attributes, filtering out empty localized custom attributes, and dropping empty localized client*Localized fields). One subtle behavior to double‑check:

  • If the user removes all customAttributes in the UI, filteredCustomAttributes becomes empty and payload.customAttributes is left undefined. Depending on how the Config API interprets missing properties vs explicit [], this may leave old attributes unchanged instead of clearing them.

If the API expects an explicit empty array to clear attributes, you may need to set payload.customAttributes = [] when the original customAttributes array existed but all entries were filtered out.

Please confirm the backend semantics for omitted vs empty customAttributes and adjust accordingly if necessary.


250-281: Date formatting helpers handle invalid input robustly

formatDateForDisplay, formatDateTime, and formatDateForInput all guard against falsy/invalid dates and return sensible fallbacks ('' or the original string), which should prevent “Invalid Date” from leaking into the UI. The try/catch plus isNaN(date.getTime()) checks are appropriate here.


283-301: URL and URI-scheme validators are minimal and well-scoped

isValidUrl (using the URL constructor) and hasValidUriScheme (regex on the scheme prefix) provide clear, low-level primitives, and the doc comment correctly points callers to higher-level isValidUri when needed. Implementation matches the documented intent.


303-316: Sanitized JSON download filename resolves earlier filesystem-safety concern

Deriving rawName from displayName/clientName and normalizing via /[^a-zA-Z0-9._-]+/g before appending .json ensures the downloaded filename is safe across platforms while still human-readable. Blob creation and cleanup (URL.revokeObjectURL) are handled correctly.


330-339: Secure client secret generation with Web Crypto is appropriate

Using crypto.getRandomValues over a Uint8Array plus modulo over SECRET_GENERATION.CHARSET.length is a reasonable way to generate a high-entropy secret in modern browsers. The explicit guard and error message when crypto.getRandomValues is unavailable are helpful; just ensure callers surface that error cleanly in the UI.


341-359: Utility helpers (truncateText, sortByName, removeDuplicates, arrayEquals) are concise and fit their use-cases

The string truncation, name-based sorting, set-based deduplication, and order-insensitive arrayEquals (via sorted shallow copies) are all straightforward and suitable for the expected simple value arrays (scopes, grant types, etc.). No obvious edge cases for their current domain.


169-185: Import React types instead of relying on a global React namespace

trackFieldChange uses React.Dispatch<React.SetStateAction<ModifiedFields>>, but this file doesn't import the React type utilities. Depending on your TS config, this can cause "Cannot find namespace 'React'" type errors.

A type-only import keeps this explicit and tree-shake‑friendly:

import type {
  ExtendedClient,
  ClientFormValues,
  ModifiedFields,
  ClientScope,
  AddFormValues,
} from '../types'
+import type { Dispatch, SetStateAction } from 'react'

Then update the function signature:

export function trackFieldChange(
  fieldLabel: string,
  value: unknown,
-  setModifiedFields: React.Dispatch<React.SetStateAction<ModifiedFields>>,
+  setModifiedFields: Dispatch<SetStateAction<ModifiedFields>>,
 ): void {

This avoids reliance on ambient React types and is more robust across toolchains.

Copy link
Contributor

@duttarnab duttarnab left a comment

Choose a reason for hiding this comment

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

I don’t quite agree with the form layout used. Reason:

  1. Field labels are not visible.
  2. Moving the tabs to the left panel reduces space for fields and font size, making them harder to read and operate.
  3. I can see new tabs have been created by you. I think we need to get it approved from Mike as the existing tabs and underneath fields was designed by him.
    In my opinion we can make improvement in the existing layout with tabs placed on top horizontal bar.
Screenshot 2025-12-13 at 4 23 56 PM

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-ui/app/locales/es/translation.json (2)

847-847: Localize messages.additional_parameters_required.

"messages.additional_parameters_required" is still in English in the Spanish locale:

"additional_parameters_required": "Both key and value are required for each custom parameter.",

Translate this string to Spanish for consistency with the rest of the file.


813-895: Add Spanish translation for messages.secret_generation_failed.

BasicInfoSection uses t('messages.secret_generation_failed') when generateClientSecret fails, but this key is missing from the Spanish messages block. Add it here (mirroring the English meaning) so users see a localized error instead of the raw key.

Example:

"secret_generation_failed": "Error al generar el secreto del cliente. Verifique la configuración de seguridad."
♻️ Duplicate comments (11)
admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1)

48-50: Optional: handle missing id with navigation or an error state instead of returning null.

Returning null when id is absent yields a blank screen; consider redirecting to the client list or rendering an explicit error/“client not found” state so users get feedback.

admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (2)

150-162: Query invalidation uses fragile key comparison.

The predicate casts query.queryKey[0] to string and compares against the first element only. If the query key structure changes, this will silently fail. Consider using the full query key for more robust invalidation.

This was noted in a previous review as a nitpick. The current approach works but is fragile.


460-467: Using array index as key for grant type chips.

Since grant types are unique strings, use the grant value directly as the key for more stable React reconciliation.

         {displayGrants.map((grant, index) => (
           <Chip
-            key={index}
+            key={grant}
             label={formatGrantTypeLabel(grant)}
             size="small"
             sx={{ backgroundColor: '#fff3e0', fontSize: '0.7rem' }}
           />
         ))}
admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1)

213-213: TTL value of 0 is coerced to empty string.

Using || will convert a valid TTL of 0 to an empty string, breaking round-tripping. Use nullish coalescing (??) to preserve zero values.

-              value={formik.values.ttl || ''}
+              value={formik.values.ttl ?? ''}
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (1)

24-36: Consider adding "client not found" feedback.

When id is present but the query returns no matching client, the component renders nothing inside the loader. This may leave users confused when viewing a deleted or invalid client URL.

   return (
     <GluuLoader blocking={isLoading}>
-      {client && (
+      {!isLoading && !client ? (
+        <Box sx={{ p: 3, textAlign: 'center' }}>
+          <Typography>{t('messages.client_not_found')}</Typography>
+          <Button onClick={navigateToClientList} sx={{ mt: 2 }}>
+            {t('actions.back_to_list')}
+          </Button>
+        </Box>
+      ) : client ? (
         <ClientForm
           client={client}
           isEdit={true}
           viewOnly={true}
           onCancel={navigateToClientList}
           onSubmit={() => {}}
         />
-      )}
+      ) : null}
     </GluuLoader>
   )
admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1)

311-331: Duplicate submit button implementation.

The submit button appears twice with identical styling and logic (top and bottom of the form). This was noted in a previous review. Consider extracting to a shared variable to ensure consistency and reduce duplication.

Also applies to: 368-388

admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (1)

112-148: Consider consolidating script filtering into a single memoized object.

Ten individual useMemo calls for script filtering create visual noise. This was noted in a previous review.

const filteredScripts = useMemo(() => ({
  postAuthn: filterScriptsByType(scripts, SCRIPT_TYPES.POST_AUTHN),
  spontaneousScope: filterScriptsByType(scripts, SCRIPT_TYPES.SPONTANEOUS_SCOPE),
  consent: filterScriptsByType(scripts, SCRIPT_TYPES.CONSENT_GATHERING),
  introspection: filterScriptsByType(scripts, SCRIPT_TYPES.INTROSPECTION),
  ropc: filterScriptsByType(scripts, SCRIPT_TYPES.RESOURCE_OWNER_PASSWORD_CREDENTIALS),
  updateToken: filterScriptsByType(scripts, SCRIPT_TYPES.UPDATE_TOKEN),
  rptClaims: filterScriptsByType(scripts, SCRIPT_TYPES.UMA_RPT_CLAIMS),
  tokenExchange: filterScriptsByType(scripts, SCRIPT_TYPES.TOKEN_EXCHANGE),
  par: filterScriptsByType(scripts, SCRIPT_TYPES.PAR),
  logoutStatusJwt: filterScriptsByType(scripts, SCRIPT_TYPES.LOGOUT_STATUS_JWT),
}), [scripts])
admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1)

221-244: Silent failure when generating secret provides no user feedback.

When generateClientSecret() throws (e.g., in non-HTTPS contexts), the catch block silently swallows the error. Users have no indication why the generate button didn't work.

Consider showing a toast or error message:

   <Tooltip title={t('actions.generate_secret')}>
     <IconButton
       onClick={() => {
         try {
           const newSecret = generateClientSecret()
           formik.setFieldValue('clientSecret', newSecret)
           setShowSecret(true)
         } catch {
-          // Error generating secret - crypto API unavailable
-          // User should ensure HTTPS context
+          // Consider using a toast notification or setting an error state
+          console.warn('Failed to generate secret - secure context required')
         }
       }}
admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (1)

66-72: Include id and avoid empty strings when mapping scopes.

handleScopeChange currently maps each ClientScope to s.dn || s.inum || '', ignoring id and allowing empty strings into scopes. This can break lookups when only id is present and may persist invalid empty values.

Update to prefer dn, then inum, then id, and filter out falsy results:

-  const handleScopeChange = useCallback(
-    (newScopes: ClientScope[]) => {
-      const scopeValues = newScopes.map((s) => s.dn || s.inum || '')
-      handleFieldChange('scopes', t('fields.scopes'), scopeValues)
-    },
-    [handleFieldChange, t],
-  )
+  const handleScopeChange = useCallback(
+    (newScopes: ClientScope[]) => {
+      const scopeValues = newScopes
+        .map((s) => s.dn || s.inum || s.id || '')
+        .filter(Boolean)
+      handleFieldChange('scopes', t('fields.scopes'), scopeValues)
+    },
+    [handleFieldChange, t],
+  )
admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (1)

92-98: Remove incorrect fallback from CIBA backchannel signing algs.

backchannelSigningAlgs currently falls back to oidcConfiguration?.id_token_signing_alg_values_supported, which is semantically different from backchannel_authentication_request_signing_alg_values_supported and may expose unsupported algorithms for CIBA backchannel requests.

Use only the CIBA-specific discovery field and otherwise default to an empty array:

-  const backchannelSigningAlgs = useMemo(
-    () =>
-      (oidcConfiguration?.backchannel_authentication_request_signing_alg_values_supported as string[]) ||
-      (oidcConfiguration?.id_token_signing_alg_values_supported as string[]) ||
-      [],
-    [oidcConfiguration],
-  )
+  const backchannelSigningAlgs = useMemo(
+    () =>
+      (oidcConfiguration
+        ?.backchannel_authentication_request_signing_alg_values_supported as string[]) || [],
+    [oidcConfiguration],
+  )
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)

30-66: Fix Yup .when callback destructuring for grantTypes and expirable.

The functional .when overload for a single dependency passes the raw value, not an array. Using ([grantTypes], schema) and ([expirable], schema):

  • For redirectUris, destructuring the array as [grantTypes] extracts only the first element (a string), not the full grant types array. This breaks the logic: grants.includes('authorization_code') operates on a single grant string instead of the array, so the redirect URI requirement is not enforced correctly.
  • For expirationDate, destructuring a boolean as [expirable] throws a runtime error because booleans are not iterable. This prevents the expiration date from ever being validated.

Use the scalar form:

-  redirectUris: Yup.array()
-    .of(uriValidation)
-    .when('grantTypes', ([grantTypes], schema) => {
-      const grants = grantTypes || []
-      const needsRedirect = grants.includes('authorization_code') || grants.includes('implicit')
-      return needsRedirect
-        ? schema.min(
-            1,
-            'At least one redirect URI is required for authorization_code or implicit grants',
-          )
-        : schema
-    }),
+  redirectUris: Yup.array()
+    .of(uriValidation)
+    .when('grantTypes', (grantTypes: string[] = [], schema) => {
+      const needsRedirect =
+        grantTypes.includes('authorization_code') || grantTypes.includes('implicit')
+      return needsRedirect
+        ? schema.min(
+            1,
+            'At least one redirect URI is required for authorization_code or implicit grants',
+          )
+        : schema
+    }),
@@
-  expirationDate: Yup.string()
-    .nullable()
-    .when('expirable', ([expirable], schema) =>
-      expirable
-        ? schema.required('Expiration date is required when client is set to expire')
-        : schema,
-    ),
+  expirationDate: Yup.string()
+    .nullable()
+    .when('expirable', (expirable: boolean, schema) =>
+      expirable
+        ? schema.required('Expiration date is required when client is set to expire')
+        : schema,
+    ),

Optionally (non-blocking), consider tightening isValidUri to explicitly reject dangerous schemes like javascript: or data: even if new URL accepts them, if those should never be valid client redirect or logout URIs.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 370667f and ee474aa.

📒 Files selected for processing (28)
  • admin-ui/app/context/theme/config.ts (1 hunks)
  • admin-ui/app/helpers/navigation.ts (1 hunks)
  • admin-ui/app/locales/en/translation.json (17 hunks)
  • admin-ui/app/locales/es/translation.json (16 hunks)
  • admin-ui/app/locales/fr/translation.json (12 hunks)
  • admin-ui/app/locales/pt/translation.json (13 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useDebounce.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1 hunks)
  • admin-ui/plugins/auth-server/plugin-metadata.js (3 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
📚 Learning: 2025-11-26T12:25:34.923Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2475
File: admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js:111-216
Timestamp: 2025-11-26T12:25:34.923Z
Learning: In the admin-ui codebase, avoid suggesting comments for small functionalities or straightforward layout decisions in smaller components. Comments should be reserved for more complex or non-obvious logic.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-12-05T18:24:41.713Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.713Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/helper/validations.ts
📚 Learning: 2025-11-03T08:47:33.943Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.943Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
🧬 Code graph analysis (17)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (3)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • useClientScopes (10-10)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • DEFAULT_SCOPE_SEARCH_LIMIT (136-136)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • transformScopesResponse (19-29)
admin-ui/app/context/theme/config.ts (1)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (6)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (2)
  • ClientFormValues (18-20)
  • AddFormValues (22-31)
admin-ui/plugins/auth-server/components/AuthN/AuthNForm.js (1)
  • initialValues (21-42)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (1)
  • useClientScopes (6-40)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • buildAddFormPayload (31-42)
  • buildClientPayload (58-125)
  • generateClientSecret (288-297)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • clientAddValidationSchema (144-157)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • GRANT_TYPES (1-12)
admin-ui/plugins/auth-server/components/Clients/hooks/useDebounce.ts (1)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • useDebounce (12-12)
admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (71-81)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • usePageSize (11-11)
admin-ui/plugins/auth-server/components/Clients/sections/BasicInfoSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (71-81)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • generateClientSecret (288-297)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (2)
  • APPLICATION_TYPES (20-23)
  • SUBJECT_TYPES (25-28)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.tsx (2)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-110)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (1)
  • useClientById (68-88)
admin-ui/plugins/auth-server/components/Clients/sections/UrisSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (71-81)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/sections/CibaSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (71-81)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • BACKCHANNEL_TOKEN_DELIVERY_MODES (41-45)
admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (71-81)
admin-ui/plugins/services/Components/Configuration/PersistenceDetail.js (1)
  • labelStyle (37-39)
admin-ui/plugins/auth-server/plugin-metadata.js (1)
admin-ui/app/utils/PermChecker.ts (1)
  • CLIENT_READ (11-11)
admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (4)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-110)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientApi.ts (2)
  • useClientById (68-88)
  • useUpdateClient (114-136)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (71-81)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatDateTime (219-228)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/sections/ScopesGrantsSection.tsx (4)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (71-81)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ClientScope (37-43)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatScopeDisplay (145-152)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (2)
  • GRANT_TYPES (1-12)
  • RESPONSE_TYPES (14-18)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • schema (58-58)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (4)
  • ExtendedClient (31-35)
  • ModifiedFields (57-59)
  • ClientScope (37-43)
  • ClientScript (45-51)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: sonar scan (admin-ui)
🔇 Additional comments (28)
admin-ui/app/context/theme/config.ts (1)

3-16: Dark theme font color aligns with background and other dark variants.

Switching darkBlack.fontColor to customColors.white matches the dark background and existing menu text color; no issues detected.

admin-ui/plugins/auth-server/components/Clients/hooks/useDebounce.ts (1)

1-17: Debounce hook implementation is correct and idiomatic.

Generic typing, effect cleanup, and dependency list ([value, delay]) all look good.

admin-ui/plugins/auth-server/components/Clients/ClientEditPage.tsx (1)

12-44: Client edit flow, mutation, and audit logging are wired coherently.

  • useClientById(id || '', Boolean(id)) correctly guards the query when id is missing.
  • useUpdateClient(handleSuccess) handles success/error via shared mutation handlers; outer try/catch adds extra logging and audit‑log error toast.
  • SetTitle is invoked at the component’s top level, matching the project’s convention for that hook. Based on learnings, this is the expected usage.
  • Loading and form rendering (GluuLoader + ClientForm in edit mode) look consistent with the rest of the Clients UI.

No blocking issues identified here.

Also applies to: 52-65

admin-ui/app/locales/fr/translation.json (1)

368-371: FR client/tokens/localization keys look structurally consistent and de‑duplicated.

The new fields, messages, titles, and sections entries for client sections (paging, PAR/DPoP/CIBA, token lifetimes, spontaneous scopes, active tokens, etc.) are well‑grouped, and keys like logout_status_jwt_signed_response_alg and spontaneous_scopes now appear only once within fields, avoiding the earlier duplicate‑key problems.

Also applies to: 474-475, 567-569, 685-755, 780-781, 825-939, 1026-1032, 1034-1152, 1153-1164

admin-ui/app/locales/pt/translation.json (1)

335-339: PT translations for new client/tokens UI are consistent; duplicate‑key issues appear fixed.

The added fields, messages, placeholders, titles, and sections entries for client details, tokens, CIBA, localization, and active tokens match the new UI structure, and previously duplicated keys (logout_status_jwt_signed_response_alg, spontaneous_scopes, introspection, jarm, token_endpoint_auth) now each appear only once per object, which should keep JSON linters happy.

Also applies to: 486-486, 580-580, 680-749, 752-752, 771-782, 821-840, 922-934, 1019-1024, 1027-1146, 1147-1157

admin-ui/app/helpers/navigation.ts (1)

74-84: New client view route template is consistent with existing routing scheme.

AUTH_SERVER_CLIENT_VIEW_TEMPLATE follows the established pattern (/client/view/:id) alongside the edit template and keeps all auth‑server client routes centralized in ROUTES.

admin-ui/plugins/auth-server/plugin-metadata.js (1)

9-9: ClientDetailPage route wiring and permissions look correct.

The new route for ClientDetailPage uses the /client/view/:id template, is guarded by CLIENT_READ, and reuses the Clients resource key, which fits a read‑only detail view.

Also applies to: 171-176

admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)

1-12: Hooks barrel cleanly exposes all client-related hooks.

Re‑exporting useClientActions, API hooks, useClientScopes, usePageSize, and useDebounce from a single index simplifies imports for the Clients feature.

admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)

6-22: LGTM!

The hook correctly handles localStorage persistence with proper NaN fallback and uses useCallback for the setter. The as const return type ensures proper tuple typing.

admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1)

28-37: LGTM!

The handleFieldChange helper correctly updates both Formik state and the modified fields tracker in a single callback, maintaining consistency between form values and audit tracking.

admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1)

105-247: LGTM! Good test coverage for ClientForm.

The test suite now properly renders ClientForm and covers key scenarios including rendering, navigation, cancel/save buttons, view-only vs edit mode, field editing, and section navigation. The mock setup is comprehensive and follows good testing practices.

admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (2)

219-233: LGTM!

The client filtering logic correctly handles the scopeInumFilter case and properly renames the inner variable to scopes to avoid shadowing the outer clientScopes (Cedar resource scopes). The implementation is clean and efficient.


362-377: LGTM!

The deletion flow correctly handles the async audit logging with a fire-and-forget pattern, ensuring the modal closes promptly while still attempting to log the action. Errors in logging don't block the UI.

admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1)

102-114: JSON error handling looks good.

The error handling now properly tracks parse errors per field and displays appropriate feedback. The implementation correctly updates Formik only on valid JSON and maintains local editor state for invalid input.

admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1)

126-129: Good implementation of scripts truncation warning.

The scriptsTruncated calculation properly checks if totalEntriesCount exceeds the fetch limit, addressing the previous concern about missing scripts in selection.

admin-ui/plugins/auth-server/components/Clients/sections/ScriptsSection.tsx (2)

187-193: Scripts truncation warning is well implemented.

The conditional Alert properly warns users when the scripts list may be incomplete due to pagination limits.


150-185: Script selector implementation is clean and correct.

The renderScriptSelector properly handles multi-select with stable keys (option.dn), correct option comparison, and theme-aware chip styling.

admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (2)

84-96: Good use of translated field labels for audit consistency.

The fieldLabelMap properly maps form field keys to their translated labels, ensuring audit logs show human-readable field names.


291-337: Scopes autocomplete implementation is well-structured.

The component correctly handles scope search with the useClientScopes hook, displays loading state, and uses stable keys for chips.

admin-ui/plugins/auth-server/components/Clients/sections/AuthenticationSection.tsx (1)

140-162: AuthenticationSection wiring and algorithm derivations look consistent.

Signing/encryption algorithm options are correctly derived from oidcConfiguration, and all form fields (including nested attributes.*) use the shared change handlers consistently. No issues from a correctness or maintainability standpoint.

Also applies to: 164-658

admin-ui/app/locales/en/translation.json (7)

65-69: New client action labels are consistent and descriptive

refresh, add_uri, save_changes, copy, and generate_secret align with existing actions naming and will read clearly in the Clients UI. No issues spotted.


106-106: New generic field labels fit existing conventions

filter_by and section use clear, neutral wording and match the style of other field labels. They should integrate cleanly wherever they’re wired in.

Also applies to: 136-136


356-358: Logout and sort-related field labels look correct

logout_uris, logout_status_jwt_signed_response_alg, and sort_order accurately describe their purposes and match existing capitalization. Also confirms the earlier duplicate key for logout_status_jwt_signed_response_alg is now resolved and unique within fields.

Also applies to: 467-467


656-733: OIDC client metadata field keys are comprehensive and non-duplicated

The new fields.* entries (access token, PAR, JARM, TX token, ACR, logout status JWT, localized URIs, etc.) are:

  • Named consistently with underlying OIDC/OpenID client attributes.
  • Unique within the fields object (no duplicate keys).
  • Textually clear for admin users configuring advanced client options.

This gives good coverage for the new typed Clients pages without introducing JSON key conflicts.


827-870: New client/token-related messages are clear and user-focused

Clipboard, token, and client-view messages (client_id_copied, token_revoked, save_client_first, view_client, error_loading_data, and the various no_* selections) are concise and consistent with existing tone. They give concrete guidance for common error/empty states in the Clients UI.

Also applies to: 898-907, 919-919, 941-941, 990-993


1118-1125: New titles for Clients sections and advanced settings are coherent

Added titles.* entries (actions/id_token/access_token/userinfo, SP titles, client_detail/client_information, OpenID Connect client flows, section titles like basic_info, scopes_and_grants, token_settings, advanced_token, etc.) are:

  • Well grouped and clearly named.
  • Aligned with the domain vocabulary used in OIDC and Jans/Gluu docs.
  • Free of duplicate keys within titles.

They should cover the new Clients UI pages without conflicts with existing titles.

Also applies to: 1141-1142, 1157-1157, 1222-1256


1262-1273: Confirm mapping between sections i18n keys and ClientSection ids

The new sections.* keys (basic_info, scopes_and_grants, system_info, active_tokens, etc.) don’t match the raw ClientSection union values in admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts ('basic', 'scopes', 'system', 'activeTokens', etc.).

This is fine as long as you always use an explicit labelKey (e.g., via SectionConfig.labelKey = 'sections.basic_info') and never compute keys like t('sections.' + sectionId).

Please double‑check any code that does t('sections.' + something) or similar so it doesn’t rely on ClientSection ids directly matching these key names.

admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)

4-39: Client form and section typing aligns well with the new Clients UI

The unions and interfaces (ClientTab, ClientSection, ClientFormValues, AddFormValues, tab/section props, OidcConfiguration, UmaResourceForTab, and the RootState re-export) are:

  • Structurally consistent with the provided clientTypes (ExtendedClient, ClientScope, ClientScript, ModifiedFields).
  • Appropriately specific for the Clients forms (e.g., ClientFormValues making expirable required while keeping the base client flexible).
  • Well-factored between per-tab props and higher-level SectionProps/SectionConfig.

Once the React dispatch import issue is fixed, this file should give solid type safety for the new TS-based Clients pages.

Also applies to: 48-129, 131-131

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (4)
admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (3)

463-470: Consider using grant value as key instead of index.

While past reviews marked this as addressed, the current code still uses array index as the React key. Since grant types are unique strings, using key={grant} would be more stable and prevent potential reconciliation issues.

Apply this diff:

 {displayGrants.map((grant, index) => (
   <Chip
-    key={index}
+    key={grant}
     label={formatGrantTypeLabel(grant)}
     size="small"
     sx={{ backgroundColor: '#fff3e0', fontSize: '0.7rem' }}
   />
 ))}

713-715: Consider documenting the key remount workaround.

Using limit as the key forces MaterialTable to remount when page size changes. A brief comment explaining this intentional behavior would help future maintainers.

+{/* Force remount when page size changes to reset MaterialTable internal state */}
 <MaterialTable
   key={limit || 0}
   components={tableComponents}

154-158: Query invalidation predicate is fragile.

Comparing only the first element of queryKey as a string is brittle. If the query key structure changes (e.g., from ['clients'] to ['api', 'clients']), invalidation will silently fail.

Consider using the queryKey directly for more robust matching:

 queryClient.invalidateQueries({
-  predicate: (query) => {
-    const queryKey = query.queryKey[0] as string
-    return queryKey === getGetOauthOpenidClientsQueryKey()[0]
-  },
+  queryKey: getGetOauthOpenidClientsQueryKey(),
 })

Also applies to lines 324-329.

admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1)

315-335: Deduplicate the two identical submit buttons.

The primary submit button is rendered twice (top toolbar and bottom action bar) with effectively identical props and styling (Lines 315–335 and 372–391). This duplication makes future changes (label, disabled condition, styling) easy to miss in one location.

Consider extracting a shared SubmitButton helper/component or function to centralize the props:

const renderSubmitButton = (disabled: boolean) => (
  <Button
    type="submit"
    variant="contained"
    disabled={disabled}
    sx={{
      backgroundColor: themeColors?.background,
      color: 'white',
      '&:hover': { backgroundColor: themeColors?.background, opacity: 0.9 },
      '&:disabled': {
        backgroundColor: themeColors?.lightBackground,
        color: 'rgba(255, 255, 255, 0.7)',
      },
    }}
  >
    {isEdit ? t('actions.save') : t('actions.add')}
  </Button>
)

and then reuse it in both places with the same disabled expression.

Also applies to: 372-391

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee474aa and 77bfb39.

📒 Files selected for processing (10)
  • admin-ui/app/locales/en/translation.json (17 hunks)
  • admin-ui/app/locales/es/translation.json (16 hunks)
  • admin-ui/app/locales/fr/translation.json (12 hunks)
  • admin-ui/app/locales/pt/translation.json (13 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx (1 hunks)
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-03T08:47:33.943Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.943Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-26T12:25:34.923Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2475
File: admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js:111-216
Timestamp: 2025-11-26T12:25:34.923Z
Learning: In the admin-ui codebase, avoid suggesting comments for small functionalities or straightforward layout decisions in smaller components. Comments should be reserved for more complex or non-obvious logic.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx
🧬 Code graph analysis (4)
admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (6)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (2)
  • ClientFormProps (33-39)
  • ClientFormValues (18-20)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (1)
  • ModifiedFields (57-59)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (1)
  • useClientScopes (7-47)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • buildClientInitialValues (44-56)
  • buildClientPayload (58-125)
  • downloadClientAsJson (261-274)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SECTIONS (147-158)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • operations (54-54)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (3)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • DEFAULT_SCOPE_SEARCH_LIMIT (136-136)
admin-ui/plugins/auth-server/components/Clients/hooks/useDebounce.ts (1)
  • useDebounce (3-17)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • transformScopesResponse (19-29)
admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (8)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (2)
  • ClientTableRow (61-65)
  • Client (17-17)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientActions.ts (1)
  • useClientActions (10-110)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)
  • usePageSize (6-22)
admin-ui/plugins/auth-server/components/Clients/hooks/useDebounce.ts (1)
  • useDebounce (3-17)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • SCOPES_FETCH_LIMIT (137-137)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (2)
  • formatGrantTypeLabel (154-168)
  • truncateText (299-302)
admin-ui/app/components/index.tsx (2)
  • Badge (37-37)
  • CardBody (44-44)
admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (5)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (2)
  • ClientFormValues (18-20)
  • AddFormValues (22-31)
admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (1)
  • useClientScopes (7-47)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (3)
  • buildAddFormPayload (31-42)
  • buildClientPayload (58-125)
  • generateClientSecret (288-297)
admin-ui/plugins/auth-server/components/Clients/helper/validations.ts (1)
  • clientAddValidationSchema (144-157)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • GRANT_TYPES (1-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: sonar scan (admin-ui)
🔇 Additional comments (30)
admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx (1)

245-245: LGTM - Conditional spacing logic is correct.

The formatting adjustment properly handles the spacing for the validation message. When the input is empty, it displays "10 characters less than 10", and when partially filled (e.g., 5 characters), it displays "5 more characters less than 10". The conditional ensures the word "more" only appears when the user has already typed something, which provides clearer feedback.

admin-ui/plugins/auth-server/components/Clients/hooks/useClientScopes.ts (1)

1-47: LGTM! Well-structured hook implementation.

The hook properly encapsulates scope fetching with debouncing, exposes error state, and follows React hooks best practices. All past review comments have been addressed.

admin-ui/plugins/auth-server/components/Clients/ClientListPage.tsx (5)

605-612: LGTM! Debounce effect properly handles state updates.

The effect correctly checks if the new pattern differs before updating state, and includes all necessary dependencies to avoid stale closures.


86-147: LGTM! Clean state management and query setup.

The component properly manages pagination, search, and sorting state with appropriate memoization and debouncing.


362-377: LGTM! Proper error handling for deletion flow.

The handler correctly awaits the delete mutation, closes the modal on success, and handles logging failures gracefully without blocking the user flow.


278-298: LGTM! Proper query parameter handling.

Both filter-clearing handlers correctly preserve other query parameters while only removing the scopeInum parameter using URLSearchParams.


179-186: LGTM! Scope limit now uses a named constant.

The hardcoded limit has been replaced with SCOPES_FETCH_LIMIT constant, addressing the previous review concern.

admin-ui/plugins/auth-server/components/Clients/components/ClientAddForm.tsx (6)

1-43: LGTM! Clean imports and well-defined interface.

The component imports are properly organized, with no unused imports. The ClientAddFormProps interface clearly defines the component's API.


72-76: LGTM! Proper clipboard error handling.

The handler correctly handles clipboard API failures gracefully with a catch block, addressing the previous review concern.


220-243: LGTM! Secret generation properly extracted and error-handled.

The secret generation uses the shared utility generateClientSecret and properly handles potential crypto API failures with a try-catch block.


97-114: LGTM! Proper modifiedFields construction with translated labels.

The handler correctly uses fieldLabelMap to convert form field keys to user-facing translated labels for audit consistency, addressing the previous review concern.


167-170: LGTM! Validation schema properly imported.

The component uses the centralized clientAddValidationSchema from the validations module, which should handle i18n per previous review resolutions.


292-335: LGTM! Well-integrated scopes selection.

The Autocomplete component properly integrates with the useClientScopes hook, handles search debouncing, loading states, and uses stable keys for rendered chips.

admin-ui/app/locales/fr/translation.json (8)

368-371: New pagination/sorting field labels look structurally correct

fields.section and fields.sort_order are added once, with consistent naming and no key collisions in fields. JSON structure stays valid.


474-474: Previous duplicate-field issues appear resolved

fields.logout_status_jwt_signed_response_alg and fields.spontaneous_scopes now each have a single definition in fields, avoiding the earlier duplicate-key problem noted in past reviews. No new duplicates for these keys are present.

Also applies to: 567-567


685-754: Token / client metadata field additions are consistent and non‑conflicting

The new fields.* entries for token lifetimes, PAR/PKCE/JARM options, localization variants, and advanced auth settings use unique keys and follow existing snake_case naming patterns. I don’t see renames of existing keys or intra‑object duplicates.


757-757: New section and identity‑provider messages wired correctly

messages.token_attributes_notice, messages.section_error, and messages.create_identity_provider are added once and fit the surrounding naming scheme. No structural or key‑collision issues.

Also applies to: 780-780, 789-789


826-836: Client copy/token and list‑metadata messages look safe

Clipboard/copy, scripts truncation, token error/status, and audit list metadata messages are introduced with unique keys under messages. They don’t overlap with existing keys and align with usage patterns in other locales.

Also applies to: 844-844, 927-939


1026-1031: New placeholders support the new OIDC client UI without conflicts

Placeholders such as add_claims, add_email, search_clients, search_scopes, and localized_json_format are well‑named and unique in placeholders. No functional risk identified.


1034-1051: Titles for token / OIDC client subsections are coherent and non‑breaking

The added titles.* entries (actions, id_token, access_token, userinfo, request_object, introspection, jarm, token_endpoint_auth, create_sp/edit_sp, client_detail, delete_identity_provider) are new keys in this object and don’t shadow existing ones. Names match patterns used in other locales.


1151-1152: New sections block aligns with page layout expectations

The sections (basic_info, authentication, scopes_and_grants, uris, tokens, ciba, scripts, localization, system_info, active_tokens) mirror other locales and use unique keys at the top level. This should integrate cleanly with the TypeScript‑driven Clients pages.

Also applies to: 1153-1163

admin-ui/app/locales/es/translation.json (7)

351-352: Field‑level additions for logout status, spontaneous scopes, and sorting look clean

fields.logout_status_jwt_signed_response_alg, fields.spontaneous_scopes, fields.section, and fields.sort_order are each defined once in fields and don’t collide with existing keys. This also confirms the earlier duplicate‑key concern is resolved in this area.

Also applies to: 448-448, 459-459, 462-462


650-719: Expanded token/client configuration fields are structurally sound

The large batch of new fields.* entries (access_token_as_jwt, lifetimes, PAR/PKCE, logout scripts, localization variants, etc.) uses unique keys and consistent naming, matching patterns from other locales and TS models. I don’t see accidental renames of older keys inside fields.


813-813: New messages for sections, identity providers, client tokens, and audit metadata are well‑integrated

The added messages.* entries (token_attributes_notice, section_error, create_identity_provider, both_dates_required, copy/token operations, view_client, error_loading_data, and the various “no_*” plus DN/TTL/group/timestamps fields) are uniquely keyed and align with the rest of the messages namespace. No JSON or naming issues.

Also applies to: 838-838, 856-856, 867-867, 885-894, 906-906, 927-927, 974-985


1093-1098: Additional placeholders for claims/email/client/scope search and JSON format are consistent

New placeholders (more, add_claims, add_email, search_clients, search_scopes, localized_json_format) fit the existing pattern and introduce no naming conflicts.


1101-1108: Title block extensions for tokens and OIDC client views are coherent

The titles for token aspects (id_token, access_token, userinfo, request_object, introspection, jarm, token_endpoint_auth) and for OpenID Connect client flows (create/edit client, sections like scopes_and_grants, token_settings, security, advanced_token, etc.) are all unique within titles and mirror the UI structure without clashing with pre‑existing keys.

Also applies to: 1124-1125, 1140-1141, 1207-1236


1243-1254: New sections mapping matches the Clients page layout

The sections.* entries (basic_info, authentication, scopes_and_grants, uris, tokens, ciba, scripts, localization, system_info, active_tokens) form a clean, non‑duplicated block that should map directly to the new TS‑driven Clients pages.


2039-2039: other.retry message added without conflicts

other.retry is newly introduced but doesn’t duplicate any key in the other object; semantics match existing usages of “Retry” elsewhere.

admin-ui/app/locales/en/translation.json (1)

65-69: New OIDC client/metadata translations and sections look consistent; duplicate-key issues appear resolved

  • The newly added actions, fields (including logout_status_jwt_signed_response_alg and the extended OIDC/token metadata block), messages, placeholders, titles, and the sections container are internally consistent and clearly aligned with the new Clients (OIDC) UI.
  • Previously reported duplicate keys (logout_status_jwt_signed_response_alg, various titles.*) are no longer duplicated in this file; the new additions use unique keys and don’t reintroduce conflicts.
  • The updated placeholders.more value now avoids embedded leading whitespace, which is better for i18n composition, and the new placeholders/titles for client/section navigation line up with the TypeScript client concepts.

No blocking issues from this file; the additions are good to go.

Also applies to: 106-106, 136-136, 356-358, 467-467, 656-733, 827-827, 851-851, 869-869, 898-907, 919-919, 941-941, 990-993, 1107-1115, 1118-1125, 1141-1142, 1157-1157, 1222-1256, 1262-1273

admin-ui/app/locales/pt/translation.json (1)

335-338: Portuguese OIDC client/metadata translations are coherent; prior duplicate keys are fixed

  • The new fields entries (including section, sort_order, logout_status_jwt_signed_response_alg, and the extended OIDC/token metadata block) correctly mirror the EN keys and use natural PT phrasing; there are no remaining duplicate keys under fields.
  • New messages, placeholders, titles, and the top-level sections group cleanly support the new Clients (OIDC) UI flows (clipboard actions, token management, date-range validation, and per-section navigation) and read well in Portuguese.
  • Previously flagged duplicates (logout_status_jwt_signed_response_alg, spontaneous_scopes, and titles.introspection/jarm/token_endpoint_auth) now appear only once, so JSON linters should be satisfied.

Overall, these locale updates look solid and aligned with the new TS-based client pages.

Also applies to: 480-487, 580-580, 676-749, 752-752, 771-771, 781-781, 821-830, 839-839, 922-934, 1019-1024, 1027-1034, 1051-1052, 1062-1062, 1108-1140, 1145-1145, 1147-1157

Comment on lines 148 to 162
const handleFormSubmit = useCallback((values: ClientFormValues) => {
setFormValues(values)
setCommitModalOpen(true)
}, [])

const handleCommitAccept = useCallback(
(message: string) => {
if (formValues) {
const payload = buildClientPayload(formValues)
onSubmit(payload as ClientFormValues, message, modifiedFields)
}
setCommitModalOpen(false)
},
[formValues, modifiedFields, onSubmit],
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "formTypes.ts" | head -20

Repository: GluuFederation/flex

Length of output: 266


🏁 Script executed:

find . -type f -name "utils.ts" -o -name "utils.js" | grep -i helper | head -20

Repository: GluuFederation/flex

Length of output: 558


🏁 Script executed:

find . -path "*/admin-ui/plugins/auth-server/components/Clients/*" -type f | head -30

Repository: GluuFederation/flex

Length of output: 2315


🏁 Script executed:

cat -n ./admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts

Repository: GluuFederation/flex

Length of output: 4785


🏁 Script executed:

cat -n ./admin-ui/plugins/auth-server/components/Clients/helper/utils.ts

Repository: GluuFederation/flex

Length of output: 11554


🏁 Script executed:

cat -n ./admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx | head -200

Repository: GluuFederation/flex

Length of output: 7401


Align onSubmit payload type with buildClientPayload result and remove unsafe cast.

In handleCommitAccept, you transform formValues via buildClientPayload (which returns an ExtendedClient) and then cast the result back to ClientFormValues for the onSubmit call:

const payload = buildClientPayload(formValues)
onSubmit(payload as ClientFormValues, message, modifiedFields)

However, ClientFormProps is still typed as:

onSubmit: (values: ClientFormValues, message: string, modifiedFields: ModifiedFields) => void

and ClientFormValues extends ExtendedClient with an extra expirable field. Since buildClientPayload uses JSON.parse(JSON.stringify()) internally (which strips the expirable field), the cast is unsound—the returned value is not actually a ClientFormValues.

To make the contract honest and remove the unsafe assertion:

  • Change ClientFormProps.onSubmit to accept ExtendedClient (the actual payload type).
  • Drop the as ClientFormValues cast.
// In formTypes.ts
export interface ClientFormProps {
  client: Partial<ExtendedClient>
  isEdit?: boolean
  viewOnly?: boolean
-  onSubmit: (values: ClientFormValues, message: string, modifiedFields: ModifiedFields) => void
+  onSubmit: (payload: ExtendedClient, message: string, modifiedFields: ModifiedFields) => void
  onCancel?: () => void
}
// In ClientForm.tsx handleCommitAccept
const payload = buildClientPayload(formValues)
-onSubmit(payload as ClientFormValues, message, modifiedFields)
+onSubmit(payload, message, modifiedFields)
🤖 Prompt for AI Agents
In admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx
around lines 148 to 162, the handler calls buildClientPayload which returns an
ExtendedClient but then unsafely casts it to ClientFormValues when calling
onSubmit; update the ClientFormProps type so onSubmit accepts an ExtendedClient
(or the precise payload type returned by buildClientPayload), remove the "as
ClientFormValues" cast in handleCommitAccept, and add/update any necessary
imports or type aliases so the new signature compiles and correctly reflects the
actual payload type passed to onSubmit.

Comment on lines +168 to +170
const handleDownload = useCallback((values: ClientFormValues) => {
downloadClientAsJson(values)
}, [])
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Clarify whether the downloaded JSON should reflect raw form state or API payload.

handleDownload currently passes raw Formik values to downloadClientAsJson:

const handleDownload = useCallback((values: ClientFormValues) => {
  downloadClientAsJson(values)
}, [])

and the top toolbar uses:

<Button
  variant="outlined"
  onClick={() => handleDownload(formik.values)}
  // ...
>
  {t('fields.download_summary')}
</Button>

Given buildClientPayload already normalizes form values into the API-ready ExtendedClient shape (stripping UI-only fields, cleaning localized attributes, etc.), it may be more consistent—if the “summary” is meant to mirror what would be sent to the backend—to reuse that transformation here:

- const handleDownload = useCallback((values: ClientFormValues) => {
-   downloadClientAsJson(values)
- }, [])
+ const handleDownload = useCallback((values: ClientFormValues) => {
+   const payload = buildClientPayload(values)
+   downloadClientAsJson(payload)
+ }, [])

If the intent is instead to export the raw in-form state (including helper fields like expirable), the current approach is fine—but it would be good to confirm that intent.

Based on helper logic in helper/utils.ts for buildClientPayload and downloadClientAsJson.

Also applies to: 299-314

🤖 Prompt for AI Agents
In admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx
around lines 168-170 (and also for the related download logic at lines 299-314),
the handler currently downloads raw Formik values which include UI-only helper
fields; instead, call buildClientPayload(formik.values) to produce the API-ready
ExtendedClient shape (cleaning localized attributes and stripping UI-only flags)
and pass that result to downloadClientAsJson so the downloaded JSON matches what
would be sent to the backend; update both handleDownload and the other download
call sites to transform values through buildClientPayload before invoking
downloadClientAsJson.

Resolved conflicts:
- Kept both error_loading_data and insufficient_token_read_permission in translation files
- Removed deleted JS files (replaced by TypeScript versions)
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-ui/app/locales/es/translation.json (2)

4-4: Fix concatenated text.

The translation value appears to have "Aceptar" concatenated with "Agregar mapeo de atributos". It should be just "Agregar mapeo de atributos".

🔎 Proposed fix
-    "add_attribute_mapping": "AceptarAgregar mapeo de atributos",
+    "add_attribute_mapping": "Agregar mapeo de atributos",

847-847: Translate message to Spanish.

This error message is in English but should be in Spanish for this locale file. Spanish-speaking users will see English text when this validation error occurs.

🔎 Proposed fix
-    "additional_parameters_required": "Both key and value are required for each custom parameter.",
+    "additional_parameters_required": "Se requieren tanto la clave como el valor para cada parámetro personalizado.",
♻️ Duplicate comments (3)
admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (1)

207-234: Preserve 0 TTL values by using nullish coalescing instead of ||.

value={formik.values.ttl || ''} coerces a valid ttl of 0 to an empty string, so users cannot see/edit a zero TTL. Prefer ?? so only null/undefined become empty:

-              value={formik.values.ttl || ''}
+              value={formik.values.ttl ?? ''}

This keeps 0 round‑trippable while still rendering “no value” as empty.

admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx (2)

168-170: Clarify whether download should use raw form state or the normalized payload.

handleDownload currently exports raw ClientFormValues, while submit uses buildClientPayload to normalize to the API/ExtendedClient shape. If the “summary” is meant to mirror what is actually sent to the backend, consider reusing the same transformation:

-  const handleDownload = useCallback((values: ClientFormValues) => {
-    downloadClientAsJson(values)
-  }, [])
+  const handleDownload = useCallback((values: ClientFormValues) => {
+    const payload = buildClientPayload(values)
+    downloadClientAsJson(payload)
+  }, [])

If the intent is explicitly to export the raw in-form state (including UI-only fields), the current behavior is fine, but documenting that intent would avoid confusion.


315-335: Avoid duplicating the submit button implementation.

The “Save/Add” submit button is implemented twice with identical props and styles (top toolbar and footer). Extracting a small shared component or memoized element would reduce duplication and keep behavior consistent.

Example extraction sketch
const SubmitButton: React.FC<{
  disabled: boolean
  isEdit: boolean
  labelSave: string
  labelAdd: string
  themeColors: typeof themeColors
}> = ({ disabled, isEdit, labelSave, labelAdd, themeColors }) => (
  <Button
    type="submit"
    variant="contained"
    disabled={disabled}
    sx={{
      backgroundColor: themeColors?.background,
      color: 'white',
      '&:hover': { backgroundColor: themeColors?.background, opacity: 0.9 },
      '&:disabled': {
        backgroundColor: themeColors?.lightBackground,
        color: 'rgba(255, 255, 255, 0.7)',
      },
    }}
  >
    {isEdit ? labelSave : labelAdd}
  </Button>
)

Then reuse SubmitButton in both locations.

Also applies to: 372-391

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77bfb39 and 02ea5e4.

📒 Files selected for processing (11)
  • admin-ui/app/locales/en/translation.json
  • admin-ui/app/locales/es/translation.json
  • admin-ui/app/locales/fr/translation.json
  • admin-ui/app/locales/pt/translation.json
  • admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx
  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts
  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/components/ClientForm.tsx
📚 Learning: 2025-12-05T18:24:41.713Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.713Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts
🧬 Code graph analysis (4)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • usePageSize (11-11)
admin-ui/plugins/auth-server/components/Clients/sections/SystemInfoSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (72-82)
admin-ui/plugins/auth-server/components/Clients/helper/utils.ts (1)
  • formatDateTime (219-228)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (2)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (72-82)
admin-ui/plugins/services/Components/Configuration/PersistenceDetail.js (1)
  • labelStyle (37-39)
admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (72-82)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
🔇 Additional comments (13)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)

4-5: Past review feedback addressed.

The backward-compatibility comment has been added as suggested in the previous review. This resolves the storage key typo concern.

admin-ui/plugins/auth-server/__tests__/components/Clients/ClientForm.test.tsx (1)

107-293: ClientForm tests provide solid, behavior-focused coverage.

The suite exercises navigation, view-only vs edit modes, field editing, commit dialog flow, and validates the onSubmit payload shape; structure and mocks look appropriate.

admin-ui/plugins/auth-server/components/Clients/sections/LocalizationSection.tsx (1)

28-151: JSON editor error handling and UX look correct and robust.

Local editor state, validation, and error feedback (border + helper text) are wired cleanly; malformed JSON no longer silently fails and Formik state is only updated on successful parse.

admin-ui/app/locales/fr/translation.json (1)

368-371: New FR translations align with the new Clients UI and avoid key duplication.

The added fields, messages, titles, and sections entries for OIDC Clients (tokens, localization, system info, active tokens, etc.) are structurally consistent, and previously duplicated keys in fields have been resolved so each appears only once.

Also applies to: 685-755, 757-837, 828-833, 1036-1154, 1155-1166

admin-ui/app/locales/pt/translation.json (4)

335-749: Fields: new OIDC client metadata keys look consistent and deduplicated

The added fields entries (section, sort_order, logout_status_jwt_signed_response_alg, spontaneous_scopes, and the 680–749 OIDC client/token fields) are unique within "fields" and align with the English keys. Previously duplicated keys (logout_status_jwt_signed_response_alg, spontaneous_scopes) are now single-source, so JSON and linters should be clean.


752-937: Messages: client/token UX strings are clear and match EN semantics

New messages for token attributes, section-level errors, identity‑provider creation, clipboard/tokens handling, and active-token states are idiomatic Portuguese and track the English meanings closely. No conflicts or obvious i18n issues.


1021-1026: Placeholders: new client/scope helpers and JSON format hint look good

placeholders.more, add_claims, add_email, search_clients, search_scopes, and localized_json_format are concise, correctly localized, and free of embedded spacing quirks. Nothing to change.


1029-1159: Titles and sections: OIDC client clusters added without duplicate keys

The new titles.* entries for tokens/JARM/token-endpoint-auth plus the OpenID Connect client pages, and the new root "sections" block, all map cleanly to the English structure. There are no remaining duplicate keys for introspection, jarm, or token_endpoint_auth, so previous Biome noDuplicateObjectKeys issues should be resolved.

admin-ui/app/locales/en/translation.json (4)

65-69: Actions/fields: new client/metadata keys are coherent and non-duplicated

  • actions.add_uri, save_changes, copy, and generate_secret are named and worded consistently with the rest of the UI.
  • In fields, filter_by, section, sort_order, and the large OIDC metadata cluster (access/refresh/id/tx token settings, PAR/CIBA/logout, localized URIs, etc.) are unique within "fields" and mirror the new PT keys.
  • Previously duplicated logout_status_jwt_signed_response_alg is now defined only once in fields.

No JSON or naming issues spotted here.

Also applies to: 105-734


827-907: Messages: new client/tokens and IDP strings are clear and aligned with behavior

The added messages for token‑attribute notice, section‑level error, IDP creation, clipboard copy outcomes, scripts truncation, token fetch/revoke flows, “save client first”, and the “no_* selected” variants read clearly and match the new Clients/Active Tokens UX. No collisions with existing message keys.

Also applies to: 919-919, 941-941, 992-995


1109-1117: Placeholders: client/scopes helpers and JSON format hint are well-formed

The new placeholders (more, add_claims, add_email, search_clients, search_scopes, localized_json_format, enter_client_name, enter_description, select_grant_types) improve discoverability in the new client forms. The more key no longer embeds leading spaces, which is better for i18n composition.


1120-1257: Titles/sections: OIDC client navigation labels added without reintroducing duplicates

  • New titles entries for token “views” (id_token, access_token, userinfo, request_object, introspection, jarm, token_endpoint_auth) and the OpenID Connect client pages (add/edit/view client, scopes & grants, token settings, TX token, ACR & security, etc.) are cohesive and match the rest of the UI.
  • The new root "sections" mapping (basic_info, authentication, scopes_and_grants, uris, tokens, ciba, scripts, localization, system_info, active_tokens) lines up with how the new client detail layout is structured.
  • Prior duplicate‑key problems in titles (for these token‑related keys) are not present in this version.

Looks good from both JSON and UX labelling perspectives.

Also applies to: 1264-1275

admin-ui/app/locales/es/translation.json (1)

1-2045: LGTM - Comprehensive localization additions for client management.

The extensive additions to this Spanish translation file align well with the PR objectives to support TypeScript-generated client management UI. The file structure is well-organized with clear sections for actions, fields, messages, titles, and the new sections block. Translation quality is generally professional and consistent throughout.

The duplicate keys issue noted in previous reviews appears to have been successfully resolved.

@syntrydy syntrydy requested a review from duttarnab December 22, 2025 23:57
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02ea5e4 and 22e4861.

📒 Files selected for processing (3)
  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts
  • admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx
  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts
📚 Learning: 2025-12-05T18:24:41.713Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2498
File: admin-ui/plugins/saml/components/SamlConfigurationForm.tsx:30-30
Timestamp: 2025-12-05T18:24:41.713Z
Learning: In the GluuFederation/flex admin-ui codebase, `SetTitle` (imported from 'Utils/SetTitle') is a custom React hook that should be called at the component's top level, not inside `useEffect` or other hooks, because it internally manages side effects for setting page titles.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts
🧬 Code graph analysis (3)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • usePageSize (11-11)
admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (3)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
  • SectionProps (75-85)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • TOKEN_ENDPOINT_AUTH_METHODS (30-39)
admin-ui/plugins/admin/redux/features/mappingSlice.js (1)
  • index (47-47)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)
admin-ui/plugins/auth-server/components/Clients/types/clientTypes.ts (6)
  • ExtendedClient (31-35)
  • Client (17-17)
  • ModifiedFields (57-59)
  • ClientScope (37-43)
  • ClientScript (45-51)
  • UmaResource (67-84)
🔇 Additional comments (5)
admin-ui/plugins/auth-server/components/Clients/types/formTypes.ts (1)

1-131: LGTM! Well-structured type definitions.

The type definitions are clean and well-organized. All previous review concerns have been addressed:

  • Proper import of Dispatch/SetStateAction from React (line 1)
  • AdvancedTabProps.scripts correctly uses ClientScript[] (line 67)
  • Appropriate use of Pick utility types to derive from generated API types

The discriminated unions, form value interfaces, and component props provide a solid type-safe foundation for the client form UI.

admin-ui/plugins/auth-server/components/Clients/sections/TokensSection.tsx (1)

1-831: LGTM! Comprehensive token configuration section with all previous issues resolved.

The component is well-structured and follows React best practices:

  • Proper use of useCallback and useMemo for handlers and styles with correct dependencies
  • All previous review concerns have been addressed:
    • parseInt calls include radix parameter (lines 132, 154, 174, 196, 216, 237, 388, 545)
    • Numeric fields use nullish coalescing ?? to preserve zero values (lines 127, 148, 169, 190, 211, 232, 383, 540)
    • Autocomplete chips use stable keys key={option} instead of indices (lines 518, 620, 652, 688, 729, 816)
  • Consistent patterns for field changes and modification tracking
  • Theme-aware styling with proper responsive behavior
  • Appropriate use of controlled inputs with Formik integration

The freeSolo Autocomplete fields with empty options (lines 595-627, 631-659, 663-695, 704-737, 791-823) are intentional to allow free-text entry, which is the correct pattern for those use cases.

admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (3)

4-5: Well done addressing the previous feedback.

The backward compatibility comment clearly documents the intentional spelling of 'paggingSize', resolving the earlier concern about the typo.


7-13: LGTM: Clean lazy initialization.

The lazy initializer properly handles missing or invalid localStorage values and falls back gracefully to defaultSize. This addresses the previous optimization feedback.


28-28: Excellent use of TypeScript best practices.

The as const assertion ensures proper tuple typing for the hook's return value, preventing unintended array mutations and improving type inference for consumers.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22e4861 and feff1de.

📒 Files selected for processing (1)
  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • usePageSize (11-11)
🔇 Additional comments (3)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (3)

1-2: LGTM: Clean imports.

The imports are appropriate and necessary for the hook implementation.


4-5: LGTM: Backward compatibility properly documented.

The intentional typo preservation with explanatory comment is the right approach. This ensures existing user preferences remain intact.


7-13: LGTM: Solid lazy initialization.

The lazy initialization pattern is correctly implemented, avoiding unnecessary function calls on re-renders. The localStorage read logic with proper fallback handling is robust.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between feff1de and a3c9965.

📒 Files selected for processing (1)
  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (2)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • usePageSize (11-11)
admin-ui/plugins/auth-server/components/Clients/helper/constants.ts (1)
  • DEFAULT_PAGE_SIZE (135-135)
🔇 Additional comments (1)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)

1-5: LGTM! Imports and constants are clean.

The backward compatibility comment for the storage key typo is excellent. All previous feedback has been properly addressed.

@sonarqubecloud
Copy link

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3c9965 and 271eb65.

📒 Files selected for processing (1)
  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (1)
admin-ui/plugins/auth-server/components/Clients/hooks/index.ts (1)
  • usePageSize (11-11)
🔇 Additional comments (3)
admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts (3)

4-5: Excellent backward compatibility handling.

The comment clearly explains why the typo in the storage key is intentional, addressing potential confusion for future maintainers.


9-23: Robust initialization with comprehensive safeguards.

The hook properly validates the defaultSize parameter, uses lazy initialization, and handles all localStorage read errors gracefully. All edge cases (NaN, Infinity, negative values, disabled storage) are covered.


25-36: Excellent validation and error handling.

The setter properly validates input, enforces integer values with Math.round, updates state consistently, and gracefully handles localStorage failures. The dependency array correctly includes safeDefault.


const setPageSize = useCallback(
(size: number) => {
const validatedSize = Number.isFinite(size) && size > 0 ? Math.round(size) : safeDefault
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Optional: Consider adding an upper bound for page size.

While the current validation handles lower bounds (positive, finite numbers), there's no maximum limit. Extremely large page sizes (e.g., 10,000+) could cause performance issues in pagination components. Consider defining a MAX_PAGE_SIZE constant and clamping values:

const MAX_PAGE_SIZE = 1000 // or appropriate limit
const validatedSize = 
  Number.isFinite(size) && size > 0 
    ? Math.min(Math.round(size), MAX_PAGE_SIZE) 
    : safeDefault

This is entirely optional and depends on whether your pagination components can handle arbitrarily large page sizes.

🤖 Prompt for AI Agents
In admin-ui/plugins/auth-server/components/Clients/hooks/usePageSize.ts around
line 27, the validation only enforces a positive finite lower bound but no upper
bound, so extremely large sizes can be passed; add a MAX_PAGE_SIZE constant
(e.g., 1000 or an appropriate limit) and clamp the validatedSize to
Math.min(Math.round(size), MAX_PAGE_SIZE) when size is finite and > 0, otherwise
use safeDefault, ensuring the page size cannot exceed the defined maximum to
avoid performance issues.

Copy link
Contributor

@duttarnab duttarnab left a comment

Choose a reason for hiding this comment

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

  1. Client column missing on Clients search page
  2. The delete icon colour should match with theme colour
  3. All Grants info not displayed on Clients search page
image
  1. Client Create form: unable to search scopes
image
  1. Client create form: The form must have all fields in Basic tab
image 7. Please match all the field labels from the previous client create/edit form . These field name was chosen by Mike. 8. Client secret should be generated by API is not provided. So it should not be the mandatory field on form. 9. Please match the Edit/View form field arrangements with the fields underneath the tabs of existing Edit/View forms. image 10. In view form field label is not visible image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-admin-ui Component affected by issue or PR comp-docker-admin-ui Component affected by issue or PR kind-bug Issue or PR is a bug in existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(admin-ui): Use typescript generated Clients pages

4 participants