Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
209b5ad
DEVELOPMENT: Bump version to 4.0.0-SNAPSHOT
MrBurtyyy Sep 27, 2024
04a5bb9
SDK-2531: Update SessionSpec to use strongly typed object for Identit…
MrBurtyyy Sep 27, 2024
097af1c
SDK-2532: Update SessionSpec to use strongly typed object for Identit…
MrBurtyyy Sep 27, 2024
4e53eca
SDK-2533: Change IdentityProfileResponse to use a stronly typed objec…
MrBurtyyy Sep 27, 2024
c23ba66
SDK-2532: Rename IdentityProfileSubjectPayload -> SubjectPayload
MrBurtyyy Sep 27, 2024
49c5c80
NA: Inline JSON property name in IDV classes
MrBurtyyy Sep 27, 2024
606757e
NA: Optimize imports
MrBurtyyy Sep 27, 2024
404ac45
NA: Update README with breaking changes in 4.0.0
MrBurtyyy Sep 30, 2024
ccc772b
SDK-2534: Move Identity Profile responses and associated classes to t…
MrBurtyyy Sep 30, 2024
f8475df
SDK-2771: Rename SignedRequest->YotiHttpRequest
bucky-boy Dec 5, 2025
5cee1cf
SDK-2771: [MB] Introduce support for auth tokens
bucky-boy Dec 10, 2025
42a1015
SDK-2771: [MB] Tidy up DigitalIdentityServiceTest
bucky-boy Dec 11, 2025
f20b970
SDK-2771: [MB] Address SonarQube quality concern surrounding use of r…
bucky-boy Dec 12, 2025
f6a4967
SDK-2771: Rename some internal methods createSignedRequest->createReq…
bucky-boy Dec 15, 2025
b2d94d0
SDK-2771: Add NoAuthStrategy to be used on endpoints that don't requi…
MrBurtyyy Dec 16, 2025
58ac25d
SDK-2771: Add new maven module for supporting the creation of Yoti au…
MrBurtyyy Dec 10, 2025
ebea14e
SDK-2771: Read from the error stream if we get >= 400 HTTP status cod…
MrBurtyyy Dec 17, 2025
8404aae
SDK-2771: Specify exact json property names for response from auth se…
MrBurtyyy Dec 17, 2025
58c5244
SDK-2771: Allow the DocScanSandboxClient to use authentication token …
MrBurtyyy Dec 12, 2025
a53d1a1
Test: see if running jobs in parallel is causing issues with maven
MrBurtyyy Jan 6, 2026
3f19734
SDK-2756: Add support for requesting, and fetching Share Code resourc…
MrBurtyyy Jan 6, 2026
47b32b7
SDK-2779: Expose capture_type property on StaticLivenessResourceResponse
MrBurtyyy Jan 6, 2026
c973f55
SDK-2741: Expose process property on BreakdownResponse
MrBurtyyy Jan 6, 2026
44d814b
NA: Use Maven cache when running junit tests on Github Actions
MrBurtyyy Jan 6, 2026
caac317
SDK-2782: Correct constructor visibility for classes that have builders
MrBurtyyy Jan 6, 2026
65375e6
SDK-2756: Revert ability to request share codes as part of a regular …
MrBurtyyy Feb 16, 2026
1e51c55
SDK-2784: Use MediaResponse class instead of Media interface for Shar…
MrBurtyyy Feb 16, 2026
56957fa
Release 4.0.0: Bump version for release
MrBurtyyy Feb 23, 2026
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
7 changes: 7 additions & 0 deletions .github/workflows/junit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
fail-fast: false
matrix:
jdk-version: [8,11,17]
max-parallel: 1

