Skip to content

Improve WalletConfig and VPTokenSigningResult / UnsignedVPToken#124

Open
KiruthikaJeyashankar wants to merge 8 commits into
inji:developfrom
tw-mosip:lsh-feedback-1.0
Open

Improve WalletConfig and VPTokenSigningResult / UnsignedVPToken#124
KiruthikaJeyashankar wants to merge 8 commits into
inji:developfrom
tw-mosip:lsh-feedback-1.0

Conversation

@KiruthikaJeyashankar

@KiruthikaJeyashankar KiruthikaJeyashankar commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Wallet Config updates

Rename validatePreRegisteredVerifier → validateTrustedVerifier aligning with the trustedVerifiers convention
Remove supportedRequestUriMethods config

VPTokenSigningResult / UnsignedVPToken Updates

Include id in the VPTokenSigningResult / UnsignedVPToken data as random UUID
i. This id stays as the linkability factor for UnsignedVPToken and VPTokenSigningResult for building VP
ii. Ordering of UnsignedVPToken and VPTokenSigningResult does not matter, maintenance of order MAY add complexity to consumer considering that the the linkability factor as ID is introduced

Relates: inji/inji-wallet#2499

Summary by CodeRabbit

  • New Features

    • Improved identifier-based VP token and authorization-response construction across credential formats.
    • Added/updated wallet configuration for trusted-verifier validation.
  • Bug Fixes

    • Fixed request URI handling so unsupported .post methods are no longer silently downgraded.
    • Prevented duplicate response processing after request timeouts.
    • Strengthened VP token signing/validation matching to better align unsigned tokens, signing results, and identifiers.
  • Breaking Changes

    • Updated wallet configuration fields and VP token/signing result structures to include identifiers, affecting Codable and builder inputs.

    1. rename validatePreRegisteredVerifier -> validateTrustedVerifier
    2. remove supportedRequestUriMethods

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
- The id will be the linkability factor between data to be signed and signed data which is used for VP construction

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@KiruthikaJeyashankar, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 2 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d01aa418-ad47-41f4-9255-a7f651d66dcc

📥 Commits

Reviewing files that changed from the base of the PR and between ee62cc3 and a8e3c55.

📒 Files selected for processing (9)
  • Sources/OpenID4VP/AuthorizationResponse/AuthorizationResponseHandler.swift
  • Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/SdJwt/UnsignedSdJwtVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/VPTokenBuilderUtils.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/SdJwt/SdJwtVPTokenBuilder.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/Mdoc/MdocVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/SdJwt/SdJwtVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/VPTokenBuilderUtilsTests.swift
  • Tests/OpenID4VPTests/Common/UtilsTest.swift

Walkthrough

WalletConfig now uses validateTrustedVerifier instead of validatePreRegisteredVerifier, and requestUriMethodsSupported is removed. VP token unsigned payloads and signing results now carry ids, and builders, helpers, and tests switch to identifier-based matching.

Changes

WalletConfig API Cleanup

Layer / File(s) Summary
Config contract and constants
Sources/OpenID4VP/Wallet/WalletConfig.swift, Sources/OpenID4VP/Constants/RequestUriMethod.swift, Sources/OpenID4VP/Constants/OpenId4VPSpecConstants/WalletMetadataConstants.swift
WalletConfig stores validateTrustedVerifier, updates coding keys, init, encode/decode, and defaults; RequestUriMethod becomes internal; requestUriMethodsSupported is removed from wallet metadata constants.
Authorization request handling
Sources/OpenID4VP/AuthorizationRequest/AuthorizationRequestHandler/types/PreRegisteredPrefixAuthorizationRequestHandler.swift, Sources/OpenID4VP/AuthorizationRequest/Utils/AuthorizationRequestUtils.swift, Sources/OpenID4VP/AuthorizationRequest/AuthorizationRequestHandler/ClientIdPrefixBasedAuthorizationRequestHandler.swift, Sources/OpenID4VP/NetworkManager/NetworkManager.swift
PreRegisteredPrefixAuthorizationRequestHandler and AuthorizationRequestUtils use validateTrustedVerifier; ClientIdPrefixBasedAuthorizationRequestHandler no longer downgrades POST request_uri_method to GET; NetworkManager returns immediately after timeout.
Tests: Wallet and request handling
Tests/OpenID4VPTests/Wallet/WalletConfigTests.swift, Tests/OpenID4VPTests/AuthorizationRequest/..., Tests/OpenID4VPTests/TestData/TestUtils.swift, Tests/OpenID4VPTests/OpenID4VPTests.swift
WalletConfig tests, authorization request tests, utilities, and integration tests switch to validateTrustedVerifier, drop requestUriMethodsSupported assertions, update request fixtures, and remove the POST fallback test.

