[Devportal] Fix the tryout functionality using a proxy - #2818
Conversation
|
Warning Review limit reached
Next review available in: 42 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe developer portal adds a configurable server-side Try It proxy with same-site checks, endpoint allowlisting, header filtering, and SSRF protection. Existing sample API documentation is replaced with a Reading-List-API CRUD example, and YAML definition discovery is expanded. ChangesTry It proxy
Reading List sample APIs
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant APIUser
participant DeveloperPortal
participant tryoutProxyController
participant tryoutProxyService
participant RegisteredAPI
APIUser->>DeveloperPortal: Open API documentation
DeveloperPortal->>APIUser: Render Try It with portal proxy
APIUser->>tryoutProxyController: Submit Try It request
tryoutProxyController->>tryoutProxyService: Validate and proxy request
tryoutProxyService->>RegisteredAPI: Forward allowed request
RegisteredAPI-->>tryoutProxyService: Return response
tryoutProxyService-->>tryoutProxyController: Return filtered response
tryoutProxyController-->>APIUser: Return status, headers, and body
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 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: 5
🧹 Nitpick comments (1)
portals/developer-portal/src/utils/ssrfGuard.js (1)
63-132: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winAdd regression coverage for the SSRF guard, including IPv4-mapped IPv6 loopback and private addresses.
The guard is implemented, but there are no existing test/spec references covering
isDenied,createGuardedLookup, or Happy Eyeballs[all: true]behavior, and the project’s test scripts are absent.🤖 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/developer-portal/src/utils/ssrfGuard.js` around lines 63 - 132, Add regression tests for the SSRF guard covering isDenied with IPv4-mapped IPv6 loopback and private addresses, including allowPrivate behavior, and createGuardedLookup rejection of denied destinations. Also cover the dns.lookup callback path with options.all true, verifying every resolved candidate is checked and denied candidates produce an error. Use the repository’s existing test conventions or add an appropriate test script if none exists.Source: Coding guidelines
🤖 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/developer-portal/samples/apis/reading-list-api-v1.0/docs/overview.md`:
- Around line 51-54: Replace the hardcoded admin:admin authorization value in
the REST API registration curl example with environment-variable credentials
such as GATEWAY_USER and GATEWAY_PASSWORD, and explicitly mark any documented
default credentials as local-only.
In `@portals/developer-portal/src/config/configDefaults.js`:
- Around line 179-197: Set DEFAULTS.tryout.allowPrivateEndpoints to false so
private-endpoint access is disabled by default. Also update
portals/developer-portal/configs/config-template.toml lines 207-214 to set
allow_private_endpoints to false and revise its inline comment to describe
explicit operator opt-in.
In `@portals/developer-portal/src/controllers/tryoutProxyController.js`:
- Around line 49-61: Update isSameSiteRequest to fail closed when both
sec-fetch-site and Origin are absent: return false instead of treating the
request as an allowed non-browser caller. Preserve the existing same-site Fetch
Metadata and Origin host validation behavior.
- Around line 63-92: Update proxyTryoutRequest to perform the same
authentication, visibility, subscription, and organization-membership
authorization used by the corresponding documentation/page routes before calling
tryoutProxyService.proxyTryout. Resolve the organization UUID and validate
access to the requested orgName, apiHandle, apiType, and view context before
relaying any target request, while preserving the existing early config, origin,
type, and target validation responses.
In `@portals/developer-portal/src/routes/pages/tryoutProxyRoute.js`:
- Around line 29-36: Handle errors from the express.raw middleware locally in
the tryout-proxy router before they reach the global error handler. Add
router-level error handling around the middleware and return the controller’s
JSON error shape for body-size violations, using HTTP 413 and a generic message;
preserve byte-for-byte parsing and normal delegation to
tryoutProxyController.proxyTryoutRequest.
---
Nitpick comments:
In `@portals/developer-portal/src/utils/ssrfGuard.js`:
- Around line 63-132: Add regression tests for the SSRF guard covering isDenied
with IPv4-mapped IPv6 loopback and private addresses, including allowPrivate
behavior, and createGuardedLookup rejection of denied destinations. Also cover
the dns.lookup callback path with options.all true, verifying every resolved
candidate is checked and denied candidates produce an error. Use the
repository’s existing test conventions or add an appropriate test script if none
exists.
🪄 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: 0e6f03ca-0497-401d-9298-de314e188ec4
⛔ Files ignored due to path filters (2)
portals/developer-portal/package-lock.jsonis excluded by!**/package-lock.jsonportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/web/api-icon.pngis excluded by!**/*.png
📒 Files selected for processing (30)
portals/developer-portal/README.mdportals/developer-portal/configs/config-template.tomlportals/developer-portal/docs/administer/design-mode.mdportals/developer-portal/docs/introduction/quick-start.mdportals/developer-portal/package.jsonportals/developer-portal/samples/apis/booking-api/api.yamlportals/developer-portal/samples/apis/booking-api/definition.yamlportals/developer-portal/samples/apis/booking-api/docs/overview.mdportals/developer-portal/samples/apis/ping-api/api.yamlportals/developer-portal/samples/apis/ping-api/definition.yamlportals/developer-portal/samples/apis/ping-api/docs/overview.mdportals/developer-portal/samples/apis/reading-list-api-v1.0/api.yamlportals/developer-portal/samples/apis/reading-list-api-v1.0/definition.ymlportals/developer-portal/samples/apis/reading-list-api-v1.0/docs/overview.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/api.yamlportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/definition.ymlportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/FAQ/faq.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/getting-started.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/overview.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/web/api-content.hbsportals/developer-portal/src/app.jsportals/developer-portal/src/config/configDefaults.jsportals/developer-portal/src/controllers/apiContentController.jsportals/developer-portal/src/controllers/tryoutProxyController.jsportals/developer-portal/src/pages/partials/api-specification.hbsportals/developer-portal/src/pages/settings/partials/cfg-apis-panel.hbsportals/developer-portal/src/routes/pages/tryoutProxyRoute.jsportals/developer-portal/src/services/tryoutProxyService.jsportals/developer-portal/src/utils/sampleApiLoader.jsportals/developer-portal/src/utils/ssrfGuard.js
💤 Files with no reviewable changes (12)
- portals/developer-portal/samples/apis/booking-api/api.yaml
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/getting-started.md
- portals/developer-portal/samples/apis/ping-api/definition.yaml
- portals/developer-portal/samples/apis/ping-api/docs/overview.md
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/FAQ/faq.md
- portals/developer-portal/samples/apis/booking-api/docs/overview.md
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/overview.md
- portals/developer-portal/samples/apis/ping-api/api.yaml
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/api.yaml
- portals/developer-portal/samples/apis/booking-api/definition.yaml
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/web/api-content.hbs
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/definition.yml
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
portals/developer-portal/src/utils/sampleApiLoader.js (1)
41-46: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winReject percent-encoded traversal sequences before resolving.
Line 42 rejects literal null bytes, but accepts raw
%2e,%2f, and%5csequences. Fail closed on encoded dot, separator, and null-byte forms as required.Proposed fix
function safeResolve(rootDir, ...segments) { - if (segments.some(s => typeof s !== 'string' || s.includes('\0'))) return null; + if (segments.some(s => + typeof s !== 'string' + || s.includes('\0') + || /%(?:00|2e|2f|5c)/i.test(s) + )) return null;As per coding guidelines, user-controlled paths must “reject traversal, null bytes, and URL-encoded traversal.”
🤖 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/developer-portal/src/utils/sampleApiLoader.js` around lines 41 - 46, Update safeResolve to reject percent-encoded traversal and separator sequences, including encoded dots, forward/backslashes, and null bytes, before calling path.resolve. Apply the validation to every segment and return null for any matching encoding while preserving the existing literal null-byte and root-containment checks.Source: Coding guidelines
🤖 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/developer-portal/samples/apis/reading-list-api-v1.0/docs/overview.md`:
- Around line 42-45: Replace the localhost value in the Production gateway URL
in the overview documentation with the deployed production hostname, and update
the corresponding productionUrl in the reading-list API definition consistently;
keep the Sandbox URL unchanged.
In `@portals/developer-portal/src/routes/pages/tryoutProxyRoute.js`:
- Around line 94-105: Update authenticateLikeSpecPage to handle
ensureAuthenticated outcomes locally: return the proxy route’s generic JSON 401
response for unauthenticated redirects and authorization errors, and do not
forward those failures to the global handler. Preserve normal next() behavior
for authenticated requests and unrelated errors.
In `@portals/developer-portal/src/utils/ssrfGuard.js`:
- Around line 59-68: Update the PRIVATE_CIDRS definition to include the legacy
IPv6 site-local range fec0::/10 so isDenied rejects fec0::1 when allowPrivate is
false. Add a regression test covering that behavior.
---
Outside diff comments:
In `@portals/developer-portal/src/utils/sampleApiLoader.js`:
- Around line 41-46: Update safeResolve to reject percent-encoded traversal and
separator sequences, including encoded dots, forward/backslashes, and null
bytes, before calling path.resolve. Apply the validation to every segment and
return null for any matching encoding while preserving the existing literal
null-byte and root-containment checks.
🪄 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: e80f7be8-1ef2-42dc-91b2-bf2f188049d8
⛔ Files ignored due to path filters (2)
portals/developer-portal/package-lock.jsonis excluded by!**/package-lock.jsonportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/web/api-icon.pngis excluded by!**/*.png
📒 Files selected for processing (32)
portals/developer-portal/README.mdportals/developer-portal/configs/config-template.tomlportals/developer-portal/docs/administer/design-mode.mdportals/developer-portal/docs/introduction/quick-start.mdportals/developer-portal/package.jsonportals/developer-portal/samples/apis/booking-api/api.yamlportals/developer-portal/samples/apis/booking-api/definition.yamlportals/developer-portal/samples/apis/booking-api/docs/overview.mdportals/developer-portal/samples/apis/ping-api/api.yamlportals/developer-portal/samples/apis/ping-api/definition.yamlportals/developer-portal/samples/apis/ping-api/docs/overview.mdportals/developer-portal/samples/apis/reading-list-api-v1.0/api.yamlportals/developer-portal/samples/apis/reading-list-api-v1.0/definition.ymlportals/developer-portal/samples/apis/reading-list-api-v1.0/docs/overview.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/api.yamlportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/definition.ymlportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/FAQ/faq.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/getting-started.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/overview.mdportals/developer-portal/samples/apis/swagger-petstore-v1.0.7/web/api-content.hbsportals/developer-portal/src/app.jsportals/developer-portal/src/config/configDefaults.jsportals/developer-portal/src/controllers/apiContentController.jsportals/developer-portal/src/controllers/tryoutProxyController.jsportals/developer-portal/src/middlewares/ensureAuthenticated.jsportals/developer-portal/src/pages/partials/api-specification.hbsportals/developer-portal/src/pages/settings/partials/cfg-apis-panel.hbsportals/developer-portal/src/routes/pages/tryoutProxyRoute.jsportals/developer-portal/src/services/tryoutProxyService.jsportals/developer-portal/src/utils/sampleApiLoader.jsportals/developer-portal/src/utils/ssrfGuard.jsportals/developer-portal/src/utils/ssrfGuard.test.js
💤 Files with no reviewable changes (12)
- portals/developer-portal/samples/apis/ping-api/docs/overview.md
- portals/developer-portal/samples/apis/booking-api/definition.yaml
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/FAQ/faq.md
- portals/developer-portal/samples/apis/booking-api/docs/overview.md
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/getting-started.md
- portals/developer-portal/samples/apis/booking-api/api.yaml
- portals/developer-portal/samples/apis/ping-api/definition.yaml
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/api.yaml
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/docs/overview.md
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/web/api-content.hbs
- portals/developer-portal/samples/apis/ping-api/api.yaml
- portals/developer-portal/samples/apis/swagger-petstore-v1.0.7/definition.yml
🚧 Files skipped from review as they are similar to previous changes (10)
- portals/developer-portal/src/config/configDefaults.js
- portals/developer-portal/docs/administer/design-mode.md
- portals/developer-portal/src/pages/partials/api-specification.hbs
- portals/developer-portal/samples/apis/reading-list-api-v1.0/api.yaml
- portals/developer-portal/src/pages/settings/partials/cfg-apis-panel.hbs
- portals/developer-portal/docs/introduction/quick-start.md
- portals/developer-portal/src/controllers/apiContentController.js
- portals/developer-portal/configs/config-template.toml
- portals/developer-portal/src/controllers/tryoutProxyController.js
- portals/developer-portal/src/services/tryoutProxyService.js
Purpose
Fix #2610
Goals
Fixing the tryout
Approach
Added a proxy for invoking the APIs
Passed the proxy url to the elements-ui, so the APIs invoked through the devportal UI will go through the proxy and give the responses.
In the UI, it will show the real url as usual.
Additionally some of the redundant samples were removed.