Skip to content

feat(rn-oidc): add device authorization grant support (SDKS-5166) - #69

Merged
pingidentity-gaurav merged 4 commits into
mainfrom
feat/SDKS-5166-oidc-device-flow
Sep 10, 2026
Merged

feat(rn-oidc): add device authorization grant support (SDKS-5166)#69
pingidentity-gaurav merged 4 commits into
mainfrom
feat/SDKS-5166-oidc-device-flow

Conversation

@pingidentity-gaurav

Copy link
Copy Markdown
Contributor

Summary

  • Add RFC 8628 Device Authorization Grant support to @ping-identity/rn-oidc: createOidcDeviceClient, useDeviceAuthGrant hook with DeviceAuthGrantProvider, and the new deviceOpenVerificationUrl / openVerificationUrl API for on-device browser approval
  • Bridge the grant end-to-end on iOS (SFSafariViewController) and Android (Custom/Auth Tab), TurboModule + classic bridge on both platforms
  • Support partial openId endpoint overrides (notably deviceAuthorizationEndpoint for Advanced Identity Cloud) with merge-onto-discovery semantics in rn-oidc, rn-journey, and rn-core
  • Add verification-uri start option support across Journey and DaVinci flows for approve-device scenarios
  • Sample app: new Device Authorization screen with verify sheet (DaVinci / Journey / Browser approval paths), token and user-profile panels
  • READMEs: document device-grant approval via hooks (journey, davinci, oidc)

Test plan

  • yarn workspace @ping-identity/rn-oidc test - 48/48 (facade, hook, client-swap, openVerificationUrl tests)
  • All 17 package jest suites pass; lint, typecheck, prettier clean
  • iOS RNPackagesTests - 167/167 (incl. new missing-handle rejection test)
  • Android :ping-identity_rn-oidc:compileDebugKotlin - clean rebuild
  • Manual device-grant flow on iOS simulator and Android emulator (PingOne + AIC presets)

Changesets

  • device-auth-grant-hook, oidc-partial-openid-override-and-cancel-fix, oidc-openid-config-optional-fields, journey-partial-openid-override, core-openid-config-optional-fields, journey-verification-uri, davinci-verification-uri, device-open-verification-url

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 104 files, which is 4 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: d4688ee6-0d62-4877-9553-0a0873c49812

📥 Commits

Reviewing files that changed from the base of the PR and between 496b149 and 394895a.