VP Token Identifier Threading

Layer / File(s) Summary
VP token data model and protocol
Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/UnsignedVPToken.swift, Sources/OpenID4VP/AuthorizationResponse/VPTokenSigningResult/VpTokenSigningResult.swift, Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/UnsignedVPTokenBuilder.swift, Sources/OpenID4VP/AuthorizationResponse/AuthorizationResponseHandler.swift, Sources/OpenID4VP/AuthorizationResponse/VPToken/VPTokenBuilder.swift
UnsignedVPToken and VPTokenSigningResult add id; VPTokenSigningPayload narrows to [String: Any]; builder protocols use the typed payload; AuthorizationResponseHandler stores typed unsigned-token results.
Unsigned builders thread identifiers
Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/LdpVP/UnsignedLdpVPTokenBuilder.swift, Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/Mdoc/UnsignedMdocVPTokenBuilder.swift, Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/SdJwt/UnsignedSdJwtVPTokenBuilder.swift
All three builders generate identifiers, write them back to mappings, key payloads by identifier, and create UnsignedVPToken values with matching id fields.
Identifier lookup helpers
Sources/OpenID4VP/AuthorizationResponse/VPToken/VPTokenBuilderUtils.swift
Adds getVPTokenSigningResult and getUnsignedVPToken helpers that filter by id, enforce uniqueness, and throw typed errors on missing or duplicate matches.
Signed builders use identifier lookup
Sources/OpenID4VP/AuthorizationResponse/VPToken/types/LdpVp/LdpVPTokenBuilder.swift, Sources/OpenID4VP/AuthorizationResponse/VPToken/types/Mdoc/MdocVPTokenBuilder.swift, Sources/OpenID4VP/Common/Utils.swift
LdpVPTokenBuilder, MdocVPTokenBuilder, and constructSigningResults move from iterator-based matching to identifier-based lookup; MdocVPTokenBuilder extracts buildMdocVPToken; LdpVPTokenBuilder changes proof handling and descriptor iteration.
Tests: VP token and response flow
Tests/OpenID4VPTests/AuthorizationResponse/..., Tests/OpenID4VPTests/Common/UtilsTest.swift, Tests/OpenID4VPTests/OpenID4VPTests.swift, Tests/OpenID4VPTests/TestData/TestData.swift
Builder tests, response handler tests, signing-result tests, utility tests, and fixtures switch to id-based payloads and id-bearing signing results, and update error expectations to identifier-based messages.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • swatigoel

Poem

🐰 Hop, hop—new ids in the light,
Old verifier flags took flight.
Payloads now follow a name of their own,
And every token gets homeward shown.
A nibble of CBOR, a bounce through the chain,
Then UUID carrots sprout again.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.37% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is broad, but it correctly reflects the main API changes to WalletConfig, VPTokenSigningResult, and UnsignedVPToken.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (2)
Tests/OpenID4VPTests/TestData/TestUtils.swift (1)

296-306: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename the helper argument to match the updated API terminology.

Keeping validatePreregisteredVerifier in this shared test utility makes the migration look partial and can mislead future test updates.

♻️ Suggested patch
-    validatePreregisteredVerifier: Bool = true
+    validateTrustedVerifier: Bool = true
 ) -> WalletConfig {
     return WalletConfig(
@@
-        validateTrustedVerifier: validatePreregisteredVerifier
+        validateTrustedVerifier: validateTrustedVerifier
     )
 }
🤖 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 `@Tests/OpenID4VPTests/TestData/TestUtils.swift` around lines 296 - 306, Rename
the function parameter `validatePreregisteredVerifier` to
`validateTrustedVerifier` to align with the updated API terminology reflected in
the WalletConfig field name. This change should be made in the function
signature where the parameter is declared with its default value, and then use
the renamed parameter in the subsequent WalletConfig initialization where it is
assigned to the validateTrustedVerifier property.
Tests/OpenID4VPTests/AuthorizationRequest/AuthorizationRequestHandler/ClientIdPrefixBasedAuthorizationRequestTests.swift (1)

91-91: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make wallet_nonce explicit in the request-object payload setup.

This path now validates POST semantics; explicitly injecting wallet_nonce here avoids hidden fixture coupling and makes the test intent clearer.

♻️ Suggested patch
-        let requestUriResponse = createRequestUriResponse(createAuthorizationRequestObject(clientIdPrefix: .decentralizedIdentifier, authorizationRequestParams: mergeMaps(authorizationRequestParamsWithValue, DidSchemeClientIdParameters[.v1]!), applicableFields: authRequestWithDidByValue + [AuthorizationRequestFieldConstants.walletNonce], specVersion: .draft23) )
+        let requestUriResponse = createRequestUriResponse(
+            createAuthorizationRequestObject(
+                clientIdPrefix: .decentralizedIdentifier,
+                authorizationRequestParams: mergeMaps(
+                    authorizationRequestParamsWithValue,
+                    DidSchemeClientIdParameters[.v1]!,
+                    [AuthorizationRequestFieldConstants.walletNonce: "mock-nonce"]
+                ),
+                applicableFields: authRequestWithDidByValue + [AuthorizationRequestFieldConstants.walletNonce],
+                specVersion: .draft23
+            )
+        )
🤖 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
`@Tests/OpenID4VPTests/AuthorizationRequest/AuthorizationRequestHandler/ClientIdPrefixBasedAuthorizationRequestTests.swift`
at line 91, The test is implicitly relying on fixture coupling for wallet_nonce
instead of explicitly injecting it into the request object. Modify the
createAuthorizationRequestObject call to explicitly pass wallet_nonce as a
parameter value in the authorizationRequestParams (using mergeMaps to include
it) rather than only specifying it in the applicableFields array, so that the
test clearly shows the actual wallet_nonce value being used and makes the POST
semantics validation intent explicit.
🤖 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
`@Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/Mdoc/UnsignedMdocVPTokenBuilder.swift`:
- Around line 36-49: The existingDocTypes set is no longer needed because the
payload is now keyed by per-credential identifier rather than docType, so
duplicate docTypes across credentials no longer cause collisions. Remove the
existingDocTypes variable declaration and eliminate the existingDocTypes
parameter from all calls to buildPayloadAndUnsignedVPToken throughout the file.
Also remove any logic that checks or updates this set, including at the other
locations mentioned (lines around 66-78 and 115-123).

In `@Sources/OpenID4VP/Common/Utils.swift`:
- Around line 254-264: The current implementation in the loop iterating over
unsignedVPTokenResults only collects matching VPTokenSigningResults for known
unsigned token identifiers, silently dropping any signing results with unmatched
ids. After the loop completes, add validation to check if all signing results
from signingResults have been accounted for by comparing the matched identifiers
against all identifiers in the original signingResults collection. If any
signing results have identifiers that were never matched to an unsigned token,
throw an error with details about which identifiers were unexpected instead of
silently ignoring them, ensuring the fail-fast behavior expected from the
caller-facing response construction path.

In
`@Tests/OpenID4VPTests/AuthorizationResponse/AuthorizationResponseHandlerTests.swift`:
- Around line 403-412: The test verifies that a missing signing result (when
constructUnsignedVPTokens drops the last token but VPTokenSigningResult only
maps the others) causes an error, but it only checks the wrapped server error on
line 425 and does not assert the underlying root cause. Add an assertion after
the wrapped error check to verify that the underlying cause of the error
specifically relates to the missing identifier-linked signing result, ensuring
the failure path is correctly diagnosed rather than just catching any server
error.

In
`@Tests/OpenID4VPTests/AuthorizationResponse/UnsignedVPToken/UnsignedMdocVPTokenBuilderTests.swift`:
- Around line 84-86: The test at lines 85 and 220 assumes each payload map
(draft23Payload and v1Payload) contains exactly one UUID-keyed entry but does
not assert this assumption before accessing .values.first. Add XCTAssertEqual
assertions to verify that the count property of each dictionary equals 1 before
extracting the first value, ensuring the test will fail if extra entries are
accidentally produced in the payload maps.

In
`@Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/SdJwt/SdJwtVPTokenBuilderTests.swift`:
- Line 30: The VPTokenSigningResult instances throughout the test file use
hardcoded id: "uuid1" values that do not match their corresponding mapping or
payload identifiers, which prevents proper testing of id-linkability behavior.
Update each VPTokenSigningResult(id:) call to use the actual identifier from its
associated mapping or payload rather than the hardcoded "uuid1" value. This
applies to all instances mentioned at lines 30, 110, 158, 211, 212, 431, 497,
544, 545, 617, 670, 702, 836, 884, and 931 where the id parameter should be
replaced with the correct corresponding identifier for that test case.

In
`@Tests/OpenID4VPTests/AuthorizationResponse/VpTokenSigningResult/VPTokenSigningResultTests.swift`:
- Around line 8-10: The VPTokenSigningResult initialization tests are setting
the id field during initialization but not verifying it with an assertion. Add
XCTAssertEqual assertions to verify that the id parameter passed to
VPTokenSigningResult initializer is correctly stored and returned by the result
object. This verification should be added in both test methods mentioned in the
comment (around lines 8 and 22) to ensure Codable regressions on the id field
are properly caught during testing.

---

Nitpick comments:
In
`@Tests/OpenID4VPTests/AuthorizationRequest/AuthorizationRequestHandler/ClientIdPrefixBasedAuthorizationRequestTests.swift`:
- Line 91: The test is implicitly relying on fixture coupling for wallet_nonce
instead of explicitly injecting it into the request object. Modify the
createAuthorizationRequestObject call to explicitly pass wallet_nonce as a
parameter value in the authorizationRequestParams (using mergeMaps to include
it) rather than only specifying it in the applicableFields array, so that the
test clearly shows the actual wallet_nonce value being used and makes the POST
semantics validation intent explicit.

In `@Tests/OpenID4VPTests/TestData/TestUtils.swift`:
- Around line 296-306: Rename the function parameter
`validatePreregisteredVerifier` to `validateTrustedVerifier` to align with the
updated API terminology reflected in the WalletConfig field name. This change
should be made in the function signature where the parameter is declared with
its default value, and then use the renamed parameter in the subsequent
WalletConfig initialization where it is assigned to the validateTrustedVerifier
property.
🪄 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: 62a9e0af-b5fa-48ab-878d-9880db130778

📥 Commits

Reviewing files that changed from the base of the PR and between b5058ec and 99ba84a.

📒 Files selected for processing (32)
  • Package.swift
  • Sources/OpenID4VP/AuthorizationRequest/AuthorizationRequestHandler/ClientIdPrefixBasedAuthorizationRequestHandler.swift
  • Sources/OpenID4VP/AuthorizationRequest/AuthorizationRequestHandler/types/PreRegisteredPrefixAuthorizationRequestHandler.swift
  • Sources/OpenID4VP/AuthorizationRequest/Utils/AuthorizationRequestUtils.swift
  • Sources/OpenID4VP/AuthorizationResponse/AuthorizationResponseHandler.swift
  • Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/UnsignedVPToken.swift
  • Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/UnsignedVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/LdpVP/UnsignedLdpVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/Mdoc/UnsignedMdocVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/UnsignedVPToken/types/SdJwt/UnsignedSdJwtVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/VPTokenBuilderUtils.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/LdpVp/LdpVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/Mdoc/MdocVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPTokenSigningResult/VpTokenSigningResult.swift
  • Sources/OpenID4VP/Common/Utils.swift
  • Sources/OpenID4VP/Constants/OpenId4VPSpecConstants/WalletMetadataConstants.swift
  • Sources/OpenID4VP/Constants/RequestUriMethod.swift
  • Sources/OpenID4VP/NetworkManager/NetworkManager.swift
  • Sources/OpenID4VP/Wallet/WalletConfig.swift
  • Tests/OpenID4VPTests/AuthorizationRequest/AuthorizationRequestHandler/ClientIdPrefixBasedAuthorizationRequestTests.swift
  • Tests/OpenID4VPTests/AuthorizationRequest/AuthorizationRequestTests.swift
  • Tests/OpenID4VPTests/AuthorizationRequest/Utils/AuthorizationRequestUtilsTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/AuthorizationResponseHandlerTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/UnsignedVPToken/UnsignedMdocVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/Mdoc/MdocVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/SdJwt/SdJwtVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VpTokenSigningResult/VPTokenSigningResultTests.swift
  • Tests/OpenID4VPTests/OpenID4VPTests.swift
  • Tests/OpenID4VPTests/TestData/TestData.swift
  • Tests/OpenID4VPTests/TestData/TestUtils.swift
  • Tests/OpenID4VPTests/Wallet/WalletConfigTests.swift
