fix(oauth): updated oauth providers that had unstable reference IDs leading to duplicate oauth records (#2441)
-
fix(oauth): updated oauth providers that had unstable reference IDs leading to duplicate oauth records
-
ack PR comments
Summary
Brief description of what this PR does and why.
Fixes #(issue)
Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation
- [ ] Other: ___________
Testing
How has this been tested? What should reviewers focus on?
Checklist
- [ ] Code follows project style guidelines
- [ ] Self-reviewed my changes
- [ ] Tests added/updated and passing
- [ ] No new warnings introduced
- [ ] I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)
Screenshots/Videos
The latest updates on your projects. Learn more about Vercel for GitHub.
Greptile Summary
This PR modernizes Salesforce OAuth to support Production, Sandbox (Developer Edition), and Custom Domain (My Domain) organizations through a flexible multi-endpoint authentication flow.
Key Changes:
- Replaced framework-based OAuth provider with custom routes (
/api/auth/salesforce/authorizeand/api/auth/oauth2/callback/salesforce) to support org type selection - Implemented proper PKCE flow with secure cookie-based state management
- Store both
instanceUrl(for API calls) andauthBaseUrl(for token refresh) as JSON in theidTokenfield - Modified account creation hook to replace existing accounts by
(userId, providerId)instead of(userId, providerId, accountId), allowing users to reconnect different Salesforce orgs - Added
refreshSalesforceTokenwith intelligent fallback: tries storedauthBaseUrlfirst, then production endpoint, then sandbox endpoint - Created
parseSalesforceMetadatautility with backward compatibility for legacy token formats (JSON, raw URL, JWT) - Updated all Salesforce tool blocks to use the new metadata parser
Previous Thread Resolutions: Most security concerns from previous threads have been addressed:
- XSS risk mitigated through proper HTML escaping in inline script
- Open redirect vulnerability fixed with origin validation (lines 197-202 in callback)
- Custom domain validation properly enforced server-side (line 285 in authorize)
- Token refresh now supports custom domains through stored
authBaseUrl
Unrelated Change:
The Wealthbox provider changes (lines 725-738 in auth.ts) appear unrelated to Salesforce improvements and change ID generation from timestamp-based to static, which could cause issues.
Confidence Score: 4/5
- This PR is safe to merge with only minor concerns about an unrelated change
- The Salesforce OAuth implementation is solid with proper security measures (PKCE, state validation, origin checks). Previous security concerns have been addressed. The score is 4 instead of 5 due to the unrelated Wealthbox changes that should ideally be in a separate PR.
- The Wealthbox changes in
apps/sim/lib/auth/auth.ts(lines 725-738) are unrelated and change behavior in a way that may need verification
Important Files Changed
| Filename | Overview |
|---|---|
| apps/sim/app/api/auth/salesforce/authorize/route.ts | New authorization flow with org type selection (production/sandbox/custom domain), PKCE implementation, and custom HTML form. Client-side validation exists but server-side validation on line 285 properly enforces format. |
| apps/sim/app/api/auth/oauth2/callback/salesforce/route.ts | OAuth callback handler with proper state/PKCE validation, token exchange, and stores instanceUrl + authBaseUrl as JSON in idToken field. returnUrl validation improved from previous thread concerns. |
| apps/sim/lib/oauth/oauth.ts | Added Salesforce token refresh with fallback endpoints (authBaseUrl → production → sandbox). Properly extracts authBaseUrl from idToken JSON metadata and tries multiple endpoints sequentially. |
| apps/sim/lib/auth/auth.ts | Modified account creation hook to replace existing accounts by (userId, providerId) instead of (userId, providerId, accountId), allowing users to reconnect different Salesforce orgs. Removed old Salesforce provider config. |
| apps/sim/tools/salesforce/utils.ts | Added parseSalesforceMetadata helper supporting multiple formats (JSON, raw URL, JWT) for backward compatibility with legacy data. |
Sequence Diagram
sequenceDiagram
participant User
participant Browser
participant AuthRoute as Salesforce Authorize
participant SF as Salesforce
participant Callback as Callback Handler
participant DB
User->>Browser: Click Connect Salesforce
Browser->>AuthRoute: Request without orgType
AuthRoute->>Browser: HTML form with org options
Browser->>User: Show form
User->>Browser: Select Production/Sandbox/Custom
Browser->>AuthRoute: Request with orgType
AuthRoute->>AuthRoute: Validate custom domain
AuthRoute->>AuthRoute: Generate PKCE
AuthRoute->>Browser: Set secure cookies
Browser->>SF: OAuth authorization
SF->>User: Login prompt
User->>SF: Authenticate
SF->>Callback: Return auth code
Callback->>Callback: Verify state and PKCE
Callback->>SF: Exchange code for token
SF->>Callback: Access token and instanceUrl
Callback->>Callback: Build metadata JSON
Callback->>DB: Save or update account
Callback->>Browser: Redirect to app
Note over DB: Token Refresh Later
DB->>SF: Refresh with authBaseUrl
alt Primary endpoint works
SF->>DB: New token
else Try production fallback
SF->>DB: New token
else Try sandbox fallback
SF->>DB: New token
end
@greptile
@greptile