From 9ad4efa5217f7ec7fc2c6842d1eb309415831d95 Mon Sep 17 00:00:00 2001 From: KiruthikaJeyashankar Date: Wed, 8 Jul 2026 12:38:33 +0530 Subject: [PATCH 1/4] docs: update mobile wallet mimoto backend service Signed-off-by: KiruthikaJeyashankar --- .../backend-services/mimoto.md | 127 +++++++++++++++--- 1 file changed, 106 insertions(+), 21 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md b/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md index 3438314..ab76367 100644 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md @@ -7,30 +7,53 @@ Detailed API documentation of Mimoto is available [here](https://mosip.stoplight ## Support for downloading VC from multiple Issuers -* To get a list of issuers, [this](https://mosip.stoplight.io/docs/mimoto/67ec1f78ee034-list-issuers) API is called. For retrieving the credential types and display properties, `.well-known` location is referred for every issuer from the [mimoto-issuers-config.json](https://github.com/mosip/mosip-config/blob/collab/mimoto-issuers-config.json) +### Issuers Listing + +The user is currently on the `+` button on the Home screen, which will open `Add new card` screen, where all the issuers are displayed Below issuers list API gives out all the issuers list + +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/issuers" method="get" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} + +To get complete configuration of the specific issuer, below api is called. + +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/issuers/{issuer-id}" method="get" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} + +### Retrieve accessToken for OIDC flow +This endpoint exchanges an OAuth 2.0 authorization code for an access token as part of the OpenID4VCI authorization flow for a Mimoto client registered with an Authorization Server (AS). + +The issuer name is used to resolve the corresponding Authorization Server and its token endpoint from the issuer configuration (`issuers-config.json`). The client authenticates with the Authorization Server using the same cryptographic key pair that was registered during client registration. The token request includes a signed client assertion JWT to authenticate the client before the Authorization Server issues an access token. -### Download via eSignet -Inji Wallet allows the users to download VC by redirecting the user to eSignet UI. Multiple APIs are being called to complete the process in the backend. +API: POST /v1/mimoto/get-token/{issuer} -* Inji Wallet initiates authenticate API by redirecting users to eSignet UI. On eSignet UI, user is given option to enter the unique ID, the user is asked to enter an OTP on the next screen. In the backend, token API is called to get a token. Refer [here](https://docs.esignet.io/integration/wallet/credential-holder) for more details. -* After getting a token response, Inji Wallet initiates a download request. Refer[ here](https://docs.mosip.io/inji/inji-mobile-wallet/backend-services/esignet#download-vc) +https://mosip.stoplight.io/docs/mimoto/6fc8a9a1587a5-retrieve-access-token-for-oidc-flow + +## Online Login + +There is a usecase of activating / binding a credential to an Authorization server and using that Authorization Server, an online service can be logged in +using that binded credential. This usecase is avaiklable within Inji ecosystem as "Mosip or National ID" usecase. +This usecase uses eSignet as an Authorization Server for the Mosip / National ID credential downloaded from Inji Certify for logging in to health id services. + +### Activate credentials -## Activate credentials Credentials have to be activated in order to use them for online login. When a user selects **Activate** option, an OTP is sent to the user and credentials are activated. * To send an OTP to a user, the below API is called. -{% openapi src="../../../../.gitbook/assets/mimoto (1).json" path="/binding-otp" method="post" %} -[mimoto (1).json](<../../../../.gitbook/assets/mimoto (1).json>) -{% endopenapi %} +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/binding-otp" method="post" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} * After successful OTP validation, a keypair is generated in the phone and the public key is synced with server. The mimoto receives a certificate and create thumbprint which it stores in the keystore securely. This is called as the **activation process.** -{% openapi src="../../../../.gitbook/assets/mimoto (1).json" path="/wallet-binding" method="post" %} -[mimoto (1).json](<../../../../.gitbook/assets/mimoto (1).json>) -{% endopenapi %} +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/wallet-binding" method="post" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} + ## Configuration @@ -40,16 +63,78 @@ The configurable properties for mimoto can be found at [mimoto-default.propertie The implementers can choose to use the existing configurations or add new configurations to them. -### Issuers Listing +### Wallet Configurations -The user is currently on the `+` button on the Home screen, which will open `Add new card` screen, where all the issuers are displayed Below issuers list API gives out all the issuers list +**API:** `GET /v1/mimoto/allProperties` -{% openapi src="../../../../.gitbook/assets/mimoto (1).json" path="/issuers" method="get" %} -[mimoto (1).json](<../../../../.gitbook/assets/mimoto (1).json>) -{% endopenapi %} +**Reference:** [inji-default.properties](https://github.com/inji/inji-config/blob/collab/inji-default.properties) -To get complete configuration of the specific issuer, below api is called. +```properties +# Timeout for VC download API via OpenID4VCI flow in milliseconds +mosip.inji.openId4VCIDownloadVCTimeout=30000 +# Inji documentation URL +mosip.inji.aboutInjiUrl=https://docs.inji.io/inji-wallet/inji-mobile +# Minimum storage space required for making audit entries in MB +mosip.inji.minStorageRequiredForAuditEntry=2 +# Minimum storage space required for downloading/receiving VCs in MB +mosip.inji.minStorageRequired=2 +# Specifies whether to perform client validation during the OpenID4VP sharing flow +mosip.inji.openid4vpClientValidation=false +# Defines the lifetime of cached data in storage, measured in milliseconds +mosip.inji.cacheTTLInMilliSeconds=3600000 + +# Specifies whether to perform credential offer VC verification in OpenID4VCI flow (To be removed in future releases) +mosip.inji.disableCredentialOfferVcVerification=true + +# OpenID4VP wallet configuration defining the wallet capabilities +mosip.inji.openid4vpWalletConfig={"response_types_supported":["vp_token"],"vp_formats_supported":{"mso_mdoc":{"issuerauth_alg_values":[-7],"deviceauth_alg_values":[-7]},"ldp_vc":{"proof_type_values":["Ed25519Signature2020","JsonWebSignature2020"]},"dc+sd-jwt":{"sd-jwt_alg_values":["EdDSA","ES256"],"kb-jwt_alg_values":["ES256","EdDSA"]},"vc+sd-jwt":{"sd-jwt_alg_values":["EdDSA","ES256"],"kb-jwt_alg_values":["ES256","EdDSA"]}},"client_id_prefixes_supported":["redirect_uri","decentralized_identifier","pre-registered"],"request_object_signing_alg_values_supported":["EdDSA"],"authorization_encryption_alg_values_supported":["ECDH-ES"],"authorization_encryption_enc_values_supported":["A256GCM"],"presentation_definition_uri_supported":true,"request_uri_methods_supported":["get","post"]} +``` + +[//]: # (TODO: Add swagger) + +#### Property Descriptions + +1. **`cacheTTLInMilliSeconds`**: Defines the cache expiration time, in milliseconds, for API fallback. If an API request fails, the SDK uses the cached response for the APIs listed in the table below, provided the cache entry has not expired. + +**API Fallbacks available as cache** + +| API | Endpoint | +|:-------------------------------------------|:---------------------------| +| **getAllProperties** | `/v1/mimoto/allProperties` | +| **fetchIssuers** | `/v1/mimoto/issuers` | +| **fetchTrustedVerifiersList** | `/v1/mimoto/verifiers` | +| **fetchIssuerWellknownConfig** | `{issuer}/.well-known/...` | +| **fetchIssuerAuthorizationServerMetadata** | `{server}/.well-known/...` | + +2. **`minStorageRequired`**: Defines the minimum available device storage required for operations such as VC downloads and VC backup restoration. If sufficient storage is not available, the operation cannot proceed, and an error screen is displayed. +3. **`minStorageRequiredForAuditEntry`**: Defines the minimum available device storage required before initiating operations such as VC sharing, QR-based sharing, and BLE-based VC sharing, as these operations create audit history entries. +4. **`aboutInjiUrl`**: Defines the "About Inji" URL, which is displayed on the application's "About Inji" page. +5. VC Download-related Properties + 1. **`openId4VCIDownloadVCTimeout`**: Timeout, in milliseconds, for downloading a Verifiable Credential (VC) using the OpenID4VCI flow. + 2. **`disableCredentialOfferVcVerification`**: Disables verification of Verifiable Credentials (VCs) received through the OpenID4VCI credential offer flow. +6. OpenID4VP-related Properties + 1. **`openid4vpWalletConfig`**: Defines wallet-specific configuration for the OpenID4VP flow. + 2. **`openid4vpClientValidation`**: Enables or disables client validation against the pre-registered client list for the OpenID4VP flow. + 1. true – validate clients against the pre-registered list. + 2. false – skip client validation. + 3. For more information, see [Inji Wallet Usage](https://github.com/inji/inji-wallet/blob/master/docs/openid4vp/openid4vp-support.md#wallet-configuration-for-the-openid4vp-flow) + + + +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/allProperties" method="get" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} + + + +### Wallet's Trusted / Pre-registered Verifier list + +The Inji Wallet retrieves the list of pre-registered (trusted) verifiers from the Mimoto backend service. + +- **Backend Service:** Mimoto +- **API:** `/v1/mimoto/verifiers` + +The API response provides the list of trusted verifiers, which is then embedded into the `walletConfig`. This configuration is supplied to the Inji OpenID4VP library to execute **client validation** during the OpenID4VP flow. + +[//]: # (TODO: Add swagger) -{% openapi src="../../../../.gitbook/assets/mimoto (1).json" path="/issuers/{issuer-id}" method="get" %} -[mimoto (1).json](<../../../../.gitbook/assets/mimoto (1).json>) -{% endopenapi %} From 34910b9c31cf2dabf9c916a9f583b05b86fe9a0d Mon Sep 17 00:00:00 2001 From: KiruthikaJeyashankar Date: Thu, 9 Jul 2026 11:44:59 +0530 Subject: [PATCH 2/4] docs: update backend services Signed-off-by: KiruthikaJeyashankar --- .gitbook/assets/mimoto (1).json | 5477 ++++++++++++----- .gitbook/assets/verify-decode.png | Bin 99103 -> 44209 bytes .gitbook/assets/wallet-encode.png | Bin 104543 -> 48018 bytes SUMMARY.md | 6 +- .../backend-services/README.md | 6 +- .../backend-services/esignet.md | 31 - .../backend-services/inji-certify.md | 26 - .../backend-services/issuer.md | 33 + .../login-using-credential.md | 81 + .../backend-services/mimoto.md | 48 +- .../openid4vp.md | 150 +- .../pixelpass.md | 188 +- 12 files changed, 4317 insertions(+), 1729 deletions(-) delete mode 100644 inji-wallet/inji-mobile/technical-overview/backend-services/esignet.md delete mode 100644 inji-wallet/inji-mobile/technical-overview/backend-services/inji-certify.md create mode 100644 inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md create mode 100644 inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md diff --git a/.gitbook/assets/mimoto (1).json b/.gitbook/assets/mimoto (1).json index e305d51..f9363ea 100644 --- a/.gitbook/assets/mimoto (1).json +++ b/.gitbook/assets/mimoto (1).json @@ -14,7 +14,7 @@ }, "servers": [ { - "url": "https://api.collab.mosip.net/residentmobileapp", + "url": "https://api.collab.mosip.net/v1/mimoto", "description": "For Swagger" } ], @@ -60,13 +60,17 @@ "type": "string" }, "str": { - "type": "null" + "type": "string", + "nullable": true }, "responsetime": { - "type": "null" + "type": "string", + "format": "date-time", + "nullable": true }, "metadata": { - "type": "null" + "type": "object", + "nullable": true }, "response": { "type": "object", @@ -80,7 +84,19 @@ } }, "errors": { - "type": "null" + "type": "array", + "items": { + "type": "object", + "properties": { + "errorCode": { + "type": "string" + }, + "errorMessage": { + "type": "string" + } + } + }, + "nullable": true } }, "x-examples": { @@ -119,9 +135,274 @@ } }, "description": "Request new otp", + "tags": [ + "Credential Download - OTP Flow" + ], "summary": "Generate Credential - Request Otp" } }, + "/verifiers": { + "get": { + "operationId": "getAllTrustedVerifiers", + "tags": [ + "Verifiers" + ], + "description": "This API retrieves all trusted verifiers for Inji Wallet.", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "verifiers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "client_id": { + "type": "string" + }, + "redirect_uris": { + "type": "array", + "items": { + "type": "string" + } + }, + "response_uris": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "examples": { + "Success response": { + "value": { + "verifiers": [ + { + "client_id": "https://injiverify.collab.mosip.net", + "redirect_uris": [ + "https://injiverify.collab.mosip.net/redirect" + ], + "response_uris": [ + "https://injiverify.collab.mosip.net/redirect" + ] + } + ] + } + }, + "Failure response": { + "value": { + "id": null, + "version": "v1", + "responsetime": "2022-10-31T05:07:34.789Z", + "metadata": null, + "response": null, + "errors": [ + { + "errorCode": "VERIFIER-API-26", + "errorMessage": "API not accessible failure" + } + ] + } + } + } + } + } + } + } + } + }, + "/get-token/{issuer}": { + "post": { + "tags": [ + "Credentials Download" + ], + "summary": "Retrieve accessToken for OIDC flow", + "description": "This endpoint allows you to retrieve the access token in exchange for the authorization code.", + "operationId": "getToken", + "parameters": [ + { + "name": "arg0", + "in": "query", + "required": true, + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + { + "name": "issuer", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "string" + }, + "str": { + "type": "string", + "nullable": true + }, + "responsetime": { + "type": "string", + "format": "date-time" + }, + "metadata": { + "type": "object", + "nullable": true + }, + "response": { + "type": "object", + "properties": { + "access_token": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "expires_in": { + "type": "integer" + }, + "scope": { + "type": "string" + }, + "refresh_token": { + "type": "string", + "nullable": true + } + } + }, + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "errorCode": { + "type": "string" + }, + "errorMessage": { + "type": "string" + } + } + }, + "nullable": true + } + } + }, + "examples": { + "Success response": { + "value": { + "id": "mosip.mimoto.issuers", + "version": "v1", + "str": null, + "responsetime": "2024-04-25T05:56:55.890Z", + "metadata": null, + "response": { + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "token_type": "bearer", + "expires_in": 3600, + "scope": "mosip_identity_vc_ldp", + "refresh_token": "xyz123" + }, + "errors": [] + } + } + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "string" + }, + "str": { + "type": "string", + "nullable": true + }, + "responsetime": { + "type": "string", + "format": "date-time" + }, + "metadata": { + "type": "object", + "nullable": true + }, + "response": { + "type": "object", + "nullable": true + }, + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "errorCode": { + "type": "string" + }, + "errorMessage": { + "type": "string" + } + } + } + } + } + }, + "examples": { + "Failure response": { + "value": { + "id": null, + "version": "v1", + "str": null, + "responsetime": "2022-10-31T05:07:34.789Z", + "metadata": null, + "response": null, + "errors": [ + { + "errorCode": "RESIDENT-APP-26", + "errorMessage": "Api not accessible failure" + } + ] + } + } + } + } + } + } + } + } + }, "/credentialshare/request": { "post": { "operationId": "request", @@ -182,13 +463,17 @@ "type": "string" }, "str": { - "type": "null" + "type": "string", + "nullable": true }, "responsetime": { - "type": "string" + "type": "string", + "format": "date-time", + "nullable": true }, "metadata": { - "type": "null" + "type": "object", + "nullable": true }, "response": { "type": "object", @@ -202,7 +487,19 @@ } }, "errors": { - "type": "null" + "type": "array", + "items": { + "type": "object", + "properties": { + "errorCode": { + "type": "string" + }, + "errorMessage": { + "type": "string" + } + } + }, + "nullable": true } }, "x-examples": { @@ -257,6 +554,9 @@ } }, "description": "Credential request", + "tags": [ + "Credential Download - OTP Flow" + ], "summary": "Generate Credential - request new credential" } }, @@ -281,21 +581,6 @@ "schema": { "type": "object", "properties": { - "id": { - "type": "null" - }, - "version": { - "type": "null" - }, - "str": { - "type": "null" - }, - "responsetime": { - "type": "string" - }, - "metadata": { - "type": "null" - }, "response": { "type": "object", "properties": { @@ -307,24 +592,19 @@ }, "statusCode": { "type": "string" + }, + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": {} + } } } - }, - "errors": { - "type": "array", - "items": { - "type": "object", - "properties": {} - } } }, "x-examples": { "Example 1": { - "id": null, - "version": null, - "str": null, - "responsetime": "2022-10-31T05:10:58.337Z", - "metadata": null, "response": { "id": "2057135194", "requestId": "2bc3bb7f-6156-46d1-ae03-bf7b76e0c257", @@ -337,11 +617,6 @@ "examples": { "success response": { "value": { - "id": null, - "version": null, - "str": null, - "responsetime": "2022-10-31T05:10:58.337Z", - "metadata": null, "response": { "id": "2057135194", "requestId": "2bc3bb7f-6156-46d1-ae03-bf7b76e0c257", @@ -356,6 +631,9 @@ } }, "description": "Credential request status", + "tags": [ + "Credential Download - OTP Flow" + ], "summary": "Generate Credential - Check Status of Credential Share" }, "parameters": [ @@ -543,9 +821,45 @@ } } }, + "tags": [ + "Credential Download - OTP Flow" + ], "summary": "Generate Credential - Download Credential" } }, + "/credentialshare/callback/notify": { + "post": { + "operationId": "handleSubscribeEvent", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EventModel" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenericResponseDTO" + } + } + } + } + }, + "description": "callback uri used by websub to notify", + "summary": "Callback API - Notify when credential is ready", + "tags": [ + "Credential Download - OTP Flow" + ], + "x-internal": true + } + }, "/binding-otp": { "post": { "operationId": "bindingOtpGenerate", @@ -745,6 +1059,9 @@ } }, "summary": "Wallet Binding - Generate Otp", + "tags": [ + "Wallet Binding" + ], "description": "This api is used to generate otp for wallet binding.\nThis api is used as a proxy to call [Identity Provider - Send Binding OTP Endpoint](https://mosip.stoplight.io/docs/identity-provider/a34e5371d4876-send-binding-otp-endpoint-draft) api internally." } }, @@ -1003,190 +1320,77 @@ } }, "summary": "Wallet Binding - Bind Credential with wallet", + "tags": [ + "Wallet Binding" + ], "description": "This api is used to bind the credential with wallet.\nThis api is used as a proxy to call [Identity Provider - Wallet binding Endpoint](https://mosip.stoplight.io/docs/identity-provider/6e91115b16311-wallet-binding-endpoint) api internally." } }, - "/req/individualId/otp": { - "post": { - "operationId": "individualIdOtpRequest", + "/allProperties": { + "get": { + "operationId": "getAllProperties", "responses": { "200": { - "description": "OK", + "description": "Successfully retrieved all configurable properties for Inji.", "content": { "application/json": { "schema": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "version": { - "type": "string" - }, - "transactionID": { - "type": "string" - }, - "responseTime": { - "type": "string" - }, - "errors": { - "type": "null" - }, "response": { "type": "object", - "properties": { - "maskedMobile": { - "type": "string" - }, - "maskedEmail": { - "type": "string" - } + "additionalProperties": { + "type": "string" } }, - "metadata": { - "type": "null" - } - }, - "x-examples": { - "Example 1": { - "id": "mosip.identity.otp.internal", - "version": "1.0", - "transactionID": "1234567890", - "responseTime": "2022-10-31T05:02:29.001Z", - "errors": null, - "response": { - "maskedMobile": "XXXXXXX187599", - "maskedEmail": "XXqXXgXXyXXpXXgXXbXXtXXhXXfXXeXXzXXtXXfXXkXXwXXsXXuXXsXXfXX8XX@mailinator.com" - }, - "metadata": null + "errors": { + "type": "array", + "items": { + "type": "object" + } } } }, "examples": { - "success response": { + "example-1": { "value": { - "id": "mosip.identity.otp.internal", - "version": "1.0", - "transactionID": "1234567890", - "responseTime": "2022-10-31T05:02:29.001Z", - "errors": null, "response": { - "maskedMobile": "XXXXXXX187599", - "maskedEmail": "XXqXXgXXyXXpXXgXXbXXtXXhXXfXXeXXzXXtXXfXXkXXwXXsXXuXXsXXfXX8XX@mailinator.com" + "internal.auth.types.allowed": "otp,bio-Finger,bio-Iris,bio-Face", + "auth.types.allowed": "demo,otp,bio-Finger,bio-Iris,bio-Face", + "ekyc.auth.types.allowed": "demo,otp,bio-Finger,bio-Iris,bio-Face" }, - "metadata": null - } - }, - "Failure response": { - "value": { - "id": null, - "version": "v1", - "transactionID": null, - "responseTime": null, - "errors": [ - { - "errorCode": "RES-SER-449", - "errorMessage": "AID is not ready" - } - ], - "response": null, - "metadata": null - } - } - } - } - } - } - }, - "description": "request otp using individual id", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "aid": { - "type": "string" - }, - "otpChannel": { - "type": "array", - "items": { - "type": "string" + "errors": [] } - }, - "transactionID": { - "type": "string" - } - }, - "x-examples": { - "Example 1": { - "aid": "10257101921007120221029201608", - "otpChannel": [ - "EMAIL", - "PHONE" - ], - "transactionID": "1234567890" - } - } - }, - "examples": { - "example-1": { - "value": { - "aid": "10257101921007120221029201608", - "otpChannel": [ - "EMAIL", - "PHONE" - ], - "transactionID": "1234567890" } } } } } }, - "summary": "Request Otp for Application Id" + "description": "Get all configurable properties for Inji.", + "summary": "Get all Inji app properties", + "tags": [ + "Inji Config" + ] } }, - "/aid/get-individual-id": { - "post": { - "operationId": "aidGetIndividualId", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "aid": { - "type": "string" - }, - "otp": { - "type": "string" - }, - "transactionID": { - "type": "string" - } - }, - "x-examples": { - "Example 1": { - "aid": "10257101921007120221029201609", - "otp": "111111", - "transactionID": "1234567890" - } - } - }, - "examples": { - "example-1": { - "value": { - "aid": "10257101921007120221029201609", - "otp": "111111", - "transactionID": "1234567890" - } - } - } + "/issuers": { + "get": { + "operationId": "getAllIssuers", + "parameters": [ + { + "name": "search", + "in": "query", + "required": false, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], + "tags": [ + "Trusted Issuers" + ], + "description": "This API provides data with search capability to populate the list of supported issuers in Inji Web, which is then displayed under the List of Issuers", "responses": { "200": { "description": "OK", @@ -1195,71 +1399,197 @@ "schema": { "type": "object", "properties": { - "id": { - "type": "null" - }, - "version": { - "type": "string" - }, - "str": { - "type": "null" - }, - "responsetime": { - "type": "string" - }, - "metadata": { - "type": "null" - }, - "response": { - "type": "null" - }, - "errors": { + "issuers": { "type": "array", "items": { "type": "object", "properties": { - "errorCode": { + "issuer_id": { "type": "string" }, - "errorMessage": { + "protocol": { + "type": "string" + }, + "display": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "logo": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "alt_text": { + "type": "string" + } + } + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "language": { + "type": "string" + } + } + } + }, + "client_id": { + "type": "string" + }, + "wellknown_endpoint": { + "type": "string" + }, + "redirect_uri": { + "type": "string" + }, + "authorization_audience": { + "type": "string" + }, + "token_endpoint": { + "type": "string" + }, + "proxy_token_endpoint": { + "type": "string" + }, + "client_alias": { + "type": "string" + }, + "qr_code_type": { + "type": "string", + "enum": [ + "OnlineSharing", + "EmbeddedVC", + "None" + ] + }, + "enabled": { + "type": "string" + }, + "credential_issuer": { + "type": "string" + }, + "credential_issuer_host": { "type": "string" } } } } - }, - "x-examples": { - "Example 1": { - "id": null, - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:29:08.687Z", - "metadata": null, - "response": null, - "errors": [ - { - "errorCode": "RES-SER-422", - "errorMessage": "Unsupported Authentication Type for child - otp" - } - ] - } + } + }, + "x-examples": { + "Example 1": { + "id": "mosip.resident.vid", + "version": "v1", + "str": null, + "responsetime": "2022-10-31T05:08:14.846Z", + "metadata": null, + "response": { + "issuers": [ + { + "issuer_id": "MOSIPInsurance", + "credential_issuer": "MOSIPInsurance", + "credential_issuer_host": "https://injicertify-insurance.collab.mosip.net", + "protocol": "OpenId4VCI", + "display": [ + { + "name": "MOSIP Insurance", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "MOSIP-Logo" + }, + "title": "Download via LIC", + "description": "This API provides data to populate the list of supported issuers in Inji Web, which is then displayed under the List of Issuers section on the Home page of Inji Web.", + "language": "en" + } + ], + "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", + "wellknown_endpoint": "http://localhost:8088/.well-known/openid-credential-issuer" + }, + { + "issuer_id": "MOSIPNationalID", + "credential_issuer": "MOSIPNationalID", + "credential_issuer_host": "https://injicertify-mosipid.released.mosip.net", + "protocol": "OpenId4VCI", + "display": [ + { + "name": "MOSIP National ID", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "MOSIP-Logo" + }, + "title": "Download via LIC", + "description": "Enter your policy number to download your card.", + "language": "en" + } + ], + "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", + "wellknown_endpoint": "http://localhost:8088/.well-known/openid-credential-issuer" + } + ] + }, + "errors": null } }, "examples": { - "success response": { + "Success response": { "value": { - "id": null, + "id": "mosip.resident.vid", "version": "v1", "str": null, - "responsetime": "2022-10-31T05:29:08.687Z", + "responsetime": "2022-10-31T05:08:14.846Z", "metadata": null, - "response": null, - "errors": [ - { - "errorCode": "RES-SER-422", - "errorMessage": "Unsupported Authentication Type for child - otp" - } - ] + "response": { + "issuers": [ + { + "issuer_id": "MOSIPInsurance", + "credential_issuer": "MOSIPInsurance", + "credential_issuer_host": "https://injicertify-insurance.collab.mosip.net", + "protocol": "OpenId4VCI", + "display": [ + { + "name": "MOSIP Insurance", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "MOSIP-Logo" + }, + "title": "Download via LIC", + "description": "Enter your policy number to download your card.", + "language": "en" + } + ], + "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", + ".well-known": "http://localhost:8088/.well-known/openid-credential-issuer" + }, + { + "issuer_id": "MOSIPNationalID", + "credential_issuer": "MOSIPNationalID", + "credential_issuer_host": "https://injicertify-mosipid.released.mosip.net", + "protocol": "OpenId4VCI", + "display": [ + { + "name": "MOSIP National ID", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "MOSIP-Logo" + }, + "title": "Download via LIC", + "description": "Enter your policy number to download your card.", + "language": "en" + } + ], + "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", + ".well-known": "http://localhost:8088/.well-known/openid-credential-issuer" + } + ] + } } }, "Failure response": { @@ -1267,13 +1597,13 @@ "id": null, "version": "v1", "str": null, - "responsetime": "2022-10-31T05:27:38.546Z", + "responsetime": "2022-10-31T05:07:34.789Z", "metadata": null, "response": null, "errors": [ { - "errorCode": "RES-SER-457", - "errorMessage": "AID not found" + "errorCode": "RESIDENT-APP-26", + "errorMessage": "Api not accessible failure" } ] } @@ -1282,248 +1612,297 @@ } } } - }, - "description": "get individual id using application id", - "summary": "Generate Credential with Application id - Request Id for an aid" + } } }, - "/safetynet/online/verify": { - "post": { - "operationId": "processOnline", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } + "/issuers/{issuer-id}": { + "get": { + "operationId": "getIssuerConfig", + "parameters": [ + { + "name": "issuer-id", + "in": "path", + "required": true, + "schema": { + "type": "string" } } - }, - "summary": "Safetynet Verify Online", - "description": "" - } - }, - "/safetynet/offline/verify": { - "post": { - "operationId": "processOffline", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - }, - "required": true - }, + ], + "tags": [ + "Trusted Issuers" + ], + "description": "This API provides the complete configuration details for the specific issuers passed in the path variable", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "object" - } - } - } - } - }, - "summary": "Safetynet Verify Offline" - } - }, - "/vid": { - "post": { - "operationId": "vidGenerate", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "individualId": { - "type": "string" - }, - "individualIdType": { - "type": "string" - }, - "otp": { - "type": "string" - }, - "vidType": { - "type": "string" - }, - "transactionID": { - "type": "string" + "type": "object", + "properties": { + "response": { + "type": "object", + "properties": { + "issuer_id": { + "type": "string" + }, + "protocol": { + "type": "string" + }, + "display": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "logo": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "alt_text": { + "type": "string" + } + } + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "language": { + "type": "string" + } + } + } + }, + "client_id": { + "type": "string" + }, + "wellknown_endpoint": { + "type": "string" + }, + "redirect_uri": { + "type": "string" + }, + "authorization_audience": { + "type": "string" + }, + "token_endpoint": { + "type": "string" + }, + "proxy_token_endpoint": { + "type": "string" + }, + "client_alias": { + "type": "string" + }, + "qr_code_type": { + "type": "string", + "enum": [ + "OnlineSharing", + "EmbeddedVC", + "None" + ] + }, + "enabled": { + "type": "boolean" + }, + "credential_issuer": { + "type": "string" + }, + "credential_issuer_host": { + "type": "string" + } + } + }, + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + } + } + } } }, "x-examples": { "Example 1": { - "individualId": "2057135194", - "individualIdType": "UIN", - "otp": "111111", - "vidType": "PERPETUAL", - "transactionID": "1234567890" - } - } - }, - "examples": { - "VID REQUEST": { - "value": { - "individualId": "2057135194", - "individualIdType": "UIN", - "otp": "111111", - "vidType": "PERPETUAL", - "transactionID": "1234567890" - } - }, - "example-2": { - "value": { - "individualId": "string", - "individualIdType": "string", - "otp": "string", - "vidType": "string", - "transactionID": "string" - } - } - } - }, - "application/xml": { - "schema": { - "type": "object", - "properties": { - "individualId": { - "type": "string" - }, - "individualIdType": { - "type": "string" - }, - "otp": { - "type": "string" - }, - "vidType": { - "type": "string" - }, - "transactionID": { - "type": "string" - } - }, - "x-examples": { - "Example 1": { - "individualId": "2057135194", - "individualIdType": "UIN", - "otp": "111111", - "vidType": "PERPETUAL", - "transactionID": "1234567890" - } - } - }, - "examples": { - "example-1": { - "value": "{\n \"individualId\": \"2057135194\",\n \"individualIdType\": \"UIN\",\n \"otp\": \"111111\",\n \"vidType\": \"PERPETUAL\",\n \"transactionID\": \"1234567890\"\n}" - } - } - } - }, - "required": true, - "description": "" - }, - "responses": { - "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "version": { - "type": "string" - }, - "str": { - "type": "null" - }, - "responsetime": { - "type": "string" - }, - "metadata": { - "type": "null" - }, "response": { - "type": "object", - "properties": { - "vid": { - "type": "string" + "issuer_id": "ESignet", + "protocol": "OpenId4VCI", + "display": [ + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "mosip-logo" + }, + "title": "Download MOSIP Credentials", + "description": "Download credentials by providing UIN or VID", + "language": "en" }, - "message": { - "type": "string" + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "شعار موسيب" + }, + "title": "قم بتنزيل بيانات اعتماد MOSIP", + "description": "توفير UIN أو VIDقم بتنزيل بيانات الاعتماد عن طريق", + "language": "ar" + }, + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "मोसिप लोगो" + }, + "title": "MOSIP क्रेडेंशियल डाउनलोड करेंं", + "description": "यूआईएन या वीआईडी प्रदान करके क्रेडेंशियल डाउनलोड करें", + "language": "hi" } - } + ], + "client_id": "*****", + "redirect_uri": "io.mosip.residentapp.inji://oauthredirect", + "scopes_supported": [ + "mosip_identity_vc_ldp" + ], + "authorization_endpoint": "https://esignet.collab.mosip.net/authorize", + "authorization_audience": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", + "token_endpoint": "https://api.collab.mosip.net/v1/mimoto/get-token/ESignet", + "proxy_token_endpoint": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", + "credential_endpoint": "https://esignet.collab.mosip.net/v1/esignet/vci/credential", + "credential_type": [ + "VerifiableCredential", + "MOSIPVerifiableCredential" + ], + "credential_audience": "https://esignet.collab.mosip.net", + "client_alias": "mpartner-default-mimotooidc", + "additional_headers": { + "Accept": "application/json" + }, + "wellknown_endpoint": "https://esignet.collab.mosip.net/.well-known/openid-credential-issuer" }, - "errors": { - "type": "array", - "items": { - "type": "object", - "properties": {} - } - } + "errors": [] }, - "x-examples": { - "Example 1": { - "id": "mosip.resident.vid", - "version": "v1", - "str": null, - "responsetime": "2022-10-31T04:49:43.085Z", - "metadata": null, - "response": { - "vid": "6924813502849610", - "message": "Notification has been sent to the provided email " - }, - "errors": [] - } - } + "errors": null }, "examples": { "Success response": { "value": { - "id": "mosip.resident.vid", + "id": "mosip.mimoto.issuers", "version": "v1", "str": null, - "responsetime": "2022-10-31T04:49:43.085Z", + "responsetime": "2024-04-25T05:56:55.890Z", "metadata": null, "response": { - "vid": "6924813502849610", - "message": "Notification has been sent to the provided email " + "issuer_id": "mosip.mimoto.issuers", + "protocol": "OpenId4VCI", + "display": [ + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "mosip-logo" + }, + "title": "Download MOSIP Credentials", + "description": "Download credentials by providing UIN or VID", + "language": "en" + }, + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "شعار موسيب" + }, + "title": "قم بتنزيل بيانات اعتماد MOSIP", + "description": "توفير UIN أو VIDقم بتنزيل بيانات الاعتماد عن طريق", + "language": "ar" + }, + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "मोसिप लोगो" + }, + "title": "MOSIP क्रेडेंशियल डाउनलोड करेंं", + "description": "यूआईएन या वीआईडी प्रदान करके क्रेडेंशियल डाउनलोड करें", + "language": "hi" + }, + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "mosip ಲೋಗೋ" + }, + "title": "MOSIP ರುಜುವಾತುಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಿ", + "description": "UIN ಅಥವಾ VID ಒದಗಿಸುವ ಮೂಲಕ ರುಜುವಾತುಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಿ", + "language": "kn" + }, + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "mosip லோகோ" + }, + "title": "MOSIP சான்றுகளைப் பதிவிறக்கவும்", + "description": "UIN அல்லது VIDஐ வழங்குவதன் மூலம் நற்சான்றிதழ்களைப் பதிவிறக்கவும்", + "language": "ta" + }, + { + "name": "e-Signet", + "logo": { + "url": "https://api.collab.mosip.net/inji/mosip-logo.png", + "alt_text": "logo ng mosip" + }, + "title": "I-download ang Mga Kredensyal ng MOSIP", + "description": "Mag-download ng mga kredensyal sa pamamagitan ng pagbibigay ng UIN o VID", + "language": "fil" + } + ], + "client_id": "DEqVWfdKe9cQWikLdjak3vlDF0Pq7jtnwTcGdEXoT1I", + "redirect_uri": "io.mosip.residentapp.inji://oauthredirect", + "authorization_audience": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", + "token_endpoint": "https://api.collab.mosip.net/v1/mimoto/get-token/ESignet", + "proxy_token_endpoint": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", + "credential_endpoint": "https://esignet.collab.mosip.net/v1/esignet/vci/credential", + "credential_type": [ + "VerifiableCredential", + "MOSIPVerifiableCredential" + ], + "credential_audience": "https://esignet.collab.mosip.net", + "client_alias": "mpartner-default-mimotooidc", + "additional_headers": { + "Accept": "application/json" + }, + "wellknown_endpoint": "https://esignet.collab.mosip.net/.well-known/openid-credential-issuer" }, "errors": [] } }, "Failure response": { "value": { - "id": "mosip.resident.vid", + "id": null, "version": "v1", "str": null, - "responsetime": "2022-10-31T04:57:10.792Z", + "responsetime": "2022-10-31T05:07:34.789Z", "metadata": null, "response": null, "errors": [ { - "errorCode": "RES-SER-422", - "errorMessage": "OTP is invalid" + "errorCode": "RESIDENT-APP-26", + "errorMessage": "Api not accessible failure" } ] } @@ -1532,170 +1911,149 @@ } } } - }, - "summary": "Generate VID", - "description": "Generate new VID" + } } }, - "/req/auth/unlock": { - "post": { - "operationId": "authUnlock", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AuthUnlockRequestDTO" - } - } - }, - "required": true - }, + "/v2/issuers": { + "get": { + "operationId": "getAllIssuersV2", + "parameters": [], + "tags": [ + "Trusted Issuers V2" + ], + "summary": "Retrieve all onboarded issuers (V2)", + "description": "Retrieve all onboarded issuers in V2 response format. Returns minimal issuer data from configuration (issuer_id, client_id, credential_issuer_host, qr_code_type, token_endpoint, protocol, display, etc.) without fetching well-known endpoints.", "responses": { "200": { "description": "OK", "content": { - "*/*": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { "type": "string", "nullable": true }, + "version": { "type": "string", "nullable": true }, + "responsetime": { "type": "string", "format": "date-time", "nullable": true }, + "metadata": { "type": "object", "nullable": true }, + "response": { + "type": "object", + "properties": { + "issuers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IssuerV2DTO" + } + } + } + }, + "errors": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } } }, "nullable": true } + } + } + } + } + }, + "400": { + "description": "Bad Request - API not accessible or configuration error", + "content": { + "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "response": { "type": "object", "nullable": true }, + "errors": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } } } } + } } } } } - }, - "summary": "Auth Unlock", - "description": "Auth unlock" + } } }, - "/req/auth/lock": { - "post": { - "operationId": "authLock", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AuthLockRequestDTO" - } - } - }, - "required": true - }, + "/v2/issuers/{issuer-id}": { + "get": { + "operationId": "getIssuerByIdV2", + "parameters": [ + { + "name": "issuer-id", + "in": "path", + "required": true, + "schema": { "type": "string" }, + "description": "Unique identifier of the issuer" + } + ], + "tags": [ + "Trusted Issuers V2" + ], + "summary": "Retrieve specific issuer (V2)", + "description": "Retrieve a single issuer in V2 response format by issuer ID. Returns configuration-only data.", "responses": { "200": { "description": "OK", "content": { - "*/*": { + "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "id": { "type": "string", "nullable": true }, + "version": { "type": "string", "nullable": true }, + "responsetime": { "type": "string", "format": "date-time", "nullable": true }, + "metadata": { "type": "object", "nullable": true }, + "response": { "$ref": "#/components/schemas/IssuerV2DTO" }, + "errors": { "type": "array", "items": { "type": "object" }, "nullable": true } + } } } } - } - }, - "description": "Auth lock", - "summary": "Auth Lock" - } - }, - "/allProperties": { - "get": { - "operationId": "getAllProperties", - "responses": {}, - "description": "get all configurable properties for inji.", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "version": { - "type": "string" - }, - "str": { - "type": "null" - }, - "responsetime": { - "type": "string" - }, - "metadata": { - "type": "null" - }, - "response": { - "type": "object", - "properties": { - "internal.auth.types.allowed": { - "type": "string" - }, - "auth.types.allowed": { - "type": "string" - }, - "ekyc.auth.types.allowed": { - "type": "string" - } - } - }, - "errors": { - "type": "array", - "items": { - "type": "object", - "properties": {} - } - } - }, - "x-examples": { - "Example 1": { - "id": "mosip.inji.properties", - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:22:21.009Z", - "metadata": null, - "response": { - "internal.auth.types.allowed": "otp,bio-Finger,bio-Iris,bio-Face", - "auth.types.allowed": "demo,otp,bio-Finger,bio-Iris,bio-Face", - "ekyc.auth.types.allowed": "demo,otp,bio-Finger,bio-Iris,bio-Face" - }, - "errors": [] + }, + "404": { + "description": "Not Found - Invalid issuer ID", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "response": { "type": "object", "nullable": true }, + "errors": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } } } } } } - }, - "examples": { - "example-1": { - "value": { - "id": "mosip.inji.properties", - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:22:21.009Z", - "metadata": null, - "response": { - "internal.auth.types.allowed": "otp,bio-Finger,bio-Iris,bio-Face", - "auth.types.allowed": "demo,otp,bio-Finger,bio-Iris,bio-Face", - "ekyc.auth.types.allowed": "demo,otp,bio-Finger,bio-Iris,bio-Face" - }, - "errors": [] + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "response": { "type": "object", "nullable": true }, + "errors": { "type": "array" } } } } } } - }, - "summary": "Get all Inji app properties" + } } }, - "/issuers": { + "/issuers/{issuer-id}/well-known-proxy": { "get": { - "operationId": "getAllIssuers", + "operationId": "getCredentialWellknown", "parameters": [ { - "name": "search", - "in": "query", - "required": false, + "name": "issuer-id", + "in": "path", + "required": true, "schema": { "type": "string" } } ], - "description": "This API provides data with search capability to populate the list of supported issuers in Inji Web, which is then displayed under the List of Issuers", + "tags": [ + "Trusted Issuers" + ], + "deprecated": true, + "description": "This API fetches and allows searching for Credential Types offered by the issuer, all sourced from the issuer's well-known configuration. Since version 0.16.0, this endpoint is deprecated and will be removed in a future release. Use issuers new endpoint issuers/{issuer-id}/configuration instead.", "responses": { "200": { "description": "OK", @@ -1704,160 +2062,426 @@ "schema": { "type": "object", "properties": { - "issuers": [ - { - "credential_issuer": "string", - "protocol": "string", - "display": [ - { - "name": "string", - "logo": { - "url": "string", - "alt_text": "string" - }, - "title": "string", - "description": "string", - "language": "string" + "credential_issuer": { + "type": "string" + }, + "authorization_servers": { + "type": "array", + "items": { + "type": "string" + } + }, + "credential_endpoint": { + "type": "string" + }, + "credential_configurations_supported": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "format": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "doctype": { + "type": "string" + }, + "proof_types_supported": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "proof_signing_alg_values_supported": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "claims": { + "type": "object" + }, + "credential_definition": { + "type": "object", + "properties": { + "type": { + "type": "array", + "items": { + "type": "string" + } + }, + "credentialSubject": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "display": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "locale": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "display": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "logo": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "alt_text": { + "type": "string" + } + } + }, + "background_image": { + "type": "object", + "properties": { + "uri": { + "type": "string" + } + } + }, + "background_color": { + "type": "string" + }, + "text_color": { + "type": "string" + } + } + } + }, + "order": { + "type": "array", + "items": { + "type": "string" + } } - ], - "client_id": "string", - "redirect_uri": "string", - "scopes_supported": [ - "string" - ], - "authorization_endpoint": "string", - "authorization_audience": "string", - "token_endpoint": "string", - "proxy_token_endpoint": "string", - "credential_endpoint": "string", - "credential_type": [ - "string" - ], - "credential_audience": "string", - "client_alias": "string", - "additional_headers": { - "additionalProp1": "string", - "additionalProp2": "string", - "additionalProp3": "string" - }, - ".well-known": "string" + } } - ] + } } }, - "x-examples": { - "Example 1": { - "id": "mosip.resident.vid", - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:08:14.846Z", - "metadata": null, - "response": { - "issuers": [ - { - "credential_issuer": "MOSIPInsurance", - "protocol": "OpenId4VCI", + "examples": { + "Success response": { + "value": { + "credential_issuer": "https://injicertify-insurance.dev1.mosip.net", + "authorization_servers": [ + "https://esignet-insurance.dev1.mosip.net" + ], + "credential_endpoint": "https://injicertify-insurance.dev1.mosip.net/v1/certify/issuance/credential", + "credential_configurations_supported": { + "InsuranceCredential": { + "format": "ldp_vc", + "scope": "sunbird_rc_insurance_vc_ldp", + "order": [ + "fullName", + "policyName", + "policyExpiresOn", + "policyIssuedOn", + "policyNumber", + "mobile", + "dob", + "gender", + "benefits", + "email" + ], + "proof_types_supported": { + "jwt": { + "proof_signing_alg_values_supported": [ + "RS256", + "PS256" + ] + } + }, + "credential_definition": { + "type": [ + "VerifiableCredential", + "InsuranceCredential" + ], + "credentialSubject": { + "fullName": { + "display": [ + { + "name": "Name", + "locale": "en" + } + ] + }, + "mobile": { + "display": [ + { + "name": "Phone Number", + "locale": "en" + } + ] + }, + "dob": { + "display": [ + { + "name": "Date of Birth", + "locale": "en" + } + ] + }, + "gender": { + "display": [ + { + "name": "Gender", + "locale": "en" + } + ] + }, + "benefits": { + "display": [ + { + "name": "Benefits", + "locale": "en" + } + ] + }, + "email": { + "display": [ + { + "name": "Email Id", + "locale": "en" + } + ] + }, + "policyIssuedOn": { + "display": [ + { + "name": "Policy Issued On", + "locale": "en" + } + ] + }, + "policyExpiresOn": { + "display": [ + { + "name": "Policy Expires On", + "locale": "en" + } + ] + }, + "policyName": { + "display": [ + { + "name": "Policy Name", + "locale": "en" + } + ] + }, + "policyNumber": { + "display": [ + { + "name": "Policy Number", + "locale": "en" + } + ] + } + } + }, "display": [ { - "name": "MOSIP Insurance", + "name": "Health Insurance", + "locale": "en", "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "MOSIP-Logo" + "url": "https://raw.githubusercontent.com/tw-mosip/file-server/master/StayProtectedInsurance.png", + "alt_text": "a square logo of a Veridonia" }, - "title": "Download via LIC", - "description": "This API provides data to populate the list of supported issuers in Inji Web, which is then displayed under the List of Issuers section on the Home page of Inji Web.", - "language": "en" + "background_image": { + "uri": "https://api.dev1.mosip.net/inji/veridonia-logo.png" + }, + "background_color": "#FDFAF9", + "text_color": "#7C4616" } - ], - "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", - ".well-known": "http://localhost:8088/.well-known/openid-credential-issuer" + ] }, - { - "credential_issuer": "MOSIPNationalID", - "protocol": "OpenId4VCI", + "LifeInsuranceCredential": { + "format": "ldp_vc", + "scope": "life_insurance_vc_ldp", + "order": [ + "fullName", + "policyName", + "policyExpiresOn", + "policyIssuedOn", + "policyNumber", + "mobile", + "dob", + "gender", + "benefits", + "email" + ], + "proof_types_supported": { + "jwt": { + "proof_signing_alg_values_supported": [ + "RS256", + "ES256" + ] + } + }, + "credential_definition": { + "type": [ + "VerifiableCredential", + "LifeInsuranceCredential" + ], + "credentialSubject": { + "fullName": { + "display": [ + { + "name": "Name", + "locale": "en" + } + ] + }, + "mobile": { + "display": [ + { + "name": "Phone Number", + "locale": "en" + } + ] + }, + "dob": { + "display": [ + { + "name": "Date of Birth", + "locale": "en" + } + ] + }, + "gender": { + "display": [ + { + "name": "Gender", + "locale": "en" + } + ] + }, + "benefits": { + "display": [ + { + "name": "Benefits", + "locale": "en" + } + ] + }, + "email": { + "display": [ + { + "name": "Email Id", + "locale": "en" + } + ] + }, + "policyIssuedOn": { + "display": [ + { + "name": "Policy Issued On", + "locale": "en" + } + ] + }, + "policyExpiresOn": { + "display": [ + { + "name": "Policy Expires On", + "locale": "en" + } + ] + }, + "policyName": { + "display": [ + { + "name": "Policy Name", + "locale": "en" + } + ] + }, + "policyNumber": { + "display": [ + { + "name": "Policy Number", + "locale": "en" + } + ] + } + } + }, "display": [ { - "name": "MOSIP National ID", + "name": "Life Insurance", + "locale": "en", "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "MOSIP-Logo" + "url": "https://raw.githubusercontent.com/tw-mosip/file-server/master/StayProtectedInsurance.png", + "alt_text": "a square logo of a Veridonia" }, - "title": "Download via LIC", - "description": "Enter your policy number to download your card.", - "language": "en" + "background_image": { + "uri": "https://api.dev1.mosip.net/inji/veridonia-logo.png" + }, + "background_color": "#FDFAF9", + "text_color": "#7C4616" } - ], - "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", - ".well-known": "http://localhost:8088/.well-known/openid-credential-issuer" + ] + } + } + } + }, + "Failure response": { + "value": { + "id": null, + "version": "v1", + "str": null, + "responsetime": "2022-10-31T05:07:34.789Z", + "metadata": null, + "response": null, + "errors": [ + { + "errorCode": "RESIDENT-APP-026", + "errorMessage": "Api not accessible failure" } ] } }, - "errors": null - }, - "examples": { - "Success response": { + "Failure response 2": { "value": { - "id": "mosip.resident.vid", + "id": null, "version": "v1", "str": null, - "responsetime": "2022-10-31T05:08:14.846Z", - "metadata": null, - "response": { - "issuers": [ - { - "credential_issuer": "MOSIPInsurance", - "protocol": "OpenId4VCI", - "display": [ - { - "name": "MOSIP Insurance", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "MOSIP-Logo" - }, - "title": "Download via LIC", - "description": "Enter your policy number to download your card.", - "language": "en" - } - ], - "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", - ".well-known": "http://localhost:8088/.well-known/openid-credential-issuer" - }, - { - "credential_issuer": "MOSIPNationalID", - "protocol": "OpenId4VCI", - "display": [ - { - "name": "MOSIP National ID", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "MOSIP-Logo" - }, - "title": "Download via LIC", - "description": "Enter your policy number to download your card.", - "language": "en" - } - ], - "client_id": "3yz7-j3xRzU3SODdoNgSGvO_cD8UijH3AIWRDAg1x-M", - ".well-known": "http://localhost:8088/.well-known/openid-credential-issuer" - } - ] - } - }, - "errors": null - }, - "Failure response": { - "value": { - "id": null, - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:07:34.789Z", + "responsetime": "2022-10-31T05:07:34.789Z", "metadata": null, "response": null, "errors": [ { - "errorCode": "RESIDENT-APP-26", - "errorMessage": "Api not accessible failure" + "errorCode": "RESIDENT-APP-035", + "errorMessage": "Invalid issuer ID" } ] } @@ -1866,268 +2490,205 @@ } } } - } + }, + "summary": "Get Issuers Wellknown" } }, - "/issuers/{issuer-id}": { + "/issuers/{issuer-id}/configuration": { "get": { - "operationId": "getIssuerConfig", + "operationId": "getCredentialIssuerConfiguration", "parameters": [ { "name": "issuer-id", "in": "path", "required": true, + "description": "The unique identifier of the credential issuer.", "schema": { "type": "string" } } ], - "description": "This API provides the complete configuration details for the specific issuers passed in the path variable", + "tags": [ + "Trusted Issuers" + ], + "description": "Retrieve the required configuration details for a specific issuer and its authorization server from their respective well-known endpoints.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "issuers": [ - { - "credential_issuer": "string", - "protocol": "string", - "display": [ + "$ref": "#/components/schemas/IssuerConfigurationSuccessResponse" + }, + "examples": { + "SuccessResponse": { + "summary": "Issuer Configuration Response", + "value": { + "response": { + "credentials_supported": [ { - "name": "string", - "logo": { - "url": "string", - "alt_text": "string" - }, - "title": "string", - "description": "string", - "language": "string" + "name": "InsuranceCredential", + "scope": "sunbird_rc_insurance_vc_ldp", + "display": [ + { + "name": "Health Insurance", + "locale": "en", + "logo": "https://raw.githubusercontent.com/tw-mosip/file-server/master/StayProtectedInsurance.png" + } + ] } ], - "client_id": "string", - "redirect_uri": "string", - "scopes_supported": [ - "string" - ], - "authorization_endpoint": "string", - "authorization_audience": "string", - "token_endpoint": "string", - "proxy_token_endpoint": "string", - "credential_endpoint": "string", - "credential_type": [ - "string" - ], - "credential_audience": "string", - "client_alias": "string", - "additional_headers": { - "additionalProp1": "string", - "additionalProp2": "string", - "additionalProp3": "string" - }, - ".well-known": "string" - } - ] + "authorization_endpoint": "https://esignet-insurance.collab.mosip.net/authorize", + "grant_types_supported": [ + "authorization_code" + ] + }, + "errors": [] + } } + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IssuerConfigurationErrorResponse" }, - "x-examples": { - "Example 1": { - "id": "mosip.mimoto.issuers", - "version": "v1", - "str": null, - "responsetime": "2024-04-25T05:56:55.890Z", - "metadata": null, - "response": { - "credential_issuer": "ESignet", - "protocol": "OpenId4VCI", - "display": [ - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "mosip-logo" - }, - "title": "Download MOSIP Credentials", - "description": "Download credentials by providing UIN or VID", - "language": "en" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "شعار موسيب" - }, - "title": "قم بتنزيل بيانات اعتماد MOSIP", - "description": "توفير UIN أو VIDقم بتنزيل بيانات الاعتماد عن طريق", - "language": "ar" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "मोसिप लोगो" - }, - "title": "MOSIP क्रेडेंशियल डाउनलोड करेंं", - "description": "यूआईएन या वीआईडी प्रदान करके क्रेडेंशियल डाउनलोड करें", - "language": "hi" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "mosip ಲೋಗೋ" - }, - "title": "MOSIP ರುಜುವಾತುಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಿ", - "description": "UIN ಅಥವಾ VID ಒದಗಿಸುವ ಮೂಲಕ ರುಜುವಾತುಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಿ", - "language": "kn" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "mosip லோகோ" - }, - "title": "MOSIP சான்றுகளைப் பதிவிறக்கவும்", - "description": "UIN அல்லது VIDஐ வழங்குவதன் மூலம் நற்சான்றிதழ்களைப் பதிவிறக்கவும்", - "language": "ta" - }, + "examples": { + "FailureResponse1": { + "summary": "Api not accessible failure", + "value": { + "errors": [ { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "logo ng mosip" - }, - "title": "I-download ang Mga Kredensyal ng MOSIP", - "description": "Mag-download ng mga kredensyal sa pamamagitan ng pagbibigay ng UIN o VID", - "language": "fil" + "errorCode": "RESIDENT-APP-026", + "errorMessage": "Api not accessible failure" } ], - "client_id": "*****", - "redirect_uri": "io.mosip.residentapp.inji://oauthredirect", - "scopes_supported": [ - "mosip_identity_vc_ldp" + "response": null + } + }, + "FailureResponse2": { + "summary": "Invalid issuer ID", + "value": { + "errors": [ + { + "errorCode": "RESIDENT-APP-035", + "errorMessage": "Invalid issuer ID" + } ], - "authorization_endpoint": "https://esignet.collab.mosip.net/authorize", - "authorization_audience": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", - "token_endpoint": "https://api.collab.mosip.net/residentmobileapp/get-token/ESignet", - "proxy_token_endpoint": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", - "credential_endpoint": "https://esignet.collab.mosip.net/v1/esignet/vci/credential", - "credential_type": [ - "VerifiableCredential", - "MOSIPVerifiableCredential" + "response": null + } + }, + "FailureResponse3": { + "summary": "Invalid Authorization Server well-known endpoint", + "value": { + "errors": [ + { + "errorCode": "RESIDENT-APP-042", + "errorMessage": "Invalid Authorization Server well-known from server:\nAuthorization Server host url cannot be null" + } ], - "credential_audience": "https://esignet.collab.mosip.net", - "client_alias": "mpartner-default-mimotooidc", - "additional_headers": { - "Accept": "application/json" - }, - ".well-known": "https://esignet.collab.mosip.net/.well-known/openid-credential-issuer" - }, - "errors": [] + "response": null + } + } + } + } + } + } + } + } + }, + "/credentials/download": { + "post": { + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "grant_type": { + "type": "string", + "example": "authorization_code" }, - "errors": null + "code": { + "type": "string", + "example": "GL9N1V-authorizationcodeyBkoaonjplms" + }, + "redirect_uri": { + "type": "string", + "example": "https://injiweb.collab.mosip.net/redirect" + }, + "code_verifier": { + "type": "string", + "example": "Sq6nZNToevcodeVerifierjXw70LCJ" + }, + "issuer": { + "type": "string", + "example": "Mosip" + }, + "credential": { + "type": "string", + "example": "MosipVerifiableCredential" + }, + "vcStorageExpiryLimitInTimes": { + "type": "string", + "example": "1" + }, + "locale": { + "type": "string", + "example": "en" + } + } + } + } + }, + "required": true + }, + "tags": [ + "Credentials Download" + ], + "description": "This API is responsible for generating PDFs for the received VC content. It fetches display properties from the well-known configuration of the issuer and incorporates them into the predefined template of the PDF file.", + "responses": { + "200": { + "description": "OK", + "content": { + "application/pdf": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "400": { + "description": "BAD_REQUEST", + "content": { + "application/pdf": { + "schema": { + "type": "string", + "format": "binary" }, "examples": { - "Success response": { + "Failure response 1": { "value": { - "id": "mosip.mimoto.issuers", + "id": null, "version": "v1", "str": null, - "responsetime": "2024-04-25T05:56:55.890Z", + "responsetime": "2022-10-31T05:07:34.789Z", "metadata": null, - "response": { - "credential_issuer": "ESignet", - "protocol": "OpenId4VCI", - "display": [ - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "mosip-logo" - }, - "title": "Download MOSIP Credentials", - "description": "Download credentials by providing UIN or VID", - "language": "en" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "شعار موسيب" - }, - "title": "قم بتنزيل بيانات اعتماد MOSIP", - "description": "توفير UIN أو VIDقم بتنزيل بيانات الاعتماد عن طريق", - "language": "ar" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "मोसिप लोगो" - }, - "title": "MOSIP क्रेडेंशियल डाउनलोड करेंं", - "description": "यूआईएन या वीआईडी प्रदान करके क्रेडेंशियल डाउनलोड करें", - "language": "hi" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "mosip ಲೋಗೋ" - }, - "title": "MOSIP ರುಜುವಾತುಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಿ", - "description": "UIN ಅಥವಾ VID ಒದಗಿಸುವ ಮೂಲಕ ರುಜುವಾತುಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಿ", - "language": "kn" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "mosip லோகோ" - }, - "title": "MOSIP சான்றுகளைப் பதிவிறக்கவும்", - "description": "UIN அல்லது VIDஐ வழங்குவதன் மூலம் நற்சான்றிதழ்களைப் பதிவிறக்கவும்", - "language": "ta" - }, - { - "name": "e-Signet", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "logo ng mosip" - }, - "title": "I-download ang Mga Kredensyal ng MOSIP", - "description": "Mag-download ng mga kredensyal sa pamamagitan ng pagbibigay ng UIN o VID", - "language": "fil" - } - ], - "client_id": "DEqVWfdKe9cQWikLdjak3vlDF0Pq7jtnwTcGdEXoT1I", - "redirect_uri": "io.mosip.residentapp.inji://oauthredirect", - "scopes_supported": [ - "mosip_identity_vc_ldp" - ], - "authorization_endpoint": "https://esignet.collab.mosip.net/authorize", - "authorization_audience": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", - "token_endpoint": "https://api.collab.mosip.net/residentmobileapp/get-token/ESignet", - "proxy_token_endpoint": "https://esignet.collab.mosip.net/v1/esignet/oauth/v2/token", - "credential_endpoint": "https://esignet.collab.mosip.net/v1/esignet/vci/credential", - "credential_type": [ - "VerifiableCredential", - "MOSIPVerifiableCredential" - ], - "credential_audience": "https://esignet.collab.mosip.net", - "client_alias": "mpartner-default-mimotooidc", - "additional_headers": { - "Accept": "application/json" - }, - ".well-known": "https://esignet.collab.mosip.net/.well-known/openid-credential-issuer" - }, - "errors": [] - }, - "errors": null + "response": null, + "errors": [ + { + "errorCode": "RESIDENT-APP-036", + "errorMessage": "Invalid Credential Type Id" + } + ] + } }, - "Failure response": { + "Failure response 2": { "value": { "id": null, "version": "v1", @@ -2137,465 +2698,2094 @@ "response": null, "errors": [ { - "errorCode": "RESIDENT-APP-26", + "errorCode": "RESIDENT-APP-026", "errorMessage": "Api not accessible failure" } ] } + }, + "Failure response 3": { + "value": { + "id": null, + "version": "v1", + "str": null, + "responsetime": "2022-10-31T05:07:34.789Z", + "metadata": null, + "response": null, + "errors": [ + { + "errorCode": "RESIDENT-APP-028", + "errorMessage": "error occured while signing pdf" + } + ] + } } } } } } + }, + "summary": "Download Credential As PDF", + "x-stoplight": { + "id": "42bjevdfa0stx" } } }, - "/issuers/{issuer-id}/credentialTypes": { + "/authorize": { "get": { - "operationId": "getCredentialTypes", + "summary": "Authorize Verifiable Presentation", + "tags": [ + "Authorize the Verifiable Presentation" + ], + "responses": { + "302": { + "description": "Found\n\n**Success Case :**\n\n```json\n\n{redirectUri}#vp_token={base64_encoded_vpToken}&presentation_submission={url_encoded_presentation_submission}\n\n```\n**Error Case :** \n\n```json\n\n{redirectUri}?error={error_codes}&error_messages={error_messages}\n\n```\n\n\n**Possible Error Codes and Error Messages :**\n\n- **invalid_request** - \"Some incorrect parameters in the request\"\n- **unsupported_format** - \"No VC of this format is found\"\n- **resource_not_found** - \"The requested resource doesn’t exist.\"\n- **server_unavailable** - \"The server is not reachable right now.\"\n- **resource_expired** - \"The requested resource expired.\"\n- **resource_invalid** - \"The requested resource is invalid.\"\n- **request_timed_out** - \"We are unable to process your request right now\"\n- **uri_too_long** - \"Resource URI is too long to be handled\"\n- **invalid_client** - \"The requested client doesn’t match.\"\n- **invalid_redirect_uri** - \"The requested redirect URI doesn’t match.\"\n- **internal_server_error** - \"We are unable to process request now\"\n\n" + } + }, + "operationId": "get-v1-mimoto-authorize", + "x-stoplight": { + "id": "x4k8ruhin2f09" + }, "parameters": [ { - "name": "issuer-id", + "schema": { + "type": "string", + "default": "vp_token" + }, + "in": "query", + "name": "response_type", + "description": "Response Type of the authorization" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "resource", + "description": "Credential Resource url" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "presentation_definition", + "description": "URL Encoded Value of the presentation Definition" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "client_id", + "description": "Client ID of the registered verifier" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "redirect_uri", + "description": "One of the Redirect uri of the registered verifiers" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "state", + "description": "Unique session identifier to prevent CSRF" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "nonce", + "description": "Cryptographic challenge used to bind the presentation to this request" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "response_uri", + "description": "Where to send the VP token" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "response_mode", + "description": "Specifies how the Verifier will receive the Authorization Response from the Wallet" + } + ] + } + }, + "/users/me": { + "get": { + "tags": [ + "Users" + ], + "summary": "Retrieve user metadata", + "description": "First attempts to retrieve user metadata from the session cache. If not available, fetches from the database. This API is secured using session-based authentication.", + "operationId": "getUserProfile", + "security": [ + { + "SessionAuth": [] + } + ], + "responses": { + "200": { + "description": "User profile retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserMetadataDTO" + }, + "examples": { + "Success response from DB": { + "value": { + "displayName": "John Doe", + "profilePictureUrl": "https://example.com/profile.jpg", + "email": "john.doe@example.com" + } + }, + "Success response from cache": { + "value": { + "displayName": "John Doe", + "profilePictureUrl": "john.doe@example.com", + "email": "john.doe@example.com", + "walletId": "123e4567-e89b-12d3-a456-426614174000" + } + } + } + } + } + }, + "401": { + "description": "User data not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User data not available in DB" : { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User not found. Please check your credentials or login again" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + }, + "Decryption Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "Failed to process user data" + } + } + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Database connection failure": { + "value": { + "errorCode": "database_unavailable", + "errorMessage": "Failed to connect to the database" + } + } + } + } + } + } + } + } + }, + "/wallets/{walletId}/credentials": { + "post": { + "tags": [ + "Wallet Credentials" + ], + "summary": "Download and store a Verifiable Credential under a specific Wallet", + "description": "This API is secured using session-based authentication. Upon receiving a request, the session ID is extracted from the Cookie header and used to retrieve session details from Redis for authentication. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests. It then retrieves the wallet key from the session and use it to decrypt the signing algorithm's secret key(which is used for signing the JWT in credential request) and encrypt the downloaded Verifiable Credential. If the process completes successfully, the credential is stored in the database and certain fields will be returned in the response. In case of any issues, an appropriate error response is returned.", + "operationId": "downloadCredential", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "walletId", "in": "path", "required": true, "schema": { "type": "string" - } + }, + "description": "Unique identifier of the user's wallet where the credential will be stored" }, { - "name": "search", - "in": "query", + "name": "X-XSRF-TOKEN", + "in": "header", "required": false, "schema": { "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + }, + { + "name": "Accept-Language", + "in": "header", + "required": false, + "schema": { + "type": "string", + "default": "en" + }, + "description": "Locale is used to determine the language in which credential's issuer display details should be stored. Input should be a 2-letter code (e.g., 'en' for English, 'fr' for French). If not provided, defaults to 'en'." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifiableCredentialRequestDTO" + }, + "examples": { + "Default download": { + "value": { + "issuer": "Mosip", + "credentialConfigurationId": "MosipVerifiableCredential", + "code": "abc123", + "grant_type": "authorization_code", + "redirectUri": "https://example.com/redirect", + "codeVerifier": "xyz-secret-verifier" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Verifiable Credential downloaded and stored successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifiableCredentialResponseDTO" + }, + "examples": { + "Success response": { + "value": { + "issuerDisplayName": "Mosip", + "issuerLogo": "https://example.com/logo.png", + "credentialTypeDisplayName": "National Identity Department Mosip", + "credentialTypeLogo": "https://example.com/credential-logo.png", + "credentialId": "1234567890" + } + } + } + } + } + }, + "400": { + "description": "Bad request - Wallet key is null / blank or Wallet ID is null / blank / mismatch with session Wallet ID or required params are missing / invalid or any invalid request data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Wallet ID is null or blank": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Wallet ID cannot be blank" + } + }, + "Invalid Accept-Language header": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Locale must be a 2-letter code" + } + }, + "Invalid Wallet ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Wallet ID not found in session": { + "value": { + "errorCode": "wallet_locked", + "errorMessage": "Wallet is locked" + } + }, + "Wallet key not found in session" : { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Wallet key not found in session" + } + }, + "Invalid issuer": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "issuerId cannot be blank" + } + }, + "Invalid credentialConfigurationId": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "credentialConfigurationId cannot be blank" + } + }, + "Invalid code": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "code cannot be blank" + } + }, + "Invalid grantType": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "grantType cannot be blank" + } + }, + "Invalid redirectUri": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "redirectUri cannot be blank" + } + }, + "Invalid codeVerifier": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "codeVerifier cannot be blank" + } + }, + "Credential already exists for given Issuer and Credential Type in the wallet": { + "value": { + "errorCode": "credential_download_error", + "errorMessage": "Duplicate credential for issuer and type" + } + } + } + } + } + }, + "500": { + "description": "Internal server error - along with below examples it will return this status code when error occurred while serializing the VC response or unable to store the response in data share or unable to encrypt the credential", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Exception occurred while fetching Issuer config": { + "value": { + "errorCode": "credential_download_error", + "errorMessage": "Unable to fetch issuer configuration" + } + }, + "Failed to generate VC Credential request": { + "value": { + "errorCode": "credential_download_error", + "errorMessage": "Unable to generate credential request" + } + }, + "Signature verification failed for downloaded Credential": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + }, + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + }, + "503": { + "description": "Service unavailable - along with below examples it will return this status code when any error occurred while fetching Issuer wellknown or Auth Server wellknown", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "API is not accessible": { + "value": { + "errorCode": "credential_download_error", + "errorMessage": "Failed to download and store the credential" + } + }, + "Failed to download credential from Issuer": { + "value": { + "errorCode": "server_unavailable", + "errorMessage": "Unable to download credential from issuer" + } + }, + "Database connection failure": { + "value": { + "errorCode": "database_unavailable", + "errorMessage": "Failed to connect to the database" + } + } + } + } + } + } + } + }, + "get": { + "tags": [ + "Wallet Credentials" + ], + "summary": "Fetch all credentials for the given wallet", + "description": "This API is secured using session-based authentication. When a request is made, the session ID is extracted from the Cookie header and used to fetch session details from Redis for authentication. It then retrieves the wallet key from the session and uses it to decrypt all stored Verifiable Credentials for the given wallet. If successful, it returns a list of credentials otherwise an appropriate error is returned.", + "operationId": "fetchAllCredentialsForWallet", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Unique identifier of the user's wallet from where the credential will be fetched" + }, + { + "name": "Accept-Language", + "in": "header", + "required": false, + "schema": { + "type": "string", + "default": "en" + }, + "description": "Language preference in which the user expects the Verifiable Credential to be rendered. Input should be a 2-letter code (e.g., 'en' for English, 'fr' for French). If not provided, defaults to 'en'." + } + ], + "responses": { + "200": { + "description": "Credentials retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VerifiableCredentialResponseDTO" + } + }, + "examples": { + "Success response": { + "value": [ + { + "issuerDisplayName": "Mosip", + "issuerLogo": "https://example.com/logo.png", + "credentialTypeDisplayName": "National Identity Department Mosip", + "credentialTypeLogo": "https://example.com/credential-logo.png", + "credentialId": "1234567890" + } + ] + } + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid Wallet Id": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Wallet ID is not available in session" : { + "value": { + "errorCode": "wallet_locked", + "errorMessage": "Wallet is locked" + } + }, + "Wallet key not found in session": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Wallet key not found in session" + } + }, + "Invalid Accept-Language header": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Locale must be a 2-letter code" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Database connection failure": { + "value": { + "errorCode": "database_unavailable", + "errorMessage": "Failed to connect to the database" + } + } + } + } + } + } + } + } + }, + "/wallets/{walletId}/credentials/{credentialId}": { + "get": { + "tags": [ + "Wallet Credentials" + ], + "summary": "Fetch a Verifiable Credential by ID to either preview it or download it based on the requirement", + "description": "This API is protected using session-based authentication. When a request is received, the session ID is extracted from the Cookie header and used to fetch session data from Redis for user authentication. Upon successful authentication, the wallet key is retrieved from the session and used to decrypt the credential data obtained from the database.\n\nThe API retrieves a specific Verifiable Credential based on the provided wallet ID and credential ID. Depending on the action query parameter (inline or download) received in the request, the Content-Disposition header in the response is adjusted to either display the credential in the browser or prompt a file download. On success, the API returns the credential as a PDF byte stream. In case of any errors, an appropriate error response is returned.", + "operationId": "fetchVerifiableCredentialById", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Unique identifier of the user's wallet" + }, + { + "name": "credentialId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Unique identifier of the Verifiable Credential to be retrieved" + }, + { + "name": "action", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "inline" + }, + "description": "Controls how the credential should be displayed. If it is sent as download, the response will include a header to download the file. For any other value or if not provided, it defaults to inline to preview the file in the browser." + }, + { + "name": "Accept-Language", + "in": "header", + "required": false, + "schema": { + "type": "string", + "default": "en" + }, + "description": "Language preference in which the user expects the Verifiable Credential to be rendered. Input should be a 2-letter code (e.g., 'en' for English, 'fr' for French). If not provided, defaults to 'en'." + }, + { + "name": "Accept", + "in": "header", + "required": true, + "schema": { + "type": "string", + "example": "application/pdf" + }, + "description": "The Accept header must be set to application/pdf to indicate that the response should be in PDF format. If not provided or set to a different value, the API will return a 400 Bad Request error." + } + ], + "responses": { + "200": { + "description": "Verifiable Credential fetched successfully", + "headers": { + "Content-Disposition": { + "description": "Indicates if the verifiable credential is displayed inline or downloaded", + "schema": { + "type": "string", + "example": "inline; filename=\"credential.pdf\"" + } + } + }, + "content": { + "application/pdf": { + "schema": { + "type": "string", + "format": "binary" + }, + "examples": { + "Success response": { + "value": "PDF content in Binary Format" + } + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid Wallet Id": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Wallet ID is not available in session" : { + "value": { + "errorCode": "wallet_locked", + "errorMessage": "Wallet is locked" + } + }, + "Wallet key not found in session": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Wallet key not found in session" + } + }, + "Invalid Accept-Language header": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Locale must be a 2-letter code" + } + }, + "Invalid Accept header" : { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Accept header must be application/pdf" + } + } + } + } + } + }, + "404": { + "description": "Not Found - Credential not found for given Wallet ID and Credential ID", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "No credentials found for the given Credential ID and Wallet ID": { + "value": { + "errorCode": "resource_not_found", + "errorMessage": "The requested resource doesn’t exist." + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Failed to decrypt the Credential": { + "value": { + "errorCode": "credential_fetch_error", + "errorMessage": "Decryption failed" + } + }, + "Credential Type is invalid": { + "value": { + "errorCode": "credential_fetch_error", + "errorMessage": "Invalid credential type configuration" + } + }, + "Exception occurred while fetching Issuer config": { + "value": { + "errorCode": "credential_download_error", + "errorMessage": "Unable to fetch issuer configuration" + } + }, + "Exception occurred when generating PDF": { + "value": { + "errorCode": "credential_download_error", + "errorMessage": "Failed to generate credential PDF" + } + }, + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Database connection failure": { + "value": { + "errorCode": "database_unavailable", + "errorMessage": "Failed to connect to the database" + } + } + } + } + } + } + } + }, + "delete": { + "tags": [ + "Wallet Credentials" + ], + "summary": "Delete a credential from a wallet", + "description": "This endpoint allows you to delete a specific credential from a wallet. The API is secured using session-based authentication. The session ID is extracted from the Cookie header to authenticate the user. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests. The wallet ID is validated against the session to ensure the user has access to the wallet. If the credential is successfully deleted, a 200 OK response is returned.", + "operationId": "deleteCredential", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Unique identifier of the wallet containing the credential" + }, + { + "name": "credentialId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Unique identifier of the credential to be deleted" + }, + { + "name": "X-XSRF-TOKEN", + "in": "header", + "required": false, + "schema": { + "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + } + ], + "responses": { + "200": { + "description": "Credential successfully deleted" + }, + "400": { + "description": "Provided request is invalid", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid Wallet Id": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Wallet ID is not available in session" : { + "value": { + "errorCode": "wallet_locked", + "errorMessage": "Wallet is locked" + } + } + } + } + } + }, + "404": { + "description": "Credential not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Credential not found": { + "value": { + "errorCode": "resource_not_found", + "errorMessage": "The requested resource doesn’t exist." + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + } + } + } + }, + "/wallets": { + "post": { + "tags": [ + "Wallets" + ], + "summary": "Create a new wallet", + "description": "This API is secured using session-based authentication. The session ID is extracted from the Cookie header and used to retrieve session details from Redis for authentication. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests. The user ID is then obtained from the session and along with the provided wallet name and PIN is used to create a new wallet in the database. If the wallet is created successfully, response including unique identifier of the wallet and and the provided name is returned otherwise an appropriate error response is provided.", + "operationId": "createWallet", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "X-XSRF-TOKEN", + "in": "header", + "required": false, + "schema": { + "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + } + ], + "requestBody": { + "required": true, + "description": "Wallet creation request containing the wallet name and wallet PIN", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateWalletRequestDto" + }, + "examples": { + "Create wallet request": { + "value": { + "walletPin": "1234", + "confirmWalletPin": "1234", + "walletName": "My Personal Wallet" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Wallet created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletResponseDTO" + }, + "examples": { + "Success response": { + "value": { + "walletId": "123e4567-e89b-12d3-a456-426614174000", + "walletName": "My Personal Wallet" + } + } + } + } + } + }, + "400": { + "description": "Invalid wallet creation request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid User ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "User ID cannot be null or empty" + } + }, + "Invalid Wallet name": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Wallet name must be alphanumeric with allowed special characters" + } + }, + "Invalid Wallet PIN": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "PIN must be numeric with 6 digits" + } + }, + "Entered Pin and Confirm Pin Mismatch": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Entered PIN and Confirm PIN do not match" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized user creating a wallet", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User ID is not present in session": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "500": { + "description": "Internal server error while creating Wallet - error occurred while generating Wallet key or encrypting it with Wallet PIN", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Database connection failure": { + "value": { + "errorCode": "database_unavailable", + "errorMessage": "Failed to connect to the database" + } + } + } + } + } + } + } + }, + "get": { + "tags": [ + "Wallets" + ], + "summary": "Retrieve all wallets for the user", + "description": "This API is secured using session-based authentication. Upon receiving a request, the session is first retrieved using the session ID extracted from the Cookie header to authenticate the user. Once authenticated, the user's ID is obtained from the session stored in Redis. Using this user ID, the API fetches all wallets associated with the user from the database and returns them. If an error occurs while retrieving the wallets, an appropriate error response is returned.", + "operationId": "getWallets", + "security": [ + { + "SessionAuth": [] + } + ], + "responses": { + "200": { + "description": "List of wallets retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WalletDetailsResponseDto" + } + }, + "examples": { + "Success response": { + "value": [ + { + "walletId": "123e4567-e89b-12d3-a456-426614174000", + "walletName": "My Personal Wallet", + "walletStatus": null + }, + { + "walletId": "223e4567-e89b-12d3-a456-426614174001", + "walletName": "Wallet Main", + "walletStatus": "temporarily_locked" + } + ] + } + } + } + } + }, + "400": { + "description": "Invalid Wallets fetching request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid User ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "User ID cannot be null or empty" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized user fetching wallets", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User ID is not present in session": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Database connection failure": { + "value": { + "errorCode": "database_unavailable", + "errorMessage": "Failed to connect to the database" + } + } + } + } + } + } + } + } + }, + "/wallets/{walletId}": { + "delete": { + "tags": [ + "Wallets" + ], + "summary": "Delete a Wallet", + "description": "This endpoint allows you to delete a specific wallet. The API is secured using session-based authentication. The session ID is extracted from the Cookie header to authenticate the user. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests. The user's ID is obtained from the session and used to validate ownership of the Wallet before deletion. If the Wallet is successfully deleted, a 200 OK response is returned; otherwise, an appropriate error response is returned.", + "operationId": "deleteWallet", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Unique identifier of the Wallet to be deleted" + }, + { + "name": "X-XSRF-TOKEN", + "in": "header", + "required": false, + "schema": { + "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + } + ], + "responses": { + "200": { + "description": "Wallet successfully deleted" + }, + "401": { + "description": "Unauthorized user deleting a Wallet", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User ID not found in session": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "400": { + "description": "Invalid wallet deletion request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid User ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "User ID cannot be null or empty" + } + }, + "Invalid Wallet ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Wallet ID not found in session": { + "value": { + "errorCode": "wallet_locked", + "errorMessage": "Wallet is locked" + } + }, + "Wallet not found in database": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Wallet not found" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + } + } + } + }, + "/wallets/{walletId}/unlock": { + "post": { + "tags": [ + "Wallets" + ], + "summary": "Unlock an existing Wallet", + "description": "This API is secured using session-based authentication. Upon receiving a request, the session is first retrieved using the session ID extracted from the Cookie header to authenticate the user. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests. Once authenticated, the user's ID is obtained from the session stored in Redis. Using this user ID along with the provided wallet ID and PIN, the corresponding wallet key is fetched and stored in the session. If successful then the API returns a response containing the wallet ID otherwise an appropriate error response is returned.", + "operationId": "unlockWallet", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Unique identifier of the wallet to be unlocked", + "example": "123e4567-e89b-12d3-a456-426614174000" + }, + { + "name": "X-XSRF-TOKEN", + "in": "header", + "required": false, + "schema": { + "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnlockWalletRequestDto" + }, + "examples": { + "Unlock wallet request": { + "value": { + "walletPin": "1234" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Wallet unlocked successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletResponseDto" + }, + "examples": { + "Success response": { + "value": { + "walletId": "123e4567-e89b-12d3-a456-426614174000", + "walletName": "My Personal Wallet" + } + } + } + } + } + }, + "400": { + "description": "Invalid Wallet unlock request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Wallet not found": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Wallet not found" + } + }, + "Invalid User ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "User ID cannot be null or empty" + } + }, + "Invalid Wallet PIN": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "PIN must be numeric with 6 digits" + } + }, + "Incorrect Wallet PIN": { + "value": { + "errorCode": "invalid_pin", + "errorMessage": "Invalid PIN or wallet key provided" + } + }, + "Only one attempt left to unlock Wallet before Permanent Lockout": { + "value": { + "errorCode": "last_attempt_before_lockout", + "errorMessage": "Incorrect passcode. Last attempt remaining before your Wallet is permanently locked" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized user unlocking wallet", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User ID is not present in session": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "423": { + "description": "Wallet is locked temporarily or permanently", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Wallet is locked Temporarily": { + "value": { + "errorCode": "temporarily_locked", + "errorMessage": "You’ve reached the maximum number of attempts. Your wallet is now temporarily locked" + } + }, + "Wallet is locked Permanently": { + "value": { + "errorCode": "permanently_locked", + "errorMessage": "Your wallet has been permanently locked due to multiple failed attempts. Please click on forgot password to reset your wallet to continue" + } + } + } + } + } + }, + "500": { + "description": "Internal server error - any error occurred while decrypting the Wallet key with Wallet PIN or when fetching Wallet details from the database", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + }, + "503": { + "description": "Service unavailable", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Database connection failure": { + "value": { + "errorCode": "database_unavailable", + "errorMessage": "Failed to connect to the database" + } + } + } + } + } + } + } + } + }, + "/wallets/{walletId}/presentations": { + "post": { + "tags": [ + "Wallet Presentations" + ], + "summary": "Processes Verifiable Presentation Authorization Request and provides details about the verifier and presentation.", + "description": "This API is secured using session-based authentication. Upon receiving a request, the session is first retrieved using the session ID extracted from the Cookie header to authenticate the user. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests. Once authenticated, the API processes the received Verifiable Presentation Authorization Request from the Verifier for a specific wallet. It validates the session, verifies the authenticity of the request, and checks if the Verifier is pre-registered and trusted by the wallet. If all validations pass, the API returns a response containing the presentation details; otherwise, an appropriate error response is returned.", + "operationId": "processVPAuthorizationRequest", + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The unique identifier of the Wallet." + }, + { + "name": "X-XSRF-TOKEN", + "in": "header", + "required": false, + "schema": { + "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifiablePresentationAuthorizationRequest" + }, + "examples": { + "Verifier Verifiable Presentation Authorization Request": { + "value": { + "authorizationRequestUrl": "client_id=mock-client&presentation_definition_uri=https%3A%2F%2Finji-verify.collab.mosip.net%2Fverifier%2Fpresentation_definition_uri&response_type=vp_token&response_mode=direct_post&nonce=NHgLcWlae745DpfJbUyfdg%253D%253D&response_uri=https%3A%2F%2Finji-verify.collab.mosip.net%2Fverifier%2Fvp-response&state=pcmxBfvdPEcjFObgt%252BLekA%253D%253D" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Successfully processed the Verifiable Presentation Authorization Request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifiablePresentationResponseDTO" + }, + "examples": { + "Success response": { + "value": { + "presentationId": "123e4567-e89b-12d3-a456-426614174000", + "verifier": { + "id": "mock-client", + "name": "Requester name", + "logo": "https://api.collab.mosip.net/inji/verifier-logo.png", + "isTrusted": true, + "isPreregisteredWithWallet": true, + "redirectUri": "https://injiverify.collab.mosip.net/redirect" + } + } + } + } + } + } + }, + "400": { + "description": "Invalid request or missing required parameters.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "response_type is missing in Authorization request": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Missing Input: response_type param is required" + } + }, + "Invalid Wallet ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Wallet ID not found in session": { + "value": { + "errorCode": "wallet_locked", + "errorMessage": "Wallet is locked" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized user performing the Verifiable Presentation flow", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User ID is not present in session": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Failed to fetch pre-registered trusted verifiers": { + "value": { + "errorCode": "RESIDENT-APP-026", + "errorMessage": "Api not accessible failure" + } + }, + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + } + }, + "security": [ + { + "SessionAuth": [] + } + ] + } + }, + "/wallets/{walletId}/presentations/{presentationId}": { + "patch": { + "tags": [ + "Wallet Presentations" + ], + "summary": "Handles user submission or rejection of a presentation", + "description": "This API allows users to accept or reject a presentation request by selecting specific credentials. The API is secured using session-based authentication. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests. Upon acceptance, the system fetches the selected credentials, constructs and signs a VP token, shares it with the verifier, and stores the presentation record in the database.", + "operationId": "handlePresentationSubmission", + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The unique identifier of the Wallet." + }, + { + "name": "presentationId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The unique identifier of the Presentation." + }, + { + "name": "X-XSRF-TOKEN", + "in": "header", + "required": false, + "schema": { + "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { "$ref": "#/components/schemas/PresentationSubmissionRequestDTO" }, + { "$ref": "#/components/schemas/Error" } + ] + }, + "examples": { + "Presentation Submission Request": { + "value": { + "selectedCredentials": ["cred-123", "cred-456"] + } + }, + "Rejection payload": { + "value": { + "errorCode": "access_denied", + "errorMessage": "User denied authorization to share credentials" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Successfully processed the presentation submission.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubmitPresentationResponseDTO" + }, + "examples": { + "Success response": { + "value": { + "status": "success", + "redirectUri": "https://verifier.example.com/callback?state=af0ifjsldkj", + "message": "Presentation successfully submitted" + } + }, + "Response when successfully rejected": { + "value": { + "status": "success", + "redirectUri": "https://client.example.org/cb#response_code=091535f699ea575c7937fa5f0f454aee", + "message": "Presentation request rejected. An OpenID4VP error response has been sent to the verifier." + } + }, + "Response when an error occurs while submitting a rejection": { + "value": { + "status": "error", + "message": "Failed to submit Verifiable Presentation." + } + } + } + } + } + }, + "400": { + "description": "Invalid request or missing required parameters.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid Wallet ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Wallet ID not found in session": { + "value": { + "errorCode": "wallet_locked", + "errorMessage": "Wallet is locked" + } + }, + "Credential not found": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Credential not found: cred-123" + } + }, + "presentationId not found in session": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "presentationId not found in session" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized user performing the presentation submission", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User ID is not present in session": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Failed to process presentation submission": { + "value": { + "errorCode": "wallet_vp_submission_error", + "errorMessage": "Failed to process presentation submission: Error message" + } + }, + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + }, + "Failed to reject verifier": { + "value": { + "errorCode": "error", + "errorMessage": "Unable to process reject verifier request" + } + } + } + } + } + } + }, + "security": [ + { + "SessionAuth": [] + } + ] + } + }, + "/wallets/{walletId}/presentations/{presentationId}/credentials": { + "get": { + "tags": [ + "Wallet Presentations" + ], + "summary": "Get matching credentials for a presentation request", + "description": "This API retrieves credentials from the wallet that match the presentation definition requirements. It returns available credentials that can satisfy the presentation request along with any missing claims that are required but not available.", + "operationId": "getMatchingCredentials", + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The unique identifier of the Wallet." + }, + { + "name": "presentationId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The unique identifier of the Presentation." + } + ], + "responses": { + "200": { + "description": "Successfully retrieved matching credentials.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MatchingCredentialsResponseDTO" + }, + "examples": { + "Success response": { + "value": { + "availableCredentials": [ + { + "credentialId": "cred-123", + "credentialTypeDisplayName": "W3C VC", + "credentialTypeLogo": "https://mosip.github.io/inji-config/logos/mosipid-logo.png", + "format": "ldp_vc" + } + ], + "missingClaims": ["$.type"] + } + } + } + } + } + }, + "400": { + "description": "Invalid request or missing required parameters.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Invalid Wallet ID": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" + } + }, + "Presentation not found": { + "value": { + "errorCode": "invalid_request", + "errorMessage": "Presentation not found in session" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized user performing the Verifiable Presentation flow", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "User ID is not present in session": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" + } + } + } + } + } + } + }, + "security": [ + { + "SessionAuth": [] + } + ] + } + }, + "/wallets/{walletId}/trusted-verifiers": { + "post": { + "tags": [ + "Wallet Trusted Verifiers" + ], + "summary": "Add a trusted verifier to a wallet", + "description": "Adds a trusted verifier for the specified wallet after validating the session and request. Requires an active session; the path walletId must match the wallet in session. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests.", + "operationId": "addTrustedVerifier", + "security": [ + { + "SessionAuth": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "The unique identifier of the wallet." + }, + { + "name": "X-XSRF-TOKEN", + "in": "header", + "required": false, + "schema": { + "type": "string" + }, + "description": "CSRF token obtained from the XSRF-TOKEN cookie set by the server on GET requests." + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TrustedVerifierRequest" + }, + "examples": { + "Trusted Verifier Request": { + "value": { + "verifierId": "mock-client" + } + } + } } } - ], - "description": "This API fetches and allows searching for Credential Types offered by the issuer, all sourced from the issuer's well-known configuration.", + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Trusted verifier created successfully", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "supportedCredentials": [ - { - "format": "string", - "id": "string", - "scope": "string", - "display": [ - { - "name": "string", - "logo": { - "url": "string", - "alt_text": "string" - }, - "locale": "string", - "background_color": "string", - "text_color": "string" - } - ], - "proof_types_supported": [ - "string" - ], - "credential_definition": { - "type": [ - "string" - ], - "credentialSubject": { - "additionalProp1": { - "display": [ - { - "name": "string", - "locale": "string" - } - ] - }, - "additionalProp2": { - "display": [ - { - "name": "string", - "locale": "string" - } - ] - }, - "additionalProp3": { - "display": [ - { - "name": "string", - "locale": "string" - } - ] - } - } - } - } - ], - "authorization_endpoint": "string" - }, - "errors": { - "type": "null" - } + "$ref": "#/components/schemas/TrustedVerifierResponseDTO" }, - "x-examples": { - "Example 1": { - "supportedCredentials": [ - { - "format": "ldp_vc", - "id": "InsuranceCredential", - "scope": "sunbird_rc_insurance_vc_ldp", - "display": [ - { - "name": "MOSIP Insurance", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "insurance logo" - }, - "locale": "en", - "background_color": "#fafcff", - "text_color": "#00284d" - } - ], - "proof_types_supported": [ - "jwt" - ], - "credential_definition": { - "type": [ - "VerifiableCredential", - "InsuranceCredential" - ], - "credentialSubject": { - "fullName": { - "display": [ - { - "name": "Full Name", - "locale": "en" - } - ] - }, - "policyName": { - "display": [ - { - "name": "Policy Name", - "locale": "en" - } - ] - }, - "policyNumber": { - "display": [ - { - "name": "Policy Number", - "locale": "en" - } - ] - }, - "gender": { - "display": [ - { - "name": "Gender", - "locale": "en" - } - ] - }, - "expiresOn": { - "display": [ - { - "name": "Expiry Date", - "locale": "en" - } - ] - }, - "dob": { - "display": [ - { - "name": "Date Of Birth", - "locale": "en" - } - ] - } - } - } - }, - { - "format": "ldp_vc", - "id": "LifeInsuranceCredential_ldp", - "scope": "life_insurance_vc_ldp", - "display": [ - { - "name": "Sunbird Life Insurance", - "logo": { - "url": "https://sunbird.org/images/sunbird-logo-new.png", - "alt_text": "Sunbird life insurance logo" - }, - "locale": "en", - "background_color": "#fefcfa", - "text_color": "#7C4616" - } - ], - "proof_types_supported": [ - "jwt" - ], - "credential_definition": { - "type": [ - "VerifiableCredential", - "LifeInsuranceCredential" - ], - "credentialSubject": { - "fullName": { - "display": [ - { - "name": "Full Name", - "locale": "en" - } - ] - }, - "policyName": { - "display": [ - { - "name": "Policy Name", - "locale": "en" - } - ] - }, - "policyNumber": { - "display": [ - { - "name": "Policy Number", - "locale": "en" - } - ] - }, - "gender": { - "display": [ - { - "name": "Gender", - "locale": "en" - } - ] - }, - "policyExpiresOn": { - "display": [ - { - "name": "Expiry Date", - "locale": "en" - } - ] - }, - "dob": { - "display": [ - { - "name": "Date Of Birth", - "locale": "en" - } - ] - } - } - } - } - ], - "authorization_endpoint": "http://localhost:8088/authorize" + "examples": { + "Success response": { + "value": { + "id": "2d598dfc-7218-cb7a7afd5a07" + } } + } + } + } + }, + "400": { + "description": "Invalid request or missing required parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" }, "examples": { - "Success response": { + "Missing verifierId": { "value": { - "id": "mosip.resident.vid", - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:08:14.846Z", - "metadata": null, - "response": { - "supportedCredentials": [ - { - "format": "ldp_vc", - "id": "InsuranceCredential", - "scope": "sunbird_rc_insurance_vc_ldp", - "display": [ - { - "name": "MOSIP Insurance", - "logo": { - "url": "https://api.collab.mosip.net/inji/mosip-logo.png", - "alt_text": "insurance logo" - }, - "locale": "en", - "background_color": "#fafcff", - "text_color": "#00284d" - } - ], - "proof_types_supported": [ - "jwt" - ], - "credential_definition": { - "type": [ - "VerifiableCredential", - "InsuranceCredential" - ], - "credentialSubject": { - "fullName": { - "display": [ - { - "name": "Full Name", - "locale": "en" - } - ] - }, - "policyName": { - "display": [ - { - "name": "Policy Name", - "locale": "en" - } - ] - }, - "policyNumber": { - "display": [ - { - "name": "Policy Number", - "locale": "en" - } - ] - }, - "gender": { - "display": [ - { - "name": "Gender", - "locale": "en" - } - ] - }, - "expiresOn": { - "display": [ - { - "name": "Expiry Date", - "locale": "en" - } - ] - }, - "dob": { - "display": [ - { - "name": "Date Of Birth", - "locale": "en" - } - ] - } - } - } - }, - { - "format": "ldp_vc", - "id": "LifeInsuranceCredential_ldp", - "scope": "life_insurance_vc_ldp", - "display": [ - { - "name": "Sunbird Life Insurance", - "logo": { - "url": "https://sunbird.org/images/sunbird-logo-new.png", - "alt_text": "Sunbird life insurance logo" - }, - "locale": "en", - "background_color": "#fefcfa", - "text_color": "#7C4616" - } - ], - "proof_types_supported": [ - "jwt" - ], - "credential_definition": { - "type": [ - "VerifiableCredential", - "LifeInsuranceCredential" - ], - "credentialSubject": { - "fullName": { - "display": [ - { - "name": "Full Name", - "locale": "en" - } - ] - }, - "policyName": { - "display": [ - { - "name": "Policy Name", - "locale": "en" - } - ] - }, - "policyNumber": { - "display": [ - { - "name": "Policy Number", - "locale": "en" - } - ] - }, - "gender": { - "display": [ - { - "name": "Gender", - "locale": "en" - } - ] - }, - "policyExpiresOn": { - "display": [ - { - "name": "Expiry Date", - "locale": "en" - } - ] - }, - "dob": { - "display": [ - { - "name": "Date Of Birth", - "locale": "en" - } - ] - } - } - } - } - ], - "authorization_endpoint": "http://localhost:8088/authorize" - }, - "errors": null + "errorCode": "invalid_request", + "errorMessage": "Missing Input: verifierId is required" } }, - "Failure response": { + "Invalid Wallet ID": { "value": { - "id": null, - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:07:34.789Z", - "metadata": null, - "response": null, - "errors": [ - { - "errorCode": "RESIDENT-APP-026", - "errorMessage": "Api not accessible failure" - } - ] + "errorCode": "invalid_request", + "errorMessage": "Invalid Wallet ID. Session and request Wallet ID do not match" } }, - "Failure response 2": { + "Duplicate verifier": { "value": { - "id": null, - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:07:34.789Z", - "metadata": null, - "response": null, - "errors": [ - { - "errorCode": "RESIDENT-APP-035", - "errorMessage": "Invalid issuer ID" - } - ] + "errorCode": "duplicate_verifier", + "errorMessage": "Verifier is already trusted for this wallet" + } + } + } + } + } + }, + "401": { + "description": "Unauthorized - session invalid or missing user", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unauthorized": { + "value": { + "errorCode": "unauthorized", + "errorMessage": "User ID not found in session" + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "Unexpected Server Error": { + "value": { + "errorCode": "internal_server_error", + "errorMessage": "We are unable to process request now" } } } @@ -2605,92 +4795,86 @@ } } }, - "/issuers/{issuer-id}/credentials/{credentialType}/download": { - "get": { - "operationId": "generatePdfForVC", - "parameters": [ + "/auth/{provider}/token-login": { + "post": { + "tags": ["OAuth2 Authentication"], + "summary": "Login and create session using OAuth2 ID token", + "description": "This API accepts an OAuth2 ID token in the Authorization header and establishes a session by populating Spring Security context.\n\nFetch the ID token from a supported OAuth2 provider (such as Google or Microsoft) and provide it in the request as a Bearer token.", + "operationId": "loginWithOAuth2IdToken", + "security": [ { - "name": "Bearer", - "in": "header", - "required": true, - "schema": { - "type": "string" - } - }, + "bearerAuth": [] + } + ], + "parameters": [ { - "name": "issuer-id", + "name": "provider", "in": "path", "required": true, "schema": { - "type": "string" - } + "type": "string", + "example": "google" + }, + "description": "The OAuth2 provider to use for login. Example values: 'google', 'microsoft', 'facebook'." }, { - "name": "credentialType", - "in": "path", + "name": "Authorization", + "in": "header", "required": true, "schema": { - "type": "string" - } + "type": "string", + "example": "Bearer " + }, + "description": "The OAuth2 ID token that must be provided in the 'Authorization' header, prefixed with 'Bearer '." } ], - "description": "This API is responsible for generating PDFs for the received VC content. It fetches display properties from the well-known configuration of the issuer and incorporates them into the predefined template of the PDF file.", "responses": { "200": { - "description": "OK", + "description": "Successfully logged in and session created", "content": { - "application/pdf": { + "application/json": { "schema": { "type": "string", - "format": "binary" + "description": "Success message indicating that the session has been created" + }, + "examples": { + "Success response": { + "value": "Session created." + } + } + } + } + }, + "400": { + "description": "Bad Request - Missing/invalid header or unsupported provider.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" }, "examples": { - "Failure response 1": { + "UnsupportedProvider": { "value": { - "id": null, - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:07:34.789Z", - "metadata": null, - "response": null, - "errors": [ - { - "errorCode": "RESIDENT-APP-036", - "errorMessage": "Invalid Credential Type Id" - } - ] + "errorCode": "INVALID_REQUEST", + "errorMessage": "Unsupported provider: provider123" } }, - "Failure response 2": { + "MissingToken": { "value": { - "id": null, - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:07:34.789Z", - "metadata": null, - "response": null, - "errors": [ - { - "errorCode": "RESIDENT-APP-026", - "errorMessage": "Api not accessible failure" - } - ] + "errorCode": "INVALID_REQUEST", + "errorMessage": "Bearer ID token required." } }, - "Failure response 3": { + "InvalidToken": { "value": { - "id": null, - "version": "v1", - "str": null, - "responsetime": "2022-10-31T05:07:34.789Z", - "metadata": null, - "response": null, - "errors": [ - { - "errorCode": "RESIDENT-APP-028", - "errorMessage": "error occured while signing pdf" - } - ] + "errorCode": "invalid_token", + "errorMessage": "An error occurred while attempting to decode the Jwt: Signed JWT rejected: Invalid signature" + } + }, + "ExpiredToken": { + "value": { + "errorCode": "invalid_token", + "errorMessage": "An error occurred while attempting to decode the Jwt: Jwt expired at 2025-06-10T12:00:00Z" } } } @@ -2702,110 +4886,425 @@ } }, "components": { + "securitySchemes": { + "SessionAuth": { + "type": "apiKey", + "in": "cookie", + "name": "SESSION", + "description": "Session-based authentication using a session ID stored in the cookie. The client must send the 'SESSION' cookie (e.g., SESSION=) with each request. For state-changing requests (POST, PUT, DELETE, PATCH), a valid CSRF token must also be included in the X-XSRF-TOKEN header. The CSRF token can be obtained from the XSRF-TOKEN cookie set by the server on GET requests (e.g., by calling GET /issuers or GET /wallets)." + }, + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "JWT-based authentication. Use a valid OAuth2 ID token (e.g., from Google or Microsoft) in the Authorization header as a Bearer token. Example: 'Authorization: Bearer eyJhbGciOi...'. This token will be used to authenticate the user and establish a session." + } + }, "schemas": { - "AppVIDGenerateRequestDTO": { + "UserMetadataDTO": { "type": "object", "properties": { - "individualId": { - "type": "string" + "display_name": { + "type": "string", + "description": "The display name of the user provided by the Identity Provider" }, - "individualIdType": { - "type": "string" + "profile_picture_url": { + "type": "string", + "format": "uri", + "description": "The URL of the user's profile picture provided by the Identity Provider" }, - "otp": { - "type": "string" + "email": { + "type": "string", + "format": "email", + "description": "The email address of the user provided by the Identity Provider" }, - "vidType": { - "type": "string" + "walletId": { + "type": "string", + "format": "email", + "description": "The unique identifier of the user's wallet. This is available if data is fetched from session else its null" + } + } + }, + "VerifiableCredentialRequestDTO": { + "type": "object", + "properties": { + "issuer": { + "type": "string", + "description": "The unique identifier of the issuer" }, - "transactionID": { - "type": "string" + "credentialConfigurationId": { + "type": "string", + "description": "The unique identifier of the credential type from the issuer well-known configuration" + }, + "code": { + "type": "string", + "description": "The authorization code received from the authorization server" + }, + "grantType": { + "type": "string", + "description": "The grant type for the authorization request" + }, + "redirectUri": { + "type": "string", + "description": "The redirect URI for the authorization request" + }, + "codeVerifier": { + "type": "string", + "description": "The code verifier used for PKCE (Proof Key for Code Exchange)" + } + }, + "required": [ + "issuer", + "credentialConfigurationId", + "code", + "grantType", + "redirectUri", + "codeVerifier" + ] + }, + "VerifiableCredentialResponseDTO": { + "type": "object", + "properties": { + "issuerDisplayName": { + "type": "string", + "description": "Name of the Issuer" + }, + "issuerLogo": { + "type": "string", + "description": "Logo of the Issuer" + }, + "credentialTypeDisplayName": { + "type": "string", + "description": "The name of the Credential Type issued by the Issuer" + }, + "credentialTypeLogo": { + "type": "string", + "description": "Logo of the Credential Type" + }, + "credentialId": { + "type": "string", + "description": "Unique Identifier of the Credential in the database" } } }, - "AppOTPRequestDTO": { + "CreateWalletRequestDto": { "type": "object", "properties": { - "individualId": { - "type": "string" + "walletPin": { + "type": "string", + "description": "PIN used to unlock the Wallet" }, - "individualIdType": { - "type": "string" + "confirmWalletPin": { + "type": "string", + "description": "Re-entered PIN used to confirm the Wallet PIN" }, - "otpChannel": { + "walletName": { + "type": "string", + "description": "Name of the Wallet" + } + }, + "required": [ + "walletPin", + "confirmWalletPin" + ] + }, + "WalletResponseDTO": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier of the Wallet" + }, + "walletName": { + "type": "string", + "description": "Wallet name provided by the user" + } + } + }, + "UnlockWalletRequestDto": { + "type": "object", + "properties": { + "walletName": { + "type": "string", + "description": "Name of the Wallet" + }, + "walletPin": { + "type": "string", + "description": "PIN used to unlock the Wallet" + } + }, + "required": [ + "walletPin" + ] + }, + "WalletResponseDto": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier of the Wallet" + }, + "walletName" : { + "type": "string", + "description": "Name of the Wallet" + } + } + }, + "WalletDetailsResponseDto": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier of the Wallet" + }, + "walletName" : { + "type": "string", + "description": "Name of the Wallet" + }, + "walletStatus": { + "type": "string", + "description": "Wallet status indicating if it is locked or unlocked", + "enum": ["active", "temporarily_locked", "permanently_locked", "ready_for_unlock"], + "nullable": true + } + } + }, + "VerifiablePresentationAuthorizationRequest": { + "type": "object", + "properties": { + "authorizationRequestUrl": { + "type": "string", + "description": "The complete authorization request URL received from the Verifier" + } + }, + "required": [ + "authorizationRequestUrl" + ] + }, + "VerifiablePresentationResponseDTO": { + "type": "object", + "properties": { + "presentationId": { + "type": "string", + "description": "Unique identifier for the verifiable presentation request" + }, + "verifier": { + "$ref": "#/components/schemas/VerifiablePresentationVerifierDTO" + } + } + }, + "VerifiablePresentationVerifierDTO": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The client ID of the verifier" + }, + "name": { + "type": "string", + "description": "The name of the verifier" + }, + "logo": { + "type": "string", + "format": "uri", + "description": "The logo URI of the verifier" + }, + "isTrusted": { + "type": "boolean", + "description": "Indicates if the verifier is trusted by the wallet" + }, + "isPreregisteredWithWallet": { + "type": "boolean", + "description": "Indicates if the verifier is pre-registered with the wallet" + }, + "redirectUri": { + "type": "string", + "format": "uri", + "description": "The redirect URI provided in the authorization request to redirect the User back to Verifier" + } + } + }, + "PresentationSubmissionRequestDTO": { + "type": "object", + "properties": { + "selectedCredentials": { "type": "array", "items": { "type": "string" + }, + "description": "List of selected credential IDs for presentation", + "example": ["cred-123", "cred-456"] + } + }, + "required": [ + "selectedCredentials" + ] + }, + "IssuerConfigurationSuccessResponse": { + "type": "object", + "properties": { + "response": { + "type": "object", + "properties": { + "credentials_supported": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Credential" + } + }, + "authorization_endpoint": { + "type": "string", + "format": "uri" + }, + "grant_types_supported": { + "type": "array", + "items": { + "type": "string" + } + } } }, - "transactionID": { - "type": "string" + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Error" + }, + "example": [] } } }, - "IndividualIdOtpRequestDTO": { + "IssuerConfigurationErrorResponse": { "type": "object", "properties": { - "aid": { - "type": "string" + "response": { + "type": "object", + "nullable": true }, - "otpChannel": { + "errors": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/Error" } - }, - "transactionID": { - "type": "string" } } }, - "AuthUnlockRequestDTO": { + "IssuerV2DTO": { "type": "object", + "description": "Minimal issuer representation (V2 API). Data from mimoto-issuers-config only.", "properties": { - "transactionID": { - "type": "string" - }, - "individualIdType": { - "type": "string" + "issuer_id": { "type": "string", "description": "Unique identifier of the issuer" }, + "protocol": { "type": "string", "description": "Download flow protocol", "enum": ["OTP", "OpenId4VCI"] }, + "display": { + "type": "array", + "description": "Display properties of the issuer.", + "items": { + "type": "object", + "description": "Localized display entry for the issuer.", + "properties": { + "name": { "type": "string", "description": "Display name of the issuer." }, + "logo": { + "type": "object", + "description": "Display logo of the issuer.", + "properties": { + "url": { "type": "string", "description": "URL of the issuer logo image." }, + "alt_text": { "type": "string", "description": "Alternate text for the logo (accessibility)." } + } + }, + "title": { "type": "string", "description": "Display title of the issuer." }, + "description": { "type": "string", "description": "Short description of the issuer." }, + "language": { "type": "string", "description": "Language code for this display entry (e.g. en, fr)." } + } + } }, - "individualId": { + "client_id": { "type": "string", "description": "Onboarded Mimoto OIDC client ID" }, + "token_endpoint": { "type": "string", "description": "Token endpoint URL" }, + "client_alias": { "type": "string", "description": "Client alias in keyStore" }, + "qr_code_type": { "type": "string", "enum": ["OnlineSharing", "EmbeddedVC", "None"] }, + "enabled": { "type": "string", "description": "Whether issuer is enabled (\"true\", \"false\")" }, + "credential_issuer_host": { "type": "string", "description": "Credential issuer host URL" } + } + }, + "Credential": { + "type": "object", + "properties": { + "name": { "type": "string" }, - "otp": { + "scope": { "type": "string" }, - "authType": { + "display": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/Display" } + } + } + }, + "Display": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "locale": { + "type": "string" }, - "unlockForSeconds": { + "logo": { "type": "string" } } }, - "AuthLockRequestDTO": { + "Error": { "type": "object", "properties": { - "transactionID": { + "errorCode": { + "type": "string", + "description": "It represents the type or category of the error" + }, + "errorMessage": { + "type": "string", + "description": "A human-readable message providing more details about the error" + } + } + }, + "AppVIDGenerateRequestDTO": { + "type": "object", + "properties": { + "individualId": { "type": "string" }, "individualIdType": { "type": "string" }, + "otp": { + "type": "string" + }, + "vidType": { + "type": "string" + }, + "transactionID": { + "type": "string" + } + } + }, + "AppOTPRequestDTO": { + "type": "object", + "properties": { "individualId": { "type": "string" }, - "otp": { + "individualIdType": { "type": "string" }, - "authType": { + "otpChannel": { "type": "array", "items": { "type": "string" } + }, + "transactionID": { + "type": "string" } } }, @@ -2857,6 +5356,9 @@ "JsonNode": { "type": "object" }, + "StringNode": { + "type": "string" + }, "Event": { "type": "object", "properties": { @@ -2935,7 +5437,84 @@ "type": "string" } } + }, + "MatchingCredentialsResponseDTO": { + "type": "object", + "properties": { + "availableCredentials": { + "type": "array", + "description": "List of credentials that match the presentation definition", + "items": { + "$ref": "#/components/schemas/AvailableCredentialDTO" + } + }, + "missingClaims": { + "type": "array", + "description": "List of claims that are required but not available in any credential", + "items": { + "type": "string" + } + } + } + }, + "AvailableCredentialDTO": { + "type": "object", + "properties": { + "credentialId": { + "type": "string", + "description": "Unique identifier of the credential" + }, + "credentialTypeDisplayName": { + "type": "string", + "description": "Display name of the credential type" + }, + "credentialTypeLogo": { + "type": "string", + "format": "uri", + "description": "Logo URL for the credential type" + }, + "format": { + "type": "string", + "description": "Format of the credential (e.g., ldp_vc, vc+sd-jwt, dc+sd-jwt)", + "example": "ldp_vc" + } + } + }, + "TrustedVerifierRequest": { + "type": "object", + "properties": { + "verifierId": { + "type": "string", + "description": "Unique client id of the verifier" + } + }, + "required": [ + "verifierId" + ] + }, + "TrustedVerifierResponseDTO": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique ID generated after creating database record for the verifier" + } + }, + "required": [ + "id" + ] + } + , + "SubmitPresentationResponseDTO": { + "type": "object", + "properties": { + "status": { "type": "string", "description": "Status of the presentation submission request (for example success, error)" }, + "message": { "type": "string", "description": "Human readable message describing the result for successful submission or rejected by user" }, + "redirectUri": { "type": "string", "description": "Redirect URI provided to the verifier", "nullable": true } + }, + "required": [ "status", "message" ] } } - } -} + }, + "x-internal": true +} \ No newline at end of file diff --git a/.gitbook/assets/verify-decode.png b/.gitbook/assets/verify-decode.png index e37b2f8071ae4b8c462f55f6f6b32203c82dee52..64bc248c69963301d00bb95b139567838a2f89a9 100644 GIT binary patch literal 44209 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 l{~h+~qe(fA7Eh zd>>gn%&b|{U0vN>^>$Ug`Tk8x1Q8w=9t;c&QA|`&77Prc8u*2SeFNN)H!ZaR{y-V= zN%Db#RYV{>>OceUiS$HeCBeX4DZs$I{lUQQfm`0YU|&U|{TtU|?9*sf{w6 zzz5$9l*J4sCBdkH*RWs^;Amiwz$uPphMUC+vbUPs?b*MQ#H!W#4d7^gEk@Y2G-UWdrp!rao1 z-Ifx*eiiQefWy_KyI0}~q?8v`RV12Z!n@C2Qmi>1AeGo7U!>EA~F(~h8l zot~|UwY`azB@w7y9bGF2doB_ZP)Gm$`75WriQ)fxvb6hWSik@oK%X!$(K9mqw{767 zoS?hx(zYfBK+mA|xtTa$pZtH_`==jH22kh!66WtnU+)4#<%Z{E_^;Zy;c+zAV8Fn5 z!Ndgl4iC4OgC5TsF4} z_~EF1zDQrwJU$#f9POk(9B$ruF*<3NISWODkA$z#tZSkYc&umno^pc zY0-KSpBXL^?0;7x6qT{$J5FM7G@}1p)*=w^s*i6czZm}S9uas97<9>ZU&{Zr$qR8T z>g_vCkb&Fx^KpqFGSXa0W)vlVuGyuk+G0U*+5JLtZ?+`uqDdlR{T=#hoNX)95F^E{sVMfH%vMS3TotY$GXxcp9~04;Vwa`52!*bj2a8RQc2 zvrETk8-23*QUn&`BfxN}UKC>m`aNHsZe+6r;f}JvXe=MDkD#xR3AxR8tU^ZHp6|^r zJnQQeI2V>uv4EBHUfLT|HNvYql?c>!vnvFP>15>LT-DHQh2BLJ9O6>Ax#HE3n-t!z0hbB5c{~`OXN= zq^Cryt@S$hXsRf|{j>uH!U+mi`@Rcz(wPh#%~}``z(_w)`qeV5GJ`jtk42M*sPK3` z-lCzPXlr(z|3J~om(GZPi^JUC8-{m9!gxE`dOdGud$BF~OSvK|mRdoa(CC>(F7Jg+ zgVlU?^;4lwwwr26!}f>^U~g8>pp1WB-HHsuf%YWtB%1fPqsd<}hbwI>k3?ixkGf%( zZ7)yKP58~v_XoCXozQn15j^&=^n#4awdP6h=u{^Q3L{RYU6m-L)6KWJTp#;G$?p634RNh2dWtp(FrqrY1xKAds9%H!@38pKv!~%h$d0&(4m#2!99KNd1zVq{5 zYH})jyk4+kcD*znNaLv697>Sx%kAN3%31FTIgmuZ42U6weSuyZ5(IR_1(@QN9TmI0 zSK)s_mABAlVF6Y`;GvH~G?KS3J|F-C&a(mr`TZoOlCpfo8hF;bYU6SKpjF=!^W|n2 z=qBHe6;`omvibWTiM3|a#pBP_<+abx4<~sv;I(Z5D|Bd%Xnw)HhKSY%?eUEu2e=G! z9UK`PMv|bJj}p$b+32;s+?DyDUSD3U)u!q0;Zbt{hUuvT!>FwEaC1_ofv#F-NmpY! zHGxOd?o}%|fCk|Nark^SrKB~0XVpxsP^1`lFjIDLhVemGP_az2MDGs?vAgHtDV3F_a9YlcCNV27Ftxftp!Y@96Tm% zLC>#@jEq*{G#aH+(OUC4D0(Pie?R$OvU_xvOhmU`$AGzFwOTI53hki8gut4f2h=(c zhWEL;37ob9Wvu?Q?j#8{1iu4uEgfx_kB?6yy}QL<+vpu}ucsZ7u+C+-{S{;gh{R!w z)2bu~G0QF1aLGSAPo+^))+`KIA#{^G>R0R{5I2=my+vqFB^RXOy``(i*A6PjXR|dX zR?p-GZ=wK}Z^G74!hw)(usoQPZyb%1I573YqVUsi0wwr+Lvd=5Er9VmF!f?mrzx^M z|Fliw1NNO5)bz28*UNrua+{a3s5s%gsB7e5Ajn)d$MH@VtJL%d{C2qX2?0}wL;r}22Wj??nI6C(Onp#yPFEnkpXQb8^r3p@2Dq|)`s)e8+aq|Msmx|dG3wuA!^JDq<7)F^7nfxVhcW-)CqSLke!M+% zyjyB?Kv&j0#bL9}aU}QlqFrCHTxwLMw$USIq*iP?5%l%R=O6J$_W0Wjct zeX(^2@^?gou zRQ+|)115jT4Pj}y69b-X90JD@QMA0b(*XR;e4);Yfkv^IvFGExx3cAQaZ$HkvN#lW)K(v z?Quqdc^Gq@{dz@eWT$Ab+MgNBlfk0y56as1kBp*Vu%O(_MQKbXa$K<({f|4d7|H4( zzu3a<{{HFLQ1I5H(+bnZ^kk)tq2~ui%rCk8!D5xF>J*6D;ea^I8#dd`V5EhBFpP34 z#Gf6z0uN}O;LZqW!NO3x0(fEX-vqs4-eW!xso^V`BGd(qJlVt2hPSWd=FAgLaIjzS=IP-kL9Na* zNw1IXUWg15R!!MAhD=P?GGYi8hJrdh(t8F4013$=Bi~;^!X{d~F5PV{2|iZ$;qg*a zO}!v&$#BxggOoLV85r%T9$os|dR_E4!BYUB+7;5qqF0a9ABf%?!CaL_@PV%gX)Hh1 zg<+<>^mSl07>sSyGOq{w3`Hv}FiTIW(d;Y}0U57%d&>;+H!vW7<2;&5{yMoIz?GFN zVBd0A!j@q$6F*J^V5de6j08PLB0;KBe;~`lL*#Z4O^m>j{4!wTlPtkgd)E@PzB(&eri2o)|!Ble4&M z>f}1aYp3-H!z$ATLaUeW>)Jt^`IgZQYLE1UYt1TRl|q(Jlk9`v_wh3dind=jS}QQp zmhX(Fp&!z|nehjtJ3z$6?`f!6j@SX3O&0>-NL4zekpKveFoc0YQTbD`@_N(oiprP? zQg~0XxSVgY>vjNEuvh~EWt<2AIlw}}AjrmS@(0d6U)7W<`VWC6_9ulplfd0{EhxmF z3VxSVp-_ICQ^shu-KWy)#goofrzXIQ0fg*sK$DhkG?Mf>X|X8nthKXA2nda#{?OVe z&BD9%o22Qq>JX7Aa;yLdVb=wxEiYg0JYi9*HCK%-RjCp#XM&_H0k&m~w>Q|)M}#3d zG<9IRzHM!^Hu7#eDpV+{9)fhYfA!5FfVXnuvKo#5du{=H)Tro6hyop!dh=P%i$(l* z8$BLsmx;jdP9p-gFc!8{h01FX9q|PSNck8+=v6Hk@dh$GR0IT=NZP+tFJCpYsr>_( zP!h_sa0%;izKEat2|+TLEa-F(D7(~4-r4q_B~() zIWxdCkT_p(>;hjG&=ypA%*;k##K=Q?9R`z5m_M{``TX`^oCL!mzca(_B1x-x427h< zC)bG#z=q@zsgul6)1G$lOVMUn0wi5VZfe?KX&g?|fR$fMh$3>wV=>JssnYVeio@(bojRJU%3nUl#A9h! zJvccj`)tEFeDqv*T zr)l4O*6V%CM^y#^4ZmAKui32Jdbf>7@S#Kb6gsNOZbxcwrYvJw8~kVUs-dA{F!iQMcRvaje zX960a*y6~b)CJf;%*htQFvroo9R&e_psT@4GS zqMZ9`5j^q1*WuQ|wfUuo>c;cBp*3g#&yb-hH;Ftw6+M_fKX<&O%OH`Q=~U8y8vEz+ zNs#vTz25q`L+}@sfRGp9LqYI?6qTZh1oU78Mdr1*s5?uAh;&p8DR6+5hN%ACxMR0b z@bB-W1EHv`G6;}b{<*x>(1GaGL0@0TzoS#%exEzNcJj9?(e@HJYnenf9&V&`Amp(C zi_bwdvA>Wkl}|upXg-ik9Pw^MPI&&4vl?0VGsFt=lVl#TG(*cgu{ zh#ZfXn_;&r(~siRN~6VPTK1lX`Jf=;DK%)PUDdOx0K;&iEZ^xzQmN9jnf)`%sg&Tw z&RBbSz$nvtzX@6OJfHT`AN9v=_xeaYgu~;k`l>%(9P>2O zNL&8s7N?#l+c27_x-v3UN!^r|R^WhRtWq#=c>l+iK(nFnhudS5PKNn>6F>Zpr`*0g zEp_X6IuFi16Tuy$mYxm?aTb32O3tge_MA@mO))614rtNz^EX1;zf-E8U$xAoT)19pWx;yt>V;MTx4wZhZ%Aa6r(zO)&ur4Z~z_22zdLln$}k; zf!3Wf3zTli>wZjj$wr2A4iWn8d&iKe#HJ^e7W8U^WD%QIH-usR+|cUkig= z=eRGgIr(DoUX;+H>II}9#MRaWlSsAo$3dbuZ3N81TC9854QYvzC=3;k+_MyhC+cWo zw}$vZx|m^Bi>)LLrhU;@2eA#G&|<3Yjux+Z;aNjBz74Nmqikir+-oMgpWRiBFQT*b zb|dxBQg;OC#i`aS)@$w=SxnBgqsncippFpyP?3k~x=#xkXsk&%nm_XePEY4R>`<6n z?i#R@ybxuv?X`4HTcb~Ej(SvT^_fc!{UP`+Li3*=r|Fwk>c=*B!J}5_bXvdZ4D@&9 zV6Ks@Ejri5-^g{1ql@F+`^aCeuN=1C-pt@qY?J-y6KtPJZ^ zA1!DcbCus=lcL8@QRnW959XMRuz&HvgHT7ahex|J)DOwWVx^&1$6cm6jc-4h5yc)d z^4rHv-~_OMAS!qxz90~Blz0Uqe(gyTeVcwrga>NSP;dGJmn612r~WwB1-9FgPag(z zw?OfqoL|{VKU^rq4`Dk(RPar)%I2AyY9LiKdCqukx9HyYM32Z>nXZhdU#j%{N`OE-HgTjcKmI8d6H=F>aaRc34PnrNW}t z{TXoY!65f86BthbvUg8dZs7vM`Vp z31Q8gwv5PfCp60)d!6%LNpCK;ML<1~_N=#6v!XnTLCA;#hD`=GK?5XvdlAJqS}V4@ z+!H5yWKt#1D90XDcZg>7m4*Kf;sahGM zgc8}NM^JiZi${`N@%mdH_MDnVH#BPXjT)%M1Ik}un9>WQBVtXXRfWg!iRSEnm>ki` z(blAyfwO;cSPKqKT~=E*PnVr&-lCLrlb7kd`KdpwGs6Ws+Gcr!L0i1zHAn!N-qT9h zc9Bmqk7V1FLeZbtC*{MK!}JeMob(S?21#%`+Ah1;gD~3%6smnAiOZx?Ij~KW%Xd|I zrr{&r^OS2g+P@#alT4{lg#Q#=(i!wbK4Ym-X_sK_*d_K9Buues;^HZ>79A*)f^;m@>0Ix?bq%RM9?w^(13j3X;{O}caYQ6#Q7OM#n zz=Qi-GMT4Zph>iU|NKeQ)!y77K36(!jCXprBPcn+?VH_3(U|vJ zhsWN~nixN(qMe4ksMJcRHn^s-}EyZ$sTzMtcr3>P+MwMH-GfZaH-ti|Mg#PVU2H+4w8dsW%+B@249q8E)K2T`(3ihOewSFNEb9N(UmnZ@rqml=mX7YaFv zzC5}KPIGCX1R29(C1^(SV%%v@Jd*E!l((R-Sgc0s(&cjMF*TVeXr4m`rNT%OfLY!= z*S7-A@@g&Adzz)`EGL7eGt$MWuKZF6=P=Di7frU-bMI2Qiu#ra^9Y%eoTY~_GEI0j ztl%qli*f5J9{N*5cf@MnE^+)23^EsLCzdbj&S;{KTIyZ15 zazxK=&n3=IHXo#0W8PtS4BP5K2FQGDiwQ9E{Cwf(=a-{3GnOM+Rd}EhE>vYC5w&lN#$gcz(6ky(hx~}aJZUld zj2Q}!sT(X2N~5pZW>z(t%-yc(PC_=rV=9BgJ$+<{I(Ad1X=k5OJ7OlPNUm7|cazlO z?t92t-Er)BqGUp66Rl=;o(eduN|3{1mAMuHIRP2b_C^E@OFt?wR59X%hr2?J68YI_ z$EW3rgYA-Nhn#OR2CecY+pAj8DHPanr7&^x@1_#I{|Q#tx)Kz}D%O3sKrn83?=8t} zc}nzg<#XWE5FgLb!7Wx2p*q3#W4*vCtF~m~$KIdwAJB@p9X7+9|SmSl# z^U;+#j8bChz77A$-?R60qW{$+i&wiV3K47!mNDmEM$_?FDM^VO2dh;nq#{0pfLS_K zqS?JzIJ38!fq6Lp{0*}>onognHQN6SP2%~mXVS4Y4(iM$E!Ry+Fy3OB&Mm@ne0pzq z&sNMQm3-^ybKJe;YB9!zSbG(0@ly8l^OOgR*9$1G{;oRx>Y;lMz$wlA5XSCJ$1mxotk-NKl zY=I=j*1jhhA_o#IdHE;-7x@Y+{l0bk_vqYsb)iAAxp_Krs{u4ehd_6AX(S6ZgM^@v zFK1}t>+ei*zBQ=I7CAUM5EP16k0pL~Eg#087K-@D7ya&hA-+he?@??{-u5Q%;v8H2 z7lmY;=KR%*+p@5FzDU+*xM}-0!XSmJC9Xe-hjzK2IsELrPXV z3F#+od%7XzMUwZ=G<(_pdlgG~UztKMI|dh>Pp%zQIBhbkY0?Dg(;AIu##A;?!$jCt?f&^+C7r3vOx~coVS6o5 zJmaKlqyKL_gM@eWvBJal`PTD0YS(9o5`3jJw&Jo!jw=z3U96Asn_k(;wS|VGYF`yc zaB0*Mo^t&UbzGcJYVAE3f*u?1G^r%$aO;ja6xJz3a~^!AY?fBgx9ZXIQ4Fd?fZ_?+ zHi|f0_ky7?LKEh#*m**)dD{S*m-%rol zw+(DxMkU#5&HUsoXFqiwkxqd55<*NS8~$o=y5C|jQ!KcM#io0<9}8GW)5`9Pr$ zJxuzoJR2p*al!Jfj(bGiwIRh=?Z-x92A~b>#8nP0YMEm;mziP2)1SOUgJm)6q`6-s zNGX`vHn}pIH3~DB*;kmRzHfHwvTb}CcnZ4WYMi1kJsEE`7si?U)u7srUie)#k+jlv z^zD^ueWSZPZIZhtTTtl9Q$u^(WU}JOy}-?rM1rC?ekuAQ!babLCn;b5&kX57eLwOJCZS6jmuepj^ot%Ci!l3>Y4oJe+ah?RQ^?ysGtW+zoXmy08>w2Z z``p&!maFza+OA~Q;gLivioR-ezRB{ttx$P9J5La@`5OGm9{f)Dv5h8^px9_9^wyA! zL@dh$MdaFonPmOT%eO?=YSYAF~!^2wYh7VDGV22WOYOPpiR zu*pObAC8FzNp3ZLI)9T5?d_3KRYq{?p)!+_(wIzrsC@B?RK^33Cz;x_23nNm;XWqq zO}GnU0t&?#C6MUZ;n5q71YE}u951J1VY-Z^I=5N0^W|!(ravUYdQw-D{d0*KR$RdF z^}XA5zYnvSvr-ke6zj`H{`2HZb=%~_r3wxdq~Llm!vU;2ZCsX_s3({CWY58offrK3)*lhk6P{X$(yRc7@ihXo&BLgreT;jYshM|A)bF8ZMl&Y2 zP%=My?H4~OIt1R^9M5V#%~jZzzEyRWMI#R(%||}^^y3QEgG7VVMU)7N_?D+AR=f#z z7vgGT(#PVy%9!8l&fv)6PjsWhuOkKL$L@igL$|B2{h#5#y`?t9P5=T&@@>0rxBo3lq0C!a5zR3^+j6P`bJc?|Ap z8%Hg+7EF}=qL^ycIOK*gOVpKGv0K04x-*Fiy%8-8__~spJ88C);`k(R+S#pAIx5om zGEaCjzLxTQ-%w;3^Th@CD*46e&U|)7S9!-$tBK4D>5l*AkHaJGuiNLodwk5{GB34X zJmiI}ymb?~imY^o75uIHFRhVfy|fBt=NzV9YQc@AC)7<=HNDq^1Tx4Z$(2~NB`NLsm(OWn9?uV%V_#)dx0kjDd9Jj`wI5&w*(S7j zyh-L3}m0iRYW|cLCYn7DgkbmwrpPrErZvy`VZNaSXrI8?jf3mPT&pEFB zT()xHSg*APk8za{I5{YSy?2`~>8R+KhBJ!1r-ChXJXyu5qCG{;Wtw7RpHff7sXQRBenslC_?GlTQ-P7M~3mS(0Qlsic|1yLwr>3COP;>!D z`^%c;R-vwFvD^=BkTm^TMlNKEVOc!8B>KYZK@%?br}U6{&~eP?*?>y+a+eS?sdUvI z+AzA6k=c^t3|^(~dUnN;5-bCPS$(%O&2n><2KW15`XDcZpXV6nX@wc(XqsG3{90aY zwiWGz-{q?()S~MI4REgKIBd5TZ47)C^F3q{i%e=E))2^Vojd1$u+GHAvFWoHsl%_6 zf6b~QTx=nynKXSl8rs>Vg6l7y8>ATKuSGa$)SgS8pATa%=k1EX4CzK0EY!b39`4cY zSuUi89%{`dWohqhbvsgZ&`^{$EXeG8yRs6yS2bV3-t19xOlc5kK4H`-xw+0AhgTDw zSGJIT)p&<45HQ4_775puLV0aDF(*Vl%^E`Ui{ZW3+h=~YnwJz-ano9Jt9TXZ(p0uQ z_pm?7Dn8;P>qCJo@caSy7G0qxW~|%a7tk{UrjH1TDPLjJDBPjy)8W)Z+}rn8(c2XtJhmwzR+VU3rt(hTy<)`Efzs?7U$Q=I!TqMsOtf(_R~X z)>?{82qEqVt=Xw8My)}pfVR5cQ{}%VgcTurO>Ll7y!PWw=oA(E*#}9?)PnsWXa{}2 z@#46X|{IumxEgWWszm{ix{~PIu-ur-nW@jz)Ptct? z|5$zR`0h& ziDq3ttuI1wlw+9&X-Mx)Ld@Xj+p{h=ac!7_9v7c&E^ZW(rW$7c?&oV-j~zg{&RWsGMUY zEcVdUZ@oe9<#Z1H0uDbP{80}9giEaPAW*bwH1Z>vU%+iFx+ET0AB_~n5?C(Rb5?3OS+P=x z*CC3lMT4_V>$wvN>Ya7bm-oj%*fp#LGBsEk@li35{`@-j!BHK9;;=M|;21Ru#`Aey z<01qGHNq*fe7Vte7HSeh^uqGRGsTcq8g?|1}J}Z zvfp7(vw$@gY+zK@{^)DS)oc2qoqZJKqQ_<*#5h>e_v?vgTo)7K+Dj|qn@+82Vw>D- z03x1JeRMJEr)1BMs_we}wK;lzut0_zng=l>6LZ{htxf(;NPljRJ+X@Ug#4 zM{T|>;BK=?p%lWSA{2j!cdatJ4J}Q)3#k#!&|-5F@+6$qDEZ;FeSuvli;W{hJvEhE z-c2%U(eEE1w!1PHpF4dYR9iBcU~OhRTaoa=FzUOI@u)20yL57$1csa;qwqpen4ffW z5-*7befGu&jvB~oxsj);%{vceX5saL4?SiL@cUul+b{QNZ%ve>M{GX)AoDvX57$G$ z&n!!O+CAOCw@?vU>1uNxQ(+0Z3pV!ttsXel;@HI9xO`kwG^}(>AW|S?Wm=IErH$dZ zxnLG6@J%%a6{*Pg2bNmy*+-@jcH$+$;v@caD>ZI4Bb}M5x|F(@eaQv?`%O9nJW9uJ z93H32{q)X~5RO1b{>b_iNI(H42q9ol)IixJ@uF@o@i8^OY`|CLxd?xa z!sis$W!hevXH7)-!OkeDmkd%9SXDWsx=Gx%vOwJgz-``axwU{9cQVEBxW%&vpMnb#KL zUB4h3+_`<#s$H@&J4U8Y&O#D=5{uoZr?-b`!mTsBE;w4rUL>}`dX=m29)+?lP zyXJ~4&sK;R9%q`)kyDKfuKSjSf3x#EVubds6RH_c_$VqS68EfV9G=I1!H?0RD;eY} z^HGMe(UGq}K~n%wu0hM_EdCn&D6m6Q7P+CnsRA{PE)f*TXTTUa++wRU;_9 z^T6DUbCQ#sdQbaaSOdQemrIG;izWrhfaR|!7LCS|Q|^&Jv*ws%YMzXL=V=>1 zQff-`Pg%^_5AHnKCFNl~TA-CfMGuO=g&j5Vw>qR?u)k_^*Z05F&aT0S%&*SiOq?g? zJCpypXWQH;WPd|L8-FJr7mFmYV;n+78@Y=Rva6l;>E0V-w()zXQZ|{pN;s43C!dj_O}|v))RZuOhwhI@+$If4 ze!q2;BLi)8Ic5<<@=Ui+(|W49`;`3+J`Kh;l{@|di=epEMVR&YX!8BtuWxE~B8gRo zWqrSi`&K2wu6uRavXPBMl*^({$+J{rkVXslc6?W$A2t2$!))e*p*1A{0A1#Bnfe9D zXAO~n5kHIsW6G{~k*&vci4?jkD-qeA%{AUR#v%*sVQk^Kehm=}CQznEg>5srVVc;Q zG3tbYfQ0h_e?#|$o-HKyPlyK*3ZewP?uaLsW!#dPnI1&=BT*RV0le#NKqn6t2`UL} z=Qv80%0)tCM~GC?F=TIIXtoUlzC@dx+88(q8r*X=HqG{}RFRdv=Gzb}3V#j1a6id} z9}jg_#w#lFf`{{%Eqx|yFg`F9Fias2oxU8_K2H#gw!W8+_Lz zGd(Tsm7MRcJ+;mgR~*WN!zsbMO`X$2uZ}H6P~D*Be*foPhvB5ksrEkiKkdsv!6q$Ty*DCJpF*hzNv}ps7vQXbbU@NQT02Be0?y2^P4;uP{%8t=t29A%R#Aecf8OYIBvg5Z zK7I_6?#HQVIrej_BXj6Yjh6gg<5NPjf22*^{$`jb4@y@t`<{lQQ*w28lx`nEfV~Em zUZ8%%Tly>j9Y%h(c+#{B`T^S18jCNu+PrLMM$5PJC=^2z-lqZGa4=L6^??Hw2U6{| z?&je3L`(mYP>~Se%wWOKm%~B-sTC|P3_h(^w`ZXFJQ5$4)6D*UK?-csAB-fXn5z~pp;A>9ve!SIkk!0Q)SR0H~4g!rh ziyR<}WN+!MWr94zckhZ*1cWYa8wYZ}Vfr*fgojP>r_=p*Ec9 z(N?@mfqIB(Yc^{#`wxa%`+6HAppN~4hl4mprTl=0x6r+VkN)IGv@(r$iK7%MFB+H^ zdt+AP@Vxfm+UMfKj1nPg6T9f{~e6GqJ`7 zI-3iI0tw4*=L%LJ1(<;9ZQWyZwLb;G|4W3T%xAr(ImcyY+KSPAwUVlLRiji)8KBnH zK`9no%4wj=>XZZmrM$ErO}^k8pWNP3Q{5^)9?d(3$S>-$!jq8lIf;l^STvxpJ8wN8 zP?u0QJg~LWrNAIC;Yg;x%-|q-^40^|S$lMe)=A4v^my-T{)*y%0$H^{!%lnvr!f$% z7Ghvhy+wU!hL}c``k^8spZFRG91{Ub!0zfRFaXh0P#I~z1+5*W$?%=LdLL*kIU z_utVooBXS8Q6hIB;=lG$7ZGUjGdUP)NCXW+<69cqJX{Qt=^v50)8c-h;!?8HbwEz7 zRAM&(AOe-)MA{lPow~EVzNN;WppgRp>ed&eTiDPkP(BR{99Ef3N$4w?fNTsY-o&baIKo@Lr3qX&{q2Lb@AvAg0%R6-o12Y{y zS*Yp|$k=cpb5~i^mD#s|gVGp+5)gJ{WeH`rEk#fk)%cp#IPah>s$JgU!@@aJfD2SN zng#%R#CqZCPx|yNUY+xHouC2+m^&pYFz%YZ6O9-$8`=I6kuvu$gM#5iBW(L($>HgQ zQ%|g};Xu9$O!tj`g^4dJ#O~HooD;C^f~g^HPjFr|tbz;ioO#>cRlh$)VGBTk0>FR& zs)0T#V{!TJ7)o{ceICX%D#kX*tO6Rr08V@bBtxEBIN%xBk2T@cw}U+&pbL?EjNF_`)v8HnnAU?U~?p8=EGoL1mO@sAf=3W&lO#_>?#2;NcXEP^|4af z9mExjm5Bi&M-)KKltZJG!k?>)1j^0XtXI9s#G(b6_4`+CU!0B?qkw|?y?f&nD%83k z_BiipUUSwkD8P{)lvhIGf^9zQ#f$zRNAUy{!Dl387(iCA%F!&H4sf6 zlgwf!{wGh8T&vYRnnVa*1t0{dz)%9r$oNz?JJYDggj@SfBg{L>T91oT2H9lD`&gw_lfj9`jbpk3o))-5v3e$xE*aa~F zw^Re*%n|HMm2;Ee^yzd34gf>|XbYlmFo?Kh00VU#__*hcCY{R@XyJpilM za*|}%Dxr;`OBMwk~@U zouw+4{}s(`vC`UdUB_~6 z2xfz^AFh;{M%5c^O}vz|3DhxHb!BSJRlXB&)YhJ3(kOmi#d^FL<3ZRCg93l)!P4rF zBo?su!iGdUhJ4Yj4j{Cuvs}8w3d-=j7fZN+c^!`T4H`ftKJmCty`!P{1~7zu#%KhW z+)i33PugBuo1d;1=09UR{}L4m$BzP71prKo$dO8$Ukf&yDkKL=;(^l483}+z=Rlxr zw-#}Kv*Kkov<0kn{8~gBJHW#?)(eN>A{7C2!O`Irfc))f6HLg{YQOuN58)8R(E>`m zNvxB+55W9CsMD_Ue{1vf;Ho`Zs51k9SPLRFCDc()t6)TW?mt};QlqWzBKZ=m68w0+ zHH1*yVEvJIzRjzR4Jo~z!Dqg#WxLgHr+*1B=2b>Zmc#hgvjEE%F$Gyd3}DI)r*o-= zQ~{*yK|-%bVu$_7ab0ADA%MSIe1gysqz|j$fw~Su`%{z{OS&Tr90I+yRG5c2Inc#r z_cyTyl9{>lz$p$u#f)+M-rk~P6L5ubj4FJ7aq-6z{q!R%<}ZtdT1jo0zycxP18CZY z>C2JND?kSO`lu*?{_*=6wD(`EQ2MZ~5hY;Pri842GRo@Hi+;S{d_{$# z?OdQNG*QdfgW5`l!4-KZThmgc}Fx(@G)C6#xy)mpQF<2Fzm+ z>3>zHH5c%GDU0I2M`*&01G6!VDn>=_tW?Fj*%3FP=B@| zes8|F6;`(rDSky0kUSf%z_B@-uJ`jiD(aJg><9VM$egbk6FLo1doQzEwX_Q)3-MMl zT^vXuFX&zakz9V83~^dN+7#58x8JtRqH7%*MkF6ieqNdxQ>q(N=)R`tsaI0&qcp|8 z=p98Y`k|pRvdu#7nRRP>cW9u(HM30}Tc*$5(I?aB`dnC?+9C_&PUuc*93KswUbdeq zZ3cwd>W?zj+nhDf@c&2L>Q1dl>RE^oKGe&)cH3#1&}B z#bhbqScpI_A+bSnDY-9n56Lp^M`0n=PDA?Eq zdIS93xW1SOb&)8R2#Vsj&F?v#zagj|aIR{>^M!B|t***i-=6B=a5|TJ5?GZW)IlqY z{K=Ot^RN+sSDg&Vpl5aEeF!GIy&{hW(nWAltqI%h3i z@2BJp9#2iymnN0o8yp6V1BKYpHhb0|m#8Gpx+~uuUBc;4drIenrZ)d{WUy1$4mG)K z1%BQCJV4J-j3Cf#snIxPj`dOTYm%pN<1-0LzB~zHu%aBk!lVKLOBSHEU7IS! zSAD-&)8fH6kJsl6w;}e!{=*@6zd)xKgG3%})N={xbsm(W{3Yr%C7

f~X$;m(Iq; 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 CTUw?7 literal 104543 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%0D>wrGpI}~BKDVrX73+X8 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 diff --git a/SUMMARY.md b/SUMMARY.md index 71b4c3a..3d900f5 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -114,9 +114,9 @@ * [Specifications](inji-wallet/inji-mobile/technical-overview/specifications/README.md) * [Face SDK Specifications](inji-wallet/inji-mobile/technical-overview/specifications/face-sdk-specifications.md) * [Backend Services](inji-wallet/inji-mobile/technical-overview/backend-services/README.md) - * [Mimoto](inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md) - * [eSignet](inji-wallet/inji-mobile/technical-overview/backend-services/esignet.md) - * [Inji Certify](inji-wallet/inji-mobile/technical-overview/backend-services/inji-certify.md) + * [Inji Wallet Backend (Mimoto)](inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md) + * [Authorization Server for Authentication Using Inji Wallet Credentials](inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md) + * [Credential Issuer](inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md) * [Customizations](inji-wallet/inji-mobile/technical-overview/customization-overview/README.md) * [Workflow customization](inji-wallet/inji-mobile/technical-overview/customization-overview/workflow-customization.md) * [UI customization](inji-wallet/inji-mobile/technical-overview/customization-overview/ui-customization.md) diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/README.md b/inji-wallet/inji-mobile/technical-overview/backend-services/README.md index f2acc16..de39adc 100644 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/README.md +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/README.md @@ -4,6 +4,6 @@ This section contains the guides and information that could benefit the develope For more information on backend systems, read through: -1. [Mimoto service](mimoto.md) -2. [esignet service](esignet.md) -3. [Inji Certify](inji-certify.md#overview) +1. [Inji Wallet Backend (Mimoto)](./mimoto.md) +2. [Authorization Server for Authentication Using Inji Wallet Credentials](./login-using-credential.md) +3. [Credential Issuer](issuer.md#overview) diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/esignet.md b/inji-wallet/inji-mobile/technical-overview/backend-services/esignet.md deleted file mode 100644 index e714a11..0000000 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/esignet.md +++ /dev/null @@ -1,31 +0,0 @@ -# eSignet - -The eSignet service is utilized by Inji Wallet for online login. Users have the ability to log in to any service provider portal that is integrated with eSignet. - -## Online login - -### QR code scanning and login to the service provider portal - -The user is required to open the portal integrated with eSignet and utilize the app scanner to scan the QR code. - -After successfully scanning the QR code, Inji Wallet will access the API below and transmit the link code. - -#### Link Transaction endpoint V2 - -{% openapi-operation spec="api" path="/linked-authorization/v2/link-transaction" method="post" %} -[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) -{% endopenapi-operation %} - -After successfully completing the offline face authentication and selecting the required and optional information, the two specified APIs are invoked. - -#### Linked Authentication Endpoint V2 - -{% openapi-operation spec="api" path="/linked-authorization/v2/authenticate" method="post" %} -[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) -{% endopenapi-operation %} - -#### Linked Consent Endpoint V2 - -{% openapi-operation spec="api" path="/linked-authorization/v2/consent" method="post" %} -[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) -{% endopenapi-operation %} diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/inji-certify.md b/inji-wallet/inji-mobile/technical-overview/backend-services/inji-certify.md deleted file mode 100644 index 8b3ddfa..0000000 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/inji-certify.md +++ /dev/null @@ -1,26 +0,0 @@ -# Inji Certify - -## Overview - -The Inji Certify service is utilized by Inji Wallet for downloading the VC. - -### Download VC - -The user is currently on the `Add new card` screen and chooses an issuer(For example, Republic of Veridonia National ID Department). - -* Inji Wallet utilizes the `react-native-app-auth` library for authorization flow. - * It first redirects the user to the authorization server configured respective to the Issuer (For example, e-Signet). - * The user performs authentication (For example, on the eSignet UI, the input the necessary information such as a unique ID and OTP (One-time Password)). - * Post successful authentication, the user is redirected back to the Inji Wallet app with an authorization code. - * Inji Wallet then exchanges the authorization code for an access token. -* Using the access token, Inji Wallet makes a request to the credential endpoint from Inji Certify to download the credential. - -#### VC Issuance endpoint - -{% openapi-operation spec="api" path="/vci/credential" method="post" %} -[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) -{% endopenapi-operation %} - -For credential request, refer credential\_endpoint attribute in issuer's configuration response. - -Read More diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md b/inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md new file mode 100644 index 0000000..017d33a --- /dev/null +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md @@ -0,0 +1,33 @@ +# Issuer + +## Overview + +The **Issuer** is one of the backend services that Inji Wallet interacts with to obtain Verifiable Credentials (VCs). As defined by the **OpenID for Verifiable Credential Issuance (OpenID4VCI)** specification, an Issuer is responsible for issuing credentials to eligible users. + +Within the Inji ecosystem, **Inji Certify** acts as the Issuer. It exposes the OpenID4VCI endpoints that Inji Wallet uses to authenticate users, request credentials, and download the issued Verifiable Credentials. Once downloaded, Inji Wallet securely stores and manages these credentials on the user's device. + +## Credential Download Flow + +The following steps describe how Inji Wallet downloads a Verifiable Credential from an Issuer. + +1. The user opens the **Add New Card** screen in Inji Wallet and selects an issuer (for example, *Republic of Veridonia National ID Department*). + +2. Inji Wallet initiates the authorization flow. + * The wallet redirects the user to the authorization server configured for the selected issuer (for example, **eSignet**). + * The user authenticates using the configured authentication mechanism, such as a unique identifier and a One-Time Password (OTP). + * Upon successful authentication, the authorization server redirects the user back to Inji Wallet with an authorization code. + * Inji Wallet exchanges the authorization code for an access token. + +3. Using the access token, Inji Wallet invokes the Issuer's credential endpoint exposed by **Inji Certify** to download the issued Verifiable Credential. + +### Credential Endpoint + +The credential issuance endpoint is designed in accordance with the OpenID for Verifiable Credential Issuance (OpenID4VCI) specification. The endpoint URL is provided in the Issuer Metadata response through the `credential_endpoint` attribute. + +#### VC Issuance Endpoint + +{% openapi-operation spec="api" path="/vci/credential" method="post" %} +[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) +{% endopenapi-operation %} + +> **For more details**: Refer to the [Inji Certify Documentation](../../../../inji-certify/overview/README.md) to understand credential issuance workflows. diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md b/inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md new file mode 100644 index 0000000..44897d5 --- /dev/null +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md @@ -0,0 +1,81 @@ +# Online Login + +## Overview + +**Online Login** enables users to securely access digital services using a verifiable credential stored in the Inji Wallet. Instead of using traditional usernames and passwords, users can authenticate themselves by presenting a trusted digital credential, completing user verification, and consenting to share only the required information with the service provider. + +--- + +## Example Use Case +This use case is applicable to any service provider portal that supports wallet-based authentication through a compatible Authorization Server (AS). + +The following example demonstrates the online login flow within the Inji ecosystem using **eSignet** as the Authorization Server. + +* **Authorization Server (AS):** eSignet +* **Service Provider:** Health ID Services Portal +* **Credential Issuer:** Republic of Veridonia National ID Department +* **Credential:** Veridonia National ID + +In this example, a user downloads the Veridonia National ID credential into the Inji Wallet and later uses it to securely sign in to the Health ID Services Portal. + +--- + +## User Journey + +1. Open the **Inji Wallet** application. +2. Tap the **+** button and download a credential from the **Republic of Veridonia National ID Department**. +3. After the credential is downloaded, open the credential menu (⋮) and activate it. +4. Open the **Health ID Services** portal and select **Sign in with eSignet**. +5. A QR code is displayed on the portal. Using the Inji Wallet, scan the QR code from the **Share** tab or the credential's **QR Login** option. +6. Complete the face authentication. +7. Review the requested claims and choose the information to share. +8. Provide consent. +9. The requested claims are securely shared, and the user is successfully signed in to the Health ID Services portal. + +--- + +## APIs Involved + +The user is required to open the portal integrated with eSignet and utilize the app scanner to scan the QR code. + + +### Link Login Transaction +After successfully scanning the QR code, Inji Wallet will access the API below and transmit the link code. + +{% openapi-operation spec="api" path="/linked-authorization/v2/link-transaction" method="post" %} +[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) +{% endopenapi-operation %} + +### Authenticate User + +After successful face authentication, the wallet authenticates the user. + +{% openapi-operation spec="api" path="/linked-authorization/v2/authenticate" method="post" %} +[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) +{% endopenapi-operation %} + +### Submit User Consent + +Once the user approves the requested claims, the wallet submits the consent. + +{% openapi-operation spec="api" path="/linked-authorization/v2/consent" method="post" %} +[OpenAPI api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/a642986d423ac4ddb8b24e8d67b93a4e7b72f36ba27efafa5dd7ad15507aba07.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260619%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20260619T063153Z&X-Amz-Expires=172800&X-Amz-Signature=9b94089a8690b19e0b374d14c6d4fa809f268501594b2b68b212edd04cb0b2a0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) +{% endopenapi-operation %} + +--- + +## Benefits + +* Passwordless authentication using digital credentials. +* User-controlled sharing of identity attributes. +* Explicit consent before any information is shared. +* Reusable across multiple service provider portals. +* Secure authentication using trusted verifiable credentials. + +--- + +## Reference + +For details about the Wallet Authentication APIs, refer to the [eSignet Wallet Authenticator documentation](https://docs.esignet.io/esignet-authentication/develop/integration/wallet/wallet-authenticator#wallet-authentication-apis) + +[//]: # (TODO: Fix swagger esignet links) \ No newline at end of file diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md b/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md index ab76367..7987e32 100644 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md @@ -1,4 +1,4 @@ -# Mimoto +# Inji Wallet Backend - Mimoto Mimoto is a BFF(Backend for Frontend) for Inji Wallet. It's being used to get default configuration, download verifiable credentials (VC) and activate VC.\ It provides all necessary APIs to the Inji Wallet and acts as a proxy for resident services. Mimoto gets the request from Inji Wallet, performs all the validations and forwards it to respective services. Additionally, it subscribes to the web-sub event to be able to download the VC once it's ready. @@ -15,27 +15,21 @@ The user is currently on the `+` button on the Home screen, which will open `Add [mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) {% endswagger %} -To get complete configuration of the specific issuer, below api is called. - -{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/issuers/{issuer-id}" method="get" %} -[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) -{% endswagger %} - ### Retrieve accessToken for OIDC flow This endpoint exchanges an OAuth 2.0 authorization code for an access token as part of the OpenID4VCI authorization flow for a Mimoto client registered with an Authorization Server (AS). The issuer name is used to resolve the corresponding Authorization Server and its token endpoint from the issuer configuration (`issuers-config.json`). The client authenticates with the Authorization Server using the same cryptographic key pair that was registered during client registration. The token request includes a signed client assertion JWT to authenticate the client before the Authorization Server issues an access token. +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/get-token/{issuer}" method="post" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} -API: POST /v1/mimoto/get-token/{issuer} +## Online Login -https://mosip.stoplight.io/docs/mimoto/6fc8a9a1587a5-retrieve-access-token-for-oidc-flow +A use case exists where a credential is activated or bound to an Authorization Server, enabling users to access an online service by authenticating with that bound credential. -## Online Login +Within the Inji ecosystem, this is available as the **Veridonia National ID use case**. In this flow, **eSignet** acts as the Authorization Server for the MOSIP/National ID credential issued through **Inji Certify**. Users can use this credential to authenticate and log in to service such as Health ID platforms. -There is a usecase of activating / binding a credential to an Authorization server and using that Authorization Server, an online service can be logged in -using that binded credential. This usecase is avaiklable within Inji ecosystem as "Mosip or National ID" usecase. -This usecase uses eSignet as an Authorization Server for the Mosip / National ID credential downloaded from Inji Certify for logging in to health id services. ### Activate credentials @@ -57,17 +51,22 @@ Credentials have to be activated in order to use them for online login. When a u ## Configuration -The configurable properties for mimoto can be found at [mimoto-default.properties](https://github.com/mosip/mosip-config/blob/collab1/mimoto-default.properties). This property file is maintained as one for each deployment environment. On [this](https://github.com/mosip/mosip-config) repository, each environment configuration is placed in a corresponding branch specific to that environment. +The configurable properties for mimoto can be found at [mimoto-default.properties](https://github.com/inji/inji-config/blob/collab/mimoto-default.properties). This property file is maintained as one for each deployment environment. On [this](https://github.com/inji/inji-config) repository, each environment configuration is placed in a corresponding branch specific to that environment. -> Refer to [mimoto-default.properties](https://github.com/mosip/mosip-config/blob/collab1/mimoto-default.properties) of Collab environment. +> Refer to [mimoto-default.properties](https://github.com/inji/inji-config/blob/collab1/mimoto-default.properties) of Collab environment. The implementers can choose to use the existing configurations or add new configurations to them. -### Wallet Configurations +# Wallet Configurations + +The Inji wallet configurations are defined in the [inji-default.properties](https://github.com/inji/inji-config/blob/collab/inji-default.properties) file, which acts as the source of default configuration values. These configurations are exposed through the Mimoto `allProperties` API and are consumed by the Inji wallet at runtime. -**API:** `GET /v1/mimoto/allProperties` +The properties retrieved through the `allProperties` API control various wallet functionalities, including credential downloads, storage validation, caching, and OpenID4VP capabilities. -**Reference:** [inji-default.properties](https://github.com/inji/inji-config/blob/collab/inji-default.properties) + +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/allProperties" method="get" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} ```properties # Timeout for VC download API via OpenID4VCI flow in milliseconds @@ -90,8 +89,6 @@ mosip.inji.disableCredentialOfferVcVerification=true mosip.inji.openid4vpWalletConfig={"response_types_supported":["vp_token"],"vp_formats_supported":{"mso_mdoc":{"issuerauth_alg_values":[-7],"deviceauth_alg_values":[-7]},"ldp_vc":{"proof_type_values":["Ed25519Signature2020","JsonWebSignature2020"]},"dc+sd-jwt":{"sd-jwt_alg_values":["EdDSA","ES256"],"kb-jwt_alg_values":["ES256","EdDSA"]},"vc+sd-jwt":{"sd-jwt_alg_values":["EdDSA","ES256"],"kb-jwt_alg_values":["ES256","EdDSA"]}},"client_id_prefixes_supported":["redirect_uri","decentralized_identifier","pre-registered"],"request_object_signing_alg_values_supported":["EdDSA"],"authorization_encryption_alg_values_supported":["ECDH-ES"],"authorization_encryption_enc_values_supported":["A256GCM"],"presentation_definition_uri_supported":true,"request_uri_methods_supported":["get","post"]} ``` -[//]: # (TODO: Add swagger) - #### Property Descriptions 1. **`cacheTTLInMilliSeconds`**: Defines the cache expiration time, in milliseconds, for API fallback. If an API request fails, the SDK uses the cached response for the APIs listed in the table below, provided the cache entry has not expired. @@ -120,13 +117,6 @@ mosip.inji.openid4vpWalletConfig={"response_types_supported":["vp_token"],"vp_fo 3. For more information, see [Inji Wallet Usage](https://github.com/inji/inji-wallet/blob/master/docs/openid4vp/openid4vp-support.md#wallet-configuration-for-the-openid4vp-flow) - -{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/allProperties" method="get" %} -[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) -{% endswagger %} - - - ### Wallet's Trusted / Pre-registered Verifier list The Inji Wallet retrieves the list of pre-registered (trusted) verifiers from the Mimoto backend service. @@ -136,5 +126,7 @@ The Inji Wallet retrieves the list of pre-registered (trusted) verifiers from th The API response provides the list of trusted verifiers, which is then embedded into the `walletConfig`. This configuration is supplied to the Inji OpenID4VP library to execute **client validation** during the OpenID4VP flow. -[//]: # (TODO: Add swagger) +{% swagger src="../../../../.gitbook/assets/mimoto (1).json" path="/verifiers" method="get" %} +[mimoto (1).json](<../../../../.gitbook/assets/mimoto%20(1).json>) +{% endswagger %} diff --git a/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/openid4vp.md b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/openid4vp.md index d6084bf..21107b8 100644 --- a/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/openid4vp.md +++ b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/openid4vp.md @@ -2,79 +2,112 @@ ## OpenID4VP - Online Sharing -This library enables consumer applications (mobile wallet) to share users Verifiable Credentials with Verifiers who request them online. It adheres to the OpenID4VP [specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0-23.html) draft version 23, which outlines the standards for requesting and presenting Verifiable Credentials. +This library for **wallet-side** processing of [OpenID for Verifiable Presentations](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html) (OpenID4VP). This library validates incoming authorization requests, helps build Verifiable Presentations (with signing delegated to your app), and sends responses to the verifier. -#### Library Functionalities: Processing the Request from Decoding to Verifier Response +**Key Responsibilities:** -1. Receives the Verifier's Authorization Request sent by the consumer application (mobile wallet). -2. Validates the received Authorization Request to check if the required details are present or not, and then returns the Authorization Request to the consumer application once all the validations are successful. -3. Receives the list of Verifiable Credentials from the consumer application which are selected by the consumer application end-user based on the credentials requested as part of Verifier Authorization request. -4. Constructs the vp\_token without proof section and sends it back to the consumer application for generating Json Web Signature (JWS). -5. Receives the generated signature along with the other details and generates vp\_token with proof section & presentation\_submission. -6. Sends a POST request with generated vp\_token and presentation\_submission to the received Verifier's response\_uri endpoint. -7. Below sections details on the steps for integrating the Kotlin and Swift packages into the app. Below sections details on the steps for integrating the Kotlin and Swift packages into the app. +* **OpenID4VP Library** -**Supported features** + * Handles OpenID4VP protocol workflows and compliance + * Simplifies Verifiable Presentation creation and response exchange + * Reduces development complexity and integration time -| Feature | Supported values | -| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Device flow | Cross device flow, Same device flow (only `direct_post` and `direct_post.jwt` supported) | -| Client id scheme | `pre-registered`, `redirect_uri`, `did` | -| Signed authorization request verification algorithms | Ed25519 | -| Obtaining authorization request |

- By value : both signed (via request param) and unsigned (via URL encoded parameters)
- By reference ( via request_uri method)
Note: The use of signed or unsigned requests, is determined by the client_id_scheme associated with the client.

| -| Obtaining presentation definition in authorization request | By value, By reference (via `presentation_definition_uri`) | -| Authorization Response content encryption algorithms | `A256GCM` | -| Authorization Response key encryption algorithms | `ECDH-ES` | -| Credential formats | `ldp_vc`, `mso_mdoc`, `dc+sd-jwt`, `vc+sd-jwt` | -| Authorization Response mode | `direct_post`, `direct_post.jwt` (with encrypted & unsigned responses) and `iar-post` (unencrypted response), `iar-post.jwt` (Encrypted and unsigned response) | -| Authorization Response type | `vp_token` | +* **Library Consumer App** -### Android: Kotlin package for OpenID4VP: + * Owns user consent and credential selection + * Performs secure cryptographic signing -#### Repository +Build OpenID4VP capabilities faster with a library designed to remove protocol complexity, reduce implementation risk, and accelerate your journey toward interoperable digital credentials. -* inji-openid4vp kotlin repo - [here](https://github.com/inji/inji-openid4vp) +## Supported features -#### Installation +### Feature Matrix by Specification Version -Snapshot builds are available - [aar](https://central.sonatype.com/artifact/io.inji/inji-openid4vp-aar) and [jar](https://central.sonatype.com/artifact/io.inji/inji-openid4vp-jar) +**Legend:** ✅ = Supported | ❌ = Not Implemented | N/A = Not Applicable -{% hint style="info" %} -Note: implementation "io.inji:inji-openID4VP:0.7.0" -{% endhint %} +| Feature | Draft 23 | Version 1.0 | Notes | +|-----------------------------------------------|:---------:|:-----------:|--------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Device Flow** | | | | +| — Cross device flow | ✅ | ✅ | Wallet scans QR code and passes data to this library | +| — Same device flow | ✅ | ✅ | Wallet receives VP request via deeplink | +| **Client ID Prefix** | | | Equivalent to Client ID Scheme in draft 23 | +| — pre-registered | ✅ | ✅ | Validated via `WalletConfig.trustedVerifiers` | +| — redirect_uri | ✅ | ✅ | | +| — decentralized_identifier | ✅ (`did`) | ✅ | | +| **Authorization Request Delivery** | | | Per [RFC 9101](https://www.rfc-editor.org/info/rfc9101/#name-authorization-request) | +| — By value (signed request) | ✅ | ✅ | | +| — By value (unsigned request) | ✅ | ✅ | Via URL-encoded parameters | +| — By reference (request_uri) | ✅ | ✅ | Fetched via HTTP GET/POST | +| — Request signing algorithms | ✅ | ✅ | Ed25519 | +| **Presentation Request** | | | | +| — DCQL Query | ❌ | ✅ | | +| — Presentation Definition | ✅ | ❌ | By value or via `presentation_definition_uri` | +| — Scope parameter | ❌ | ❌ | Not implemented | +| **VP Response Modes** | | | | +| — direct_post | ✅ | ✅ | | +| — direct_post.jwt | ✅ | ✅ | Unsigned and Encrypted response | +| — iar-post / iae_post | ✅ | ✅ | | +| — iar-post.jwt / iae_post.jwt | ✅ | ✅ | Unsigned and Encrypted response | +| **VP Response Type** | | | | +| — vp_token | ✅ | ✅ | | +| — vp_token id_token | ❌ | ❌ | Not implemented | +| — code | ❌ | ❌ | Not implemented | +| **Authorization Response Encryption** | | | For `direct_post.jwt` and `iar-post.jwt` / `iae_post.jwt` modes | +| — Encryption algorithm (content) | ✅ | ✅ | A256GCM | +| — Key agreement algorithm | ✅ | ✅ | ECDH-ES | +| **VP Token Generation** | | | | +| — DCQL Query-based | ❌ | ✅ | | +| — Presentation Definition-based | ✅ | ❌ | | +| — Error responses | ✅ | ✅ | Any failure during VP request validation / user consent rejection / VP response preparation is prepared as Authorization Error response and sent to Verifier | +| **Supported Verifiable Presentation Formats** | | | | +| — ldp_vp | ✅ | ✅ | | +| — mso_mdoc | ✅ | ✅ | | +| — vc+sd-jwt / dc+sd-jwt | ✅ | ✅ | | -### iOS: Swift package for OpenID4VP: -#### Repository +## Libraries Available in -* inji-openid4vp-ios-swift swift repo -> [here](https://github.com/inji/inji-openid4vp-ios-swift) +This library is available in Kotlin and Swift, supporting Android, JVM and iOS platforms. -#### Installation +- **Kotlin**: [Android (AAR) & JVM (JAR)](https://github.com/inji/inji-openid4vp/tree/master/kotlin) +- **Swift**: [iOS](https://github.com/inji/inji-openid4vp-ios-swift) -1. Clone the repo. -2. In your swift application go to file > add package dependency > add the https://github.com/inji/inji-openid4vp-ios-swift in git search bar > add package. -3. Import the library and use. +### Core Methods -### APIs +The library provides the following methods organized into different workflow patterns: -The OpenID4VP library provides the following APIs for implementing the OpenID4VP flow: +#### Primary Flow Methods -| API Method | Use Case | -| ---------------------------- | -------------------------------------------------------------------------------------------------- | -| `authenticateVerifier` | Validate and decode the verifier's authorization request | -| `constructUnsignedVPToken` | Create unsigned VP tokens (V1 API) from verifiable credentials for signing by the wallet | -| `constructUnsignedVPTokenV2` | Create flattened list of unsigned VP tokens (V2 API) with signing metadata for simplified workflow | -| `constructVPResponse` | Construct the VP response (V1 API) with signed tokens ready to be sent to the verifier | -| `constructVPResponseV2` | Construct the VP response (V2 API) from simplified signing results | -| `sendVPResponseToVerifier` | Construct VP response and send it to the verifier via HTTP POST | -| `constructErrorInfo` | Construct an authorization error response as per OpenID4VP specification | -| `sendErrorInfoToVerifier` | Construct and send error response to the verifier via HTTP POST | +| Method | Purpose | +|----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| **`authenticateVerifier()`** | Validates incoming authorization requests from verifiers. Resolves request objects, verifies signatures, and returns a structured request. | +| **`getMatchingCredentials()`** | *(DCQL Helper)* Evaluates DCQL queries against your wallet's credentials to determine which satisfy the verifier's requirements. | +| **`constructUnsignedVPToken()`** | Prepares VP tokens based on selected credentials. Returns unsigned data that your wallet must sign. | -> **For detailed API reference including parameters, response structures, examples, and exceptions, refer to the** [**Kotlin API Reference**](https://github.com/inji/inji-openid4vp/tree/master/kotlin#apis) **or** [**Swift API Reference**](https://github.com/inji/inji-openid4vp-ios-swift?tab=readme-ov-file#apis) **accordingly.** +#### Response Submission — Two Patterns Available -#### OpenID4VP library and Inji Wallet integration: +**Option 1: Construct & Send (Recommended)** — SDK handles VP Response submission -The below diagram shows the interactions between Inji Wallet, Verifier and OpenID4VP library. +| Method | Purpose | +|----------------------------------|----------------------------------------------------------------------------------------------------------| +| **`sendVPResponseToVerifier()`** | Assembles signed VP tokens into an OpenID4VP response **and submits it** to the verifier. | +| **`sendErrorInfoToVerifier()`** | Constructs and sends error/rejection responses to the verifier (e.g., user denial, validation failures). | + +**Option 2: Construct Only (Advanced)** — You handle VP Response submission yourself + +| Method | Purpose | +|-----------------------------|--------------------------------------------------------------------------------------| +| **`constructVPResponse()`** | Constructs the VP response **without sending**. You handle VP Response submission. | +| **`constructErrorInfo()`** | Constructs an error response **without sending**. You handle VP Response submission. | + + +> **For detailed API reference including parameters, response structures, examples, and exceptions, refer to the** [**Kotlin API Reference**](https://github.com/inji/inji-openid4vp/tree/master/docs/integration-guide.md) **or** [**Swift API Reference**](https://github.com/inji/inji-openid4vp-ios-swift/docs/integration-guide.md) **accordingly.** + +--- + +#### OpenID4VP library and Wallet integration: + +The below diagram shows the interactions between Wallet, Verifier and OpenID4VP library. ```mermaid sequenceDiagram @@ -103,17 +136,14 @@ sequenceDiagram activate Wallet Note over Wallet: Sign VP Token - Note over Wallet: Construct JWS Token deactivate Wallet - Wallet-->>Library: Send Signed JWS Token + Wallet-->>Library: Send Signed data activate Library - Note over Library: Construct Proof Object - Note over Library: Attach Proof to VP Token + Note over Library: Create Verifiable Presentation + Note over Library: Populate VP response deactivate Library - Library-->>Verifier: HTTP POST Request with:
1. VP Token
2. Presentation Submission
3. State - -``` + Library-->>Verifier: HTTP POST Request with: VP Response -_Note: Currently, the `vp_token` uses the `Ed25519Signature2020` type for digital signatures._ +``` \ No newline at end of file diff --git a/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/pixelpass.md b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/pixelpass.md index 94f0a0d..61fb8a0 100644 --- a/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/pixelpass.md +++ b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/pixelpass.md @@ -4,167 +4,97 @@ PixelPass is a versatile and easy-to-use library designed to simplify working with QR codes and data compression. It allows you to generate QR codes from any given data with just a single function. If you’re working with JSON, PixelPass can take that data, compress it, and convert it into a compact format using CBOR encoding, making it smaller and more efficient for QR code generation. The library can also decode this compressed data, turning CBOR back into the original JSON format. Additionally, for more complex use cases, PixelPass offers the ability to map your JSON data to a specific structure, compress it, and encode it into CBOR. Later, you can also reverse this process, decoding the CBOR back into its mapped JSON structure. With these capabilities, PixelPass makes managing, compressing, and encoding data for QR codes easy and efficient. -PixelPass has NPM, Kotlin, Swift and Java artifacts available. +### Availability + +PixelPass is available across multiple platforms and programming languages, making it accessible for diverse development environments: + +- **[Node.js/JavaScript](https://github.com/inji/pixelpass/tree/master/js)**: Available as an NPM package for web and Node.js applications +- **[Kotlin/Android](https://github.com/inji/pixelpass/tree/master/kotlin)**: Published as an AAR (Android Archive) library for native Android development +- **[Java](https://github.com/inji/pixelpass/tree/master/kotlin)**: Available as a JAR (Java Archive) for Java backend applications +- **[Swift/iOS](https://github.com/inji/pixelpass-ios-swift)**: Available as a Swift package for native iOS development + ### Features +PixelPass provides essential features for efficient data encoding and QR code generation: + * Compresses data using zlib with the highest compression level (level 9). * Encodes and decodes data with the base45 format. * For JSON data, applies CBOR encoding/decoding to achieve additional size reduction. * With JSON and a Mapper provided, maps the JSON and then performs CBOR encoding/decoding to further shrink the data size. +* Supports multiple output formats including base64-encoded PNG images and base45-encoded strings. +* Provides comprehensive error handling for robust data processing. -### Usage - -1. As a node project: - -`npm i @mosip/pixelpass` - -2. As a Kotlin/Java dependency: - -_Gradle_ - -`implementation("io.mosip:pixelpass:0.5.0")` - -_Maven_ - -``` - - io.mosip - pixelpass - 0.5.0 - -``` - -3. To include PixelPass in your Swift project, follow the below steps: - 1. Clone the PixelPass library locally. - 2. Create a new Swift project. - 3. Add package dependency: PixelPass - -## APIs - -Below are the APIs provided by the PixelPass library: - -**generateQRCode( data, ecc , header )** - -The `generateQRCode` takes a data, ECC (Error correction level) which when not passed defaults to L and header which defaults to empty string if not passed. Returns a base64 encoded PNG image. - -* `data` - Data needs to be compressed and encoded. -* `ecc` - Error Correction Level for the QR generated. defaults to `"L"`. -* `header` - Data header need to be prepend to identify the encoded data. defaults to `""`. - -```javascript -import { generateQRCode } from '@mosip/pixelpass'; - -const data = "Hello"; -const qrCode = generateQRCode(data, ecc, header); - -// ecc is Error Correction Level for the QR generated. defaults to "L". -// header defaults to empty string if not passed. -``` - -**generateQRData( data, header )** +### APIs Overview -The `generateQRData` takes a valid JSON string and a header which when not passed defaults to an empty string. This API will return a base45 encoded string which is `Compressed > CBOR Encoded > Base45 Encoded`. +PixelPass exposes six primary APIs for different use cases: -* `data` - Data needs to be compressed and encoded. -* `header` - Data header need to be prepend to identify the encoded data. defaults to `""`. +- **generateQRCode**: Creates a visual QR code (base64 PNG) from compressed and encoded data +- **generateQRData**: Produces base45-encoded strings suitable for raw data transfer +- **decode**: Reverses the encoding process to retrieve original JSON from base45 strings +- **decodeBinary**: Decompresses binary zip data +- **getMappedData**: Transforms JSON using a mapper and applies optional CBOR encoding for reduced size +- **decodeMappedData**: Reverses mapped and encoded data back to original JSON structure +- **toJson(base64UrlEncodedCborEncodedString: String)**: Decodes base64 URL-encoded CBOR data and converts it into its JSON structure. -```javascript -import { generateQRData } from '@mosip/pixelpass'; +These APIs support multiple compression and encoding strategies, allowing developers to choose the approach that best fits their credential sharing scenarios. -const jsonString = "{\"name\":\"Steve\",\"id\":\"1\",\"l_name\":\"jobs\"}"; -const header = "jsonstring"; +> **Note**: For comprehensive API documentation and detailed usage examples, refer to the API sections in the respective repositories: +> - [JavaScript/Node.js API Guide](https://github.com/inji/pixelpass/tree/master/js#apis) +> - [Kotlin/Android API Guide/Java API Guide](https://github.com/inji/pixelpass/blob/master/kotlin/Readme.md#apis) +> - [Swift/iOS API Guide](https://github.com/inji/pixelpass-ios-swift#api-reference) -const encodedCBORData = generateQRData(jsonString, header); -// header defaults to empty string if not passed. -``` +## Use Cases -**decode( data )** +### 1. Sharing Credentials as QR Codes -The `decode` will take a `string` as parameter and gives us decoded JSON string which is Base45 `Decoded > CBOR Decoded > Decompressed`. +Credential sharing as QR codes is a core use case that leverages the PixelPass library. A Wallet application encodes credential data using `pixelPass.generateQRData(data, header)` into a QR code, which can then be shared with or scanned by a Verifier application. The Verifier uses PixelPass to decode and validate the credential data. -* `data` - Data needs to be decoded and decompressed without header. +This use case is available within the Inji Ecosystem with the following components: -```javascript -import { decode } from '@mosip/pixelpass'; +- **Wallet**: Inji Wallet +- **Verifier**: Inji Verify +- **Issuer**: Inji Certify +- **Applicable Credential Formats**: + - ldp_vc -const b45EncodedData = "NCFWTL$PPB$PN$AWGAE%5UW5A%ADFAHR9 IE:GG6ZJJCL2.AJKAMHA100+8S.1"; -const jsonString = decode(b45EncodedData); -``` +**User Flow** -**decodeBinary( data )** +1. User downloads a credential from Inji Certify via Inji Wallet +2. User opens the credential detail view, which displays a QR code +3. User opens Inji Verify and chooses to scan or upload the credential QR code: + - **Scan Option**: Select the "Scan QR Code" tab and allow Inji Verify to scan the QR code using the device camera + - **Upload Option**: Select the "Upload QR Code" tab and upload the QR code image downloaded from Inji Wallet +4. After scanning or uploading, Inji Verify decodes the QR data, validates the credential, and displays it in the UI -The `decodeBinary` will take a `UInt8ByteArray` as parameter and gives us unzipped string. Currently only zip binary data is only supported. +**PixelPass & Inji Wallet Integration:** -* `data` - Data needs to be decoded and decompressed without header. - -```javascript -import { decodeBinary } from '@mosip/pixelpass'; - -const zipdata = ; -const decompressedData = decodeBinary(zipdata); -``` - -**getMappedData( jsonData, mapper, cborEnable )** - -The `getMappedData` takes 3 arguments a JSON and a map with which we will be creating a new map with keys and values mapped based on the mapper. The third parameter is an optional value to enable or disable CBOR encoding on the mapped data. - -* `jsonData` - A JSON data. -* `mapper` - A Map which is used to map with the JSON. -* `cborEnable` - A Boolean which is used to enable or disable CBOR encoding on mapped data. Defaults to `false` if not provided. - -```javascript -import { getMappedData } from '@mosip/pixelpass'; - -const jsonData = {"name": "Jhon", "id": "207", "l_name": "Honay"}; -const mapper = {"id": "1", "name": "2", "l_name": "3"}; - -const byteBuffer = getMappedData(jsonData, mapper,true); - -const cborEncodedString = byteBuffer.toString('hex'); -``` - -The example of a converted map would look like, `{ "1": "207", "2": "Jhon", "3": "Honay"}` - -**decodeMappedData( data, mapper )** - -The `decodeMappedData` takes 2 arguments a string which is CBOR Encoded or a mapped JSON and a map with which we will be creating a JSON by mapping the keys and values. If the data provided is CBOR encoded string the API will do a CBOR decode first ad then proceed with re-mapping the data. - -* `data` - A CBOREncoded string or a mapped JSON. -* `mapper` - A Map which is used to map with the JSON. +The below diagram shows how Inji Wallet utilises PixelPass library. -```javascript -import { decodeMappedData } from '@mosip/pixelpass'; +
-const cborEncodedString = "a302644a686f6e01633230370365486f6e6179"; -const mapper = {"1": "id", "2": "name", "3": "l_name"}; +**PixelPass & Inji Verify Integration:** -const jsonData = decodeMappedData(cborEncodedString, mapper); -``` +The below diagram shows how Inji Verify utilises PixelPass library. -The example of the returned JSON would look like, `{"name": "Jhon", "id": "207", "l_name": "Honay"}` +
-### Errors / Exceptions +For more details on this use case, refer to the [detailed guide](../../../../../inji-verify/build-and-deploy/creating-verifiable-credentials-and-generating-qr-codes.md). -Shall you encounter any errors while using the APIs, please refer to the below: +### 2. Displaying mDoc Credential Data -1. **Cannot read properties of null (reading 'length')** - This error denotes that the string passed to encode is null. -2. **Cannot read properties of undefined (reading 'length')** - This error denotes that the string passed to encode is undefined. -3. **byteArrayArg is null or undefined.** - This error denotes that the string passed to encode is null or undefined. -4. **utf8StringArg is null or undefined**. - This error denotes that the string passed to decode is null or undefined. -5. **utf8StringArg has incorrect length**. - This error denotes that the string passed to decode is of invalid length. -6. **Invalid character at position X**. - This error denotes that the string passed to decode is invalid with an unknown character then base45 character set. Also denotes the invalid character position. -7. **incorrect data check** - This error denotes that the string passed to decode is invalid. +For credentials in the `mso_mdoc` format, the Issuer provides credentials as base64 URL-encoded CBOR data. Wallet applications can use the `toJson(base64UrlEncodedCborEncodedString)` API to convert the CBOR data to JSON format for display in the UI. -## PixelPass & Inji Wallet Integration: +This use case is available within the Inji Ecosystem with the following components: -The below diagram shows how Inji Wallet utilises PixelPass library. +- **Wallet**: Inji Wallet +- **Issuer**: Inji Certify -
+**User Flow** -## PixelPass & Inji Verify Integration: +1. User downloads a Mobile Driving License from Inji Certify via Inji Wallet +2. User opens the credential detail view where the mDoc data is displayed in a readable format -The below diagram shows how Inji Verify utilises PixelPass library. +--- -
From 7752721e346f7aa6fe8cf47622d6d90f7c1d72ea Mon Sep 17 00:00:00 2001 From: KiruthikaJeyashankar Date: Thu, 9 Jul 2026 13:36:52 +0530 Subject: [PATCH 3/4] docs: add vc-renderer library support Signed-off-by: KiruthikaJeyashankar --- .../inji-vc-renderer.md | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/inji-vc-renderer.md diff --git a/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/inji-vc-renderer.md b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/inji-vc-renderer.md new file mode 100644 index 0000000..ada6f3d --- /dev/null +++ b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/inji-vc-renderer.md @@ -0,0 +1,83 @@ +# Inji VC Renderer + +## Overview + +Inji VC Renderer is a library designed to render Verifiable Credentials (VCs) by converting SVG templates into visual SVG images. The library dynamically replaces placeholders in SVG templates with actual Verifiable Credential JSON data, strictly following the JSON Pointer Algorithm (RFC6901) for value extraction. + +**Key Responsibilities:** + +* **VC Rendering Library** + + * Downloads SVG templates from the VC's render method + * Replaces template placeholders with actual VC data + * Supports multiple rendering methods and generates visual credential displays + * Follows JSON Pointer Algorithm (RFC6901) for accurate data extraction + +* **Library Consumer App** + + * Provides the Verifiable Credential data + * Handles the display of credentials + + +## Supported Features + +### Core Capabilities + +* **SVG Template Processing**: Downloads SVG templates from URLs specified in the VC render method +* **Dynamic Placeholder Replacement**: Replaces Mustache-style placeholders with actual VC data using JSON Pointer Algorithm (RFC6901) +* **VC Data Model 2.0 Support**: Compatible with the latest Verifiable Credential specification +* **QR Code Embedding**: Optionally embeds QR codes within SVG templates for credential verification + +### Supported Credential Formats + +Currently supported credential format: +- **ldp_vc** - Linked Data Proofs Verifiable Credentials + +## Libraries Available In + +Inji VC Renderer is available in Kotlin and Swift, supporting Android, JVM and iOS platforms. + +- **Kotlin**: [Android (AAR) & JVM (JAR)](https://github.com/inji/inji-vc-renderer/tree/master/kotlin) +- **Swift**: [iOS](https://github.com/inji/inji-vc-renderer-ios-swift/tree/master) + +### Core Methods + +The library provides a primary API for rendering credential display content: + +#### `generateCredentialDisplayContent()` + +Converts a Verifiable Credential into visual SVG representation by processing render methods and replacing template placeholders. + +**Parameters:** + +* `credentialFormat` - Enum specifying the credential format (currently supports `ldp_vc`) +* `vcJsonString` - The Verifiable Credential in stringified JSON format +* `wellKnownJson` (Optional) - Well-known metadata in stringified JSON format +* `qrCodeData` (Optional) - Custom data for QR code generation. If provided, QR code is generated using this value; if not provided or empty, the full VC JSON string is used as fallback. **Note**: `qrCodeData` should be pre-encoded (e.g., Base45-encoded) + +**Returns:** + +* List of rendered SVG templates as strings +* Multiple SVG templates are returned if multiple render methods are present in the VC + +> **For comprehensive API documentation and detailed usage examples, refer to the respective repository documentation:** +> - [Kotlin/Java Repository](https://github.com/inji/inji-vc-renderer/tree/master/kotlin#api) +> - [Swift/iOS Repository](https://github.com/inji/inji-vc-renderer-ios-swift/tree/master#api) + +### Rendering Process Flow + +The library follows these steps to render credential display content: + +1. **Render Method Extraction** - Extracts render method information from the VC JSON +2. **SVG Template Download** - Downloads the SVG template from the URL specified in the render method +3. **Placeholder Replacement** - Uses JSON Pointer Algorithm (RFC6901) to extract values from VC JSON and replace placeholders in the SVG +4. **QR Code Generation** - Optionally generates and embeds a QR code (if `qrCodeData` is provided) +5. **Output Generation** - Returns the fully rendered SVG as a string + +If multiple render methods exist in the VC, this process is repeated for each, and all rendered SVGs are returned as a list. + +--- + +> Refer to the [Inji Certify documentation](../../../../../inji-certify/overview/features/README.md#9-svg-rendering-support) for details on issuing credentials with SVG Rendering Support and the corresponding credential structure. + + From 5880035799d7c3880ce6cdef1622e95321df37f0 Mon Sep 17 00:00:00 2001 From: KiruthikaJeyashankar Date: Thu, 9 Jul 2026 13:42:55 +0530 Subject: [PATCH 4/4] docs: fix typo Signed-off-by: KiruthikaJeyashankar --- .../inji-mobile/technical-overview/backend-services/issuer.md | 2 +- .../backend-services/login-using-credential.md | 2 -- .../inji-mobile/technical-overview/backend-services/mimoto.md | 2 +- .../tuvali/tuvali-inji.md | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md b/inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md index 017d33a..4fdb395 100644 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/issuer.md @@ -4,7 +4,7 @@ The **Issuer** is one of the backend services that Inji Wallet interacts with to obtain Verifiable Credentials (VCs). As defined by the **OpenID for Verifiable Credential Issuance (OpenID4VCI)** specification, an Issuer is responsible for issuing credentials to eligible users. -Within the Inji ecosystem, **Inji Certify** acts as the Issuer. It exposes the OpenID4VCI endpoints that Inji Wallet uses to authenticate users, request credentials, and download the issued Verifiable Credentials. Once downloaded, Inji Wallet securely stores and manages these credentials on the user's device. +Within the Inji ecosystem, **Inji Certify** acts as the Issuer. It exposes the OpenID4VCI endpoints that Inji Wallet uses to request and download issued Verifiable Credentials. User authentication is handled by a separate authorization server (eSignet) before the credential issuance process begins. Once downloaded, Inji Wallet securely stores and manages these credentials on the user's device. ## Credential Download Flow diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md b/inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md index 44897d5..51cb0c4 100644 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/login-using-credential.md @@ -77,5 +77,3 @@ Once the user approves the requested claims, the wallet submits the consent. ## Reference For details about the Wallet Authentication APIs, refer to the [eSignet Wallet Authenticator documentation](https://docs.esignet.io/esignet-authentication/develop/integration/wallet/wallet-authenticator#wallet-authentication-apis) - -[//]: # (TODO: Fix swagger esignet links) \ No newline at end of file diff --git a/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md b/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md index 7987e32..67d63b1 100644 --- a/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md +++ b/inji-wallet/inji-mobile/technical-overview/backend-services/mimoto.md @@ -89,7 +89,7 @@ mosip.inji.disableCredentialOfferVcVerification=true mosip.inji.openid4vpWalletConfig={"response_types_supported":["vp_token"],"vp_formats_supported":{"mso_mdoc":{"issuerauth_alg_values":[-7],"deviceauth_alg_values":[-7]},"ldp_vc":{"proof_type_values":["Ed25519Signature2020","JsonWebSignature2020"]},"dc+sd-jwt":{"sd-jwt_alg_values":["EdDSA","ES256"],"kb-jwt_alg_values":["ES256","EdDSA"]},"vc+sd-jwt":{"sd-jwt_alg_values":["EdDSA","ES256"],"kb-jwt_alg_values":["ES256","EdDSA"]}},"client_id_prefixes_supported":["redirect_uri","decentralized_identifier","pre-registered"],"request_object_signing_alg_values_supported":["EdDSA"],"authorization_encryption_alg_values_supported":["ECDH-ES"],"authorization_encryption_enc_values_supported":["A256GCM"],"presentation_definition_uri_supported":true,"request_uri_methods_supported":["get","post"]} ``` -#### Property Descriptions +### Property Descriptions 1. **`cacheTTLInMilliSeconds`**: Defines the cache expiration time, in milliseconds, for API fallback. If an API request fails, the SDK uses the cached response for the APIs listed in the table below, provided the cache entry has not expired. diff --git a/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/tuvali/tuvali-inji.md b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/tuvali/tuvali-inji.md index 6de384d..8a34e19 100644 --- a/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/tuvali/tuvali-inji.md +++ b/inji-wallet/inji-mobile/technical-overview/integration-guide/building-verifiable-credentials-wallet-with-inji-libraries/tuvali/tuvali-inji.md @@ -18,7 +18,7 @@ The Verifier device generates a URI using the `startAdvertisement()` method and OPENID4VP://connect?name=STADONENTRY&key=8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a ``` -URI structure can be found in the [spec](https://bitbucket.org/openid/connect/src/master/openid-4-verifiable-presentations-over-ble/openid-4-verifiable-presentations-over-ble-1_0.md). Currently the library doesnot support iOS as a verifier.But it can act as a wallet for android verifier. +URI structure can be found in the [spec](https://bitbucket.org/openid/connect/src/master/openid-4-verifiable-presentations-over-ble/openid-4-verifiable-presentations-over-ble-1_0.md). Currently, the library doesn't support iOS as a verifier.But it can act as a wallet for android verifier. ``` var verifier = Verifier()