diff --git a/README.md b/README.md index c890038cf..64702c2a7 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 - 3.11.0 + 3.12.0-SNAPSHOT ``` If you are using Gradle, here is the dependency to add: -`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '3.11.0'` +`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '3.12.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 0b7e14c88..43015615b 100644 --- a/examples/doc-scan/pom.xml +++ b/examples/doc-scan/pom.xml @@ -53,7 +53,7 @@ com.yoti yoti-sdk-api - 3.11.0 + 3.12.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index d285d9d6e..979f21534 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk pom - 3.11.0 + 3.12.0-SNAPSHOT Yoti SDK Java SDK for simple integration with the Yoti platform https://github.com/getyoti/yoti-java-sdk @@ -25,11 +25,12 @@ 3.8.5 - 3.1.1 + 3.1.4 1.2.1 - 4.8.3.1 - 3.4.1 - 1.7.0 + + 4.8.6.6 + 3.5.0 + 1.10.0 diff --git a/yoti-sdk-api/pom.xml b/yoti-sdk-api/pom.xml index eba17a205..ab4e5cf7c 100644 --- a/yoti-sdk-api/pom.xml +++ b/yoti-sdk-api/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 3.11.0 + 3.12.0-SNAPSHOT ../yoti-sdk-parent @@ -19,7 +19,7 @@ org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on com.fasterxml.jackson.core diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java index 2aa6f5c5c..1690a9835 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/DigitalIdentityClient.java @@ -4,6 +4,8 @@ import java.security.KeyPair; import java.security.Security; +import com.yoti.api.client.identity.MatchRequest; +import com.yoti.api.client.identity.MatchResult; import com.yoti.api.client.identity.ShareSession; import com.yoti.api.client.identity.ShareSessionQrCode; import com.yoti.api.client.identity.ShareSessionRequest; @@ -54,6 +56,10 @@ public Receipt fetchShareReceipt(String receiptId) throws DigitalIdentityExcepti return identityService.fetchShareReceipt(sdkId, keyPair, receiptId); } + public MatchResult fetchMatch(MatchRequest request) throws DigitalIdentityException { + return identityService.fetchMatch(sdkId, keyPair, request); + } + private KeyPair loadKeyPair(KeyPairSource keyPairSource) throws InitialisationException { try { return keyPairSource.getFromStream(new KeyStreamVisitor()); diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchNotification.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchNotification.java new file mode 100644 index 000000000..26cfe756d --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchNotification.java @@ -0,0 +1,107 @@ +package com.yoti.api.client.identity; + +import static com.yoti.api.client.spi.remote.call.HttpMethod.SUPPORTED_HTTP_METHODS; + +import java.net.URI; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import com.yoti.validation.Validation; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public final class MatchNotification { + + @JsonProperty(Property.URL) + private final String endpoint; + + @JsonProperty(Property.METHOD) + private final String method; + + @JsonProperty(Property.VERIFY_TLS) + private final boolean verifyTls; + + @JsonProperty(Property.HEADERS) + private final Map headers; + + private MatchNotification(Builder builder) { + endpoint = builder.endpoint; + method = builder.method; + verifyTls = builder.verifyTls; + headers = builder.headers; + } + + public String getEndpoint() { + return endpoint; + } + + public String getMethod() { + return method; + } + + public boolean isVerifyTls() { + return verifyTls; + } + + public Map getHeaders() { + return headers; + } + + public static Builder forUrl(URI uri) { + return new Builder(uri); + } + + public static final class Builder { + + private final String endpoint; + private final Map headers; + + private String method; + private boolean verifyTls; + + private Builder(URI uri) { + Validation.notNull(uri, Property.URL); + + endpoint = uri.toString(); + headers = new HashMap<>(); + } + + public Builder withMethod(String method) { + Validation.withinList(method.toUpperCase(Locale.ROOT), SUPPORTED_HTTP_METHODS); + + this.method = method; + return this; + } + + public Builder withVerifyTls(boolean verifyTls) { + this.verifyTls = verifyTls; + return this; + } + + public Builder withHeaders(Map headers) { + this.headers.putAll(headers); + return this; + } + + public Builder withHeader(String key, String value) { + headers.put(key, value); + return this; + } + + public MatchNotification build() { + return new MatchNotification(this); + } + + } + + private static final class Property { + + private static final String URL = "url"; + private static final String METHOD = "method"; + private static final String VERIFY_TLS = "verifyTls"; + private static final String HEADERS = "headers"; + + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchRequest.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchRequest.java new file mode 100644 index 000000000..6dc333ef7 --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchRequest.java @@ -0,0 +1,62 @@ +package com.yoti.api.client.identity; + +import com.yoti.validation.Validation; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public final class MatchRequest { + + @JsonProperty(Property.VALUE) + private final String value; + + @JsonProperty(Property.NOTIFICATION) + private final MatchNotification notification; + + private MatchRequest(Builder builder) { + value = builder.value; + notification = builder.notification; + } + + public String getValue() { + return value; + } + + public MatchNotification getNotification() { + return notification; + } + + public static Builder builder(String value) { + return new Builder(value); + } + + public static final class Builder { + + private final String value; + + private MatchNotification notification; + + private Builder(String value) { + Validation.notNullOrEmpty(value, Property.VALUE); + + this.value = value; + } + + public Builder withNotification(MatchNotification notification) { + this.notification = notification; + return this; + } + + public MatchRequest build() { + return new MatchRequest(this); + } + + } + + private static final class Property { + + private static final String VALUE = "value"; + private static final String NOTIFICATION = "notification"; + + } + +} diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchResult.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchResult.java new file mode 100644 index 000000000..511b1ec3d --- /dev/null +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/identity/MatchResult.java @@ -0,0 +1,36 @@ +package com.yoti.api.client.identity; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public final class MatchResult { + + @JsonProperty(Property.ID) + private String id; + + @JsonProperty(Property.RESULT) + private String result; + + public String getId() { + return id; + } + + public String getResult() { + return result; + } + + public void setId(String id) { + this.id = id; + } + + public void setResult(String result) { + this.result = result; + } + + private static final class Property { + + private static final String ID = "id"; + private static final String RESULT = "result"; + + } + +} 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 5dc301b81..6a001832c 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 @@ -29,7 +29,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 + "-3.11.0"; + public static final String SDK_VERSION = JAVA + "-3.12.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-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java index 6b322cdf2..15ec5eaa6 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/factory/UnsignedPathFactory.java @@ -15,6 +15,9 @@ public class UnsignedPathFactory { private static final String IDENTITY_SESSION_RECEIPT_RETRIEVAL = "/v2/receipts/%s"; private static final String IDENTITY_SESSION_RECEIPT_KEY_RETRIEVAL = "/v2/wrapped-item-keys/%s"; + // Match + private static final String DIGITAL_ID_MATCH = "/v1/matches"; + // Share V1 private static final String PROFILE = "/profile/%s?appId=%s"; private static final String QR_CODE = "/qrcodes/apps/%s"; @@ -66,6 +69,10 @@ private static String base64ToBase64url(String value) { return value.replace('+', '-').replace('/', '_'); } + public String createIdentityMatchPath() { + return DIGITAL_ID_MATCH; + } + public String createProfilePath(String appId, String connectToken) { return format(PROFILE, connectToken, appId); } diff --git a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java index f2d9d6421..b79178c00 100644 --- a/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java +++ b/yoti-sdk-api/src/main/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityService.java @@ -16,6 +16,8 @@ import java.security.KeyPair; import java.util.Optional; +import com.yoti.api.client.identity.MatchRequest; +import com.yoti.api.client.identity.MatchResult; import com.yoti.api.client.identity.ShareSession; import com.yoti.api.client.identity.ShareSessionQrCode; import com.yoti.api.client.identity.ShareSessionRequest; @@ -189,6 +191,30 @@ private ReceiptItemKey fetchShareReceiptKey(String sdkId, KeyPair keyPair, Wrapp } } + public MatchResult fetchMatch(String sdkId, KeyPair keyPair, MatchRequest matchRequest) + throws DigitalIdentityException { + Validation.notNullOrEmpty(sdkId, "SDK ID"); + Validation.notNull(keyPair, "Application Key Pair"); + Validation.notNull(matchRequest, "DID Match request"); + + String path = pathFactory.createIdentityMatchPath(); + + LOG.debug("Requesting digital ID Match for SDK ID '{}' at '{}'", sdkId, path); + + try { + byte[] payload = ResourceMapper.writeValueAsString(matchRequest); + return createSignedRequest(sdkId, keyPair, path, HTTP_POST, payload).execute(MatchResult.class); + } catch (IOException ex) { + throw new DigitalIdentityException("Error while parsing the DID Match request", ex); + } catch (URISyntaxException ex) { + throw new DigitalIdentityException("Error while building the DID Match request", ex); + } catch (GeneralSecurityException ex) { + throw new DigitalIdentityException("Error while signing the DID Match request", ex); + } catch (ResourceException ex) { + throw new DigitalIdentityException("Error while executing the DID Match request", ex); + } + } + SignedRequest createSignedRequest(String sdkId, KeyPair keyPair, String path) throws GeneralSecurityException, UnsupportedEncodingException, URISyntaxException { return createSignedRequest(sdkId, keyPair, path, HTTP_GET, null); diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java index eaeb6abe1..4745cfa7f 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/DigitalIdentityClientTest.java @@ -13,6 +13,7 @@ import java.io.InputStream; import java.security.KeyPair; +import com.yoti.api.client.identity.MatchRequest; import com.yoti.api.client.identity.ShareSessionRequest; import com.yoti.api.client.spi.remote.KeyStreamVisitor; import com.yoti.api.client.spi.remote.call.identity.DigitalIdentityException; @@ -37,6 +38,7 @@ public class DigitalIdentityClientTest { @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPair; @Mock DigitalIdentityService identityService; @Mock ShareSessionRequest shareSessionRequest; + @Mock MatchRequest matchRequest; private KeyPairSource validKeyPairSource; @@ -224,6 +226,28 @@ public void client_FetchShareReceiptException_DigitalIdentityException() throws assertThat(ex.getMessage(), equalTo(exMessage)); } + @Test + public void client_FetchDigitalIdMatchException_DigitalIdentityException() throws IOException { + when(keyPairSource.getFromStream(any(KeyStreamVisitor.class))).thenReturn(keyPair); + + DigitalIdentityClient identityClient = new DigitalIdentityClient( + AN_SDK_ID, + keyPairSource, + identityService + ); + + String exMessage = "Fetch digital identity match error"; + when(identityService.fetchMatch(AN_SDK_ID, keyPair, matchRequest)) + .thenThrow(new DigitalIdentityException(exMessage)); + + DigitalIdentityException ex = assertThrows( + DigitalIdentityException.class, + () -> identityClient.fetchMatch(matchRequest) + ); + + assertThat(ex.getMessage(), equalTo(exMessage)); + } + private static class KeyPairSourceTest implements KeyPairSource { private final String keyPair; diff --git a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java index dd458dfbd..8e3cacdbf 100644 --- a/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java +++ b/yoti-sdk-api/src/test/java/com/yoti/api/client/spi/remote/call/identity/DigitalIdentityServiceTest.java @@ -14,6 +14,8 @@ import java.security.GeneralSecurityException; import java.security.KeyPair; +import com.yoti.api.client.identity.MatchRequest; +import com.yoti.api.client.identity.MatchResult; import com.yoti.api.client.identity.ShareSession; import com.yoti.api.client.identity.ShareSessionRequest; import com.yoti.api.client.spi.remote.call.SignedRequest; @@ -35,6 +37,7 @@ public class DigitalIdentityServiceTest { private static final String SESSION_ID = "aSessionId"; private static final String QR_CODE_ID = "aQrCodeId"; private static final String SESSION_CREATION_PATH = "aSessionCreationPath"; + private static final String DIGITAL_ID_MATCH_PATH = "aDigitalIdMatchPath"; private static final String POST = "POST"; private static final byte[] A_BODY_BYTES = "aBody".getBytes(StandardCharsets.UTF_8); @@ -44,14 +47,19 @@ public class DigitalIdentityServiceTest { @Mock(answer = RETURNS_DEEP_STUBS) SignedRequestBuilder signedRequestBuilder; @Mock SignedRequestBuilderFactory requestBuilderFactory; - @Mock ShareSessionRequest shareSessionRequest; - @Mock SignedRequest signedRequest; @Mock(answer = RETURNS_DEEP_STUBS) KeyPair keyPair; + @Mock SignedRequest signedRequest; + + @Mock ShareSessionRequest shareSessionRequest; @Mock ShareSession shareSession; + @Mock MatchRequest matchRequest; + @Mock MatchResult matchResult; + @Before public void setUp() { when(unsignedPathFactory.createIdentitySessionPath()).thenReturn(SESSION_CREATION_PATH); + when(unsignedPathFactory.createIdentityMatchPath()).thenReturn(DIGITAL_ID_MATCH_PATH); } @Test @@ -277,4 +285,147 @@ public void fetchShareQrCode_NullSessionId_Exception() { assertThat(ex.getMessage(), containsString("QR Code ID")); } + @Test + public void fetchMatch_NullSdkId_Exception() { + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> identityService.fetchMatch(null, keyPair, matchRequest) + ); + + assertThat(ex.getMessage(), containsString("SDK ID")); + } + + @Test + public void fetchMatch_EmptySdkId_Exception() { + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> identityService.fetchMatch("", keyPair, matchRequest) + ); + + assertThat(ex.getMessage(), containsString("SDK ID")); + } + + @Test + public void fetchMatch_NullKeyPair_Exception() { + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> identityService.fetchMatch(SDK_ID, null, matchRequest) + ); + + assertThat(ex.getMessage(), containsString("Application Key Pair")); + } + + @Test + public void fetchMatch_NullMatchRequest_Exception() { + IllegalArgumentException ex = assertThrows( + IllegalArgumentException.class, + () -> identityService.fetchMatch(SDK_ID, keyPair, null) + ); + + assertThat(ex.getMessage(), notNullValue()); + } + + @Test + public void fetchMatch_SerializingWrongPayload_Exception() { + JsonProcessingException causeEx = new JsonProcessingException("serialization error") {}; + + try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { + mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenThrow(causeEx); + + DigitalIdentityException ex = assertThrows( + DigitalIdentityException.class, + () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + ); + + Throwable cause = ex.getCause(); + assertTrue(cause instanceof JsonProcessingException); + assertThat(cause.getMessage(), containsString("serialization error")); + } + } + + @Test + public void fetchMatch_BuildingRequestWithWrongEndpoint_Exception() throws Exception { + try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { + mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); + when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + + String exMessage = "URI wrong format"; + URISyntaxException causeEx = new URISyntaxException("", exMessage); + when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + .thenThrow(causeEx); + + DigitalIdentityException ex = assertThrows( + DigitalIdentityException.class, + () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + ); + + Throwable cause = ex.getCause(); + assertTrue(cause instanceof URISyntaxException); + assertThat(cause.getMessage(), containsString(exMessage)); + } + } + + @Test + public void fetchMatch_BuildingRequestWithWrongQueryParams_Exception() throws Exception { + try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { + mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); + + when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + + String exMessage = "Wrong query params format"; + UnsupportedEncodingException causeEx = new UnsupportedEncodingException(exMessage); + when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + .thenThrow(causeEx); + + DigitalIdentityException ex = assertThrows( + DigitalIdentityException.class, + () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + ); + + Throwable cause = ex.getCause(); + assertTrue(cause instanceof UnsupportedEncodingException); + assertThat(cause.getMessage(), containsString(exMessage)); + } + } + + @Test + public void fetchMatch_BuildingRequestWithWrongDigest_Exception() throws Exception { + try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { + mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); + + when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + + String exMessage = "Wrong digest"; + GeneralSecurityException causeEx = new GeneralSecurityException(exMessage); + when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + .thenThrow(causeEx); + + DigitalIdentityException ex = assertThrows( + DigitalIdentityException.class, + () -> identityService.fetchMatch(SDK_ID, keyPair, matchRequest) + ); + + Throwable cause = ex.getCause(); + assertTrue(cause instanceof GeneralSecurityException); + assertThat(cause.getMessage(), containsString(exMessage)); + } + } + + @Test + public void fetchMatch_SessionRequest_exception() throws Exception { + try (MockedStatic mapper = Mockito.mockStatic(ResourceMapper.class)) { + mapper.when(() -> ResourceMapper.writeValueAsString(matchRequest)).thenReturn(A_BODY_BYTES); + + when(requestBuilderFactory.create()).thenReturn(signedRequestBuilder); + + when(identityService.createSignedRequest(SDK_ID, keyPair, DIGITAL_ID_MATCH_PATH, POST, A_BODY_BYTES)) + .thenReturn(signedRequest); + + when(signedRequest.execute(MatchResult.class)).thenReturn(matchResult); + + MatchResult result = identityService.fetchMatch(SDK_ID, keyPair, matchRequest); + assertSame(matchResult, result); + } + } + } diff --git a/yoti-sdk-parent/pom.xml b/yoti-sdk-parent/pom.xml index d413cb090..2c80095c9 100644 --- a/yoti-sdk-parent/pom.xml +++ b/yoti-sdk-parent/pom.xml @@ -5,7 +5,7 @@ com.yoti yoti-sdk-parent pom - 3.11.0 + 3.12.0-SNAPSHOT Yoti SDK Parent Pom Parent pom for the Java SDK projects https://github.com/getyoti/yoti-java-sdk @@ -24,9 +24,9 @@ - scm:http://github.com/getyoti/yoti-java-sdk.git - scm:http://github.com/getyoti/yoti-java-sdk.git - http://github.com/getyoti/yoti-java-sdk.git + scm:git:https://github.com/getyoti/yoti-java-sdk.git + scm:git:https://github.com/getyoti/yoti-java-sdk.git + https://github.com/getyoti/yoti-java-sdk.git @@ -58,16 +58,6 @@ false false - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - nexus @@ -98,10 +88,10 @@ 8 - 2.0.9 - 1.70 - 2.16.1 - 3.25.3 + 2.0.16 + 1.81 + 2.19.0 + 3.25.8 4.5.14 @@ -112,42 +102,44 @@ 4.13.2 4.11.0 - 2.2 - 3.13.0 + 3.0 + 3.17.0 3.8.5 - 3.11.0 + 3.14.0 - 4.8.3 - 4.8.3.1 - 1.13.0 + + 4.8.6 + 4.8.6.6 + 1.14.0 - 8.4.3 + + 10.0.4 12 - 1.23 + 1.24 java18 1.0 - 3.4.1 - 1.7.0 + 3.5.0 + 1.10.0 - 1.6.13 + 0.8.0 - 3.3.0 + 3.3.1 - 3.6.3 + 3.11.2 8 - 3.1.0 + 3.2.7 - 3.5.0 + 3.9.0 4.3.0 - 0.8.11 + 0.8.13 @@ -156,8 +148,8 @@ org.bouncycastle - bcpkix-jdk15on - ${bouncy.castle.version} + bcpkix-jdk18on + ${bouncycastle.version} com.fasterxml.jackson @@ -228,7 +220,7 @@ org.apache.commons commons-lang3 - ${commons.lang3.version} + ${commons-lang3.version} test @@ -362,14 +354,13 @@ - org.sonatype.plugins - nexus-staging-maven-plugin - ${nexus-staging-maven-plugin.version} + org.sonatype.central + central-publishing-maven-plugin + ${central-publishing-maven-plugin.version} true - ossrh - https://oss.sonatype.org/ - true + central + true @@ -460,8 +451,8 @@ - org.sonatype.plugins - nexus-staging-maven-plugin + org.sonatype.central + central-publishing-maven-plugin diff --git a/yoti-sdk-sandbox/pom.xml b/yoti-sdk-sandbox/pom.xml index 1db785842..7b81829ae 100644 --- a/yoti-sdk-sandbox/pom.xml +++ b/yoti-sdk-sandbox/pom.xml @@ -11,7 +11,7 @@ com.yoti yoti-sdk-parent - 3.11.0 + 3.12.0-SNAPSHOT ../yoti-sdk-parent @@ -19,7 +19,7 @@ org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on com.fasterxml.jackson.core diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReports.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReports.java index e1a1aff29..1b1c3d097 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReports.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReports.java @@ -1,12 +1,17 @@ package com.yoti.api.client.sandbox.docs.request; +import static com.yoti.api.client.docs.DocScanConstants.FACE_COMPARISON; import static com.yoti.api.client.docs.DocScanConstants.ID_DOCUMENT_AUTHENTICITY; import static com.yoti.api.client.docs.DocScanConstants.ID_DOCUMENT_COMPARISON; import static com.yoti.api.client.docs.DocScanConstants.ID_DOCUMENT_FACE_MATCH; import static com.yoti.api.client.docs.DocScanConstants.ID_DOCUMENT_TEXT_DATA_CHECK; import static com.yoti.api.client.docs.DocScanConstants.LIVENESS; import static com.yoti.api.client.docs.DocScanConstants.SUPPLEMENTARY_DOCUMENT_TEXT_DATA_CHECK; +import static com.yoti.api.client.docs.DocScanConstants.SYNECTICS_IDENTITY_FRAUD; import static com.yoti.api.client.docs.DocScanConstants.THIRD_PARTY_IDENTITY; +import static com.yoti.api.client.docs.DocScanConstants.THIRD_PARTY_IDENTITY_FRAUD_ONE; +import static com.yoti.api.client.docs.DocScanConstants.WATCHLIST_ADVANCED_CA; +import static com.yoti.api.client.docs.DocScanConstants.WATCHLIST_SCREENING; import java.util.ArrayList; import java.util.List; @@ -14,10 +19,15 @@ import com.yoti.api.client.sandbox.docs.request.check.SandboxDocumentAuthenticityCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxDocumentTextDataCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxDocumentFaceMatchCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxFaceComparisonCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxIdDocumentComparisonCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxLivenessCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxSupplementaryDocumentTextDataCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxSynecticsIdentityFraudCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxThirdPartyIdentityCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxThirdPartyIdentityFraudOneCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxWatchlistAdvancedCaCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxWatchlistScreeningCheck; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -46,6 +56,21 @@ public class SandboxCheckReports { @JsonProperty(THIRD_PARTY_IDENTITY) private final SandboxThirdPartyIdentityCheck thirdPartyIdentityCheck; + @JsonProperty(FACE_COMPARISON) + private final SandboxFaceComparisonCheck faceComparisonCheck; + + @JsonProperty(SYNECTICS_IDENTITY_FRAUD) + private final List synecticsIdentityFraudChecks; + + @JsonProperty(THIRD_PARTY_IDENTITY_FRAUD_ONE) + private final SandboxThirdPartyIdentityFraudOneCheck thirdPartyIdentityFraudOneCheck; + + @JsonProperty(WATCHLIST_SCREENING) + private final SandboxWatchlistScreeningCheck watchlistScreeningCheck; + + @JsonProperty(WATCHLIST_ADVANCED_CA) + private final List watchlistAdvancedCaChecks; + @JsonProperty("async_report_delay") private final Integer asyncReportDelay; @@ -56,6 +81,11 @@ public class SandboxCheckReports { List idDocumentComparisonChecks, List supplementaryDocumentTextDataChecks, SandboxThirdPartyIdentityCheck thirdPartyIdentityCheck, + SandboxFaceComparisonCheck faceComparisonCheck, + List synecticsIdentityFraudChecks, + SandboxThirdPartyIdentityFraudOneCheck thirdPartyIdentityFraudOneCheck, + SandboxWatchlistScreeningCheck watchlistScreeningCheck, + List watchlistAdvancedCaChecks, Integer asyncReportsDelay) { this.documentTextDataChecks = documentTextDataChecks; this.documentAuthenticityChecks = documentAuthenticityChecks; @@ -64,6 +94,11 @@ public class SandboxCheckReports { this.idDocumentComparisonChecks = idDocumentComparisonChecks; this.supplementaryDocumentTextDataChecks = supplementaryDocumentTextDataChecks; this.thirdPartyIdentityCheck = thirdPartyIdentityCheck; + this.faceComparisonCheck = faceComparisonCheck; + this.synecticsIdentityFraudChecks = synecticsIdentityFraudChecks; + this.thirdPartyIdentityFraudOneCheck = thirdPartyIdentityFraudOneCheck; + this.watchlistScreeningCheck = watchlistScreeningCheck; + this.watchlistAdvancedCaChecks = watchlistAdvancedCaChecks; this.asyncReportDelay = asyncReportsDelay; } @@ -97,6 +132,26 @@ public SandboxThirdPartyIdentityCheck getThirdPartyIdentityCheck() { return thirdPartyIdentityCheck; } + public SandboxFaceComparisonCheck getFaceComparisonCheck() { + return faceComparisonCheck; + } + + public List getSynecticsIdentityFraudChecks() { + return synecticsIdentityFraudChecks; + } + + public SandboxThirdPartyIdentityFraudOneCheck getThirdPartyIdentityFraudOneCheck() { + return thirdPartyIdentityFraudOneCheck; + } + + public SandboxWatchlistScreeningCheck getWatchlistScreeningCheck() { + return watchlistScreeningCheck; + } + + public List getWatchlistAdvancedCaChecks() { + return watchlistAdvancedCaChecks; + } + public Integer getAsyncReportDelay() { return asyncReportDelay; } @@ -120,6 +175,16 @@ public static class Builder { private SandboxThirdPartyIdentityCheck thirdPartyIdentityCheck; + private SandboxFaceComparisonCheck faceComparisonCheck; + + private List synecticsIdentityFraudChecks = new ArrayList<>(); + + private SandboxThirdPartyIdentityFraudOneCheck thirdPartyIdentityFraudOneCheck; + + private SandboxWatchlistScreeningCheck watchlistScreeningCheck; + + private List watchlistAdvancedCaChecks = new ArrayList<>(); + private Integer asyncReportDelay; private Builder() {} @@ -159,6 +224,31 @@ public Builder withThirdPartyIdentityCheck(SandboxThirdPartyIdentityCheck thirdP return this; } + public Builder withFaceComparisonCheck(SandboxFaceComparisonCheck faceComparisonCheck) { + this.faceComparisonCheck = faceComparisonCheck; + return this; + } + + public Builder withSynecticsIdentityFraudCheck(SandboxSynecticsIdentityFraudCheck synecticsIdentityFraudCheck) { + this.synecticsIdentityFraudChecks.add(synecticsIdentityFraudCheck); + return this; + } + + public Builder withThirdPartyIdentityFraudOneCheck(SandboxThirdPartyIdentityFraudOneCheck thirdPartyIdentityFraudOneCheck) { + this.thirdPartyIdentityFraudOneCheck = thirdPartyIdentityFraudOneCheck; + return this; + } + + public Builder withWatchlistScreeningCheck(SandboxWatchlistScreeningCheck watchlistScreeningCheck) { + this.watchlistScreeningCheck = watchlistScreeningCheck; + return this; + } + + public Builder withWatchlistAdvancedCaCheck(SandboxWatchlistAdvancedCaCheck watchlistAdvancedCaCheck) { + this.watchlistAdvancedCaChecks.add(watchlistAdvancedCaCheck); + return this; + } + public Builder withAsyncReportDelay(int asyncReportDelay) { this.asyncReportDelay = asyncReportDelay; return this; @@ -166,7 +256,8 @@ public Builder withAsyncReportDelay(int asyncReportDelay) { public SandboxCheckReports build() { return new SandboxCheckReports(textDataCheck, documentAuthenticityCheck, livenessCheck, documentFaceMatchCheck, idDocumentComparisonCheck, - supplementaryDocumentTextDataCheck, thirdPartyIdentityCheck, asyncReportDelay); + supplementaryDocumentTextDataCheck, thirdPartyIdentityCheck, faceComparisonCheck, synecticsIdentityFraudChecks, + thirdPartyIdentityFraudOneCheck, watchlistScreeningCheck, watchlistAdvancedCaChecks, asyncReportDelay); } } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaProfileSourcesFilter.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaProfileSourcesFilter.java new file mode 100644 index 000000000..463e8c851 --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaProfileSourcesFilter.java @@ -0,0 +1,18 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SandboxCaProfileSourcesFilter extends SandboxCaSourcesFilter { + + @JsonProperty("search_profile") + private String searchProfile; + + SandboxCaProfileSourcesFilter(String searchProfile) { + this.searchProfile = searchProfile; + } + + public String getSearchProfile() { + return searchProfile; + } + +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaSourcesFilter.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaSourcesFilter.java new file mode 100644 index 000000000..70885f6c6 --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaSourcesFilter.java @@ -0,0 +1,13 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") +@JsonSubTypes({ + @JsonSubTypes.Type(value = SandboxCaTypeListSourcesFilter.class, name = "TYPE_LIST"), + @JsonSubTypes.Type(value = SandboxCaProfileSourcesFilter.class, name = "PROFILE") +}) +public abstract class SandboxCaSourcesFilter { + +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaTypeListSourcesFilter.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaTypeListSourcesFilter.java new file mode 100644 index 000000000..3f0ee2ae0 --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCaTypeListSourcesFilter.java @@ -0,0 +1,20 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SandboxCaTypeListSourcesFilter extends SandboxCaSourcesFilter { + + @JsonProperty("types") + private final List types; + + SandboxCaTypeListSourcesFilter(List types) { + this.types = types; + } + + public List getTypes() { + return types; + } + +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheck.java index 0e4eca284..b494f5eea 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheck.java @@ -28,7 +28,8 @@ public SandboxCheckResult getResult() { static abstract class Builder> { protected SandboxRecommendation recommendation; - protected List breakdown = new ArrayList<>(); + protected List breakdown; + protected String reportTemplate; public T withRecommendation(SandboxRecommendation recommendation) { this.recommendation = recommendation; @@ -36,16 +37,23 @@ public T withRecommendation(SandboxRecommendation recommendation) { } public T withBreakdown(SandboxBreakdown breakdown) { + if (this.breakdown == null) { + this.breakdown = new ArrayList<>(); + } this.breakdown.add(breakdown); return self(); } public T withBreakdowns(List breakdowns) { - notNull(breakdowns, "breakdowns"); this.breakdown = breakdowns; return self(); } + public T withReportTemplate(String reportTemplate) { + this.reportTemplate = reportTemplate; + return self(); + } + protected abstract T self(); public abstract SandboxCheck build(); diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheckResult.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheckResult.java index ad3d6202d..5a827e1e6 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheckResult.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxCheckResult.java @@ -9,12 +9,20 @@ class SandboxCheckResult { @JsonProperty("report") private final SandboxCheckReport report; - SandboxCheckResult(SandboxCheckReport report) { + @JsonProperty("report_template") + private final String reportTemplate; + + SandboxCheckResult(SandboxCheckReport report, String reportTemplate) { this.report = report; + this.reportTemplate = reportTemplate; } public SandboxCheckReport getReport() { return report; } + public String getReportTemplate() { + return reportTemplate; + } + } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java index fd3d40505..a3225442f 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheck.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; - import com.yoti.api.client.sandbox.docs.request.SandboxDocumentFilter; import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; @@ -30,10 +28,10 @@ protected Builder self() { @Override public SandboxDocumentAuthenticityCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxCheckResult result = new SandboxCheckResult(report); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); return new SandboxDocumentAuthenticityCheck(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java index d3ec8a5a9..80bc3a66f 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheck.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; - import com.yoti.api.client.sandbox.docs.request.SandboxDocumentFilter; import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; @@ -30,10 +28,10 @@ protected Builder self() { @Override public SandboxDocumentFaceMatchCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxCheckResult result = new SandboxCheckResult(report); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); return new SandboxDocumentFaceMatchCheck(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java index 6ba037e6e..ae5dc902a 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheck.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; - import java.util.HashMap; import java.util.Map; @@ -57,10 +55,10 @@ protected Builder self() { @Override public SandboxDocumentTextDataCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxDocumentTextDataCheckResult result = new SandboxDocumentTextDataCheckResult(report, documentFields); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxDocumentTextDataCheckResult result = new SandboxDocumentTextDataCheckResult(report, reportTemplate, documentFields); return new SandboxDocumentTextDataCheck(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckResult.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckResult.java index 76ba5c6a5..0b9fdfba2 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckResult.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckResult.java @@ -11,8 +11,8 @@ public class SandboxDocumentTextDataCheckResult extends SandboxCheckResult { @JsonProperty("document_fields") private Map documentFields; - SandboxDocumentTextDataCheckResult(SandboxCheckReport report, Map documentFields) { - super(report); + SandboxDocumentTextDataCheckResult(SandboxCheckReport report, String reportTemplate, Map documentFields) { + super(report, reportTemplate); this.documentFields = documentFields; } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxFaceComparisonCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxFaceComparisonCheck.java new file mode 100644 index 000000000..e4dc1cdb5 --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxFaceComparisonCheck.java @@ -0,0 +1,38 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; + +public class SandboxFaceComparisonCheck extends SandboxCheck { + + SandboxFaceComparisonCheck(SandboxCheckResult result) { + super(result); + } + + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link SandboxFaceComparisonCheck} + */ + public static class Builder extends SandboxCheck.Builder { + + private Builder() {} + + @Override + protected Builder self() { + return this; + } + + @Override + public SandboxFaceComparisonCheck build() { + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); + + return new SandboxFaceComparisonCheck(result); + } + + } +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java index 6efb6a4c8..4a05675b1 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheck.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; - import com.yoti.api.client.sandbox.docs.request.SandboxDocumentFilter; import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; @@ -41,10 +39,10 @@ protected Builder self() { @Override public SandboxIdDocumentComparisonCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxCheckResult result = new SandboxCheckResult(report); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); return new SandboxIdDocumentComparisonCheck(result, secondaryDocumentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxStaticLivenessCheckBuilder.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxStaticLivenessCheckBuilder.java index 441d0f2ce..96b8c0837 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxStaticLivenessCheckBuilder.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxStaticLivenessCheckBuilder.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.validation.Validation.notNull; - import com.yoti.api.client.docs.DocScanConstants; import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; @@ -23,10 +21,10 @@ protected SandboxStaticLivenessCheckBuilder self() { @Override public SandboxLivenessCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxCheckResult result = new SandboxCheckResult(report); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); return new SandboxLivenessCheck(result, DocScanConstants.STATIC, responseDelay); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java index ee58d2663..c03053847 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheck.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; - import java.util.HashMap; import java.util.Map; @@ -54,10 +52,10 @@ protected Builder self() { @Override public SandboxSupplementaryDocumentTextDataCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxSupplementaryDocumentTextDataCheckResult result = new SandboxSupplementaryDocumentTextDataCheckResult(report, documentFields); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxSupplementaryDocumentTextDataCheckResult result = new SandboxSupplementaryDocumentTextDataCheckResult(report, reportTemplate, documentFields); return new SandboxSupplementaryDocumentTextDataCheck(result, documentFilter); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckResult.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckResult.java index e479a23f4..6771bdaf7 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckResult.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckResult.java @@ -11,8 +11,8 @@ public class SandboxSupplementaryDocumentTextDataCheckResult extends SandboxChec @JsonProperty("document_fields") private Map documentFields; - SandboxSupplementaryDocumentTextDataCheckResult(SandboxCheckReport report, Map documentFields) { - super(report); + SandboxSupplementaryDocumentTextDataCheckResult(SandboxCheckReport report, String reportTemplate, Map documentFields) { + super(report, reportTemplate); this.documentFields = documentFields; } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSynecticsIdentityFraudCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSynecticsIdentityFraudCheck.java new file mode 100644 index 000000000..db3dc0cd7 --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSynecticsIdentityFraudCheck.java @@ -0,0 +1,38 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; + +public class SandboxSynecticsIdentityFraudCheck extends SandboxCheck { + + SandboxSynecticsIdentityFraudCheck(SandboxCheckResult result) { + super(result); + } + + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link SandboxSynecticsIdentityFraudCheck} + */ + public static class Builder extends SandboxCheck.Builder { + + private Builder() {} + + @Override + protected Builder self() { + return this; + } + + @Override + public SandboxSynecticsIdentityFraudCheck build() { + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); + + return new SandboxSynecticsIdentityFraudCheck(result); + } + + } +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java index bea61d0b6..7df9c8846 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityCheck.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.api.client.spi.remote.util.Validation.notNull; - import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; public class SandboxThirdPartyIdentityCheck extends SandboxCheck { @@ -29,10 +27,10 @@ protected Builder self() { @Override public SandboxThirdPartyIdentityCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxCheckResult result = new SandboxCheckResult(report); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); return new SandboxThirdPartyIdentityCheck(result); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityFraudOneCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityFraudOneCheck.java new file mode 100644 index 000000000..c2499643f --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxThirdPartyIdentityFraudOneCheck.java @@ -0,0 +1,38 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; + +public class SandboxThirdPartyIdentityFraudOneCheck extends SandboxCheck { + + SandboxThirdPartyIdentityFraudOneCheck(SandboxCheckResult result) { + super(result); + } + + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link SandboxThirdPartyIdentityFraudOneCheck} + */ + public static class Builder extends SandboxCheck.Builder { + + private Builder() {} + + @Override + protected Builder self() { + return this; + } + + @Override + public SandboxThirdPartyIdentityFraudOneCheck build() { + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); + + return new SandboxThirdPartyIdentityFraudOneCheck(result); + } + + } +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistAdvancedCaCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistAdvancedCaCheck.java new file mode 100644 index 000000000..477501c96 --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistAdvancedCaCheck.java @@ -0,0 +1,62 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import java.util.List; + +import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SandboxWatchlistAdvancedCaCheck extends SandboxCheck { + + @JsonProperty("sources_filter") + private final SandboxCaSourcesFilter sourcesFilter; + + SandboxWatchlistAdvancedCaCheck(SandboxCheckResult result, SandboxCaSourcesFilter sourcesFilter) { + super(result); + this.sourcesFilter = sourcesFilter; + } + + public SandboxCaSourcesFilter getSourcesFilter() { + return sourcesFilter; + } + + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link SandboxWatchlistAdvancedCaCheck} + */ + public static class Builder extends SandboxCheck.Builder { + + private SandboxCaSourcesFilter sourcesFilter; + + private Builder() {} + + public Builder withTypeListFilter(List types) { + this.sourcesFilter = new SandboxCaTypeListSourcesFilter(types); + return self(); + } + + public Builder withProfileFilter(String searchProfile) { + this.sourcesFilter = new SandboxCaProfileSourcesFilter(searchProfile); + return self(); + } + + @Override + protected Builder self() { + return this; + } + + @Override + public SandboxWatchlistAdvancedCaCheck build() { + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); + + return new SandboxWatchlistAdvancedCaCheck(result, sourcesFilter); + } + + } +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistScreeningCheck.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistScreeningCheck.java new file mode 100644 index 000000000..5d17d7be3 --- /dev/null +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxWatchlistScreeningCheck.java @@ -0,0 +1,38 @@ +package com.yoti.api.client.sandbox.docs.request.check; + +import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; + +public class SandboxWatchlistScreeningCheck extends SandboxCheck { + + SandboxWatchlistScreeningCheck(SandboxCheckResult result) { + super(result); + } + + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link SandboxWatchlistScreeningCheck} + */ + public static class Builder extends SandboxCheck.Builder { + + private Builder() {} + + @Override + protected Builder self() { + return this; + } + + @Override + public SandboxWatchlistScreeningCheck build() { + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); + + return new SandboxWatchlistScreeningCheck(result); + } + + } +} diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckBuilder.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckBuilder.java index 262267b95..334203664 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckBuilder.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckBuilder.java @@ -1,7 +1,5 @@ package com.yoti.api.client.sandbox.docs.request.check; -import static com.yoti.validation.Validation.notNull; - import com.yoti.api.client.docs.DocScanConstants; import com.yoti.api.client.sandbox.docs.request.check.report.SandboxCheckReport; @@ -23,10 +21,10 @@ public SandboxZoomLivenessCheckBuilder withResponseDelay(Integer responseDelay) @Override public SandboxLivenessCheck build() { - notNull(recommendation, "recommendation"); - - SandboxCheckReport report = new SandboxCheckReport(recommendation, breakdown); - SandboxCheckResult result = new SandboxCheckResult(report); + SandboxCheckReport report = recommendation == null && breakdown == null + ? null + : new SandboxCheckReport(recommendation, breakdown); + SandboxCheckResult result = new SandboxCheckResult(report, reportTemplate); return new SandboxLivenessCheck(result, DocScanConstants.ZOOM, responseDelay); } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java index ca31eadcd..ba58ae883 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTask.java @@ -23,10 +23,17 @@ public class SandboxDocumentTextDataExtractionTask { @JsonProperty("response_delay") private final Integer responseDelay; - SandboxDocumentTextDataExtractionTask(SandboxDocumentTextDataExtractionTaskResult result, SandboxDocumentFilter documentFilter, Integer responseDelay) { + @JsonProperty("result_template") + private final String resultTemplate; + + SandboxDocumentTextDataExtractionTask(SandboxDocumentTextDataExtractionTaskResult result, + SandboxDocumentFilter documentFilter, + Integer responseDelay, + String resultTemplate) { this.result = result; this.documentFilter = documentFilter; this.responseDelay = responseDelay; + this.resultTemplate = resultTemplate; } public static Builder builder() { @@ -45,6 +52,10 @@ public Integer getResponseDelay() { return responseDelay; } + public String getResultTemplate() { + return resultTemplate; + } + /** * Builder for {@link SandboxDocumentTextDataExtractionTask} */ @@ -57,6 +68,7 @@ public static class Builder { private String detectedDocumentType; private SandboxTextExtractionTaskRecommendation recommendation; private Integer responseDelay; + private String resultTemplate; private Builder() {} @@ -106,13 +118,24 @@ public Builder withResponseDelay(Integer responseDelay) { return this; } + public Builder withResultTemplate(String resultTemplate) { + this.resultTemplate = resultTemplate; + return this; + } + public SandboxDocumentTextDataExtractionTask build() { - SandboxDocumentTextDataExtractionTaskResult result = new SandboxDocumentTextDataExtractionTaskResult(documentFields, - documentIdPhoto, - detectedCountry, - detectedDocumentType, - recommendation); - return new SandboxDocumentTextDataExtractionTask(result, documentFilter, responseDelay); + SandboxDocumentTextDataExtractionTaskResult result; + if (documentFields == null && documentIdPhoto == null && detectedCountry == null && detectedDocumentType == null && recommendation == null) { + result = null; + } else { + result = new SandboxDocumentTextDataExtractionTaskResult(documentFields, + documentIdPhoto, + detectedCountry, + detectedDocumentType, + recommendation); + } + + return new SandboxDocumentTextDataExtractionTask(result, documentFilter, responseDelay, resultTemplate); } } } diff --git a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java index beb290b79..ff0f7a866 100644 --- a/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java +++ b/yoti-sdk-sandbox/src/main/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTask.java @@ -22,12 +22,17 @@ public class SandboxSupplementaryDocTextDataExtractionTask { @JsonProperty("response_delay") private final Integer responseDelay; + @JsonProperty("result_template") + private final String resultTemplate; + SandboxSupplementaryDocTextDataExtractionTask(SandboxSupplementaryDocTextDataExtractionTaskResult result, SandboxDocumentFilter documentFilter, - Integer responseDelay) { + Integer responseDelay, + String resultTemplate) { this.result = result; this.documentFilter = documentFilter; this.responseDelay = responseDelay; + this.resultTemplate = resultTemplate; } public static Builder builder() { @@ -46,6 +51,10 @@ public Integer getResponseDelay() { return responseDelay; } + public String getResultTemplate() { + return resultTemplate; + } + /** * Builder for {@link SandboxSupplementaryDocTextDataExtractionTask} */ @@ -56,6 +65,7 @@ public static class Builder { private String detectedCountry; private SandboxTextExtractionTaskRecommendation recommendation; private Integer responseDelay; + private String resultTemplate; private Builder() {} @@ -94,10 +104,21 @@ public Builder withResponseDelay(Integer responseDelay) { return this; } + public Builder withResultTemplate(String resultTemplate) { + this.resultTemplate = resultTemplate; + return this; + } + public SandboxSupplementaryDocTextDataExtractionTask build() { - SandboxSupplementaryDocTextDataExtractionTaskResult result = new SandboxSupplementaryDocTextDataExtractionTaskResult(documentFields, - detectedCountry, recommendation); - return new SandboxSupplementaryDocTextDataExtractionTask(result, documentFilter, responseDelay); + SandboxSupplementaryDocTextDataExtractionTaskResult result; + if (documentFields == null && detectedCountry == null && recommendation == null) { + result = null; + } else { + result = new SandboxSupplementaryDocTextDataExtractionTaskResult(documentFields, + detectedCountry, + recommendation); + } + return new SandboxSupplementaryDocTextDataExtractionTask(result, documentFilter, responseDelay, resultTemplate); } } } diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReportsTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReportsTest.java index e19fa5721..5d9af361e 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReportsTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/SandboxCheckReportsTest.java @@ -6,11 +6,16 @@ import com.yoti.api.client.sandbox.docs.request.check.SandboxDocumentAuthenticityCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxDocumentFaceMatchCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxFaceComparisonCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxIdDocumentComparisonCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxLivenessCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxDocumentTextDataCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxSupplementaryDocumentTextDataCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxSynecticsIdentityFraudCheck; import com.yoti.api.client.sandbox.docs.request.check.SandboxThirdPartyIdentityCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxThirdPartyIdentityFraudOneCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxWatchlistAdvancedCaCheck; +import com.yoti.api.client.sandbox.docs.request.check.SandboxWatchlistScreeningCheck; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,6 +32,11 @@ public class SandboxCheckReportsTest { @Mock SandboxIdDocumentComparisonCheck idDocumentComparisonCheckMock; @Mock SandboxSupplementaryDocumentTextDataCheck supplementaryDocumentTextDataCheckMock; @Mock SandboxThirdPartyIdentityCheck thirdPartyIdentityCheckMock; + @Mock SandboxFaceComparisonCheck faceComparisonCheckMock; + @Mock SandboxSynecticsIdentityFraudCheck synecticsIdentityFraudCheckMock; + @Mock SandboxThirdPartyIdentityFraudOneCheck thirdPartyIdentityFraudOneCheckMock; + @Mock SandboxWatchlistScreeningCheck watchlistScreeningCheckMock; + @Mock SandboxWatchlistAdvancedCaCheck watchlistAdvancedCaCheckMock; @Test public void builder_shouldAllowDocumentAuthenticityChecks() { @@ -97,6 +107,53 @@ public void builder_shouldAllowThirdPartyIdentityChecks() { assertThat(result.getThirdPartyIdentityCheck(), is(thirdPartyIdentityCheckMock)); } + @Test + public void builder_shouldAllowFaceComparisonCheck() { + SandboxCheckReports result = SandboxCheckReports.builder() + .withFaceComparisonCheck(faceComparisonCheckMock) + .build(); + + assertThat(result.getFaceComparisonCheck(), is(faceComparisonCheckMock)); + } + + @Test + public void builder_shouldAllowSynecticsIdentityFraudChecks() { + SandboxCheckReports result = SandboxCheckReports.builder() + .withSynecticsIdentityFraudCheck(synecticsIdentityFraudCheckMock) + .build(); + + assertThat(result.getSynecticsIdentityFraudChecks(), hasSize(1)); + assertThat(result.getSynecticsIdentityFraudChecks().get(0), is(synecticsIdentityFraudCheckMock)); + } + + @Test + public void builder_shouldAllowThirdPartyIdentityFraudOneCheck() { + SandboxCheckReports result = SandboxCheckReports.builder() + .withThirdPartyIdentityFraudOneCheck(thirdPartyIdentityFraudOneCheckMock) + .build(); + + assertThat(result.getThirdPartyIdentityFraudOneCheck(), is(thirdPartyIdentityFraudOneCheckMock)); + } + + @Test + public void builder_shouldAllowWatchlistScreeningCheck() { + SandboxCheckReports result = SandboxCheckReports.builder() + .withWatchlistScreeningCheck(watchlistScreeningCheckMock) + .build(); + + assertThat(result.getWatchlistScreeningCheck(), is(watchlistScreeningCheckMock)); + } + + @Test + public void builder_shouldAllowWatchlistAdvancedCaChecks() { + SandboxCheckReports result = SandboxCheckReports.builder() + .withWatchlistAdvancedCaCheck(watchlistAdvancedCaCheckMock) + .build(); + + assertThat(result.getWatchlistAdvancedCaChecks(), hasSize(1)); + assertThat(result.getWatchlistAdvancedCaChecks().get(0), is(watchlistAdvancedCaCheckMock)); + } + @Test public void builder_shouldAllowOverridingOfAsyncReportDelay() { SandboxCheckReports result = SandboxCheckReports.builder() diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheckTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheckTest.java index c60c238fa..8974c6c38 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheckTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentAuthenticityCheckTest.java @@ -27,17 +27,6 @@ public class SandboxDocumentAuthenticityCheckTest { @Mock SandboxBreakdown sandboxBreakdownMock; @Mock SandboxDocumentFilter sandboxDocumentFilterMock; - @Test - public void builder_shouldThrowExceptionWhenMissingRecommendation() { - try { - SandboxDocumentAuthenticityCheck.builder().build(); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage(), containsString("recommendation")); - return; - } - fail("Expected an exception"); - } - @Test public void builder_shouldBuildWithoutDocumentFilter() { SandboxDocumentAuthenticityCheck result = SandboxDocumentAuthenticityCheck.builder() diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheckTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheckTest.java index 22ac25b78..2408b1f6a 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheckTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentFaceMatchCheckTest.java @@ -21,17 +21,6 @@ public class SandboxDocumentFaceMatchCheckTest { @Mock SandboxRecommendation sandboxRecommendationMock; @Mock SandboxBreakdown sandboxBreakdownMock; - @Test - public void builder_shouldThrowExceptionWhenMissingRecommendation() { - try { - SandboxDocumentFaceMatchCheck.builder().build(); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage(), containsString("recommendation")); - return; - } - fail("Expected an exception"); - } - @Test public void builder_shouldBuildCorrectly() { SandboxDocumentFaceMatchCheck result = SandboxDocumentFaceMatchCheck.builder() diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckTest.java index d8b447874..168c6449c 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxDocumentTextDataCheckTest.java @@ -33,17 +33,6 @@ public class SandboxDocumentTextDataCheckTest { @Mock SandboxRecommendation sandboxRecommendationMock; @Mock SandboxBreakdown sandboxBreakdownMock; - @Test - public void builder_shouldThrowExceptionForMissingRecommendation() { - try { - SandboxDocumentTextDataCheck.builder().build(); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage(), containsString("recommendation")); - return; - } - fail("Expected an exception"); - } - @Test public void builder_shouldInitialiseDocumentFieldsMap() { SandboxDocumentTextDataCheck result = SandboxDocumentTextDataCheck.builder() diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheckTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheckTest.java index 213a5595c..daeb3f6f7 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheckTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxIdDocumentComparisonCheckTest.java @@ -22,17 +22,6 @@ public class SandboxIdDocumentComparisonCheckTest { @Mock SandboxBreakdown sandboxBreakdownMock; @Mock SandboxDocumentFilter secondaryDocumentFilterMock; - @Test - public void builder_shouldThrowExceptionForMissingRecommendation() { - try { - SandboxIdDocumentComparisonCheck.builder().build(); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage(), containsString("recommendation")); - return; - } - fail("Expected an exception"); - } - @Test public void builder_shouldBuildCorrectly() { SandboxIdDocumentComparisonCheck result = SandboxIdDocumentComparisonCheck.builder() diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckTest.java index c1b67d983..441301394 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxSupplementaryDocumentTextDataCheckTest.java @@ -33,17 +33,6 @@ public class SandboxSupplementaryDocumentTextDataCheckTest { @Mock SandboxRecommendation sandboxRecommendationMock; @Mock SandboxBreakdown sandboxBreakdownMock; - @Test - public void builder_shouldThrowExceptionForMissingRecommendation() { - try { - SandboxSupplementaryDocumentTextDataCheck.builder().build(); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage(), containsString("recommendation")); - return; - } - fail("Expected an exception"); - } - @Test public void builder_shouldInitialiseDocumentFieldsMap() { SandboxSupplementaryDocumentTextDataCheck result = SandboxSupplementaryDocumentTextDataCheck.builder() @@ -67,4 +56,4 @@ public void builder_shouldAllowMapForDocumentFields() { assertThat(result.getResult().getDocumentFields(), hasEntry("firstKey", (Object) "firstValue")); assertThat(result.getResult().getDocumentFields(), hasEntry("secondKey", (Object) 100)); } -} \ No newline at end of file +} diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckTest.java index 9e5d013c1..ee61c401d 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/check/SandboxZoomLivenessCheckTest.java @@ -21,17 +21,6 @@ public class SandboxZoomLivenessCheckTest { @Mock SandboxRecommendation sandboxRecommendationMock; @Mock SandboxBreakdown sandboxBreakdownMock; - @Test - public void builder_shouldThrowExceptionForMissingRecommendation() { - try { - SandboxLivenessCheck.forZoomLiveness().build(); - } catch (IllegalArgumentException ex) { - assertThat(ex.getMessage(), containsString("recommendation")); - return; - } - fail("Expected an exception"); - } - @Test public void builder_shouldBuildWithCorrectValues() { SandboxLivenessCheck result = new SandboxZoomLivenessCheckBuilder() diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTaskTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTaskTest.java index d8dfc328c..d519b304f 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTaskTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxDocumentTextDataExtractionTaskTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import java.util.Base64; import java.util.HashMap; @@ -105,4 +106,14 @@ public void builder_shouldSetResponseDelay() { assertThat(result.getResponseDelay(), is(10)); } + @Test + public void builder_shouldSetResultTemplate() { + SandboxDocumentTextDataExtractionTask result = SandboxDocumentTextDataExtractionTask.builder() + .withResultTemplate("someResultTemplate") + .build(); + + assertThat(result.getResultTemplate(), is("someResultTemplate")); + assertThat(result.getResult(), is(nullValue())); + } + } diff --git a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTaskTest.java b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTaskTest.java index 93cb6df02..d9cd17e07 100644 --- a/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTaskTest.java +++ b/yoti-sdk-sandbox/src/test/java/com/yoti/api/client/sandbox/docs/request/task/SandboxSupplementaryDocTextDataExtractionTaskTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import java.util.HashMap; import java.util.Map; @@ -90,4 +91,14 @@ public void builder_shouldSetResponseDelay() { assertThat(result.getResponseDelay(), is(10)); } + @Test + public void builder_shouldSetResultTemplate() { + SandboxSupplementaryDocTextDataExtractionTask result = SandboxSupplementaryDocTextDataExtractionTask.builder() + .withResultTemplate("someResultTemplate") + .build(); + + assertThat(result.getResultTemplate(), is("someResultTemplate")); + assertThat(result.getResult(), is(nullValue())); + } + } diff --git a/yoti-sdk-spring-boot-auto-config/README.md b/yoti-sdk-spring-boot-auto-config/README.md index 4deab4d1c..1e1b254e2 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 - 3.11.0 + 3.12.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: '3.11.0' +compile group: 'com.yoti', name: 'yoti-sdk-spring-boot-auto-config', version: '3.12.0-SNAPSHOT' ``` diff --git a/yoti-sdk-spring-boot-auto-config/pom.xml b/yoti-sdk-spring-boot-auto-config/pom.xml index dd7598274..5ce5fd9bf 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 - 3.11.0 + 3.12.0-SNAPSHOT ../yoti-sdk-parent diff --git a/yoti-sdk-spring-boot-example/README.md b/yoti-sdk-spring-boot-example/README.md index 57accbcde..074d66185 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 - 3.11.0 + 3.12.0-SNAPSHOT ``` @@ -45,6 +45,11 @@ The logic for all the v1 share examples can be found in the `YotiLoginController * Navigate to: * [https://localhost:8443/v2/digital-identity-share](https://localhost:8443/v2/digital-identity-share) to initiate a login using the Yoti share v2 +### Digital Identity Match +* You can run your server-app by executing `java -jar -Dyoti.api.url="https://api.yoti.com/did" target/yoti-sdk-spring-boot-example.jar`. The JVM argument is required to override the default `https://api.yoti.com/api/v1` +* Navigate to: + * [https://localhost:8443/did/](https://localhost:8443/did/) to display the form to initiate a digital ID match + The logic for the v2 share example session creation and receipt can be found respectively in the `IdentitySessionController` and `IdentityLoginController` ## Requirements for running the application diff --git a/yoti-sdk-spring-boot-example/pom.xml b/yoti-sdk-spring-boot-example/pom.xml index fa66ee46e..708829fd8 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 - 3.11.0 + 3.12.0-SNAPSHOT org.springframework.boot @@ -45,12 +45,13 @@ 3.8.5 - 33.0.0-jre + 33.2.1-jre - 4.8.3.1 - 3.4.1 - 1.7.0 - 3.11.0 + + 4.8.6.6 + 3.5.0 + 1.10.0 + 3.14.0 diff --git a/yoti-sdk-spring-boot-example/src/main/java/com/yoti/api/examples/springboot/DigitalIdController.java b/yoti-sdk-spring-boot-example/src/main/java/com/yoti/api/examples/springboot/DigitalIdController.java new file mode 100644 index 000000000..8b4efa9d6 --- /dev/null +++ b/yoti-sdk-spring-boot-example/src/main/java/com/yoti/api/examples/springboot/DigitalIdController.java @@ -0,0 +1,100 @@ +package com.yoti.api.examples.springboot; + +import java.net.URI; +import java.util.AbstractMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import com.yoti.api.client.DigitalIdentityClient; +import com.yoti.api.client.identity.MatchNotification; +import com.yoti.api.client.identity.MatchRequest; +import com.yoti.api.client.identity.MatchResult; +import com.yoti.api.client.spi.remote.call.ResourceException; +import com.yoti.api.examples.springboot.model.MatchInputForm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Controller +@RequestMapping("/did") +public class DigitalIdController implements WebMvcConfigurer { + + private final DigitalIdentityClient client; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); + } + + @Autowired + public DigitalIdController(DigitalIdentityClient client) { + this.client = client; + } + + @RequestMapping("/") + public String home(Model model) { + model.addAttribute("matchInputForm", new MatchInputForm()); + return "match-input"; + } + + @PostMapping("/match") + public String match(@ModelAttribute("matchInputForm") MatchInputForm form, Model model) { + MatchNotification.Builder notification = MatchNotification.forUrl(URI.create(form.getEndpoint())) + .withVerifyTls(form.isVerifyTls()) + .withMethod(form.getHttpMethod()); + + List keys = form.getHeaderKeys(); + List values = form.getHeaderValues(); + + Map headers = IntStream.range(0, keys.size()) + .mapToObj(i -> new AbstractMap.SimpleEntry<>( + keys.get(i), + i < values.size() ? values.get(i) : "" + )) + .filter(entry -> entry.getKey() != null && !entry.getKey().isEmpty()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (!headers.isEmpty()) { + notification.withHeaders(headers); + } + + MatchRequest.Builder match = MatchRequest.builder(form.getValue()).withNotification(notification.build()); + + MatchResult result = execute(() -> client.fetchMatch(match.build()), model); + + return Optional.ofNullable(result) + .map(r -> { + model.addAttribute("matchId", r.getId()); + model.addAttribute("matchResult", r.getResult()); + + return "match-result"; + }) + .orElse("match-error"); + } + + private static T execute(Supplier supplier, Model model) { + try { + return supplier.get(); + } catch (Exception ex) { + if (ex.getCause() instanceof ResourceException) { + ResourceException resourceEx = (ResourceException) ex.getCause(); + model.addAttribute("jsonError", resourceEx.getResponseBody()); + } else { + model.addAttribute("error", ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage()); + } + + return null; + } + } + +} diff --git a/yoti-sdk-spring-boot-example/src/main/java/com/yoti/api/examples/springboot/model/MatchInputForm.java b/yoti-sdk-spring-boot-example/src/main/java/com/yoti/api/examples/springboot/model/MatchInputForm.java new file mode 100644 index 000000000..471891c9a --- /dev/null +++ b/yoti-sdk-spring-boot-example/src/main/java/com/yoti/api/examples/springboot/model/MatchInputForm.java @@ -0,0 +1,73 @@ +package com.yoti.api.examples.springboot.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class MatchInputForm { + + private String value; + private String endpoint; + private String httpMethod; + private boolean verifyTls; + private List headerKeys = new ArrayList<>(); + private List headerValues = new ArrayList<>(); + + public MatchInputForm() { + value = "+442532733270"; + endpoint = "https://company.com/callback/did-match"; + httpMethod = "POST"; + verifyTls = true; + headerKeys.add("X-Request-ID"); + headerValues.add(UUID.randomUUID().toString()); + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getEndpoint() { + return endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public String getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(String httpMethod) { + this.httpMethod = httpMethod; + } + + public boolean isVerifyTls() { + return verifyTls; + } + + public void setVerifyTls(boolean verifyTls) { + this.verifyTls = verifyTls; + } + + public List getHeaderKeys() { + return headerKeys; + } + + public void setHeaderKeys(List headerKeys) { + this.headerKeys = headerKeys; + } + + public List getHeaderValues() { + return headerValues; + } + + public void setHeaderValues(List headerValues) { + this.headerValues = headerValues; + } + +} diff --git a/yoti-sdk-spring-boot-example/src/main/resources/templates/match-error.html b/yoti-sdk-spring-boot-example/src/main/resources/templates/match-error.html new file mode 100644 index 000000000..7672af2f0 --- /dev/null +++ b/yoti-sdk-spring-boot-example/src/main/resources/templates/match-error.html @@ -0,0 +1,35 @@ + + + + + + Error + + + + + + +
+
+
+ Yoti +
+
+

