Skip to content

W-24224590: Select request authentication by path - #4175

Merged
wmathurin merged 2 commits into
forcedotcom:devfrom
wmathurin:W-24224590-ui-sid-bearer-path
Sep 22, 2026
Merged

wmathurin merged 2 commits into
forcedotcom:devfrom
wmathurin:W-24224590-ui-sid-bearer-path

Conversation

@wmathurin

@wmathurin wmathurin commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Let SalesforceSDKManager synchronously choose ui_sid Bearer authentication by request path when a DPoP access token is present.
  • Default the policy to select no paths; apps opt specific paths into ui_sid Bearer, and all other requests keep DPoP.
  • Centralize the decision in REST authentication handling and add coverage for policy, fallback, nonce, and race behavior.
  • Update DPoP authentication documentation.

Test plan

  • Focused SalesforceSDKCore unit tests: 79 passed.
  • SalesforceSDKCore build: passed.

@github-actions

Copy link
Copy Markdown
1 Warning
⚠️ Static Analysis found an issue with one or more files you modified. Please fix the issue(s).

Clang Static Analysis Issues

File Type Category Description Line Col
SalesforceSDKManager Nil value used as mutex for @synchronized() (no synchronization will occur) Logic error Nil value used as mutex for @synchronized() (no synchronization will occur) 171 5
SalesforceSDKManager Nil value used as mutex for @synchronized() (no synchronization will occur) Logic error Nil value used as mutex for @synchronized() (no synchronization will occur) 183 5

Generated by 🚫 Danger

@github-actions

Copy link
Copy Markdown
TestsPassedSkippedFailed ❌️
AuthFlowTester UI Test Results all1 ran1 ❌
TestResult
AuthFlowTester UI Test Results all
AuthFlowTesterUITests.xctest
LegacyLoginTests.testCAOpaque_DefaultScopes_WebServerFlow()❌ failure

@codecov

codecov Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.82%. Comparing base (d796edb) to head (ef4aae7).
⚠️ Report is 3 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #4175      +/-   ##
==========================================
- Coverage   71.82%   67.82%   -4.00%     
==========================================
  Files         254      254              
  Lines       23027    23045      +18     
==========================================
- Hits        16539    15631     -908     
- Misses       6488     7414     +926     
Components Coverage Δ
Analytics 70.78% <ø> (ø)
Common 71.20% <ø> (ø)
Core 61.72% <100.00%> (-5.97%) ⬇️
SmartStore 73.45% <ø> (ø)
MobileSync 88.84% <ø> (-0.03%) ⬇️
Files with missing lines Coverage Δ
...forceSDKCore/Classes/Common/SalesforceSDKManager.m 75.80% <100.00%> (-1.15%) ⬇️
...Core/Classes/OAuth/DPoP/DPoPRequestDecorator.swift 96.10% <100.00%> (+0.58%) ⬆️
...Core/SalesforceSDKCore/Classes/RestAPI/SFRestAPI.m 89.08% <100.00%> (-2.18%) ⬇️
.../SalesforceSDKCore/Classes/RestAPI/SFRestRequest.m 95.11% <100.00%> (-0.05%) ⬇️

... and 33 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown
TestsPassed ☑️SkippedFailed ❌️
SalesforceSDKCore iOS ^18 Test Results1052 ran1051 ✅1 ❌
TestResult
SalesforceSDKCore iOS ^18 Test Results
testAccessToken()❌ failure

@sfdctaka sfdctaka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full diff plus surrounding source (DPoPRequestDecorator, SFRestAPI, SFRestRequest, credential model). This is tightly scoped and well-tested — approving.

Verified it holds up:

  • Gate is consistent end to end. isDPoPTokenType && uiSid nonempty && policy(path), and the credential model only ever populates uiSid for DPoP tokens and clears it on downgrade, so the invariant lines up.
  • Nonce-retry gate has no false negatives. Genuine DPoP requests still carry both Authorization: DPoP … and the proof header, so the anchored/case-insensitive check keeps the retry; Bearer <ui_sid> attempts correctly skip it. finalRequest is the stamped request, so it's the right object to inspect.
  • Other call sites stay DPoP. Identity and revoke/refresh remain on the 4-arg overload — only the REST client path opts into the policy. Good.
  • Additive, backward-compatible public API with doc comments; setValue(nil, …) header removal is asserted by the LWR test.

Two non-blocking notes:

  1. Expired ui_sid → 401 replay. A Bearer <ui_sid> /lwr request that 401s runs normal token refresh; replay works only if the refresh updates uiSid (it does), and degrades gracefully to DPoP if a refresh returns no ui_sid. Worth a quick sanity-check against a live LWR org.
  2. Subtle (practically inert) semantic change. SFRestRequest moved from the 4-arg overload (strict token-type) to the credentials overload (shouldAttachDPoP, with the nil-token-type key-material fallback). Can't flip behavior in practice since tokenType is always persisted for logged-in users and no REST calls happen in the /authorize→/token window — just flagging that the gate changed.

@wmathurin
wmathurin merged commit b3ccc43 into forcedotcom:dev Sep 22, 2026
21 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants