Skip to content

feat: move expires_in field after scope in OAuth2 datasource config#41623

Open
shanliuling wants to merge 3 commits intoappsmithorg:releasefrom
shanliuling:feat/move-expires-in-after-scope
Open

feat: move expires_in field after scope in OAuth2 datasource config#41623
shanliuling wants to merge 3 commits intoappsmithorg:releasefrom
shanliuling:feat/move-expires-in-after-scope

Conversation

@shanliuling
Copy link

@shanliuling shanliuling commented Mar 16, 2026

Description

This PR moves the expires_in field to appear after the scope field in the OAuth2 datasource configuration, keeping all authentication-related fields together for better UX.

Fixes #31059

Changes

  • Moved expiresIn input field from renderOauth2AuthorizationCode to renderOauth2Common (after scopeString)
  • This ensures the field appears right after the Scope(s) input in all OAuth2 authorization flows

Testing

  • Verified the field order change in the code
  • The field now appears: Access token URL → Client ID → Client secret → Scope(s) → Authorization expires in

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Summary by CodeRabbit

  • Refactor
    • Moved the OAuth2 "Authorization expires in (seconds)" field into the Authorization Code flow of the REST API datasource form, changing its placement in the UI without affecting validation or data shapes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7db5efc7-dd13-400c-8ed4-f90aa91797da

📥 Commits

Reviewing files that changed from the base of the PR and between 6b52e22 and c17a9e6.

📒 Files selected for processing (1)
  • app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx

Walkthrough

The authentication.expiresIn input was relocated within RestAPIDatasourceForm.tsx: the field was added inside the Authorization Code flow render (after the common OAuth2 content) and the previous expiresIn input block (after authentication.customAuthenticationParameters) was removed. No validation or data-shape changes.

Changes

Cohort / File(s) Summary
OAuth2 ExpiresIn relocation
app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx
Moved the authentication.expiresIn input into the Authorization Code-specific rendering path (placed directly after the common OAuth2 content). Removed the now-duplicated expiresIn block that existed after authentication.customAuthenticationParameters. No validation/data-shape edits.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🔁 A little field took a graceful hop,
From one form corner to the OAuth Code stop.
Now scope and expiry sit side by side,
Users spot them quick — no need to hide. 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: moving the expires_in field to appear after scope in OAuth2 configuration.
Description check ✅ Passed The description covers the key aspects: what changed, why it changed, the fix reference, and testing verification. Follows the template structure adequately.
Linked Issues check ✅ Passed The PR satisfies the objective from #31059 by relocating the expiresIn field to appear after the scope field in OAuth2 configuration for improved UX.
Out of Scope Changes check ✅ Passed All changes are scoped to relocating the expiresIn field position within RestAPIDatasourceForm.tsx; no extraneous modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can use your project's `biome` configuration to improve the quality of JS/TS/CSS/JSON code reviews.

