[Devportal] Integrate platform API for local authentication#2201
[Devportal] Integrate platform API for local authentication#2201Piumal1999 wants to merge 5 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughOverviewThis PR integrates the platform API as a local authentication backend for the developer portal, replacing basic authentication with JWT-based authentication. The platform API serves as the credential validation service, issuing JWT tokens upon successful login that are used for subsequent API requests. Key ChangesAuthentication Architecture
Configuration
Docker Compose UpdatesBoth Docker Compose files now include:
Authentication Controllers
Middleware & Validation
Utilities
Documentation Updates
Database Model
Minor Changes
WalkthroughThe Developer Portal's local authentication system has been replaced with a Platform API sidecar model. A new Login controllers ( The OpenAPI auth middleware introduces a new The Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
portals/developer-portal/src/services/seeder.js (1)
111-121:⚠️ Potential issue | 🟠 MajorSeeder does not update existing provider records during upgrades.
The seeder creates the WSO2 provider only on initial setup. When a provider already exists,
createProviderraisesUniqueConstraintError(lines 114–120), which is caught and silently ignored—no update occurs. This creates an inconsistency:
- Fresh installations: WSO2 provider created with
providerURL: 'https://wso2.com'- Existing installations (upgrades): Provider retains its previous value unchanged
Other seeded data (identity providers, labels, views) use an upsert pattern with explicit checks or
findOrCreate. Consider applying a similar pattern here or implementing a separate database migration to ensure providers are updated consistently across all installations.🤖 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/services/seeder.js` around lines 111 - 121, The seeder's createProvider call in the try block only creates a new provider but does not update existing ones. When UniqueConstraintError is caught (indicating the provider already exists), the code returns without updating the existing record, causing inconsistency between fresh installations and upgrades. Modify the catch block handling the UniqueConstraintError for the WSO2 provider to update the existing provider record with the current providerURL value instead of silently returning. Apply an upsert pattern similar to other seeded data in the codebase by either calling an update method on the existing provider or using a findOrCreate/updateOrCreate pattern with adminDao to ensure the provider is consistently configured across all installations.portals/developer-portal/src/openapi/middleware/auth.js (1)
220-226:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHydrate a platform-jwt principal for bearer-token REST calls.
After validating a Platform API bearer token, this path only sets
req.authandreq[constants.USER_ID]; downstream handlers in this file readreq.user[...]. Populatereq.userfrom the token’s user/org claims and setmode: 'platform-jwt'for local 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/developer-portal/src/openapi/middleware/auth.js` around lines 220 - 226, In the Platform API bearer token validation path (where jwt.decode extracts the decoded token), the code currently only sets req.auth and req[constants.USER_ID] but does not populate req.user. After decoding the token, extract the user and org claims from the decoded token object and assign them to req.user (e.g., req.user[constants.USER_ID], req.user[constants.ORG_ID], etc.). Additionally, update the mode property in the req.auth object from 'oauth2' to 'platform-jwt' to correctly identify this as a local token authentication path for downstream handlers that read from req.user.
🤖 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/distribution/docker-compose.yaml`:
- Around line 102-110: The commented PostgreSQL dependency block creates a
duplicate depends_on key which would override the existing platform-api
dependency when uncommented. Instead of having a separate commented depends_on
section, move the postgres service entry to be nested as an additional service
within the existing depends_on block alongside platform-api. This way, when
users uncomment the postgres section, it adds to the existing dependencies
rather than replacing them. Update the comment to reflect that users should
uncomment the postgres entry within the active depends_on block.
In `@portals/developer-portal/docs/administer/manage-organizations.md`:
- Line 260: The text on line 260 contains "devportal" written in lowercase,
which is inconsistent with the standard product naming convention. Replace
"devportal" with "Developer Portal" to maintain consistent product terminology
throughout the documentation and improve readability.
- Around line 193-205: The documentation now describes token-based
authentication for local development, but organization and IdP command examples
throughout the document still use basic credentials instead of Bearer tokens.
Update all curl examples at the referenced line numbers (42, 70, 90, 98, 133,
178, 186) to replace basic authentication (such as `-u username:password` or
`Authorization: Basic` headers) with Bearer token authentication using the `-H
"Authorization: Bearer <token>"` pattern, ensuring consistency with the newly
documented token-based auth flow described in the updated section.
In `@portals/developer-portal/src/controllers/authController.js`:
- Around line 311-314: The scope suffix check in both authController.js and
devportalController.js is using `:manage` but the platform API template grants
scopes with `_manage` suffix (like `dp:api_manage`), causing manage-scoped users
to be incorrectly classified as subscribers. In
portals/developer-portal/src/controllers/authController.js at lines 311-314,
update the isAdmin check in the scope filtering logic to use `_manage` suffix
instead of `:manage`. In
portals/developer-portal/src/controllers/devportalController.js at lines
442-445, apply the same fix to ensure consistent admin classification between UI
and REST login paths. Consider extracting this scope checking logic into a
shared helper function to prevent future inconsistencies between the two
controllers.
- Around line 291-293: The logger.warn call in the Platform API login failure
handler is currently logging the username parameter, which should not be exposed
in logs for security reasons. Remove the username parameter from the logger.warn
call that logs 'Platform API login failed: invalid credentials', keeping only
the orgName in the logged context to maintain org/request traceability without
exposing user credentials.
- Around line 326-345: The profile object is being populated with orgName
sourced directly from the route parameter, but this does not validate that the
platformToken actually belongs to that organization. Extract the organization
claim from the platformToken (similar to how claims are extracted from other
tokens), and either reject the request if the token's org claim does not match
the route orgName, or populate the session profile using the token's org claim
instead. Specifically, update the assignments to
[constants.ROLES.ORGANIZATION_CLAIM], userOrg, and authorizedOrgs in the profile
object to use the validated org claim from the platformToken rather than the
unvalidated route parameter.
- Around line 280-286: Both the axios.post call in authController.js (lines
280-286) and the equivalent HTTPS client configuration in devportalController.js
(lines 419-425) disable certificate verification by setting rejectUnauthorized:
false in the httpsAgent, which creates a security vulnerability. Instead of
disabling certificate verification, configure the HTTPS agents in both locations
to use a properly validated CA certificate by loading the Platform API
certificate from your configuration or environment and passing it via the ca
option in the https.Agent constructor, or alternatively gate the relaxed
validation behind an explicit development-only flag to ensure it is never used
in production.
In `@portals/developer-portal/src/controllers/devportalController.js`:
- Around line 437-459: The current implementation silently catches token parsing
errors with an empty catch block and continues to create a user profile even
with missing or malformed tokens, leaving org fields empty. Modify the exception
handling so that after attempting to parse the platformToken, you validate that
claims were successfully extracted and that required fields like the org_handle
claim are present; if either the token parsing fails or required claims are
missing, return an auth-service error instead of proceeding with profile
creation. This ensures that only valid tokens with complete organization
information can establish a session.
In `@portals/developer-portal/src/middlewares/ensureAuthenticated.js`:
- Around line 45-57: The ensureAuthenticated middleware is incorrectly skipping
authorization checks when a local-auth user has no platform token. Currently,
when the condition `!platformToken` is true, the code calls `return next()`
which bypasses the scope validation. Instead, return an authentication error
(using util.handleError with a 401 status code or appropriate authentication
error) to ensure that local-auth sessions without a valid platform token are
properly rejected rather than allowed through.
- Around line 330-332: The `scopes` variable on Line 331 may be undefined or
null when the scope is absent from the validated token payload, causing a
runtime error when calling `.split(' ')` on it. Normalize `scopes` by coercing
it to a string before splitting (e.g., using a logical OR operator or similar
coercion technique) to ensure safe evaluation, preventing the application from
crashing when processing tokens with missing scope information in the
ensureAuthenticated middleware.
In `@portals/developer-portal/src/models/application.js`:
- Around line 57-64: Remove the composite unique index on ['APP_ID', 'ORG_ID']
from the Application model since APP_ID is already the primary key and makes
this composite index redundant for uniqueness enforcement. If this index serves
a specific purpose beyond uniqueness (such as being a covering index for
particular queries), clarify that intent and document it. Additionally, create a
database migration file to drop the global UNIQUE constraint on ORG_ID from the
Postgres schema to prevent constraint conflicts. Ensure that both the model
definition and the actual database schema remain synchronized after these
changes.
In `@portals/developer-portal/src/openapi/middleware/auth.js`:
- Around line 153-158: Consolidate Platform API JWT validation across multiple
files and add production safety guards. At
portals/developer-portal/src/openapi/middleware/auth.js anchor site (lines
153-158), remove the unverified fallback that returns valid claims when
jwtSecret is null—instead, require the secret to be configured or implement
explicit server-side token validation for production deployments. At the sibling
location in auth.js (lines 187-195), replace the manual base64url decoding logic
with a call to extractPlatformJwtClaims() to ensure consistent verification
across all JWT validation points. In
portals/developer-portal/src/middlewares/ensureAuthenticated.js (lines 48-54),
portals/developer-portal/src/controllers/devportalController.js (lines 437-442),
and portals/developer-portal/src/controllers/authController.js (lines 299-304),
replace all duplicate unverified decode logic with calls to
extractPlatformJwtClaims() using the configured jwtSecret. In
portals/developer-portal/configs/config-platform-api.toml.example (lines 22-25),
portals/developer-portal/docker-compose.yaml (lines 32-34 and 109-113), and
portals/developer-portal/distribution/docker-compose.yaml (lines 30-32 and
149-153), add documentation comments explicitly marking AUTH_JWT_SECRET_KEY and
DP_PLATFORMAPI_JWTSECRET as development-only settings, and ensure the
application fails startup in production if local auth is enabled without a
configured shared secret or proper OIDC identity provider.
In `@portals/developer-portal/src/services/seeder.js`:
- Line 112: The hardcoded provider URL `'https://wso2.com'` in the
adminDao.createProvider call should be replaced with the existing
constants.WSO2_DEFAULT_URL constant to maintain consistency with how the same
operation is handled elsewhere in the codebase. Replace the string literal with
the constant reference to ensure uniform configuration across the seeder and
other services.
---
Outside diff comments:
In `@portals/developer-portal/src/openapi/middleware/auth.js`:
- Around line 220-226: In the Platform API bearer token validation path (where
jwt.decode extracts the decoded token), the code currently only sets req.auth
and req[constants.USER_ID] but does not populate req.user. After decoding the
token, extract the user and org claims from the decoded token object and assign
them to req.user (e.g., req.user[constants.USER_ID], req.user[constants.ORG_ID],
etc.). Additionally, update the mode property in the req.auth object from
'oauth2' to 'platform-jwt' to correctly identify this as a local token
authentication path for downstream handlers that read from req.user.
In `@portals/developer-portal/src/services/seeder.js`:
- Around line 111-121: The seeder's createProvider call in the try block only
creates a new provider but does not update existing ones. When
UniqueConstraintError is caught (indicating the provider already exists), the
code returns without updating the existing record, causing inconsistency between
fresh installations and upgrades. Modify the catch block handling the
UniqueConstraintError for the WSO2 provider to update the existing provider
record with the current providerURL value instead of silently returning. Apply
an upsert pattern similar to other seeded data in the codebase by either calling
an update method on the existing provider or using a findOrCreate/updateOrCreate
pattern with adminDao to ensure the provider is consistently configured across
all installations.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fa96d254-9669-4f37-9170-3ba57df65778
📒 Files selected for processing (13)
portals/developer-portal/.gitignoreportals/developer-portal/configs/config-platform-api.toml.exampleportals/developer-portal/distribution/docker-compose.yamlportals/developer-portal/docker-compose.yamlportals/developer-portal/docs/administer/manage-organizations.mdportals/developer-portal/docs/introduction/quick-start.mdportals/developer-portal/src/config/configLoader.jsportals/developer-portal/src/controllers/authController.jsportals/developer-portal/src/controllers/devportalController.jsportals/developer-portal/src/middlewares/ensureAuthenticated.jsportals/developer-portal/src/models/application.jsportals/developer-portal/src/openapi/middleware/auth.jsportals/developer-portal/src/services/seeder.js
| const response = await axios.post( | ||
| `${platformApiUrl}/api/portal/v1/auth/login`, | ||
| new URLSearchParams({ username, password }).toString(), | ||
| { | ||
| headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, | ||
| httpsAgent: new https.Agent({ rejectUnauthorized: false }), | ||
| timeout: 10000, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify all login clients that disable HTTPS certificate validation.
rg -n -C3 'rejectUnauthorized:\s*false|httpsAgent' --type jsRepository: wso2/api-platform
Length of output: 3400
Configure the HTTPS client with a trusted Platform API certificate instead of disabling certificate validation. Both login endpoints currently disable HTTPS certificate verification, creating a security risk. Wire the Platform API CA/certificate into the devportal configuration or gate relaxed validation behind an explicit development-only flag.
portals/developer-portal/src/controllers/authController.js#L285: ReplacerejectUnauthorized: falsewith a CA-backed HTTPS agent.portals/developer-portal/src/controllers/devportalController.js#L424: Apply the same HTTPS client configuration for consistency across both login paths.
📍 Affects 2 files
portals/developer-portal/src/controllers/authController.js#L280-L286(this comment)portals/developer-portal/src/controllers/devportalController.js#L419-L425
🤖 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/controllers/authController.js` around lines 280
- 286, Both the axios.post call in authController.js (lines 280-286) and the
equivalent HTTPS client configuration in devportalController.js (lines 419-425)
disable certificate verification by setting rejectUnauthorized: false in the
httpsAgent, which creates a security vulnerability. Instead of disabling
certificate verification, configure the HTTPS agents in both locations to use a
properly validated CA certificate by loading the Platform API certificate from
your configuration or environment and passing it via the ca option in the
https.Agent constructor, or alternatively gate the relaxed validation behind an
explicit development-only flag to ensure it is never used in production.
| returning: true, | ||
| indexes: [ | ||
| { | ||
| unique: true, | ||
| fields: ['APP_ID', 'ORG_ID'], | ||
| }, | ||
| ], | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if there's a migration file addressing the ORG_ID constraint change
fd -e js -e sql migration | xargs rg -l -i "ORG_ID" 2>/dev/null || echo "No migration files found referencing ORG_ID"
# Check current schema definition for DP_APPLICATION
rg -A 5 "DP_APPLICATION" --glob "*.sql"Repository: wso2/api-platform
Length of output: 7115
🏁 Script executed:
# Read the application.js file around the changed lines
cat -n portals/developer-portal/src/models/application.js | sed -n '30,75p'Repository: wso2/api-platform
Length of output: 1350
🏁 Script executed:
# Search for migration files that might address schema changes
fd -type f -name "*migration*" -o -name "*migrate*" | head -20
rg -i "composite.*unique\|unique.*composite" --glob "*.sql" --glob "*.js" -B 2 -A 2Repository: wso2/api-platform
Length of output: 232
🏁 Script executed:
# Check for any DP_APPLICATION related changes in recent commits or other model definitions
rg -A 10 "DP_APPLICATION" portals/developer-portal/src/models/ --glob "*.js"Repository: wso2/api-platform
Length of output: 1692
🏁 Script executed:
# Check for migration files in the database directory
fd migration portals/developer-portal/database/
# Look for any sequelize migration or sync patterns
rg -i "sequelize.*sync|sequelize.*migrate" portals/developer-portal/src/ --glob "*.js" -A 3 -B 3Repository: wso2/api-platform
Length of output: 8270
🏁 Script executed:
# Check if there's any configuration or setup that syncs models to database
rg -i "sync.*true|alter.*true" portals/developer-portal/src/ --glob "*.js"Repository: wso2/api-platform
Length of output: 1245
🏁 Script executed:
# Check if there are any migration files or setup scripts in the database directory
ls -la portals/developer-portal/database/
# Look for any references to migrations or alter table statements
rg -i "alter.*table.*dp_application\|drop.*constraint.*org_id" portals/developer-portal/database/ --glob "*.sql"Repository: wso2/api-platform
Length of output: 307
🏁 Script executed:
# Check if sequelize sync is called with alter: true in any environment
rg "sequelize.sync.*alter" portals/developer-portal/src/ --glob "*.js"
# Look for any environment-specific database initialization
rg -i "process\.env\|config\.db" portals/developer-portal/src/server.js -A 10 -B 10 | head -50Repository: wso2/api-platform
Length of output: 43
🏁 Script executed:
# Check git history for changes to this file and related schema changes
git log --oneline portals/developer-portal/src/models/application.js | head -10
git log --oneline portals/developer-portal/database/schema.postgres.sql | head -10Repository: wso2/api-platform
Length of output: 199
Composite unique index conflicts with database schema and lacks migration.
The model now defines a composite unique index on ['APP_ID', 'ORG_ID'], but the Postgres schema (portals/developer-portal/database/schema.postgres.sql) enforces a global UNIQUE constraint on ORG_ID alone. These constraints are semantically different:
- Global
UNIQUEonORG_ID→ one application per organization - Composite index on
(APP_ID, ORG_ID)→ multiple applications per organization allowed
Since Postgres does not auto-sync models to the actual schema, a migration must explicitly drop the global uniqueness constraint and apply the composite index. No migration file currently exists for this change.
Additionally, because APP_ID is the primary key (globally unique), any composite unique index including it is redundant for uniqueness enforcement—each APP_ID already appears at most once. If the index serves other purposes (e.g., covering index for specific queries), clarify the intent.
🤖 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/models/application.js` around lines 57 - 64,
Remove the composite unique index on ['APP_ID', 'ORG_ID'] from the Application
model since APP_ID is already the primary key and makes this composite index
redundant for uniqueness enforcement. If this index serves a specific purpose
beyond uniqueness (such as being a covering index for particular queries),
clarify that intent and document it. Additionally, create a database migration
file to drop the global UNIQUE constraint on ORG_ID from the Postgres schema to
prevent constraint conflicts. Ensure that both the model definition and the
actual database schema remain synchronized after these changes.
| if (!idp || !idp.clientId) { | ||
| // No IdP configured — accept bearer presence (legacy parity), no scopes. | ||
| return { valid: true, scopes: '' }; | ||
| // Local auth mode: verify Platform API JWT with shared secret when configured. | ||
| const jwtSecret = config.platformApi?.jwtSecret; | ||
| const claims = extractPlatformJwtClaims(token, jwtSecret || null); | ||
| if (jwtSecret && !claims) return { valid: false, scopes: '' }; | ||
| return { valid: true, scopes: claims?.scopes?.join(' ') ?? '' }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify all Platform API JWT-secret wiring and decode/verify paths.
rg -n -C3 'AUTH_JWT_SECRET_KEY|DP_PLATFORMAPI_JWTSECRET|platformApi\.jwtSecret|extractPlatformJwtClaims|base64url' --iglob '*.{js,yaml,toml,md}'Repository: wso2/api-platform
Length of output: 20900
🏁 Script executed:
#!/bin/bash
# Check config schema and how platformApi.jwtSecret is validated/set
rg -n 'platformApi|jwtSecret' portals/developer-portal/src --type js -A 3 -B 1 | head -60
# Search for config loading and validation
fd -e js . portals/developer-portal/src -exec rg -l 'config\.platformApi|loadConfig|validateConfig' {} \;Repository: wso2/api-platform
Length of output: 20061
🏁 Script executed:
#!/bin/bash
# Check if there's any startup validation or environment-based behavior
rg -n 'DEV_MODE|NODE_ENV|production|startup|warn' portals/developer-portal/src/openapi/middleware/auth.js -C 2Repository: wso2/api-platform
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Look for documentation about local auth and when verification is required
rg -n -i 'local auth|dev.?only|unverified|fallback' portals/developer-portal --type md --type js --type tomlRepository: wso2/api-platform
Length of output: 3316
🏁 Script executed:
#!/bin/bash
# Check app startup and config loading for any validation logic
cat -n portals/developer-portal/src/config/configLoader.js | head -150Repository: wso2/api-platform
Length of output: 5632
🏁 Script executed:
#!/bin/bash
# Look for any startup checks or warnings about missing JWT secret
rg -n 'warn|error|throw|require.*jwtSecret|NODE_ENV.*production' portals/developer-portal/src/config portals/developer-portal/src/server.js -A 2Repository: wso2/api-platform
Length of output: 4197
🏁 Script executed:
#!/bin/bash
# Check if there's documentation about production safety for local auth
rg -n -i 'production|never|must|require' portals/developer-portal/docs/administer/manage-organizations.md | grep -i 'auth\|secret\|jwt'Repository: wso2/api-platform
Length of output: 257
Consolidate Platform API JWT validation and document local auth as development-only. The auth layer supports optional JWT verification for development, falling back to unverified payload decoding when DP_PLATFORMAPI_JWTSECRET is unset. This intentional behavior allows local development without shared secrets, but multiple decode paths bypass verification inconsistently, and production deployments using this mode lack startup warnings.
portals/developer-portal/src/openapi/middleware/auth.js#L156-L158: Replace unverified fallback with either a required secret or explicit server-side token validation for production deployments.portals/developer-portal/src/openapi/middleware/auth.js#L187-L195: UseextractPlatformJwtClaims()instead of manual base64url decoding to ensure consistent verification logic across all validation points.portals/developer-portal/src/middlewares/ensureAuthenticated.js#L48-L54,portals/developer-portal/src/controllers/devportalController.js#L437-L442,portals/developer-portal/src/controllers/authController.js#L299-L304: Apply the same verification helper to replace duplicate unverified decode logic.portals/developer-portal/configs/config-platform-api.toml.example,portals/developer-portal/docker-compose.yaml,portals/developer-portal/distribution/docker-compose.yaml: DocumentAUTH_JWT_SECRET_KEYandDP_PLATFORMAPI_JWTSECRETas development-only settings; for production, require OIDC identity provider configuration and fail startup if local auth is enabled without a configured shared secret.
📍 Affects 4 files
portals/developer-portal/src/openapi/middleware/auth.js#L153-L158(this comment)portals/developer-portal/src/openapi/middleware/auth.js#L187-L195portals/developer-portal/configs/config-platform-api.toml.example#L22-L25portals/developer-portal/docker-compose.yaml#L32-L34portals/developer-portal/docker-compose.yaml#L109-L113portals/developer-portal/distribution/docker-compose.yaml#L30-L32portals/developer-portal/distribution/docker-compose.yaml#L149-L153
🤖 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/openapi/middleware/auth.js` around lines 153 -
158, Consolidate Platform API JWT validation across multiple files and add
production safety guards. At
portals/developer-portal/src/openapi/middleware/auth.js anchor site (lines
153-158), remove the unverified fallback that returns valid claims when
jwtSecret is null—instead, require the secret to be configured or implement
explicit server-side token validation for production deployments. At the sibling
location in auth.js (lines 187-195), replace the manual base64url decoding logic
with a call to extractPlatformJwtClaims() to ensure consistent verification
across all JWT validation points. In
portals/developer-portal/src/middlewares/ensureAuthenticated.js (lines 48-54),
portals/developer-portal/src/controllers/devportalController.js (lines 437-442),
and portals/developer-portal/src/controllers/authController.js (lines 299-304),
replace all duplicate unverified decode logic with calls to
extractPlatformJwtClaims() using the configured jwtSecret. In
portals/developer-portal/configs/config-platform-api.toml.example (lines 22-25),
portals/developer-portal/docker-compose.yaml (lines 32-34 and 109-113), and
portals/developer-portal/distribution/docker-compose.yaml (lines 30-32 and
149-153), add documentation comments explicitly marking AUTH_JWT_SECRET_KEY and
DP_PLATFORMAPI_JWTSECRET as development-only settings, and ensure the
application fails startup in production if local auth is enabled without a
configured shared secret or proper OIDC identity provider.
|
|
||
| try { | ||
| await adminDao.createProvider(orgId, { name: 'WSO2', providerURL: config.controlPlane.url }); | ||
| await adminDao.createProvider(orgId, { name: 'WSO2', providerURL: 'https://wso2.com' }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify config.controlPlane usage and provider URL references.
# Check if config.controlPlane is still defined or used elsewhere
rg -n 'config\.controlPlane|controlPlane\s*:' --type js --type toml
# Check how WSO2 provider URL is used downstream
rg -n 'providerURL.*WSO2|provider.*WSO2.*providerURL' --type js -C3Repository: wso2/api-platform
Length of output: 816
🏁 Script executed:
# Find constants file and check WSO2_DEFAULT_URL definition
rg -n 'WSO2_DEFAULT_URL\s*=' --type js -A2
# Check what constants are imported in seeder.js
head -50 portals/developer-portal/src/services/seeder.js | grep -n "import\|require\|constants"
# Check full import section of seeder.js
sed -n '1,30p' portals/developer-portal/src/services/seeder.jsRepository: wso2/api-platform
Length of output: 1667
🏁 Script executed:
# Find the constants file location and check WSO2_DEFAULT_URL
find . -name "constants.js" -type f | head -5
# Once found, display the WSO2_DEFAULT_URL definition
rg -n 'WSO2_DEFAULT_URL' --type js -B2 -A2Repository: wso2/api-platform
Length of output: 1155
🏁 Script executed:
# Display line 112 and surrounding context in seeder.js to confirm the hardcoded URL
sed -n '105,120p' portals/developer-portal/src/services/seeder.jsRepository: wso2/api-platform
Length of output: 538
Use constants.WSO2_DEFAULT_URL instead of hardcoding the provider URL.
The provider URL is hardcoded to 'https://wso2.com', but the codebase defines constants.WSO2_DEFAULT_URL as 'https://localhost:9443' and uses this constant for the same operation in adminService.js line 209. Replace the hardcoded string with the constant to maintain consistency across the codebase.
🤖 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/services/seeder.js` at line 112, The hardcoded
provider URL `'https://wso2.com'` in the adminDao.createProvider call should be
replaced with the existing constants.WSO2_DEFAULT_URL constant to maintain
consistency with how the same operation is handled elsewhere in the codebase.
Replace the string literal with the constant reference to ensure uniform
configuration across the seeder and other services.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
portals/developer-portal/src/controllers/devportalController.js (2)
474-479:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHandle
req.session.saveerrors before returning login success.
req.logIncan succeed while the session store write fails; returning 200 in that case leaves the client with a non-persisted login.Proposed fix
- req.session.save(() => res.status(200).json({ message: 'Login successful' })); + req.session.save((saveErr) => { + if (saveErr) { + logger.error('Session save failed', { error: saveErr.message }); + return util.handleError(res, saveErr); + } + return res.status(200).json({ message: 'Login successful' }); + });🤖 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/controllers/devportalController.js` around lines 474 - 479, The req.session.save() callback does not handle potential errors from the session store write operation. Currently, if the session save fails, the code still returns a 200 success response to the client even though the session was not persisted. Add error handling to the req.session.save() callback by accepting an error parameter, checking if an error occurred, and if so, log the error and return an appropriate error response using util.handleError before attempting to send the success response.
409-415:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMirror the local-auth guards before calling Platform API.
The view login path disables local login when an IdP is configured and rejects missing credentials first; this API login path should do the same to keep authentication behavior consistent.
Proposed fix
const login = async (req, res) => { - const { username, password } = req.body; + const { username, password } = req.body || {}; + + if (config.identityProvider?.clientId) { + return res.status(404).json({ message: 'Not found' }); + } + + if (!username || !password) { + return res.status(400).json({ message: 'Username and password are required' }); + } const platformApiUrl = config.platformApi?.baseUrl;🤖 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/controllers/devportalController.js` around lines 409 - 415, The login function in devportalController.js needs to implement the same authentication guards that exist in the view login path for consistency. Before attempting to call the Platform API, add validation to check if an IdP is configured (and reject local login if it is) and verify that username and password credentials are provided in the request. These checks should happen after extracting the credentials from req.body but before checking the platformApiUrl configuration, ensuring the API endpoint enforces the same authentication behavior as the view login path.
🤖 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.
Outside diff comments:
In `@portals/developer-portal/src/controllers/devportalController.js`:
- Around line 474-479: The req.session.save() callback does not handle potential
errors from the session store write operation. Currently, if the session save
fails, the code still returns a 200 success response to the client even though
the session was not persisted. Add error handling to the req.session.save()
callback by accepting an error parameter, checking if an error occurred, and if
so, log the error and return an appropriate error response using
util.handleError before attempting to send the success response.
- Around line 409-415: The login function in devportalController.js needs to
implement the same authentication guards that exist in the view login path for
consistency. Before attempting to call the Platform API, add validation to check
if an IdP is configured (and reject local login if it is) and verify that
username and password credentials are provided in the request. These checks
should happen after extracting the credentials from req.body but before checking
the platformApiUrl configuration, ensuring the API endpoint enforces the same
authentication behavior as the view login path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6470a5b5-5586-4876-ac51-05e02ad218e9
📒 Files selected for processing (8)
portals/developer-portal/distribution/docker-compose.yamlportals/developer-portal/docker-compose.yamlportals/developer-portal/docs/administer/manage-organizations.mdportals/developer-portal/src/config/configLoader.jsportals/developer-portal/src/controllers/authController.jsportals/developer-portal/src/controllers/devportalController.jsportals/developer-portal/src/middlewares/ensureAuthenticated.jsportals/developer-portal/src/openapi/middleware/auth.js
🚧 Files skipped from review as they are similar to previous changes (7)
- portals/developer-portal/src/config/configLoader.js
- portals/developer-portal/distribution/docker-compose.yaml
- portals/developer-portal/docs/administer/manage-organizations.md
- portals/developer-portal/docker-compose.yaml
- portals/developer-portal/src/controllers/authController.js
- portals/developer-portal/src/middlewares/ensureAuthenticated.js
- portals/developer-portal/src/openapi/middleware/auth.js
|
@coderabbitai review |
✅ Action performedReview finished.
|
Purpose
$subject
Goals
Using platform API for the local auth
Approach
Added platform API to the distribution
Reused the platfrom API's file based auth in the devportal
successful login will return the JWT, and it will be stored in the devportal backend session
Removed support for basic auth for REST APIs. Users has to use the login ednpoint to get a token and use that with the RestAPIs.