@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.
- package/README.md +128 -99
- 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
|
|
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
|
|
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
|
-
| `
|
|
282
|
-
| `
|
|
283
|
-
| `
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
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: ["
|
|
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:
|
|
342
|
-
|
|
343
|
-
|
|
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:
|
|
373
|
+
VerifierBackend-->>UserBrowser: ACTIVE
|
|
354
374
|
end
|
|
355
|
-
|
|
356
|
-
VerifierBackend
|
|
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
|
|
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:
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
VerifierBackend
|
|
408
|
-
|
|
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:
|
|
425
|
+
VerifierBackend-->>UserBrowser: ACTIVE
|
|
419
426
|
end
|
|
420
|
-
|
|
421
|
-
VerifierBackend
|
|
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:
|
|
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
|
|
479
|
-
|
|
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
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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
|
-
|
|
557
|
-
|
|
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
|
-
"
|
|
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`
|
|
578
|
-
| `verifiableCredential`
|
|
579
|
-
| `holderProofCheck`
|
|
580
|
-
| `
|
|
581
|
-
| `
|
|
582
|
-
| `
|
|
583
|
-
| `
|
|
584
|
-
| `
|
|
585
|
-
| `
|
|
586
|
-
| `
|
|
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: ["
|
|
614
|
-
{ path: ["
|
|
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.
|
|
4
|
-
"description": "
|
|
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
|
],
|