steps:
- uses: actions/checkout@v4
Expand All @@ -25,4 +26,10 @@ jobs:
distribution: 'zulu'
java-version: ${{ matrix.jdk-version }}
architecture: x64
- uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- run: mvn test -B -pl yoti-sdk-api -Ddependency-check.skip=true
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ If you are using Maven, you need to add the following dependency:
<dependency>
<groupId>com.yoti</groupId>
<artifactId>yoti-sdk-api</artifactId>
<version>3.12.0</version>
<version>4.0.0</version>
</dependency>
```

If you are using Gradle, here is the dependency to add:

`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '3.12.0'`
`compile group: 'com.yoti', name: 'yoti-sdk-api', version: '4.0.0'`

You will find all classes packaged under `com.yoti.api`

Expand Down Expand Up @@ -294,6 +294,10 @@ Instructions on how to run the Spring example projects can be found at the follo
This major update does not have any major updates to the API, but instead builds upon and
standardizes our implementation.

## Breaking changes and enhancements made in v4.0.0

- Creating an Identity Profile session now uses strongly typed classes, instead of a Map

### Dropped support for Java 7
Minimum supported Java version is now 8.

Expand Down
2 changes: 1 addition & 1 deletion examples/doc-scan/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<dependency>
<groupId>com.yoti</groupId>
<artifactId>yoti-sdk-api</artifactId>
<version>3.12.0</version>
<version>4.0.0</version>
</dependency>
</dependencies>

Expand Down
8 changes: 8 additions & 0 deletions examples/doc-scan/src/main/resources/templates/success.html
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,14 @@ <h2>Identity Profile</h2>
</div>
</div>

<th:block th:if="${sessionResult.getIdentityProfile().getIdentityProfileReport()() != null}">
<div th:if="${sessionResult.getIdentityProfile().getIdentityProfileReport().getMedia() != null}">
Generated Profile Media: <a th:href="${'/media?mediaId=' + sessionResult.getIdentityProfile().getIdentityProfileReport().getMedia().getId()}"
th:text="${sessionResult.getIdentityProfile().getIdentityProfileReport().getMedia().getId()}">
</a>
</div>
</th:block>

<!-- Identity Profile Failure Reason -->
<th:block th:if="${sessionResult.getIdentityProfile().getFailureReason() != null}">
<div class="row pt-4">
Expand Down
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
<groupId>com.yoti</groupId>
<artifactId>yoti-sdk</artifactId>
<packaging>pom</packaging>
<version>3.12.0</version>
<version>4.0.0</version>
<name>Yoti SDK</name>
<description>Java SDK for simple integration with the Yoti platform</description>
<url>https://github.com/getyoti/yoti-java-sdk</url>

<modules>
<module>yoti-sdk-parent</module>
<module>yoti-sdk-api</module>
<module>yoti-sdk-auth</module>
<module>yoti-sdk-sandbox</module>
<module>yoti-sdk-spring-boot-auto-config</module>
<module>yoti-sdk-spring-security</module>
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 @@ -11,7 +11,7 @@
<parent>
<groupId>com.yoti</groupId>
<artifactId>yoti-sdk-parent</artifactId>
<version>3.12.0</version>
<version>4.0.0</version>
<relativePath>../yoti-sdk-parent</relativePath>
</parent>

Expand Down
4 changes: 2 additions & 2 deletions yoti-sdk-api/spotbugs/exclude-filter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
</Match>

<Match>
<Class name="com.yoti.api.client.spi.remote.call.SignedRequest"/>
<Class name="com.yoti.api.client.spi.remote.call.YotiHttpRequest"/>
<Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/>
</Match>

<Match>
<Class name="com.yoti.api.client.spi.remote.call.SignedRequestBuilder"/>
<Class name="com.yoti.api.client.spi.remote.call.YotiHttpRequestBuilder"/>
<Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"/>
</Match>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,49 +23,36 @@ public class DigitalIdentityClient {
Security.addProvider(new BouncyCastleProvider());
}

private final String sdkId;
private final KeyPair keyPair;
private final DigitalIdentityService identityService;

DigitalIdentityClient(String sdkId, KeyPairSource keyPair, DigitalIdentityService identityService) {
Validation.notNullOrEmpty(sdkId, "SDK ID");
Validation.notNull(keyPair, "Application Key Pair");

this.sdkId = sdkId;
this.keyPair = loadKeyPair(keyPair);
private DigitalIdentityClient(KeyPair keyPair, DigitalIdentityService identityService) {
this.keyPair = keyPair;
this.identityService = identityService;
}

public ShareSession createShareSession(ShareSessionRequest request) throws DigitalIdentityException {
return identityService.createShareSession(sdkId, keyPair, request);
return identityService.createShareSession(request);
}

public ShareSession fetchShareSession(String sessionId) throws DigitalIdentityException {
return identityService.fetchShareSession(sdkId, keyPair, sessionId);
return identityService.fetchShareSession(sessionId);
}

public ShareSessionQrCode createShareQrCode(String sessionId) throws DigitalIdentityException {
return identityService.createShareQrCode(sdkId, keyPair, sessionId);
return identityService.createShareQrCode(sessionId);
}

public ShareSessionQrCode fetchShareQrCode(String qrCodeId) throws DigitalIdentityException {
return identityService.fetchShareQrCode(sdkId, keyPair, qrCodeId);
return identityService.fetchShareQrCode(qrCodeId);
}

public Receipt fetchShareReceipt(String receiptId) throws DigitalIdentityException {
return identityService.fetchShareReceipt(sdkId, keyPair, receiptId);
return identityService.fetchShareReceipt(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());
} catch (IOException ex) {
throw new InitialisationException("Cannot load Key Pair", ex);
}
return identityService.fetchMatch(request);
}

public static Builder builder() {
Expand Down Expand Up @@ -94,7 +81,19 @@ public Builder withKeyPairSource(KeyPairSource keyPairSource) {
}

public DigitalIdentityClient build() {
return new DigitalIdentityClient(sdkId, keyPairSource, DigitalIdentityService.newInstance());
Validation.notNullOrEmpty(sdkId, "SDK ID");
Validation.notNull(keyPairSource, "Application Key Pair");

KeyPair keyPair = loadKeyPair(keyPairSource);
return new DigitalIdentityClient(keyPair, DigitalIdentityService.newInstance(keyPair, sdkId));
}

private KeyPair loadKeyPair(KeyPairSource keyPairSource) throws InitialisationException {
try {
return keyPairSource.getFromStream(new KeyStreamVisitor());
} catch (IOException ex) {
throw new InitialisationException("Cannot load Key Pair", ex);
}
}

}
Expand Down
37 changes: 19 additions & 18 deletions yoti-sdk-api/src/main/java/com/yoti/api/client/YotiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ public class YotiClient {
private final DynamicSharingService dynamicSharingService;

YotiClient(String applicationId,
KeyPairSource kpSource,
KeyPair keyPair,
ReceiptFetcher receiptFetcher,
ActivityDetailsFactory activityDetailsFactory,
RemoteAmlService remoteAmlService,
ActivityDetailsFactory activityDetailsFactory,
DynamicSharingService dynamicSharingService) throws InitialisationException {
this.appId = notNull(applicationId, "Application id");
this.keyPair = loadKeyPair(notNull(kpSource, "Key pair source"));
this.keyPair = keyPair;
this.receiptFetcher = notNull(receiptFetcher, "receiptFetcher");
this.remoteAmlService = notNull(remoteAmlService, "amlService");
this.activityDetailsFactory = notNull(activityDetailsFactory, "activityDetailsFactory");
Expand Down Expand Up @@ -80,7 +80,7 @@ public static YotiClient.Builder builder() {
* @throws ProfileException aggregate exception signalling issues during the call
*/
public ActivityDetails getActivityDetails(String encryptedYotiToken) throws ProfileException {
Receipt receipt = receiptFetcher.fetch(encryptedYotiToken, keyPair, appId);
Receipt receipt = receiptFetcher.fetch(encryptedYotiToken, keyPair);
return activityDetailsFactory.create(receipt, keyPair.getPrivate());
}

Expand All @@ -96,7 +96,7 @@ public ActivityDetails getActivityDetails(String encryptedYotiToken) throws Prof
*/
public AmlResult performAmlCheck(AmlProfile amlProfile) throws AmlException {
LOG.debug("Performing aml check...");
return remoteAmlService.performCheck(keyPair, appId, amlProfile);
return remoteAmlService.performCheck(amlProfile);
}

/**
Expand All @@ -113,15 +113,7 @@ public AmlResult performAmlCheck(AmlProfile amlProfile) throws AmlException {
*/
public ShareUrlResult createShareUrl(DynamicScenario dynamicScenario) throws DynamicShareException {
LOG.debug("Request a share url for a dynamicScenario...");
return dynamicSharingService.createShareUrl(appId, keyPair, dynamicScenario);
}

private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException {
try {
return kpSource.getFromStream(new KeyStreamVisitor());
} catch (IOException e) {
throw new InitialisationException("Cannot load key pair", e);
}
return dynamicSharingService.createShareUrl(appId, dynamicScenario);
}

public static class Builder {
Expand All @@ -144,14 +136,15 @@ public Builder withKeyPair(KeyPairSource keyPairSource) {

public YotiClient build() {
checkBuilderState();
KeyPair keyPair = loadKeyPair(notNull(keyPairSource, "Key pair source"));

return new YotiClient(
sdkId,
keyPairSource,
ReceiptFetcher.newInstance(),
keyPair,
ReceiptFetcher.newInstance(keyPair, sdkId),
RemoteAmlService.newInstance(keyPair, sdkId),
ActivityDetailsFactory.newInstance(),
RemoteAmlService.newInstance(),
DynamicSharingService.newInstance()
DynamicSharingService.newInstance(keyPair)
);
}

Expand All @@ -164,6 +157,14 @@ private void checkBuilderState() {
}
}

private KeyPair loadKeyPair(KeyPairSource kpSource) throws InitialisationException {
try {
return kpSource.getFromStream(new KeyStreamVisitor());
} catch (IOException e) {
throw new InitialisationException("Cannot load key pair", e);
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class AmlAddress {
@JsonProperty("country")
private final String country;

public AmlAddress(String postCode, String country) {
private AmlAddress(String postCode, String country) {
this.postCode = postCode;
this.country = country;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class AmlProfile {
@JsonProperty("address")
private final AmlAddress amlAddress;

AmlProfile(String givenNames, String familyName, String ssn, AmlAddress amlAddress) {
private AmlProfile(String givenNames, String familyName, String ssn, AmlAddress amlAddress) {
this.givenNames = givenNames;
this.familyName = familyName;
this.ssn = ssn;
Expand Down
Loading