Home

+

Oops, something went wrong.

+

Error:

+ +
+

+
+                
+            
+
+
+
+ + + diff --git a/yoti-sdk-spring-boot-example/src/main/resources/templates/match-input.html b/yoti-sdk-spring-boot-example/src/main/resources/templates/match-input.html new file mode 100644 index 000000000..04e79b9e1 --- /dev/null +++ b/yoti-sdk-spring-boot-example/src/main/resources/templates/match-input.html @@ -0,0 +1,66 @@ + + + + + Run Match + + + + + + +
+
+
+ Yoti +
+

Run Digital ID Match

+ +
+
+ + + + diff --git a/yoti-sdk-spring-boot-example/src/main/resources/templates/match-result.html b/yoti-sdk-spring-boot-example/src/main/resources/templates/match-result.html new file mode 100644 index 000000000..e6c411128 --- /dev/null +++ b/yoti-sdk-spring-boot-example/src/main/resources/templates/match-result.html @@ -0,0 +1,37 @@ + + + + + Match Result + + + + + + + +
+
+
+ Yoti +
+

Match Result

+ +
+
+ + + diff --git a/yoti-sdk-spring-security/README.md b/yoti-sdk-spring-security/README.md index 314b4fb63..97b3fa1d1 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 - 3.11.0 + 3.12.0-SNAPSHOT ``` If you are using Gradle, here is the dependency to add: ``` -compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '3.11.0' +compile group: 'com.yoti', name: 'yoti-sdk-spring-security', version: '3.12.0-SNAPSHOT' ``` ### Provide a `YotiClient` instance diff --git a/yoti-sdk-spring-security/pom.xml b/yoti-sdk-spring-security/pom.xml index 9d1d45869..398d0d8af 100644 --- a/yoti-sdk-spring-security/pom.xml +++ b/yoti-sdk-spring-security/pom.xml @@ -12,7 +12,7 @@ com.yoti yoti-sdk-parent - 3.11.0 + 3.12.0-SNAPSHOT ../yoti-sdk-parent