⛔ Files ignored due to path filters (3)
  • .yarn/install-state.gz is excluded by !**/.yarn/**, !**/*.gz
  • PingTestRunner/ios/Podfile.lock is excluded by !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (104)
  • PingSampleApp/.env.example
  • PingSampleApp/App.tsx
  • PingSampleApp/__tests__/extractUserCode.test.ts
  • PingSampleApp/package.json
  • PingSampleApp/src/clients.ts
  • PingSampleApp/src/deviceAuthSession.ts
  • PingSampleApp/src/styles/common.ts
  • PingSampleApp/ui/ApproveDeviceScreen.tsx
  • PingSampleApp/ui/ConfigurationScreen.tsx
  • PingSampleApp/ui/DaVinciScreen.tsx
  • PingSampleApp/ui/DeviceAuthorizationScreen.tsx
  • PingSampleApp/ui/HomeScreen.tsx
  • PingSampleApp/ui/JourneyHelperScreen.tsx
  • PingSampleApp/ui/JourneyRouteScreen.tsx
  • PingSampleApp/ui/LogoutScreen.tsx
  • PingSampleApp/ui/TokenScreen.tsx
  • PingSampleApp/ui/UserProfileScreen.tsx
  • PingSampleApp/ui/components/molecules/CardSection.tsx
  • PingSampleApp/ui/components/molecules/EmptyStateCard.tsx
  • PingSampleApp/ui/components/molecules/UserCodeConfirmationBanner.tsx
  • PingSampleApp/ui/davinci/components/organisms/DaVinciClientPanel.tsx
  • PingSampleApp/ui/davinci/hooks/useDaVinciClientPanelController.ts
  • PingSampleApp/ui/journey/components/organisms/JourneyClientPanel.tsx
  • PingSampleApp/ui/oidc/components/organisms/OidcDeviceFlowPanel.tsx
  • PingSampleApp/ui/token/components/organisms/TokenDeviceAuthPanel.tsx
  • PingSampleApp/ui/userProfile/components/organisms/UserProfileAuthGrantPanel.tsx
  • PingSampleApp/ui/utils/extractUserCode.ts
  • PingTestRunner/App.tsx
  • PingTestRunner/e2e/oidc-device-flow.test.ts
  • PingTestRunner/scenarios/OidcDeviceFlowScenario.tsx
  • packages/core/android/src/main/java/com/pingidentity/rncore/oidc/OidcClientConfigHandle.kt
  • packages/core/ios/Oidc/OidcClientConfigHandle.swift
  • packages/davinci/README.md
  • packages/davinci/android/src/main/java/com/pingidentity/rndavinci/RNPingDavinciCommon.kt
  • packages/davinci/android/src/newarch/java/com/pingidentity/rndavinci/RNPingDavinciModule.kt
  • packages/davinci/android/src/oldarch/java/com/pingidentity/rndavinci/RNPingDavinciClassicModule.kt
  • packages/davinci/android/src/test/java/com/pingidentity/rndavinci/RNPingDavinciCommonTest.kt
  • packages/davinci/ios/RNPingDavinci.mm
  • packages/davinci/ios/RNPingDavinciClassic.mm
  • packages/davinci/ios/RNPingDavinciCommon.swift
  • packages/davinci/ios/RNPingDavinciImpl.swift
  • packages/davinci/ios/Tests/RNPingDavinciCommonTests.swift
  • packages/davinci/ios/Tests/RNPingDavinciImplTests.swift
  • packages/davinci/src/NativeRNPingDavinci.ts
  • packages/davinci/src/__tests__/createDaVinciClient.test.ts
  • packages/davinci/src/__tests__/davinci.test.ts
  • packages/davinci/src/__tests__/davinciMethods.test.ts
  • packages/davinci/src/davinci.ts
  • packages/davinci/src/davinciMethods.ts
  • packages/davinci/src/types/client.types.ts
  • packages/davinci/src/types/config.types.ts
  • packages/davinci/src/useDavinci.tsx
  • packages/journey/README.md
  • packages/journey/android/src/main/java/com/pingidentity/rnjourney/RNPingJourneyCommon.kt
  • packages/journey/android/src/main/java/com/pingidentity/rnjourney/config/JourneyConfigParser.kt
  • packages/journey/android/src/main/java/com/pingidentity/rnjourney/factory/JourneyClientFactory.kt
  • packages/journey/android/src/test/java/com/pingidentity/rnjourney/config/JourneyConfigParserTest.kt
  • packages/journey/android/src/test/java/com/pingidentity/rnjourney/factory/JourneyClientFactoryTest.kt
  • packages/journey/ios/Config/JourneyConfigParser.swift
  • packages/journey/ios/Factory/JourneyClientFactory.swift
  • packages/journey/ios/Models/JourneyPayloads.swift
  • packages/journey/ios/RNPingJourney.mm
  • packages/journey/ios/RNPingJourneyCommon.swift
  • packages/journey/ios/RNPingJourneyImpl.swift
  • packages/journey/ios/Tests/JourneyClientFactoryTests.swift
  • packages/journey/ios/Tests/JourneyConfigParserTests.swift
  • packages/journey/ios/Tests/RNPingJourneyCommonTests.swift
  • packages/journey/src/NativeRNPingJourney.ts
  • packages/journey/src/types/config.types.ts
  • packages/oidc/README.md
  • packages/oidc/android/src/main/java/com/pingidentity/rnoidc/OidcClientFactory.kt
  • packages/oidc/android/src/main/java/com/pingidentity/rnoidc/OidcConfigParser.kt
  • packages/oidc/android/src/main/java/com/pingidentity/rnoidc/OidcErrorCodes.kt
  • packages/oidc/android/src/main/java/com/pingidentity/rnoidc/OidcResponseMapper.kt
  • packages/oidc/android/src/main/java/com/pingidentity/rnoidc/RNPingOidcCommon.kt
  • packages/oidc/android/src/newarch/java/com/pingidentity/rnoidc/RNPingOidcModule.kt
  • packages/oidc/android/src/oldarch/java/com/pingidentity/rnoidc/RNPingOidcClassicModule.kt
  • packages/oidc/android/src/test/java/com/pingidentity/rnoidc/OidcClientFactoryTest.kt
  • packages/oidc/android/src/test/java/com/pingidentity/rnoidc/OidcConfigParserTest.kt
  • packages/oidc/ios/DeviceTaskStore.swift
  • packages/oidc/ios/OidcClientFactory.swift
  • packages/oidc/ios/OidcConfigParser.swift
  • packages/oidc/ios/OidcPayloads.swift
  • packages/oidc/ios/OidcRegistryHandles.swift
  • packages/oidc/ios/RNPingOidc.mm
  • packages/oidc/ios/RNPingOidcClassic.mm
  • packages/oidc/ios/RNPingOidcCommon.swift
  • packages/oidc/ios/RNPingOidcEventEmitterGate.h
  • packages/oidc/ios/RNPingOidcEventEmitterGate.mm
  • packages/oidc/ios/RNPingOidcEvents.swift
  • packages/oidc/ios/RNPingOidcImpl.swift
  • packages/oidc/ios/Tests/OidcClientFactoryTests.swift
  • packages/oidc/ios/Tests/OidcConfigParserTests.swift
  • packages/oidc/ios/Tests/RNPingOidcCommonTests.swift
  • packages/oidc/jest.config.js
  • packages/oidc/jest.setup.js
  • packages/oidc/src/NativeRNPingOidc.ts
  • packages/oidc/src/__tests__/index.test.tsx
  • packages/oidc/src/__tests__/useDeviceAuthGrant.test.tsx
  • packages/oidc/src/deviceOpenVerificationUrl.ts
  • packages/oidc/src/index.tsx
  • packages/oidc/src/types/oidc.types.ts
  • packages/oidc/src/useDeviceAuthGrant.tsx
  • packages/types/src/oidc.types.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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.

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 45.50265% with 515 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.39%. Comparing base (496b149) to head (394895a).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
packages/oidc/ios/RNPingOidcCommon.swift 4.04% 166 Missing ⚠️
...n/java/com/pingidentity/rnoidc/RNPingOidcCommon.kt 0.00% 124 Missing ⚠️
packages/oidc/src/useDeviceAuthGrant.tsx 74.31% 33 Missing and 23 partials ⚠️
.../java/com/pingidentity/rnoidc/OidcClientFactory.kt 0.00% 43 Missing ⚠️
packages/oidc/ios/DeviceTaskStore.swift 0.00% 28 Missing ⚠️
...java/com/pingidentity/rnoidc/OidcResponseMapper.kt 0.00% 26 Missing ⚠️
packages/oidc/ios/RNPingOidcImpl.swift 0.00% 23 Missing ⚠️
...h/java/com/pingidentity/rnoidc/RNPingOidcModule.kt 0.00% 11 Missing ⚠️
.../com/pingidentity/rndavinci/RNPingDavinciCommon.kt 0.00% 8 Missing ⚠️
.../com/pingidentity/rnjourney/RNPingJourneyCommon.kt 0.00% 6 Missing ⚠️
... and 7 more

