Fix multiple UI UX issues - #3062
Conversation
📝 WalkthroughWalkthroughChangesAPI Portal changes
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant TestRunner
participant ApiPortal
participant AuthorizationConfig
TestRunner->>ApiPortal: send request with selected authorization mode
ApiPortal->>AuthorizationConfig: resolve scope or role grants
AuthorizationConfig-->>ApiPortal: return grants
ApiPortal-->>TestRunner: allow or deny request
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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)
portals/api-portal/src/middlewares/authMiddleware.js (2)
400-412: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winFix the stale "org resolved from header" comment.
The comment on line 400 says the mTLS branch resolves the org "from the
organizationrequest header." The function it calls,resolvePortalOrg(documented at lines 246-253), does the opposite: the header no longer selects the organization, it is only checked for a mismatch. Update the line 400 comment to match the documented behavior ofresolvePortalOrg, or a future reader will misunderstand how org selection works for mTLS credentials.📝 Proposed fix
- // 4. mTLS — org resolved from the `organization` request header + // 4. mTLS — org resolved from the portal's configured organization; + // the `organization` header, if present, is only checked for a mismatch.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@portals/api-portal/src/middlewares/authMiddleware.js` around lines 400 - 412, Update the comment immediately above the mTLS branch in the authentication middleware to state that resolvePortalOrg validates the organization header for mismatches rather than selecting the organization from it; leave the resolvePortalOrg call and authentication behavior unchanged.
465-479: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winCorrect the
apiKeyAuthdocstring — it inverts the actual acceptance rule.The docstring says this handler "Accepts any preauthorized non-OAuth mode (mTLS, role-mode session)." That does not match
req.auth?.preauthorized:
- Role-mode sessions set
preauthorized: !isRoleMode(), which isfalsein role mode (line 347) — they are rejected, not accepted, contradicting "role-mode session" in the doc.- Scope-mode IDP sessions have
mode: 'oauth2'andpreauthorized: true— they are accepted, contradicting "non-OAuth mode" in the doc.This handler is currently unreachable (no operation declares
apiKeyAuth), so there is no live exposure. Still, fix the wording now so a future engineer who addssecurity: [apiKeyAuth]to an operation does not rely on an incorrect mental model of which sessions pass.📝 Proposed fix
- * Accepts any preauthorized non-OAuth mode (mTLS, role-mode session). + * Accepts any mode with req.auth.preauthorized === true — currently mTLS, + * and scope-mode OAuth2 sessions (preauthorized is false for role-mode + * sessions, platform-jwt sessions, and bearer tokens).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@portals/api-portal/src/middlewares/authMiddleware.js` around lines 465 - 479, Correct the apiKeyAuth docstring to state that the handler accepts requests only when req.auth?.preauthorized is true, including scope-mode OAuth2 sessions, and does not accept role-mode sessions when they set it false. Remove the inaccurate “non-OAuth” and “role-mode session” wording while preserving the surrounding credential-store and scope-check guidance.
🧹 Nitpick comments (1)
portals/api-portal/it/rest-api/views-and-labels/views.spec.js (1)
63-67: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winVerify persistence for an explicit empty label array.
The test checks only
201forlabels: []. It does not prove that the stored view has an empty label set. Fetch/views/${id}and assertfetched.body.labelsis[], as in the omitted-label test.Proposed test assertion
expect(res.status).toBe(201); + const fetched = await client.as('admin').get(`/views/${id}`); + expect(fetched.status).toBe(200); + expect(fetched.body.labels).toEqual([]);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@portals/api-portal/it/rest-api/views-and-labels/views.spec.js` around lines 63 - 67, Update the creates-a-view-with-an-empty-label-array test around uniqueHandle and the POST request to fetch /views/${id} after confirming creation, then assert the fetched response’s body.labels is an empty array, matching the omitted-label persistence test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@portals/api-portal/src/controllers/apiContentController.js`:
- Around line 1139-1143: Update sendMarkdownError to set the response
Content-Type to the caller’s success media type before sending either the 404 or
500 markdown body, passing that media type into the helper if necessary and
updating its callers accordingly.
In `@portals/api-portal/src/controllers/customContentController.js`:
- Line 105: Update the locally generated missing-page errors in the controller
to include a 404 status before they are passed to next(error), ensuring
pageErrorStatus(error) maps both missing-file branches to HTTP 404 instead of
500.
In `@portals/api-portal/src/pages/application/partials/manage-keys-km-card.hbs`:
- Around line 65-74: Update the removal messaging in the manage-keys footer and
the related confirmation flows in confirmAndRemoveKeys and
oauth2-key-generation.js to accurately describe the DELETE route: it removes
only the portal’s local OAuth client_id mapping, while external OAuth clients
and already-issued tokens remain active. Remove wording that claims credentials
are deleted or tokens are revoked, and synchronize any related documentation
with this behavior.
In `@portals/api-portal/src/styles/settings-layout.css`:
- Around line 612-615: Update the .cfg-form-input[readonly]:focus rule to retain
a clearly visible keyboard-focus indicator instead of removing all focus
styling. Add or preserve a distinct outline, border, or shadow that contrasts
with the base read-only input appearance.
---
Outside diff comments:
In `@portals/api-portal/src/middlewares/authMiddleware.js`:
- Around line 400-412: Update the comment immediately above the mTLS branch in
the authentication middleware to state that resolvePortalOrg validates the
organization header for mismatches rather than selecting the organization from
it; leave the resolvePortalOrg call and authentication behavior unchanged.
- Around line 465-479: Correct the apiKeyAuth docstring to state that the
handler accepts requests only when req.auth?.preauthorized is true, including
scope-mode OAuth2 sessions, and does not accept role-mode sessions when they set
it false. Remove the inaccurate “non-OAuth” and “role-mode session” wording
while preserving the surrounding credential-store and scope-check guidance.
---
Nitpick comments:
In `@portals/api-portal/it/rest-api/views-and-labels/views.spec.js`:
- Around line 63-67: Update the creates-a-view-with-an-empty-label-array test
around uniqueHandle and the POST request to fetch /views/${id} after confirming
creation, then assert the fetched response’s body.labels is an empty array,
matching the omitted-label persistence test.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: c30c0454-113e-4dee-90a7-548a1c8afd22
⛔ Files ignored due to path filters (2)
portals/api-portal/src/defaultContent/images/api-portal-logo-white.pngis excluded by!**/*.pngportals/api-portal/src/defaultContent/images/api-portal-logo-white.svgis excluded by!**/*.svg
📒 Files selected for processing (54)
portals/api-portal/configs/config-template.tomlportals/api-portal/docs/api-portal-openapi-spec-v0.9.yamlportals/api-portal/docs/consume-an-api/consume-with-oauth2.mdportals/api-portal/it/README.mdportals/api-portal/it/configs/portal-roles-role-mode-it.yamlportals/api-portal/it/docker-compose.test.postgres.yamlportals/api-portal/it/docker-compose.test.yamlportals/api-portal/it/rest-api/ai-discovery/apis-md.spec.jsportals/api-portal/it/rest-api/auth/role-mode-authorization.spec.jsportals/api-portal/it/rest-api/organizations/single-org-isolation.spec.jsportals/api-portal/it/rest-api/support/fixtures.jsportals/api-portal/it/rest-api/views-and-labels/views.spec.jsportals/api-portal/it/test-config.tomlportals/api-portal/it/ui/cypress/e2e/001-basic/001-portal-access.cy.jsportals/api-portal/it/ui/cypress/e2e/002-apis/001-api-listing.cy.jsportals/api-portal/it/ui/cypress/e2e/002-apis/002-rest-api-details.cy.jsportals/api-portal/it/ui/cypress/e2e/003-mcp-servers/001-mcp-listing.cy.jsportals/api-portal/it/ui/cypress/e2e/applications/application-flows.cy.jsportals/api-portal/it/ui/cypress/e2e/settings/001-views-labels.cy.jsportals/api-portal/it/ui/cypress/e2e/settings/002-key-managers.cy.jsportals/api-portal/it/ui/cypress/support/commands/portal.jsportals/api-portal/it/ui/cypress/support/commands/seed.jsportals/api-portal/src/config/configDefaults.jsportals/api-portal/src/controllers/apiContentController.jsportals/api-portal/src/controllers/apiKeysOverviewController.jsportals/api-portal/src/controllers/apiWorkflowsController.jsportals/api-portal/src/controllers/applicationsContentController.jsportals/api-portal/src/controllers/customContentController.jsportals/api-portal/src/controllers/orgContentController.jsportals/api-portal/src/controllers/subscriptionsContentController.jsportals/api-portal/src/dao/organizationDao.jsportals/api-portal/src/defaultContent/pages/apis/partials/apis-md.hbsportals/api-portal/src/defaultContent/pages/docs/page.hbsportals/api-portal/src/defaultContent/pages/mcp-landing/page.hbsportals/api-portal/src/defaultContent/pages/mcps/partials/mcps-md.hbsportals/api-portal/src/middlewares/authMiddleware.jsportals/api-portal/src/middlewares/csrfProtection.jsportals/api-portal/src/middlewares/ensureAuthenticated.jsportals/api-portal/src/middlewares/registerPartials.jsportals/api-portal/src/pages/application/partials/manage-keys-km-card.hbsportals/api-portal/src/pages/login-page/layout.hbsportals/api-portal/src/pages/settings/partials/cfg-apis-panel.hbsportals/api-portal/src/pages/settings/partials/cfg-labels-panel.hbsportals/api-portal/src/pages/settings/partials/cfg-modals.hbsportals/api-portal/src/pages/settings/partials/cfg-webhook-form.hbsportals/api-portal/src/pages/settings/partials/cfg-webhooks-panel.hbsportals/api-portal/src/scripts/oauth2-key-generation.jsportals/api-portal/src/scripts/settings-apis.jsportals/api-portal/src/scripts/settings-labels.jsportals/api-portal/src/scripts/settings-organization.jsportals/api-portal/src/scripts/settings-webhooks.jsportals/api-portal/src/services/apiMetadataService.jsportals/api-portal/src/styles/settings-layout.cssportals/api-portal/src/utils/util.js
💤 Files with no reviewable changes (3)
- portals/api-portal/src/config/configDefaults.js
- portals/api-portal/configs/config-template.toml
- portals/api-portal/src/middlewares/ensureAuthenticated.js
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
portals/api-portal/src/scripts/oauth2-key-generation.js (1)
61-61: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winInvoke key removal through the confirmation flow.
warning.jscallsremoveApplicationKeys(...)directly for theremoveKeyspath, soopenWarningModal('removeKeys', ...) -> Removecan bypassconfirmAndRemoveKeys. Route this modal callback throughconfirmAndRemoveKeysinstead of the direct deletion helper.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@portals/api-portal/src/scripts/oauth2-key-generation.js` at line 61, Update the removeKeys callback used by openWarningModal so its Remove action invokes confirmAndRemoveKeys(applicationId, keyMappingId, keyType) instead of calling removeApplicationKeys directly, ensuring key deletion always passes through confirmation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@portals/api-portal/src/scripts/oauth2-key-generation.js`:
- Line 93: Update the fallback confirmation prompt in the unlink-client flow
around confirm so it also states that already-issued tokens remain valid until
expiry, matching the modal text; preferably reuse a shared confirmation-message
constant if one already exists.
---
Outside diff comments:
In `@portals/api-portal/src/scripts/oauth2-key-generation.js`:
- Line 61: Update the removeKeys callback used by openWarningModal so its Remove
action invokes confirmAndRemoveKeys(applicationId, keyMappingId, keyType)
instead of calling removeApplicationKeys directly, ensuring key deletion always
passes through confirmation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 5e3d668b-13e4-49f4-87ed-1762a96c6e9a
⛔ Files ignored due to path filters (1)
portals/api-portal/it/rest-api/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (20)
.github/workflows/devportal-integration-test.ymlportals/api-portal/it/Makefileportals/api-portal/it/README.mdportals/api-portal/it/configs/config-platform-api-it.tomlportals/api-portal/it/configs/portal-roles-it.yamlportals/api-portal/it/configs/roles-platform-api-it.yamlportals/api-portal/it/docker-compose.test.postgres.yamlportals/api-portal/it/docker-compose.test.yamlportals/api-portal/it/rest-api/auth/authorization-mode.spec.jsportals/api-portal/it/rest-api/auth/grant-table-parity.spec.jsportals/api-portal/it/rest-api/package.jsonportals/api-portal/it/rest-api/support/client.jsportals/api-portal/it/rest-api/views-and-labels/views.spec.jsportals/api-portal/src/controllers/apiContentController.jsportals/api-portal/src/controllers/customContentController.jsportals/api-portal/src/middlewares/authMiddleware.jsportals/api-portal/src/pages/application/partials/manage-keys-km-card.hbsportals/api-portal/src/scripts/oauth2-key-generation.jsportals/api-portal/src/services/apiMetadataService.jsportals/api-portal/src/styles/settings-layout.css
🚧 Files skipped from review as they are similar to previous changes (5)
- portals/api-portal/src/pages/application/partials/manage-keys-km-card.hbs
- portals/api-portal/src/styles/settings-layout.css
- portals/api-portal/src/middlewares/authMiddleware.js
- portals/api-portal/it/rest-api/views-and-labels/views.spec.js
- portals/api-portal/src/controllers/apiContentController.js
Purpose
$subject
Fixes #3059
Fixes #3058
Fixes #3057
Summary