From dfb332c2ff94037b7ec9185c49c02aab52b34f93 Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Mon, 22 Jun 2026 12:54:50 +0100 Subject: [PATCH 1/2] DEVELOPMENT: Bump version to 4.2.0-SNAPSHOT --- README.md | 4 ++-- examples/doc-scan/pom.xml | 2 +- pom.xml | 2 +- yoti-sdk-api/pom.xml | 2 +- .../com/yoti/api/client/spi/remote/call/YotiConstants.java | 2 +- yoti-sdk-auth/pom.xml | 2 +- yoti-sdk-parent/pom.xml | 2 +- yoti-sdk-sandbox/pom.xml | 2 +- yoti-sdk-spring-boot-auto-config/README.md | 4 ++-- yoti-sdk-spring-boot-auto-config/pom.xml | 2 +- yoti-sdk-spring-boot-example/README.md | 2 +- yoti-sdk-spring-boot-example/pom.xml | 2 +- yoti-sdk-spring-security/README.md | 4 ++-- yoti-sdk-spring-security/pom.xml | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 7255443c..42e46c93 100644 --- a/README.md +++ b/README.md @@ -101,13 +101,13 @@ If you are using Maven, you need to add the following dependency: com.yoti yoti-sdk-api - 4.1.0 + 4.2.0-SNAPSHOT ``` If you are using Gradle, here is the dependency to add: -`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '4.1.0'` +`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '4.2.0-SNAPSHOT'` You will find all classes packaged under `com.yoti.api` diff --git a/examples/doc-scan/pom.xml b/examples/doc-scan/pom.xml index 53457e2e..afd62e17 100644 --- a/examples/doc-scan/pom.xml +++ b/examples/doc-scan/pom.xml @@ -53,7 +53,7 @@ com.yoti yoti-sdk-api - 4.1.0 + 4.2.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 54bda0af..7d5a0493 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk pom - 4.1.0 + 4.2.0-SNAPSHOT Yoti SDK Java SDK for simple integration with the Yoti platform https://github.com/getyoti/yoti-java-sdk diff --git a/yoti-sdk-api/pom.xml b/yoti-sdk-api/pom.xml index da724a70..fbc75b22 100644 --- a/yoti-sdk-api/pom.xml +++ b/yoti-sdk-api/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 4.1.0 + 4.2.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java index c5b45388..68589dc8 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/YotiConstants.java @@ -30,7 +30,7 @@ private YotiConstants() {} public static final String CONTENT_TYPE_JPEG = "image/jpeg"; public static final String JAVA = "Java"; - public static final String SDK_VERSION = JAVA + "-4.1.0"; + public static final String SDK_VERSION = JAVA + "-4.2.0-SNAPSHOT"; public static final String SIGNATURE_ALGORITHM = "SHA256withRSA"; public static final String ASYMMETRIC_CIPHER = "RSA/NONE/PKCS1Padding"; public static final String SYMMETRIC_CIPHER = "AES/CBC/PKCS7Padding"; diff --git a/yoti-sdk-auth/pom.xml b/yoti-sdk-auth/pom.xml index 50d43e11..cc7cb859 100644 --- a/yoti-sdk-auth/pom.xml +++ b/yoti-sdk-auth/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 4.1.0 + 4.2.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-parent/pom.xml b/yoti-sdk-parent/pom.xml index 9c9ca469..d8716a0f 100644 --- a/yoti-sdk-parent/pom.xml +++ b/yoti-sdk-parent/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk-parent pom - 4.1.0 + 4.2.0-SNAPSHOT Yoti SDK Parent Pom Parent pom for the Java SDK projects https://github.com/getyoti/yoti-java-sdk diff --git a/yoti-sdk-sandbox/pom.xml b/yoti-sdk-sandbox/pom.xml index fbde6a0a..7332656e 100644 --- a/yoti-sdk-sandbox/pom.xml +++ b/yoti-sdk-sandbox/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 4.1.0 + 4.2.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-spring-boot-auto-config/README.md b/yoti-sdk-spring-boot-auto-config/README.md index 64838e6d..cb6f0009 100644 --- a/yoti-sdk-spring-boot-auto-config/README.md +++ b/yoti-sdk-spring-boot-auto-config/README.md @@ -18,7 +18,7 @@ If you are using Maven, you need to add the following dependencies: com.yoti yoti-sdk-spring-boot-auto-config - 4.1.0 + 4.2.0-SNAPSHOT ``` @@ -26,7 +26,7 @@ If you are using Maven, you need to add the following dependencies: If you are using Gradle, here is the dependency to add: ``` -compile group: 'com.yoti', name: 'yoti-sdk-spring-boot-auto-config', version: '4.1.0' +compile group: 'com.yoti', name: 'yoti-sdk-spring-boot-auto-config', version: '4.2.0-SNAPSHOT' ``` diff --git a/yoti-sdk-spring-boot-auto-config/pom.xml b/yoti-sdk-spring-boot-auto-config/pom.xml index 0a613069..3efc5984 100644 --- a/yoti-sdk-spring-boot-auto-config/pom.xml +++ b/yoti-sdk-spring-boot-auto-config/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 4.1.0 + 4.2.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-spring-boot-example/README.md b/yoti-sdk-spring-boot-example/README.md index 43ba6536..32a659a4 100644 --- a/yoti-sdk-spring-boot-example/README.md +++ b/yoti-sdk-spring-boot-example/README.md @@ -17,7 +17,7 @@ Note that: com.yoti yoti-sdk-api - 4.1.0 + 4.2.0-SNAPSHOT ``` diff --git a/yoti-sdk-spring-boot-example/pom.xml b/yoti-sdk-spring-boot-example/pom.xml index 01ad32c8..6eec2b26 100644 --- a/yoti-sdk-spring-boot-example/pom.xml +++ b/yoti-sdk-spring-boot-example/pom.xml @@ -6,7 +6,7 @@ com.yoti yoti-sdk-spring-boot-example Yoti Spring Boot Example - 4.1.0 + 4.2.0-SNAPSHOT org.springframework.boot diff --git a/yoti-sdk-spring-security/README.md b/yoti-sdk-spring-security/README.md index 2edc51ad..b6ce2470 100644 --- a/yoti-sdk-spring-security/README.md +++ b/yoti-sdk-spring-security/README.md @@ -25,14 +25,14 @@ If you are using Maven, you need to add the following dependencies: com.yoti yoti-sdk-spring-security - 4.1.0 + 4.2.0-SNAPSHOT ``` If you are using Gradle, here is the dependency to add: ``` -compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '4.1.0' +compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '4.2.0-SNAPSHOT' ``` ### Provide a `YotiClient` instance diff --git a/yoti-sdk-spring-security/pom.xml b/yoti-sdk-spring-security/pom.xml index 4264b897..8dc0e1e8 100644 --- a/yoti-sdk-spring-security/pom.xml +++ b/yoti-sdk-spring-security/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 4.1.0 + 4.2.0-SNAPSHOT ../yoti-sdk-parent From bc9db69c1b560049eadd05a612fcc4c59ba4ab2f Mon Sep 17 00:00:00 2001 From: Alex Burt Date: Tue, 23 Jun 2026 10:19:22 +0100 Subject: [PATCH 2/2] SDK-2815: Add support for Digital IDs in IDV --- .../filters/AllowedProviderPayload.java | 54 +++++++++++++ .../create/filters/DocumentFilter.java | 31 +++++++- .../filters/DocumentRestrictionsFilter.java | 45 ++++++++++- .../filters/OrthogonalRestrictionsFilter.java | 46 ++++++++++- .../retrieve/DigitalIdShareErrorResponse.java | 24 ++++++ .../retrieve/DigitalIdShareResponse.java | 77 +++++++++++++++++++ .../session/retrieve/GetSessionResult.java | 12 +++ .../retrieve/IdDocumentResourceResponse.java | 12 +++ .../document/SupportedDocumentResponse.java | 14 ++++ .../api/client/docs/DocScanServiceTest.java | 26 +++++++ .../filters/AllowedProviderPayloadTest.java | 19 +++++ .../DocumentRestrictionsFilterTest.java | 55 +++++++++++++ .../OrthogonalRestrictionsFilterTest.java | 51 ++++++++++++ .../resources/GetSessionResultExample.json | 31 +++++++- 14 files changed, 488 insertions(+), 9 deletions(-) create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayload.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareErrorResponse.java create mode 100644 yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareResponse.java create mode 100644 yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayloadTest.java diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayload.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayload.java new file mode 100644 index 00000000..7c6a7bf0 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayload.java @@ -0,0 +1,54 @@ +package com.yoti.api.client.docs.session.create.filters; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Identifies a digital ID provider (e.g. {@code DIGILOCKER}) that is allowed + * to satisfy a {@link DocumentFilter}. + */ +public class AllowedProviderPayload { + + @JsonProperty("name") + private final String name; + + private AllowedProviderPayload(String name) { + this.name = name; + } + + public static AllowedProviderPayload.Builder builder() { + return new AllowedProviderPayload.Builder(); + } + + /** + * The name of the allowed digital ID provider + * + * @return the provider name + */ + public String getName() { + return name; + } + + public static class Builder { + + private String name; + + private Builder() {} + + /** + * Sets the name of the digital ID provider + * + * @param name the provider name + * @return the builder + */ + public Builder withName(String name) { + this.name = name; + return this; + } + + public AllowedProviderPayload build() { + return new AllowedProviderPayload(name); + } + + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentFilter.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentFilter.java index 43403ef3..dc7f8a3e 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentFilter.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentFilter.java @@ -1,5 +1,7 @@ package com.yoti.api.client.docs.session.create.filters; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonProperty; /** @@ -17,10 +19,19 @@ public abstract class DocumentFilter { @JsonProperty("allow_expired_documents") private final Boolean allowExpiredDocuments; - DocumentFilter(String type, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments) { + @JsonProperty("allow_digital_ids") + private final Boolean allowDigitalIds; + + @JsonProperty("allowed_providers") + private final List allowedProviders; + + DocumentFilter(String type, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments, + Boolean allowDigitalIds, List allowedProviders) { this.type = type; this.allowNonLatinDocuments = allowNonLatinDocuments; this.allowExpiredDocuments = allowExpiredDocuments; + this.allowDigitalIds = allowDigitalIds; + this.allowedProviders = allowedProviders; } /** @@ -50,4 +61,22 @@ public Boolean getAllowExpiredDocuments() { return allowExpiredDocuments; } + /** + * Whether to allow digital IDs to satisfy the filter + * + * @return boolean flag + */ + public Boolean getAllowDigitalIds() { + return allowDigitalIds; + } + + /** + * The list of digital ID providers that are allowed to satisfy the filter + * + * @return the allowed providers + */ + public List getAllowedProviders() { + return allowedProviders; + } + } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java index 30fcc216..731eaa8d 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilter.java @@ -17,8 +17,9 @@ public class DocumentRestrictionsFilter extends DocumentFilter { @JsonProperty("documents") private final List documents; - private DocumentRestrictionsFilter(String inclusion, List documents, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments) { - super(DocScanConstants.DOCUMENT_RESTRICTIONS, allowNonLatinDocuments, allowExpiredDocuments); + private DocumentRestrictionsFilter(String inclusion, List documents, Boolean allowNonLatinDocuments, + Boolean allowExpiredDocuments, Boolean allowDigitalIds, List allowedProviders) { + super(DocScanConstants.DOCUMENT_RESTRICTIONS, allowNonLatinDocuments, allowExpiredDocuments, allowDigitalIds, allowedProviders); this.inclusion = inclusion; this.documents = documents; } @@ -41,6 +42,8 @@ public static class Builder { private final List documents; private Boolean allowNonLatinDocuments; private Boolean allowExpiredDocuments; + private Boolean allowDigitalIds; + private List allowedProviders; private Builder() { this.documents = new ArrayList<>(); @@ -111,9 +114,45 @@ public Builder withAllowExpiredDocuments(boolean allowExpiredDocuments) { return this; } + /** + * Sets the flag to allow/disallow digital IDs + * + * @param allowDigitalIds the flag + * @return the builder + */ + public Builder withAllowDigitalIds(boolean allowDigitalIds) { + this.allowDigitalIds = allowDigitalIds; + return this; + } + + /** + * Sets the list of digital ID providers that are allowed to satisfy the filter + * + * @param allowedProviders the allowed providers + * @return the builder + */ + public Builder withAllowedProviders(List allowedProviders) { + this.allowedProviders = allowedProviders; + return this; + } + + /** + * Adds a digital ID provider, by name, to the list of allowed providers + * + * @param name the provider name + * @return the builder + */ + public Builder withAllowedProvider(String name) { + if (this.allowedProviders == null) { + this.allowedProviders = new ArrayList<>(); + } + this.allowedProviders.add(AllowedProviderPayload.builder().withName(name).build()); + return this; + } + public DocumentRestrictionsFilter build() { notNullOrEmpty(inclusion, "inclusion"); - return new DocumentRestrictionsFilter(inclusion, documents, allowNonLatinDocuments, allowExpiredDocuments); + return new DocumentRestrictionsFilter(inclusion, documents, allowNonLatinDocuments, allowExpiredDocuments, allowDigitalIds, allowedProviders); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java index bba774e5..dfcf373e 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilter.java @@ -1,5 +1,6 @@ package com.yoti.api.client.docs.session.create.filters; +import java.util.ArrayList; import java.util.List; import com.yoti.api.client.docs.DocScanConstants; @@ -14,8 +15,9 @@ public class OrthogonalRestrictionsFilter extends DocumentFilter { @JsonProperty("type_restriction") private final TypeRestriction typeRestriction; - private OrthogonalRestrictionsFilter(CountryRestriction countryRestriction, TypeRestriction typeRestriction, Boolean allowNonLatinDocuments, Boolean allowExpiredDocuments) { - super(DocScanConstants.ORTHOGONAL_RESTRICTIONS, allowNonLatinDocuments, allowExpiredDocuments); + private OrthogonalRestrictionsFilter(CountryRestriction countryRestriction, TypeRestriction typeRestriction, Boolean allowNonLatinDocuments, + Boolean allowExpiredDocuments, Boolean allowDigitalIds, List allowedProviders) { + super(DocScanConstants.ORTHOGONAL_RESTRICTIONS, allowNonLatinDocuments, allowExpiredDocuments, allowDigitalIds, allowedProviders); this.countryRestriction = countryRestriction; this.typeRestriction = typeRestriction; } @@ -38,6 +40,8 @@ public static class Builder { private TypeRestriction typeRestriction; private Boolean allowNonLatinDocuments; private Boolean allowExpiredDocuments; + private Boolean allowDigitalIds; + private List allowedProviders; private Builder() {} @@ -107,8 +111,44 @@ public Builder withAllowExpiredDocuments(boolean allowExpiredDocuments) { return this; } + /** + * Sets the flag to allow/disallow digital IDs + * + * @param allowDigitalIds the flag + * @return the builder + */ + public Builder withAllowDigitalIds(boolean allowDigitalIds) { + this.allowDigitalIds = allowDigitalIds; + return this; + } + + /** + * Sets the list of digital ID providers that are allowed to satisfy the filter + * + * @param allowedProviders the allowed providers + * @return the builder + */ + public Builder withAllowedProviders(List allowedProviders) { + this.allowedProviders = allowedProviders; + return this; + } + + /** + * Adds a digital ID provider, by name, to the list of allowed providers + * + * @param name the provider name + * @return the builder + */ + public Builder withAllowedProvider(String name) { + if (this.allowedProviders == null) { + this.allowedProviders = new ArrayList<>(); + } + this.allowedProviders.add(AllowedProviderPayload.builder().withName(name).build()); + return this; + } + public OrthogonalRestrictionsFilter build() { - return new OrthogonalRestrictionsFilter(countryRestriction, typeRestriction, allowNonLatinDocuments, allowExpiredDocuments); + return new OrthogonalRestrictionsFilter(countryRestriction, typeRestriction, allowNonLatinDocuments, allowExpiredDocuments, allowDigitalIds, allowedProviders); } } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareErrorResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareErrorResponse.java new file mode 100644 index 00000000..ed3d9013 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareErrorResponse.java @@ -0,0 +1,24 @@ +package com.yoti.api.client.docs.session.retrieve; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Describes the error that occurred when a digital ID share was not completed successfully. + */ +public class DigitalIdShareErrorResponse { + + @JsonProperty("code") + private String code; + + @JsonProperty("description") + private String description; + + public String getCode() { + return code; + } + + public String getDescription() { + return description; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareResponse.java new file mode 100644 index 00000000..4218b756 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/DigitalIdShareResponse.java @@ -0,0 +1,77 @@ +package com.yoti.api.client.docs.session.retrieve; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents a digital ID share that was performed during a session. A share that + * was not completed successfully will have an {@link #getError() error}. + */ +public class DigitalIdShareResponse { + + @JsonProperty("id") + private String id; + + @JsonProperty("document_type") + private String documentType; + + @JsonProperty("issuing_country") + private String issuingCountry; + + @JsonProperty("provider") + private String provider; + + @JsonProperty("created_at") + private String createdAt; + + @JsonProperty("last_updated") + private String lastUpdated; + + @JsonProperty("resource_id") + private String resourceId; + + @JsonProperty("error") + private DigitalIdShareErrorResponse error; + + public String getId() { + return id; + } + + public String getDocumentType() { + return documentType; + } + + public String getIssuingCountry() { + return issuingCountry; + } + + public String getProvider() { + return provider; + } + + public String getCreatedAt() { + return createdAt; + } + + public String getLastUpdated() { + return lastUpdated; + } + + /** + * The id of the resource linked to the share + * + * @return the resource id + */ + public String getResourceId() { + return resourceId; + } + + /** + * The error that occurred if the share was not completed successfully, otherwise {@code null} + * + * @return the error, may be {@code null} + */ + public DigitalIdShareErrorResponse getError() { + return error; + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java index 00e81162..5945246e 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/GetSessionResult.java @@ -50,6 +50,9 @@ public class GetSessionResult { @JsonProperty("import_token") private ImportTokenResponse importToken; + @JsonProperty("digital_id_shares") + private List digitalIdShares; + public long getClientSessionTokenTtl() { return clientSessionTokenTtl; } @@ -102,6 +105,15 @@ public ImportTokenResponse getImportToken() { return importToken; } + /** + * The digital ID shares that were performed during the session + * + * @return the digital ID shares + */ + public List getDigitalIdShares() { + return digitalIdShares; + } + public ResourceContainer getResourcesForCheck(String checkId) { CheckResponse checkResponse = this.checks.stream() .filter(check -> check.getId().equals(checkId)) diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdDocumentResourceResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdDocumentResourceResponse.java index 83359d8a..193ec9e5 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdDocumentResourceResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/IdDocumentResourceResponse.java @@ -24,6 +24,9 @@ public class IdDocumentResourceResponse extends ResourceResponse { @JsonProperty("expanded_document_fields") private ExpandedDocumentFieldsResponse expandedDocumentFields; + @JsonProperty("provider") + private String provider; + public String getDocumentType() { return documentType; } @@ -52,4 +55,13 @@ public ExpandedDocumentFieldsResponse getExpandedDocumentFields() { return expandedDocumentFields; } + /** + * The digital ID provider that the document was sourced from. Only present for a digital ID. + * + * @return the provider, may be {@code null} + */ + public String getProvider() { + return provider; + } + } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/document/SupportedDocumentResponse.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/document/SupportedDocumentResponse.java index 50542211..5adc96c9 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/document/SupportedDocumentResponse.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/docs/session/retrieve/configuration/capture/document/SupportedDocumentResponse.java @@ -1,5 +1,7 @@ package com.yoti.api.client.docs.session.retrieve.configuration.capture.document; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonProperty; public class SupportedDocumentResponse { @@ -10,6 +12,9 @@ public class SupportedDocumentResponse { @JsonProperty("is_strictly_latin") private Boolean isStrictlyLatin; + @JsonProperty("providers") + private List providers; + /** * Returns the type of document that is supported. * @@ -28,4 +33,13 @@ public Boolean getStrictlyLatin() { return isStrictlyLatin; } + /** + * Returns the digital ID providers supported for this document type. + * + * @return the providers + */ + public List getProviders() { + return providers; + } + } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java index 6840034b..f889cbe2 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/DocScanServiceTest.java @@ -41,7 +41,9 @@ import com.yoti.api.client.docs.session.retrieve.AuthenticityCheckResponse; import com.yoti.api.client.docs.session.retrieve.CheckResponse; import com.yoti.api.client.docs.session.retrieve.CreateFaceCaptureResourceResponse; +import com.yoti.api.client.docs.session.retrieve.DigitalIdShareResponse; import com.yoti.api.client.docs.session.retrieve.GetSessionResult; +import com.yoti.api.client.docs.session.retrieve.IdDocumentResourceResponse; import com.yoti.api.client.docs.session.retrieve.LivenessResourceResponse; import com.yoti.api.client.docs.session.retrieve.ZoomLivenessResourceResponse; import com.yoti.api.client.docs.session.retrieve.configuration.SessionConfigurationResponse; @@ -620,6 +622,30 @@ public void shouldNotFailForUnknownChecks() throws Exception { assertThat(livenessResourceResponse.get(1).getId(), is("someZoomId")); } + @Test + public void shouldDeserializeDigitalIdShares() throws Exception { + InputStream is = getClass().getResourceAsStream("/GetSessionResultExample.json"); + GetSessionResult result = MAPPER.readValue(is, GetSessionResult.class); + + List idDocuments = result.getResources().getIdDocuments(); + assertThat(idDocuments, hasSize(1)); + assertThat(idDocuments.get(0).getProvider(), is("DIGILOCKER")); + + List shares = result.getDigitalIdShares(); + assertThat(shares, hasSize(2)); + + assertThat(shares.get(0).getId(), is("someShareId")); + assertThat(shares.get(0).getDocumentType(), is("DIGITAL_AADHAAR")); + assertThat(shares.get(0).getIssuingCountry(), is("IND")); + assertThat(shares.get(0).getProvider(), is("DIGILOCKER")); + assertThat(shares.get(0).getResourceId(), is("someIdDocumentId")); + assertThat(shares.get(0).getError(), is(nullValue())); + + assertThat(shares.get(1).getId(), is("someFailedShareId")); + assertThat(shares.get(1).getError().getCode(), is("SOME_ERROR_CODE")); + assertThat(shares.get(1).getError().getDescription(), is("the share could not be completed")); + } + @Test public void putIbvInstructions_shouldThrowExceptionWhenAuthStrategyIsNull() { IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> docScanService.putIbvInstructions(null, SOME_SESSION_ID, instructionsMock)); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayloadTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayloadTest.java new file mode 100644 index 00000000..f2c333f0 --- /dev/null +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/AllowedProviderPayloadTest.java @@ -0,0 +1,19 @@ +package com.yoti.api.client.docs.session.create.filters; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; + +public class AllowedProviderPayloadTest { + + @Test + public void shouldBuildWithName() { + AllowedProviderPayload result = AllowedProviderPayload.builder() + .withName("DIGILOCKER") + .build(); + + assertThat(result.getName(), is("DIGILOCKER")); + } + +} diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilterTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilterTest.java index fb1d2efe..38b41182 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilterTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/DocumentRestrictionsFilterTest.java @@ -126,4 +126,59 @@ public void shouldSetNullForAllowExpiredDocumentsFlagWhenNotProvidedExplicitly() assertThat(result.getAllowExpiredDocuments(), nullValue()); } + @Test + public void shouldSetAllowDigitalIdsFlag() { + DocumentRestrictionsFilter result = DocumentRestrictionsFilter.builder() + .forWhitelist() + .withAllowDigitalIds(true) + .build(); + + assertThat(result.getAllowDigitalIds(), is(true)); + } + + @Test + public void shouldSetNullForAllowDigitalIdsFlagWhenNotProvidedExplicitly() { + DocumentRestrictionsFilter result = DocumentRestrictionsFilter.builder() + .forWhitelist() + .build(); + + assertThat(result.getAllowDigitalIds(), nullValue()); + } + + @Test + public void shouldAddAllowedProvidersByName() { + DocumentRestrictionsFilter result = DocumentRestrictionsFilter.builder() + .forWhitelist() + .withAllowedProvider("DIGILOCKER") + .withAllowedProvider("EPHIL_ID_QR") + .build(); + + assertThat(result.getAllowedProviders(), hasSize(2)); + assertThat(result.getAllowedProviders().get(0).getName(), is("DIGILOCKER")); + assertThat(result.getAllowedProviders().get(1).getName(), is("EPHIL_ID_QR")); + } + + @Test + public void shouldSetAllowedProvidersList() { + List providers = Arrays.asList( + AllowedProviderPayload.builder().withName("DIGILOCKER").build()); + + DocumentRestrictionsFilter result = DocumentRestrictionsFilter.builder() + .forWhitelist() + .withAllowedProviders(providers) + .build(); + + assertThat(result.getAllowedProviders(), hasSize(1)); + assertThat(result.getAllowedProviders().get(0).getName(), is("DIGILOCKER")); + } + + @Test + public void shouldSetNullForAllowedProvidersWhenNotProvidedExplicitly() { + DocumentRestrictionsFilter result = DocumentRestrictionsFilter.builder() + .forWhitelist() + .build(); + + assertThat(result.getAllowedProviders(), nullValue()); + } + } diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilterTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilterTest.java index d06a34cd..bcc45573 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilterTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/docs/session/create/filters/OrthogonalRestrictionsFilterTest.java @@ -2,6 +2,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; @@ -113,4 +114,54 @@ public void shouldSetNullForAllowExpiredDocumentsFlagWhenNotProvidedExplicitly() assertThat(result.getAllowExpiredDocuments(), nullValue()); } + @Test + public void shouldSetAllowDigitalIdsFlag() { + OrthogonalRestrictionsFilter result = OrthogonalRestrictionsFilter.builder() + .withAllowDigitalIds(true) + .build(); + + assertThat(result.getAllowDigitalIds(), is(true)); + } + + @Test + public void shouldSetNullForAllowDigitalIdsFlagWhenNotProvidedExplicitly() { + OrthogonalRestrictionsFilter result = OrthogonalRestrictionsFilter.builder() + .build(); + + assertThat(result.getAllowDigitalIds(), nullValue()); + } + + @Test + public void shouldAddAllowedProvidersByName() { + OrthogonalRestrictionsFilter result = OrthogonalRestrictionsFilter.builder() + .withAllowedProvider("DIGILOCKER") + .withAllowedProvider("EPHIL_ID_QR") + .build(); + + assertThat(result.getAllowedProviders(), hasSize(2)); + assertThat(result.getAllowedProviders().get(0).getName(), is("DIGILOCKER")); + assertThat(result.getAllowedProviders().get(1).getName(), is("EPHIL_ID_QR")); + } + + @Test + public void shouldSetAllowedProvidersList() { + List providers = Arrays.asList( + AllowedProviderPayload.builder().withName("DIGILOCKER").build()); + + OrthogonalRestrictionsFilter result = OrthogonalRestrictionsFilter.builder() + .withAllowedProviders(providers) + .build(); + + assertThat(result.getAllowedProviders(), hasSize(1)); + assertThat(result.getAllowedProviders().get(0).getName(), is("DIGILOCKER")); + } + + @Test + public void shouldSetNullForAllowedProvidersWhenNotProvidedExplicitly() { + OrthogonalRestrictionsFilter result = OrthogonalRestrictionsFilter.builder() + .build(); + + assertThat(result.getAllowedProviders(), nullValue()); + } + } diff --git a/yoti-sdk-api/src/test/resources/GetSessionResultExample.json b/yoti-sdk-api/src/test/resources/GetSessionResultExample.json index eed8e55c..365d4109 100644 --- a/yoti-sdk-api/src/test/resources/GetSessionResultExample.json +++ b/yoti-sdk-api/src/test/resources/GetSessionResultExample.json @@ -19,6 +19,33 @@ "liveness_type": "ZOOM", "id": "someZoomId" } + ], + "id_documents": [ + { + "id": "someIdDocumentId", + "document_type": "DIGITAL_AADHAAR", + "issuing_country": "IND", + "provider": "DIGILOCKER" + } ] - } -} \ No newline at end of file + }, + "digital_id_shares": [ + { + "id": "someShareId", + "document_type": "DIGITAL_AADHAAR", + "issuing_country": "IND", + "provider": "DIGILOCKER", + "created_at": "2026-01-01T00:00:00.000Z", + "last_updated": "2026-01-02T00:00:00.000Z", + "resource_id": "someIdDocumentId" + }, + { + "id": "someFailedShareId", + "provider": "DIGILOCKER", + "error": { + "code": "SOME_ERROR_CODE", + "description": "the share could not be completed" + } + } + ] +}