Skip to content

Release 3.12.0 #489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4381688
NA: Use HTTPS for maven scm config
irotech Jul 16, 2025
8ba0239
SDK-2640: Migrate to Sonatype Maven Central
irotech Jul 16, 2025
0588932
Merge pull request #488 from getyoti/SDK-2640_central_portal
irotech Jul 17, 2025
fdf4194
Bump maven-deploy-plugin version (3.1.1 → 3.1.4)
irotech Jun 13, 2025
9491592
Bump spotbugs-maven-plugin version (4.8.3.1 → 4.8.6.6)
irotech Jun 13, 2025
78b5adb
Bump findsecbugs-plugin version (1.13.0 → 1.14.0)
irotech Jun 13, 2025
f718164
Bump maven-compiler-plugin version (3.11.0 → 3.14.0)
irotech Jun 13, 2025
b9ae395
Bump maven-enforcer-plugin version (3.4.1 → 3.5.0)
irotech Jun 13, 2025
1189838
Bump animal-sniffer-maven-plugin version (1.23 → 1.24)
irotech Jun 13, 2025
03246c4
Bump maven-source-plugin version (3.3.0 → 3.3.1)
irotech Jun 13, 2025
5a40a2d
Bump maven-javadoc-plugin version (3.6.3 → 3.11.2)
irotech Jun 13, 2025
9fb23c4
Bump maven-gpg-plugin version (3.1.0 → 3.2.7)
irotech Jun 13, 2025
47acd04
Bump maven-project-info-reports-plugin version (3.5.0 → 3.9.0)
irotech Jun 13, 2025
4da3a9a
Bump jacoco-maven-plugin version (0.8.11 → 0.8.13)
irotech Jun 13, 2025
326283f
Bump dependency-check-maven version (8.4.3 → 10.0.4)
irotech Jun 13, 2025
970833a
Bump jackson version (2.16.1 → 2.19.0)
irotech Jun 13, 2025
fef405c
Bump guava version (33.0.0-jre → 33.2.1-jre)
irotech Jun 13, 2025
e610e70
Bump protobuf-java version (3.25.3 → 3.25.8)
irotech Jun 13, 2025
9fe9815
Bump bouncycastle bcpkix-jdk15on (1.70) → bcpkix-jdk18on (1.81)
irotech Jun 13, 2025
6c6c2a6
Bump hamcrest version (2.2 → 3.0)
irotech Jun 13, 2025
be16ced
Bump commons-lang3 version (3.13.0 → 3.17.0)
irotech Jul 17, 2025
9e697b5
Bump slf4j version (2.0.9 → 2.0.16)
irotech Jul 17, 2025
477b06a
Merge pull request #485 from getyoti/version_bumps
irotech Jul 17, 2025
721fd43
SDK-2584: Add support for digital identity match
irotech Jun 18, 2025
0e18a1f
SDK-2584: Add example for digital identity match
irotech Jun 18, 2025
f5b398f
Merge pull request #486 from getyoti/SDK-2584_did-match
irotech Jul 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
<maven.min.version>3.8.5</maven.min.version>

<!-- plugin versions -->
<maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version>
<maven-deploy-plugin.version>3.1.4</maven-deploy-plugin.version>
<properties-maven-plugin.version>1.2.1</properties-maven-plugin.version>
<spotbugs-maven-plugin.version>4.8.3.1</spotbugs-maven-plugin.version>
<maven-enforcer-plugin.version>3.4.1</maven-enforcer-plugin.version>
<extra-enforcer-rules.version>1.7.0</extra-enforcer-rules.version>
<!-- Spotbugs spotbugs-maven-plugin 4.9.x requires JDK 11+ -->
<spotbugs-maven-plugin.version>4.8.6.6</spotbugs-maven-plugin.version>
<maven-enforcer-plugin.version>3.5.0</maven-enforcer-plugin.version>
<extra-enforcer-rules.version>1.10.0</extra-enforcer-rules.version>
</properties>

<build>
Expand Down
2 changes: 1 addition & 1 deletion yoti-sdk-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<artifactId>bcpkix-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, String> 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<String, String> 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<String, String> 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<String, String> 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";

}

}
Original file line number Diff line number Diff line change
@@ -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";

}

}
Original file line number Diff line number Diff line change
@@ -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";

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
Loading