❌ Your patch status has failed because the patch coverage (45.50%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project status has failed because the head coverage (71.39%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##               main      #69      +/-   ##
============================================
- Coverage     73.09%   71.39%   -1.70%     
- Complexity      261      265       +4     
============================================
  Files           167      180      +13     
  Lines         21637    23275    +1638     
  Branches        779     1027     +248     
============================================
+ Hits          15816    16618     +802     
- Misses         5732     6502     +770     
- Partials         89      155      +66     
Flag Coverage Δ
android 17.53% <7.05%> (-0.90%) ⬇️
ios 81.31% <49.56%> (-0.86%) ⬇️
javascript 70.40% <75.60%> (-17.28%) ⬇️
Components Coverage Δ
Bridge glue 50.41% <9.35%> (-2.11%) ⬇️
Pure logic 81.89% <90.47%> (-0.11%) ⬇️
Files with missing lines Coverage Δ
...ackages/core/ios/Oidc/OidcClientConfigHandle.swift 100.00% <100.00%> (ø)
packages/davinci/ios/RNPingDavinciImpl.swift 47.05% <100.00%> (+7.05%) ⬆️
...s/davinci/ios/Tests/RNPingDavinciCommonTests.swift 95.42% <100.00%> (+0.01%) ⬆️
...ges/davinci/ios/Tests/RNPingDavinciImplTests.swift 96.72% <100.00%> (+0.05%) ⬆️
packages/davinci/src/NativeRNPingDavinci.ts 92.00% <100.00%> (ø)
packages/davinci/src/davinci.ts 91.01% <100.00%> (ø)
packages/davinci/src/davinciMethods.ts 74.57% <100.00%> (ø)
packages/davinci/src/useDavinci.tsx 80.48% <100.00%> (ø)
...kages/journey/ios/Config/JourneyConfigParser.swift 98.52% <100.00%> (-0.13%) ⬇️
packages/journey/ios/Models/JourneyPayloads.swift 100.00% <ø> (ø)
... and 30 more

... and 7 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 496b149...394895a. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://ForgeRock.github.io/ping-react-native-sdk/docs-preview/pr-69/

Built to branch gh-pages at 2026-09-10 16:28 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Comment thread packages/davinci/README.md
Comment thread packages/journey/README.md

@rodrigoareis rodrigoareis 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.

Overall changes looks good. Left comments

Comment thread packages/oidc/android/src/main/java/com/pingidentity/rnoidc/RNPingOidcCommon.kt Outdated
Comment thread packages/oidc/ios/RNPingOidcCommon.swift
Comment thread packages/oidc/ios/RNPingOidc.mm
Comment thread packages/core/ios/Oidc/OidcClientConfigHandle.swift
@tsdamas

tsdamas commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

PR reviewed. Left some comments.

Restore displaced createWebClient KDoc/annotation in Android modules; add KDoc to new device APIs (Android modules, iOS Common/Impl). Swap Android device registry to SimpleRegistry. Verify deviceClientId ownership before cancelling flows on both platforms (iOS DeviceTaskStore owner map with atomic remove(ownedBy:) and cancelAll(for:)). Cancel owned tasks before registry removal on iOS dispose. Document nextPollAt epoch-ms unit contract. Map all 10 missing config fields in RNPingOidc.mm createOidcDeviceClient for TurboModule parity. Wire deviceAuthorizationEndpoint end-to-end through core OidcOpenIdConfig, OIDC handles, and Journey parser/override paths. Restore README sections replaced by device-grant docs. Add Detox E2E for the device-flow scenario (expired/accessDenied/failure).

@tsdamas tsdamas 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.

LGTM

@rodrigoareis rodrigoareis 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.

LGTM

@pingidentity-gaurav
pingidentity-gaurav merged commit dd13a45 into main Sep 10, 2026
4 of 6 checks passed
@pingidentity-gaurav
pingidentity-gaurav deleted the feat/SDKS-5166-oidc-device-flow branch September 10, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants