@injistack/react-inji-verify-sdk 0.19.0-beta.12 → 0.19.0-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +128 -99
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -1,7 +1,28 @@
1
1
  # INJI VERIFY SDK
2
2
 
3
+ **Repository:** [github.com/mosip/inji-verify](https://github.com/mosip/inji-verify)
4
+
3
5
  Inji Verify SDK provides ready-to-use **React components** to integrate [OpenID4VP](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html)-based **Verifiable Credential (VC) and Verifiable Presentation (VP) verification** into any React TypeScript web application.
4
6
 
7
+ ## Index
8
+
9
+ 1. [Pre-requisites](#pre-requisites)
10
+ 2. [Usage Guide](#usage-guide)
11
+ - [Install](#step-1-install-the-package)
12
+ - [Choose Verification Method](#step-3-choose-verification-method)
13
+ - [Verification Response](#verification-response)
14
+ 3. [Detailed Component Guide](#detailed-component-guide)
15
+ - [Option A: QR Code Verification](#option-a-qr-code-verification-scan--upload)
16
+ - [Verification Response](#verification-response-1)
17
+ - [Option B: OpenID4VP Verification](#option-b-openid4vp-verification)
18
+ - [Verification Response](#verification-response-2)
19
+ - [DCQL Query](#dcql-query)
20
+ - [`require_cryptographic_holder_binding`](#require_cryptographic_holder_binding)
21
+ 4. [Component Options Reference](#️-component-options-reference)
22
+ 5. [Important Limitations](#️-important-limitations)
23
+
24
+ ---
25
+
5
26
  ## Pre-requisites
6
27
 
7
28
  ### What You Need:
@@ -15,7 +36,7 @@ Inji Verify SDK provides ready-to-use **React components** to integrate [OpenID4
15
36
  Your backend must support the OpenID4VP protocol. You can either:
16
37
 
17
38
  - Use the official `inji-verify-service`
18
- - Build your own following [this specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0-ID3.html)
39
+ - Build your own following [this specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html)
19
40
 
20
41
  **Important:** Your backend URL should look like:
21
42
 
@@ -116,7 +137,7 @@ If `summariseResults = true`, the response will be:
116
137
  "vcResults": [
117
138
  {
118
139
  "vc": { /* Your verified credential data */ },
119
- "vcStatus": "SUCCESS" // or "INVALID", "EXPIRED"
140
+ "vcStatus": "SUCCESS" // or "INVALID", "EXPIRED", "REVOKED"
120
141
  }
121
142
  ],
122
143
  "vpResultStatus": "SUCCESS" // Overall verification status
@@ -278,14 +299,18 @@ If `summariseResults = false`, the response will be:
278
299
 
279
300
  | Property | Type | Description |
280
301
  |---------------------------|---------|-----------------------------------------------------------|
281
- | `allChecksSuccessful` | boolean | Final aggregated validation flag |
282
- | `schemaAndSignatureCheck` | object | Validates schema and signature check |
283
- | `expiryCheck` | object | If false, the credential is EXPIRED |
284
- | `statusCheck` | array | Contains revocation and other status validations |
285
- | `statusCheck[].error` | object | If present, throws an error instead of returning a status |
286
- | `statusCheck[].purpose` | string | Identifies purpose (e.g., "revocation") |
287
- | `statusCheck[].valid` | boolean | If false for revocation → credential is revoked |
288
- | `claims` | object | Includes all claims from credentialSubject |
302
+ | `vc` | object | The VC that has been verified |
303
+ | `allChecksSuccessful` | boolean | Final aggregated validation flag |
304
+ | `schemaAndSignatureCheck` | object | Schema and signature validation result |
305
+ | `schemaAndSignatureCheck.valid`| boolean | If false, credential signature or schema is invalid |
306
+ | `schemaAndSignatureCheck.error`| object | Non-null if the check could not be performed |
307
+ | `expiryCheck` | object | Expiry validation result |
308
+ | `expiryCheck.valid` | boolean | If false, the credential is EXPIRED |
309
+ | `statusCheck` | array | Contains revocation and other status validations |
310
+ | `statusCheck[].purpose` | string | Identifies purpose (e.g., "revocation") |
311
+ | `statusCheck[].valid` | boolean | If false for revocation and `error` is null → credential is revoked |
312
+ | `statusCheck[].error` | object | Non-null if the status check could not be performed (e.g. status list unreachable) |
313
+ | `claims` | object | Includes all claims from credentialSubject |
289
314
 
290
315
  ### Option B: OpenID4VP Verification
291
316
  OpenID4VPVerification Component verifies Verifiable Presentations securely using OpenID4VP standards for both cross-device and same-device flows.
@@ -314,7 +339,7 @@ export default function VerifyCrossDevice() {
314
339
  id: "id_card",
315
340
  format: "ldp_vc",
316
341
  meta: { type_values: [["DriverLicenseCredential"]] },
317
- claims: [{ path: ["$.credentialSubject.name"] }]
342
+ claims: [{ path: ["name"] }]
318
343
  }]
319
344
  }}
320
345
  isSameDeviceFlowEnabled={false} // QR code flow
@@ -338,28 +363,17 @@ sequenceDiagram
338
363
  participant VerifierBackend as Verifier Backend
339
364
  participant MobileWallet as Wallet (Mobile)
340
365
 
341
- UserBrowser->>VerifierBackend: Start verification(/vp-session-request,response_code_validation_required=false)
342
-
343
- VerifierBackend->>VerifierBackend: Generate transaction_id and request_id
344
- VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id)
345
- VerifierBackend-->>UserBrowser: Return OpenID4VP request + QR code
346
-
366
+ UserBrowser->>VerifierBackend: POST /v2/vp-session-request
367
+ VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id) + authorization request
368
+ UserBrowser->>UserBrowser: SDK generates QR code from authorization request
347
369
  UserBrowser->>MobileWallet: User scans QR code
348
-
349
- MobileWallet->>VerifierBackend: Submit vp_token (form-encoded, keyed by DCQL query_id)
350
-
370
+ MobileWallet->>VerifierBackend: POST /v2/vp-submission/direct-post (vp_token)
351
371
  loop Long Polling
352
372
  UserBrowser->>VerifierBackend: GET /vp-request/{requestId}/status
353
- VerifierBackend-->>UserBrowser: Pending
373
+ VerifierBackend-->>UserBrowser: ACTIVE
354
374
  end
355
-
356
- VerifierBackend-->>UserBrowser: Completed
357
-
358
- UserBrowser->>VerifierBackend: POST /vp-session-results (Cookie transaction_id automatically sent)
359
-
360
- VerifierBackend->>VerifierBackend: Resolve transaction_id from cookie
361
- VerifierBackend->>VerifierBackend: Fetch transaction state
362
-
375
+ VerifierBackend-->>UserBrowser: VP_SUBMITTED
376
+ UserBrowser->>VerifierBackend: POST /vp-session-results (Cookie auto-sent)
363
377
  VerifierBackend-->>UserBrowser: Verification result
364
378
  ```
365
379
 
@@ -397,36 +411,22 @@ export default function VerifySameDevice() {
397
411
  ```mermaid
398
412
  sequenceDiagram
399
413
  autonumber
400
- participant UserBrowser as User Browser (Verifier App)
414
+ participant UserBrowser as User Browser
401
415
  participant VerifierBackend as Verifier Backend
402
416
  participant MobileWallet as Mobile Wallet App
403
417
 
404
- UserBrowser->>VerifierBackend: Start verification(/vp-session-request,response_code_validation_required=false)
405
-
406
- VerifierBackend->>VerifierBackend: Generate transaction_id and request_id
407
- VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id)
408
- VerifierBackend-->>UserBrowser: Return OpenID4VP authorization request
409
-
410
- UserBrowser->>MobileWallet: Open mobile wallet via deep link
411
-
412
- MobileWallet->>VerifierBackend: Submit vp_token (form-encoded, keyed by DCQL query_id)
413
-
414
- Note right of MobileWallet: User manually switches back to browser
415
-
418
+ UserBrowser->>VerifierBackend: POST /v2/vp-session-request
419
+ VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id) + authorization request
420
+ UserBrowser->>MobileWallet: Open via deep link
421
+ MobileWallet->>VerifierBackend: POST /v2/vp-submission/direct-post (vp_token)
422
+ Note right of MobileWallet: User switches back to browser
416
423
  loop Long Polling
417
424
  UserBrowser->>VerifierBackend: GET /vp-request/{requestId}/status
418
- VerifierBackend-->>UserBrowser: Pending
425
+ VerifierBackend-->>UserBrowser: ACTIVE
419
426
  end
420
-
421
- VerifierBackend-->>UserBrowser: Completed
422
-
423
- UserBrowser->>VerifierBackend: POST /vp-session-results (Cookie transaction_id automatically sent)
424
-
425
- VerifierBackend->>VerifierBackend: Resolve transaction_id from cookie
426
- VerifierBackend->>VerifierBackend: Fetch transaction state
427
-
427
+ VerifierBackend-->>UserBrowser: VP_SUBMITTED
428
+ UserBrowser->>VerifierBackend: POST /vp-session-results (Cookie auto-sent)
428
429
  VerifierBackend-->>UserBrowser: Verification result
429
- VerifierBackend-->>UserBrowser: Clear cookie (transaction_id)
430
430
  ```
431
431
 
432
432
  #### 3. Same Device Flow with Web Wallet
@@ -467,28 +467,14 @@ sequenceDiagram
467
467
  participant VerifierBackend as Verifier Backend
468
468
  participant WebWallet as Web Wallet
469
469
 
470
- UserBrowser->>VerifierBackend: Start verification\n(/vp-session-request,\nresponse_code_validation_required=true)
471
-
472
- VerifierBackend->>VerifierBackend: Generate transaction_id\nand request_id
473
- VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id)
474
- VerifierBackend-->>UserBrowser: Return OpenID4VP authorization request
475
-
470
+ UserBrowser->>VerifierBackend: POST /v2/vp-session-request (responseCodeValidationRequired=true)
471
+ VerifierBackend-->>UserBrowser: Set HttpOnly Cookie (transaction_id) + authorization request
476
472
  UserBrowser->>WebWallet: Open Web Wallet
477
-
478
- WebWallet->>VerifierBackend: Submit vp_token (form-encoded, keyed by DCQL query_id)
479
- VerifierBackend-->>WebWallet: Return response_code
480
-
481
- WebWallet-->>UserBrowser: Redirect to redirect_uri
482
-
483
- UserBrowser->>UserBrowser: Extract response_code
484
-
485
- UserBrowser->>VerifierBackend: POST /vp-session-results?response_code=xyz\n(Cookie transaction_id automatically sent)
486
-
487
- VerifierBackend->>VerifierBackend: Validate response_code + transaction_id
488
- VerifierBackend->>VerifierBackend: Fetch transaction state
489
-
473
+ WebWallet->>VerifierBackend: POST /v2/vp-submission/direct-post (vp_token)
474
+ VerifierBackend-->>WebWallet: response_code
475
+ WebWallet-->>UserBrowser: Redirect with response_code
476
+ UserBrowser->>VerifierBackend: POST /vp-session-results?response_code=... (Cookie auto-sent)
490
477
  VerifierBackend-->>UserBrowser: Verification result
491
- VerifierBackend-->>UserBrowser: Clear cookie (transaction_id)
492
478
  ```
493
479
 
494
480
  > **NOTE**
@@ -534,18 +520,31 @@ export default function VerifyServerToServer() {
534
520
 
535
521
  Once VP Verification is complete, the response depends on the `summariseResults` attribute (default = true)
536
522
 
537
- If `summariseResults = true`, the response will be:
523
+ If `summariseResults = true`, the response will be an array with one element per credential. Each element's `verificationResponse` contains the full `vcResults` list and the overall `vpResultStatus`:
538
524
 
539
525
  ```javascript
540
- {
541
- "vcResults": [
542
- {
543
- "vc": { /* verified credential data */ },
544
- "vcStatus": "SUCCESS" // or "INVALID", "EXPIRED","REVOKED"
545
- }
546
- ],
547
- "vpResultStatus": "SUCCESS" // or "INVALID" Overall verification status
526
+ [
527
+ {
528
+ "vc": { /* credential-1 data */ },
529
+ "verificationResponse": {
530
+ "vcResults": [
531
+ { "vc": { /* credential-1 data */ }, "vcStatus": "SUCCESS" }, // or "INVALID", "EXPIRED", "REVOKED"
532
+ { "vc": { /* credential-2 data */ }, "vcStatus": "SUCCESS" }
533
+ ],
534
+ "vpResultStatus": "SUCCESS" // or "INVALID" — overall verification status
548
535
  }
536
+ },
537
+ {
538
+ "vc": { /* credential-2 data */ },
539
+ "verificationResponse": {
540
+ "vcResults": [
541
+ { "vc": { /* credential-1 data */ }, "vcStatus": "SUCCESS" },
542
+ { "vc": { /* credential-2 data */ }, "vcStatus": "SUCCESS" }
543
+ ],
544
+ "vpResultStatus": "SUCCESS"
545
+ }
546
+ }
547
+ ]
549
548
  ```
550
549
 
551
550
  If `summariseResults = false`, the response will be:
@@ -553,42 +552,49 @@ If `summariseResults = false`, the response will be:
553
552
  ```javascript
554
553
  {
555
554
  "transactionId": "txn_11",
556
- "allChecksSuccessful": true,
557
- "credentialResults": [
555
+ "allChecksSuccessful": true,
556
+ "credentialResults": [
558
557
  {
559
558
  "verifiableCredential": "{...}",
560
559
  "allChecksSuccessful": true,
561
560
  "holderProofCheck": { "valid": true, "error": null },
562
561
  "schemaAndSignatureCheck": { "valid": true, "error": null },
563
562
  "expiryCheck": { "valid": true },
564
- "statusChecks": [
563
+ "statusCheck": [
565
564
  { "purpose": "revocation", "valid": true, "error": null }
566
565
  ],
567
- "claims": {..}
566
+ "claims": {...}
568
567
  }
569
568
  ]
570
- }
569
+ }
571
570
  ```
572
571
 
573
572
  #### Response Fields Summary
574
573
 
575
574
  | Property | Type | Description |
576
575
  |---------------------------|---------|-----------------------------------------------------------|
577
- | `allChecksSuccessful` | boolean | Final aggregated validation flag |
578
- | `verifiableCredential` | string | The VC which needs to be verified |
579
- | `holderProofCheck` | object | Validates if presenter owns the credential |
580
- | `schemaAndSignatureCheck` | object | Validates schema and signature check |
581
- | `expiryCheck` | object | If false, the credential is EXPIRED |
582
- | `statusChecks` | array | Contains revocation and other status validations |
583
- | `statusChecks.error` | object | If present, throws an error instead of returning a status |
584
- | `statusChecks.purpose` | string | Identifies purpose (e.g., "revocation") |
585
- | `statusChecks.valid` | boolean | If false for revocation → credential is revoked |
586
- | `claims` | object | Includes all claims from credentialSubject |
576
+ | `allChecksSuccessful` | boolean | Final aggregated validation flag |
577
+ | `verifiableCredential` | string | The VC that has been verified |
578
+ | `holderProofCheck` | object | Holder binding result. `null` when `require_cryptographic_holder_binding=false` |
579
+ | `holderProofCheck.valid` | boolean | If false, presenter does not own the credential |
580
+ | `holderProofCheck.error` | object | Non-null if the check could not be performed |
581
+ | `schemaAndSignatureCheck` | object | Schema and signature validation result |
582
+ | `schemaAndSignatureCheck.valid`| boolean | If false, credential signature or schema is invalid |
583
+ | `schemaAndSignatureCheck.error`| object | Non-null if the check could not be performed |
584
+ | `expiryCheck` | object | Expiry validation result |
585
+ | `expiryCheck.valid` | boolean | If false, the credential is EXPIRED |
586
+ | `statusCheck` | array | Contains revocation and other status validations |
587
+ | `statusCheck[].purpose` | string | Identifies purpose (e.g., "revocation") |
588
+ | `statusCheck[].valid` | boolean | If false for revocation and `error` is null → credential is revoked |
589
+ | `statusCheck[].error` | object | Non-null if the status check could not be performed (e.g. status list unreachable) |
590
+ | `claims` | object | Includes all claims from credentialSubject |
587
591
 
588
592
  ### DCQL Query:
589
593
 
590
594
  The `dcqlQuery` prop describes which credentials to request from the wallet, following the [DCQL (Digital Credentials Query Language)](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html) format.
591
595
 
596
+ > **Unsupported:** `trusted_authorities` is not currently supported. DCQL queries containing `trusted_authorities` will be rejected with `UNKNOWN_FIELD`.
597
+
592
598
  **Minimal example — request a single ldp_vc:**
593
599
 
594
600
  ```javascript
@@ -610,8 +616,8 @@ dcqlQuery={{
610
616
  format: "dc+sd-jwt",
611
617
  meta: { vct_values: ["DriverLicenseCredential"] },
612
618
  claims: [
613
- { path: ["$.given_name"] },
614
- { path: ["$.birth_date"] }
619
+ { path: ["given_name"] },
620
+ { path: ["birth_date"] }
615
621
  ]
616
622
  }]
617
623
  }}
@@ -631,6 +637,30 @@ dcqlQuery={{
631
637
  }}
632
638
  ```
633
639
 
640
+ **`require_cryptographic_holder_binding` — holder binding control:**
641
+
642
+ Each credential entry in `dcqlQuery` supports a `require_cryptographic_holder_binding` flag (default `true`) that controls whether the wallet must prove it cryptographically owns the credential:
643
+
644
+ | Value | Behavior | `holderProofCheck` in result |
645
+ |---|---|---|
646
+ | `true` (default) | Wallet must wrap the VC in a signed VP. The verifier checks that the presenter owns the credential. | Populated — `valid: true` if holder proof passes |
647
+ | `false` | Wallet may submit the VC without a VP wrapper (bare VC). No holder binding check is performed. | `null` |
648
+
649
+ Format-specific behavior:
650
+ - **`ldp_vc`**: when `true`, wallet submits a JSON-LD VP with a `proof` field; when `false`, bare VC is accepted.
651
+ - **`dc+sd-jwt` / `vc+sd-jwt`**: when `true`, a KB-JWT (Key Binding JWT) is required, containing `aud`, `nonce`, `iat`, and `sd_hash`; when `false`, KB-JWT is skipped.
652
+
653
+ ```javascript
654
+ dcqlQuery={{
655
+ credentials: [{
656
+ id: "id_card",
657
+ format: "ldp_vc",
658
+ meta: { type_values: [["DriverLicenseCredential"]] },
659
+ require_cryptographic_holder_binding: false // accept bare VC, skip holder check
660
+ }]
661
+ }}
662
+ ```
663
+
634
664
  ## 🎛️ Component Options Reference
635
665
 
636
666
  ### Common Props (Both Components)
@@ -642,7 +672,6 @@ dcqlQuery={{
642
672
  | `triggerElement` | React element | ❌ | Custom button/element to start verification |
643
673
  | `transactionId` | string | ❌ | Optional client-side tracking ID |
644
674
  | `clientId` | string | ✅ | Client identifier (DID or Non-DID) |
645
- | `acceptVPWithoutHolderProof` | boolean | ❌ | Allow unsigned Verifiable Presentations |
646
675
  | `summariseResults` | boolean | ❌ | Decides format of SDK Response |
647
676
 
648
677
  ### QRCodeVerification Specific
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@injistack/react-inji-verify-sdk",
3
- "version": "0.19.0-beta.12",
4
- "description": "A react component library to perform Inji verify tasks, such as OpenId4VP sharing, Reading VC QR codes",
3
+ "version": "0.19.0-beta.13",
4
+ "description": "React component library for verifying Verifiable Credentials via QR code scan/upload and OpenID4VP wallet flows",
5
5
  "sideEffects": [
6
6
  "*.css"
7
7
  ],