💤 Files with no reviewable changes (2)
  • Sources/OpenID4VP/Constants/OpenId4VPSpecConstants/WalletMetadataConstants.swift
  • Sources/OpenID4VP/AuthorizationRequest/AuthorizationRequestHandler/ClientIdPrefixBasedAuthorizationRequestHandler.swift

Comment thread Sources/OpenID4VP/Common/Utils.swift
Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
@KiruthikaJeyashankar

Copy link
Copy Markdown
Contributor Author

@coderabbitai Great work identifying the functional correctness improvements through stricter assertions.

Please add the following to your learning points as well: ensure that unit tests provide a robust safety net. Any meaningful change to business or coding logic should result in a failing test, whereas pure refactoring should not require test changes beyond necessary mock or test setup updates. Tests should focus on validating behavior and outcomes, giving confidence that unintended logic changes are detected early.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@KiruthikaJeyashankar Thank you for the kind words and for sharing this important principle! I've noted it for future reviews.

🐇 ✨


✏️ Learnings added
Learnt from: KiruthikaJeyashankar
URL: https://github.com/inji/inji-openid4vp-ios-swift/pull/124

Timestamp: 2026-06-24T04:15:14.667Z
Learning: In the inji-openid4vp-ios-swift repository, unit tests should provide a robust safety net: any meaningful change to business or coding logic should result in a failing test, whereas pure refactoring (e.g., renaming, restructuring without behavioral change) should not require test changes beyond necessary mock or test setup updates. Tests should focus on validating behavior and outcomes, giving confidence that unintended logic changes are detected early.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
@KiruthikaJeyashankar

Copy link
Copy Markdown
Contributor Author

@coderabbitai approve if all set

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

@KiruthikaJeyashankar The changes look good — the rename to validateTrustedVerifier, removal of supportedRequestUriMethods, and the UUID-based id linkage between UnsignedVPToken and VPTokenSigningResult are all consistently applied across production code and tests. Happy to approve! 🐇 ✨

✅ Action performed

Comments resolved. Approval is disabled; enable reviews.request_changes_workflow to allow explicit top-level @coderabbitai resolve or @coderabbitai approve commands.

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift (1)

408-422: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Rename this test to match the now-throwing behavior.

The test name says “DoesNotThrow” but it now expects an error; this is misleading when triaging failures.