Add a configuration file to your project to customize how CodeRabbit runs biome.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx`:
- Around line 686-695: The expiresIn field is rendered inside
renderOauth2Common() but per RestAPIForm.ts it belongs only to
AuthorizationCode; update the rendering so the FormInputContainer with
configProperty "authentication.expiresIn" (the
renderInputTextControlViaFormControl call) is shown only when the OAuth grant
type equals Authorization Code (e.g., check the grantType/auth.grantType value
or use the renderAuthorizationCode() path) instead of unconditionally in
renderOauth2Common(); either move the field into the Authorization Code render
helper or wrap it with a conditional like grantType === 'AUTHORIZATION_CODE' so
Client Credentials no longer sees the expiresIn input.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a7c93df2-9736-4cae-b6dd-f252b7f818c2

📥 Commits

Reviewing files that changed from the base of the PR and between d56a4c6 and 6b52e22.

📒 Files selected for processing (1)
  • app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx

Comment on lines +686 to +695
<FormInputContainer data-location-id={btoa("authentication.expiresIn")}>
{this.renderInputTextControlViaFormControl({
configProperty: "authentication.expiresIn",
label: "Authorization expires in (seconds)",
placeholderText: "3600",
dataType: "NUMBER",
encrypted: false,
isRequired: false,
})}
</FormInputContainer>
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:

#!/bin/bash
# Description: Verify expiresIn is only defined on AuthorizationCode interface

echo "=== Checking Oauth2Common interface ==="
rg -nA 15 'interface Oauth2Common' --type=ts

echo ""
echo "=== Checking ClientCredentials interface ==="
rg -nA 8 'interface ClientCredentials' --type=ts

echo ""
echo "=== Checking AuthorizationCode interface ==="
rg -nA 10 'interface AuthorizationCode' --type=ts

Repository: appsmithorg/appsmith

Length of output: 3132


🏁 Script executed:

#!/bin/bash
# Search for the render method definitions and their calls to renderOauth2Common

echo "=== Finding renderOauth2Common calls ==="
rg -n 'renderOauth2Common' app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx

echo ""
echo "=== Checking renderOauth2ClientCredentials and renderOauth2AuthorizationCode method signatures ==="
rg -n -A 3 'renderOauth2ClientCredentials|renderOauth2AuthorizationCode' app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx

Repository: appsmithorg/appsmith

Length of output: 918


🏁 Script executed:

#!/bin/bash
# Check GrantType import and verify formData accessibility

echo "=== Checking GrantType import ==="
rg -n 'import.*GrantType|from.*GrantType' app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx | head -5

echo ""
echo "=== Checking how grantType is accessed elsewhere ==="
rg -n 'grantType' app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx | head -10

echo ""
echo "=== Checking formData usage pattern in render methods ==="
rg -n 'formData\.authentication' app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx | head -5

Repository: appsmithorg/appsmith

Length of output: 1255


🏁 Script executed:

#!/bin/bash
# Check top of file for GrantType import

echo "=== Checking file imports ==="
head -50 app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx | rg -n 'import|GrantType'

echo ""
echo "=== Verifying GrantType is available ==="
rg -n 'enum GrantType|type GrantType' --type=ts

Repository: appsmithorg/appsmith

Length of output: 1732


expiresIn field now incorrectly appears for Client Credentials grant type.

Per the TypeScript interfaces in RestAPIForm.ts, expiresIn is defined only on AuthorizationCode, not on ClientCredentials or Oauth2Common. By placing this field in renderOauth2Common(), it renders for both grant types, violating the type contract and exposing an irrelevant field for Client Credentials flow.

Conditionally render only for Authorization Code grant type:

Suggested fix
+        {_.get(formData.authentication, "grantType") ===
+          GrantType.AuthorizationCode && (
         <FormInputContainer data-location-id={btoa("authentication.expiresIn")}>
           {this.renderInputTextControlViaFormControl({
             configProperty: "authentication.expiresIn",
             label: "Authorization expires in (seconds)",
             placeholderText: "3600",
             dataType: "NUMBER",
             encrypted: false,
             isRequired: false,
           })}
         </FormInputContainer>
+        )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<FormInputContainer data-location-id={btoa("authentication.expiresIn")}>
{this.renderInputTextControlViaFormControl({
configProperty: "authentication.expiresIn",
label: "Authorization expires in (seconds)",
placeholderText: "3600",
dataType: "NUMBER",
encrypted: false,
isRequired: false,
})}
</FormInputContainer>
{_.get(formData.authentication, "grantType") ===
GrantType.AuthorizationCode && (
<FormInputContainer data-location-id={btoa("authentication.expiresIn")}>
{this.renderInputTextControlViaFormControl({
configProperty: "authentication.expiresIn",
label: "Authorization expires in (seconds)",
placeholderText: "3600",
dataType: "NUMBER",
encrypted: false,
isRequired: false,
})}
</FormInputContainer>
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx`
around lines 686 - 695, The expiresIn field is rendered inside
renderOauth2Common() but per RestAPIForm.ts it belongs only to
AuthorizationCode; update the rendering so the FormInputContainer with
configProperty "authentication.expiresIn" (the
renderInputTextControlViaFormControl call) is shown only when the OAuth grant
type equals Authorization Code (e.g., check the grantType/auth.grantType value
or use the renderAuthorizationCode() path) instead of unconditionally in
renderOauth2Common(); either move the field into the Authorization Code render
helper or wrap it with a conditional like grantType === 'AUTHORIZATION_CODE' so
Client Credentials no longer sees the expiresIn input.

@github-actions
Copy link

This PR has not seen activitiy for a while. It will be closed in 7 days unless further activity is detected.

@github-actions github-actions bot added the Stale label Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task]: Move expires_in field after scope while configuring oauth2 datasource

1 participant