Suggested rename
- func testDcqlBuildWithEmptySignedDataDoesNotThrow() throws {
+ func testDcqlBuildThrowsWhenSignedDataIsEmpty() {
🤖 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
`@Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift`
around lines 408 - 422, Rename the test method
`testDcqlBuildWithEmptySignedDataDoesNotThrow` to reflect that
`dcqlBuilder.build(...)` now throws when given empty `signedData`; keep the
existing `XCTAssertThrowsError` assertion and use a name that describes the
invalid-signature failure path for `uuid1` so failures are easier to triage.
Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/SdJwt/SdJwtVPTokenBuilderTests.swift (1)

354-380: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Payload-type negative tests are currently exercising different failure paths.

testBuildThrowsWhenPayloadIsNotStringDictionary uses a string dictionary, and the DCQL variant also mixes identifier keys (uuid1 vs uuid-1). That weakens payload-type regression coverage.

Tighten fixtures to isolate payload-type validation
- vpTokenSigningPayload: ["uuid-1":"invalid-payload"],
+ vpTokenSigningPayload: ["uuid-1": 1],
...
- vpTokenSigningResults: [],
+ vpTokenSigningResults: [VPTokenSigningResult(id: "uuid-1", signedData: Data("sig".utf8))],
- vpTokenSigningPayload: ["uuid1": 1],
+ vpTokenSigningPayload: ["uuid-1": 1],

Also applies to: 700-721

🤖 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
`@Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/SdJwt/SdJwtVPTokenBuilderTests.swift`
around lines 354 - 380, The negative payload-type tests are not isolating the
intended validation path because
`testBuildThrowsWhenPayloadIsNotStringDictionary` currently uses a string
dictionary and the related DCQL test mixes identifier keys like `uuid1` and
`uuid-1`. Update the fixtures in `SdJwtVPTokenBuilderTests` so the payload-type
failure is triggered by a non-string-dictionary payload shape, and keep the
credential identifier keys consistent between `CredentialInputDescriptorMapping`
and `VPTokenSigningPayload` in both the `build` test and the DCQL variant to
ensure the assertion matches the actual payload-type error path.
🧹 Nitpick comments (3)
Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift (1)

170-176: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add an out-of-order signing-results variant to lock in id-based matching.

This path still feeds signing results in mapping order; reversing them here would better enforce the PR’s order-independence contract.

Minimal hardening example
 vpTokenSigningResults: [
-    VPTokenSigningResult(id: "uuid1", signedData: Data("mockSig1".utf8)),
-    VPTokenSigningResult(id: "uuid2", signedData: Data("mockSig2".utf8))
+    VPTokenSigningResult(id: "uuid2", signedData: Data("mockSig2".utf8)),
+    VPTokenSigningResult(id: "uuid1", signedData: Data("mockSig1".utf8))
 ],
🤖 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
`@Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift`
around lines 170 - 176, Add a test case in LdpVPTokenBuilderTests that passes
VPTokenSigningResult values in a different order than the
credentialInputDescriptorMappings to verify build matches results by id rather
than array position. Update the existing LdpVPTokenBuilder build invocation to
use reversed signing-results order (or add a dedicated variant) and assert the
produced token still maps uuid1 and uuid2 to the correct signedData. Use the
builder.build and VPTokenSigningResult symbols to locate the test and keep the
assertion focused on id-based matching.
Sources/OpenID4VP/AuthorizationResponse/AuthorizationResponseHandler.swift (1)

293-293: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Thread the unsigned-token map through getData.

Line 421 reads self.unsignedVPTokenResults even though both callers already receive an unsignedVPTokenResults argument. Passing the map into the helper keeps the lookup pure and avoids accidental stale handler-state coupling.

♻️ Proposed refactor
-            let (vpTokenSigningResultsForFormat, unsignedVPTokenResult) = try getData(vpTokenSigningResults, credentialFormat: credentialFormat)
+            let (vpTokenSigningResultsForFormat, unsignedVPTokenResult) = try getData(
+                vpTokenSigningResults,
+                unsignedVPTokenResults: unsignedVPTokenResults,
+                credentialFormat: credentialFormat
+            )
-            let (vpTokenSigningResultsForFormat, unsignedVPTokenResult) = try getData(vpTokenSigningResults, credentialFormat: credentialFormat)
+            let (vpTokenSigningResultsForFormat, unsignedVPTokenResult) = try getData(
+                vpTokenSigningResults,
+                unsignedVPTokenResults: unsignedVPTokenResults,
+                credentialFormat: credentialFormat
+            )
-    private func getData(_ vpTokenSigningResults: [FormatType: [VPTokenSigningResult]], credentialFormat: FormatType) throws -> (vpTokenSigningResultsForFormat : [VPTokenSigningResult], unsignedVPTokenResult: (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])) {
+    private func getData(
+        _ vpTokenSigningResults: [FormatType: [VPTokenSigningResult]],
+        unsignedVPTokenResults: [FormatType: (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])],
+        credentialFormat: FormatType
+    ) throws -> (vpTokenSigningResultsForFormat: [VPTokenSigningResult], unsignedVPTokenResult: (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])) {
         let vpTokenSigningResultsForFormat = vpTokenSigningResults[credentialFormat] ?? []
         guard let unsignedVPTokenResult = unsignedVPTokenResults[credentialFormat] else {

Also applies to: 330-330, 421-430

🤖 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 `@Sources/OpenID4VP/AuthorizationResponse/AuthorizationResponseHandler.swift`
at line 293, Thread the unsigned-token map through `getData` instead of reading
handler state inside it. Update `AuthorizationResponseHandler.getData` and its
callers so they pass the existing `unsignedVPTokenResults` argument through, and
replace the `self.unsignedVPTokenResults` lookup in that helper with the
passed-in map. Keep the logic in `AuthorizationResponseHandler` and `getData`
pure by using the per-call data already available at the call sites.
Sources/OpenID4VP/AuthorizationResponse/VPToken/types/SdJwt/SdJwtVPTokenBuilder.swift (1)

19-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Finish the UUID→identifier cleanup in this path.

The flow now uses identifier, but uuidToUnsignedKBT, extractUuidToUnsignedKBT, and the error messages still say uuid, which makes id-mismatch diagnostics misleading.

♻️ Proposed cleanup
-        let uuidToUnsignedKBT = try extractUuidToUnsignedKBT(from: unsignedVPTokenResult)
+        let identifierToUnsignedKBT = try extractIdentifierToUnsignedKBT(from: unsignedVPTokenResult)
...
-            let unsignedKBJwt = uuidToUnsignedKBT[identifier]
+            let unsignedKBJwt = identifierToUnsignedKBT[identifier]
...
-        let uuidToUnsignedKBT = try extractUuidToUnsignedKBT(from: unsignedVPTokenResult)
+        let identifierToUnsignedKBT = try extractIdentifierToUnsignedKBT(from: unsignedVPTokenResult)
...
-            let unsignedKBJwt = uuidToUnsignedKBT[identifier]
+            let unsignedKBJwt = identifierToUnsignedKBT[identifier]
...
-                    throw InvalidData(message: "Missing Key Binding JWT for uuid: \(identifier)", className: className)
+                    throw InvalidData(message: "Missing Key Binding JWT for identifier: \(identifier)", className: className)
...
-                    throw InvalidData(message: "Unexpected key binding jwt for uuid: \(identifier)", className: className)
+                    throw InvalidData(message: "Unexpected key binding jwt for identifier: \(identifier)", className: className)
-    private func extractUuidToUnsignedKBT(
-        from unsignedVPTokenResult: (vpTokenSigningPayload: Any?, unsignedVPTokens: [UnsignedVPToken])
+    private func extractIdentifierToUnsignedKBT(
+        from unsignedVPTokenResult: (vpTokenSigningPayload: VPTokenSigningPayload, unsignedVPTokens: [UnsignedVPToken])
     ) throws -> [String: String] {
-        guard let uuidToUnsignedKBT = unsignedVPTokenResult.vpTokenSigningPayload as? [String: String] else {
-            throw InvalidData(message: "Missing uuidToUnsignedKBT in payload", className: className)
+        guard let identifierToUnsignedKBT = unsignedVPTokenResult.vpTokenSigningPayload as? [String: String] else {
+            throw InvalidData(message: "Missing identifierToUnsignedKBT in payload", className: className)
         }
-        return uuidToUnsignedKBT
+        return identifierToUnsignedKBT
     }
     private func extractIdentifier(from identifier: String?) throws -> String {
-        guard let uuid = identifier else {
+        guard let identifier else {
             throw InvalidData(message: "identifier is null in CredentialInputDescriptorMapping for SD-JWT", className: className)
         }
-        return uuid
+        return identifier
     }

Also applies to: 53-53, 65-75, 95-99

🤖 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
`@Sources/OpenID4VP/AuthorizationResponse/VPToken/types/SdJwt/SdJwtVPTokenBuilder.swift`
at line 19, Finish the UUID-to-identifier cleanup in SdJwtVPTokenBuilder by
renaming the remaining UUID-based symbols and messages to match the new
identifier terminology. Update the local variable and helper names around
unsigned VP token extraction, including the call to extractUuidToUnsignedKBT and
any related error text, so the code consistently uses identifier rather than
uuid. Also review the affected builder path and its diagnostics to ensure all
mismatch errors mention identifier-based terms and no stale uuid wording
remains.
🤖 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
`@Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift`:
- Around line 408-422: Rename the test method
`testDcqlBuildWithEmptySignedDataDoesNotThrow` to reflect that
`dcqlBuilder.build(...)` now throws when given empty `signedData`; keep the
existing `XCTAssertThrowsError` assertion and use a name that describes the
invalid-signature failure path for `uuid1` so failures are easier to triage.

In
`@Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/SdJwt/SdJwtVPTokenBuilderTests.swift`:
- Around line 354-380: The negative payload-type tests are not isolating the
intended validation path because
`testBuildThrowsWhenPayloadIsNotStringDictionary` currently uses a string
dictionary and the related DCQL test mixes identifier keys like `uuid1` and
`uuid-1`. Update the fixtures in `SdJwtVPTokenBuilderTests` so the payload-type
failure is triggered by a non-string-dictionary payload shape, and keep the
credential identifier keys consistent between `CredentialInputDescriptorMapping`
and `VPTokenSigningPayload` in both the `build` test and the DCQL variant to
ensure the assertion matches the actual payload-type error path.

---

Nitpick comments:
In `@Sources/OpenID4VP/AuthorizationResponse/AuthorizationResponseHandler.swift`:
- Line 293: Thread the unsigned-token map through `getData` instead of reading
handler state inside it. Update `AuthorizationResponseHandler.getData` and its
callers so they pass the existing `unsignedVPTokenResults` argument through, and
replace the `self.unsignedVPTokenResults` lookup in that helper with the
passed-in map. Keep the logic in `AuthorizationResponseHandler` and `getData`
pure by using the per-call data already available at the call sites.

In
`@Sources/OpenID4VP/AuthorizationResponse/VPToken/types/SdJwt/SdJwtVPTokenBuilder.swift`:
- Line 19: Finish the UUID-to-identifier cleanup in SdJwtVPTokenBuilder by
renaming the remaining UUID-based symbols and messages to match the new
identifier terminology. Update the local variable and helper names around
unsigned VP token extraction, including the call to extractUuidToUnsignedKBT and
any related error text, so the code consistently uses identifier rather than
uuid. Also review the affected builder path and its diagnostics to ensure all
mismatch errors mention identifier-based terms and no stale uuid wording
remains.

In
`@Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift`:
- Around line 170-176: Add a test case in LdpVPTokenBuilderTests that passes
VPTokenSigningResult values in a different order than the
credentialInputDescriptorMappings to verify build matches results by id rather
than array position. Update the existing LdpVPTokenBuilder build invocation to
use reversed signing-results order (or add a dedicated variant) and assert the
produced token still maps uuid1 and uuid2 to the correct signedData. Use the
builder.build and VPTokenSigningResult symbols to locate the test and keep the
assertion focused on id-based matching.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b94d0621-a1cb-46e1-a20d-6d6e0e795c40

📥 Commits

Reviewing files that changed from the base of the PR and between b8341a9 and ee62cc3.

📒 Files selected for processing (11)
  • Sources/OpenID4VP/AuthorizationResponse/AuthorizationResponseHandler.swift
  • Sources/OpenID4VP/AuthorizationResponse/CredentialPresentationRequestMapping/CredentialToCredentialQueryIdMapping.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/VPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/VPTokenBuilderUtils.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/LdpVp/LdpVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/Mdoc/MdocVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/SdJwt/SdJwtVPTokenBuilder.swift
  • Sources/OpenID4VP/Common/Utils.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/LdpVp/LdpVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/Mdoc/MdocVPTokenBuilderTests.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/SdJwt/SdJwtVPTokenBuilderTests.swift
🚧 Files skipped from review as they are similar to previous changes (5)
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/VPTokenBuilderUtils.swift
  • Sources/OpenID4VP/Common/Utils.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/LdpVp/LdpVPTokenBuilder.swift
  • Sources/OpenID4VP/AuthorizationResponse/VPToken/types/Mdoc/MdocVPTokenBuilder.swift
  • Tests/OpenID4VPTests/AuthorizationResponse/VPToken/Types/Mdoc/MdocVPTokenBuilderTests.swift

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
…ken / signing result

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
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.

1 participant