diff --git a/docs/db/changelog/changesets/enrollment-server-onboarding/1.5.x/20230530-add-column-total-attempts.xml b/docs/db/changelog/changesets/enrollment-server-onboarding/1.5.x/20230530-add-column-total-attempts.xml
new file mode 100644
index 00000000..16218d4c
--- /dev/null
+++ b/docs/db/changelog/changesets/enrollment-server-onboarding/1.5.x/20230530-add-column-total-attempts.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+ Add total_attempts column
+
+
+
+
+
diff --git a/docs/db/changelog/changesets/enrollment-server-onboarding/1.5.x/db.changelog-version.xml b/docs/db/changelog/changesets/enrollment-server-onboarding/1.5.x/db.changelog-version.xml
index 53acb1ef..39cdd4d0 100644
--- a/docs/db/changelog/changesets/enrollment-server-onboarding/1.5.x/db.changelog-version.xml
+++ b/docs/db/changelog/changesets/enrollment-server-onboarding/1.5.x/db.changelog-version.xml
@@ -4,5 +4,6 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">
+
\ No newline at end of file
diff --git a/docs/onboarding/Database-Structure.md b/docs/onboarding/Database-Structure.md
index 70098372..fd1317f8 100644
--- a/docs/onboarding/Database-Structure.md
+++ b/docs/onboarding/Database-Structure.md
@@ -26,11 +26,11 @@ Only one ShedLock table is required per PowerAuth stack in case the same schema
## Auditing
-The DDL files contain an `audit_log` table definition. The table differs slightly per database.
+The DDL files contain an `audit_log` table definition. The table differs slightly per database.
Only one `audit_log` table is required per PowerAuth stack in case the same schema is used for all deployed applications.
-For more information about auditing library, see the [Wultra auditing library documentation](https://github.com/wultra/lime-java-core#wultra-auditing-library).
+For more information about auditing library, see the [Wultra auditing library documentation](https://github.com/wultra/lime-java-core#wultra-auditing-library).
## Table Documentation
@@ -78,7 +78,8 @@ Stores onboarding OTP codes used during activation and user verification.
| `type` | `VARCHAR(32)` | `NOT NULL` | OTP code type (`ACTIVATION`, `USER_VERIFICATION`). |
| `error_detail` | `VARCHAR(256)` | | Detail of error (e.g. information about timeout or exceeded number of failed attempts). |
| `error_origin` | `VARCHAR(256)` | | Origin of the error (`DOCUMENT_VERIFICATION`, `PRESENCE_CHECK`, `CLIENT_EVALUATION`, `OTP_VERIFICATION`, `PROCESS_LIMIT_CHECK`, `USER_REQUEST`). |
-| `failed_attempts` | `INTEGER` | | Number of failed attempts for verification, |
+| `failed_attempts` | `INTEGER` | | Number of failed attempts for verification. |
+| `total_attempts` | `INTEGER` | | Number of total attempts for verification. |
| `timestamp_created` | `TIMESTAMP` | `NOT NULL DEFAULT CURRENT_TIMESTAMP` | Timestamp when process was started. |
| `timestamp_expiration` | `TIMESTAMP` | `NOT NULL` | Timestamp when the OTP expires. |
| `timestamp_last_updated` | `TIMESTAMP` | | Timestamp when record was last updated. |
diff --git a/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.5.0.md b/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.5.0.md
index 977f0180..786fff4b 100644
--- a/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.5.0.md
+++ b/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.5.0.md
@@ -54,6 +54,26 @@ ALTER TABLE es_onboarding_process
ADD fds_data CLOB;
```
+### Total Attempts
+
+A new column `total_attempts` has been added to the table `es_onboarding_otp`.
+
+
+#### PostgreSQL
+
+```sql
+ALTER TABLE es_onboarding_process
+ ADD COLUMN TOTAL_ATTEMPTS INTEGER DEFAULT 0;
+```
+
+
+#### Oracle
+
+```sql
+ALTER TABLE es_onboarding_process
+ ADD total_attempts INTEGER DEFAULT 0;
+```
+
## Dependencies
diff --git a/docs/sql/oracle/onboarding/create-schema.sql b/docs/sql/oracle/onboarding/create-schema.sql
index 88889f12..e04c2559 100644
--- a/docs/sql/oracle/onboarding/create-schema.sql
+++ b/docs/sql/oracle/onboarding/create-schema.sql
@@ -51,6 +51,7 @@ CREATE TABLE ES_ONBOARDING_OTP (
ERROR_DETAIL VARCHAR2(256 CHAR),
ERROR_ORIGIN VARCHAR2(256 CHAR),
FAILED_ATTEMPTS INTEGER,
+ TOTAL_ATTEMPTS INTEGER DEFAULT 0,
TIMESTAMP_CREATED TIMESTAMP(6) NOT NULL,
TIMESTAMP_EXPIRATION TIMESTAMP(6) NOT NULL,
TIMESTAMP_LAST_UPDATED TIMESTAMP(6),
diff --git a/docs/sql/postgresql/onboarding/create-schema.sql b/docs/sql/postgresql/onboarding/create-schema.sql
index af16cae2..30d8fab2 100644
--- a/docs/sql/postgresql/onboarding/create-schema.sql
+++ b/docs/sql/postgresql/onboarding/create-schema.sql
@@ -55,6 +55,7 @@ CREATE TABLE es_onboarding_otp (
error_detail VARCHAR(256),
error_origin VARCHAR(256),
failed_attempts INTEGER,
+ total_attempts INTEGER DEFAULT 0,
timestamp_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
timestamp_expiration TIMESTAMP NOT NULL,
timestamp_last_updated TIMESTAMP,
diff --git a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/OnboardingProcessRepository.java b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/OnboardingProcessRepository.java
index c37d7055..1060b38c 100644
--- a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/OnboardingProcessRepository.java
+++ b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/OnboardingProcessRepository.java
@@ -89,8 +89,7 @@ public interface OnboardingProcessRepository extends CrudRepository findByActivationIdAndStatusWithLock(String activationId, OnboardingStatus status);
/**
diff --git a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java
index 9a042bad..f58c9219 100644
--- a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java
+++ b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/database/entity/OnboardingOtpEntity.java
@@ -92,6 +92,9 @@ public class OnboardingOtpEntity implements Serializable {
@Column(name = "failed_attempts")
private int failedAttempts;
+ @Column(name = "total_attempts")
+ private int totalAttempts;
+
@Column(name = "timestamp_created", nullable = false)
private Date timestampCreated;
diff --git a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java
index 43de3b2c..03f334bb 100644
--- a/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java
+++ b/enrollment-server-onboarding-common/src/main/java/com/wultra/app/onboardingserver/common/service/CommonOtpService.java
@@ -118,6 +118,7 @@ protected OtpVerifyResponse verifyOtpCode(String processId, OwnerId ownerId, Str
otp.setErrorOrigin(ErrorOrigin.OTP_VERIFICATION);
otp.setTimestampLastUpdated(now);
otp.setTimestampFailed(now);
+ otp.setTotalAttempts(otp.getTotalAttempts() + 1);
onboardingOtpRepository.save(otp);
auditService.audit(otp, "OTP expired for user: {}", process.getUserId());
} else if (otp.getOtpCode().equals(otpCode)) {
@@ -125,10 +126,12 @@ protected OtpVerifyResponse verifyOtpCode(String processId, OwnerId ownerId, Str
otp.setStatus(OtpStatus.VERIFIED);
otp.setTimestampVerified(now);
otp.setTimestampLastUpdated(now);
+ otp.setTotalAttempts(otp.getTotalAttempts() + 1);
onboardingOtpRepository.save(otp);
logger.info("OTP {} verified, {}", otpType, ownerId);
auditService.audit(otp, "OTP {} verified for user: {}", otpType, process.getUserId());
} else {
+ auditService.audit(otp, "OTP {} verification failed for user: {}", otpType, process.getUserId());
handleFailedOtpVerification(process, ownerId, otp, otpType);
}
@@ -168,6 +171,7 @@ private void handleFailedOtpVerification(OnboardingProcessEntity process, OwnerI
int failedAttempts = fetchFailedAttemptsCount(process, otpType);
final int maxFailedAttempts = commonOnboardingConfig.getOtpMaxFailedAttempts();
otp.setFailedAttempts(otp.getFailedAttempts() + 1);
+ otp.setTotalAttempts(otp.getTotalAttempts() + 1);
otp.setTimestampLastUpdated(ownerId.getTimestamp());
otp = onboardingOtpRepository.save(otp);
failedAttempts++;
diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java
index d3161847..8ba0e08e 100644
--- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java
+++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/OtpServiceImpl.java
@@ -172,6 +172,7 @@ private String generateOtpCode(OnboardingProcessEntity process, OtpType otpType)
otp.setTimestampCreated(timestampCreated);
otp.setTimestampExpiration(timestampExpiration);
otp.setFailedAttempts(0);
+ otp.setTotalAttempts(0);
if (otpType == OtpType.USER_VERIFICATION) {
final String activationId = process.getActivationId();
diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java
index ed660e6b..2710de77 100644
--- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java
+++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/impl/service/document/DocumentProcessingService.java
@@ -249,7 +249,7 @@ public DocumentSubmitResult submitDocumentToProvider(OwnerId ownerId, DocumentVe
try {
docsSubmitResults = documentVerificationProvider.submitDocuments(ownerId, List.of(submittedDoc));
final IdentityVerificationEntity identityVerification = docVerification.getIdentityVerification();
- auditService.auditDocumentVerificationProvider(identityVerification, "Submit documents for user: {}", ownerId.getUserId());
+ auditService.auditDocumentVerificationProvider(identityVerification, "Submit documents for user: {}, document ID: {}", ownerId.getUserId(), docVerification.getId());
docSubmitResult = docsSubmitResults.getResults().get(0);
} catch (DocumentVerificationException | RemoteCommunicationException e) {
logger.warn("Document verification ID: {}, failed: {}", docVerification.getId(), e.getMessage());
diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/config/IProovConfig.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/config/IProovConfig.java
index 5b87744c..b0c96b91 100644
--- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/config/IProovConfig.java
+++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/config/IProovConfig.java
@@ -25,6 +25,7 @@
import com.wultra.core.rest.client.base.RestClient;
import com.wultra.core.rest.client.base.RestClientConfiguration;
import com.wultra.core.rest.client.base.RestClientException;
+import io.netty.channel.ChannelOption;
import lombok.extern.slf4j.Slf4j;
import net.minidev.json.JSONObject;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -32,6 +33,7 @@
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService;
@@ -49,9 +51,14 @@
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
import org.springframework.web.util.UriComponentsBuilder;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.resources.ConnectionProvider;
+import java.time.Duration;
import java.util.Map;
+import java.util.Objects;
/**
* iProov configuration.
@@ -101,9 +108,7 @@ public WebClient iproovManagemenentWebClient(final IProovConfigProps configProps
final ServerOAuth2AuthorizedClientExchangeFilterFunction oAuth2ExchangeFilterFunction = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oAuth2ExchangeFilterFunction.setDefaultClientRegistrationId(OAUTH_REGISTRATION_ID);
- return WebClient.builder()
- .filter(oAuth2ExchangeFilterFunction)
- .build();
+ return createWebClient(oAuth2ExchangeFilterFunction, configProps, "user management client");
}
private static AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientServiceReactiveOAuth2AuthorizedClientManager(final IProovConfigProps configProps) {
@@ -124,7 +129,7 @@ private static AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager auth
final ReactiveOAuth2AuthorizedClientService clientService = new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrations);
final ClientCredentialsReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = new ClientCredentialsReactiveOAuth2AuthorizedClientProvider();
- authorizedClientProvider.setAccessTokenResponseClient(accessTokenResponseClient());
+ authorizedClientProvider.setAccessTokenResponseClient(accessTokenResponseClient(configProps));
final AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrations, clientService);
@@ -133,28 +138,55 @@ private static AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager auth
}
// TODO (racansky, 2023-06-05) remove when iProov fix API according the RFC
- private static ReactiveOAuth2AccessTokenResponseClient accessTokenResponseClient() {
+ private static ReactiveOAuth2AccessTokenResponseClient accessTokenResponseClient(final IProovConfigProps configProps) {
@SuppressWarnings("unchecked")
final ExchangeFilterFunction tokenResponseFilter = ExchangeFilterFunction.ofResponseProcessor(response -> {
- final ClientResponse.Builder builder = response.mutate();
- return response.bodyToMono(Map.class).map(map -> {
- if (map.containsKey(AuthTokenResponse.JSON_PROPERTY_SCOPE)) {
- logger.debug("Removing scope because does not comply with RFC and not needed anyway");
- map.remove(AuthTokenResponse.JSON_PROPERTY_SCOPE);
- return builder.body(JSONObject.toJSONString(map)).build();
- } else {
- return builder.build();
- }
- });
+ final ClientResponse.Builder builder = response.mutate();
+ return response.bodyToMono(Map.class).map(map -> {
+ logger.trace("Got access token");
+ if (map.containsKey(AuthTokenResponse.JSON_PROPERTY_SCOPE)) {
+ logger.debug("Removing scope because does not comply with RFC and not needed anyway");
+ map.remove(AuthTokenResponse.JSON_PROPERTY_SCOPE);
+ return builder.body(JSONObject.toJSONString(map)).build();
+ } else {
+ return builder.build();
+ }
+ })
+ .doOnError(e -> {
+ if (e instanceof final WebClientResponseException exception) {
+ logger.error("Get access token - Error response body: {}", exception.getResponseBodyAsString());
+ } else {
+ logger.error("Get access token - Error", e);
+ }
+ });
});
- final WebClient webClient = WebClient.builder()
- .filter(tokenResponseFilter)
- .build();
+ final WebClient webClient = createWebClient(tokenResponseFilter, configProps, "oAuth client");
final AbstractWebClientReactiveOAuth2AccessTokenResponseClient accessTokenResponseClient = new WebClientReactiveClientCredentialsTokenResponseClient();
accessTokenResponseClient.setWebClient(webClient);
return accessTokenResponseClient;
}
+ private static WebClient createWebClient(final ExchangeFilterFunction filter, IProovConfigProps configProps, final String logContext) {
+ final RestClientConfiguration restClientConfig = configProps.getRestClientConfig();
+ final Integer connectionTimeout = restClientConfig.getConnectionTimeout();
+ final Duration responseTimeout = restClientConfig.getResponseTimeout();
+ final Duration maxIdleTime = Objects.requireNonNull(restClientConfig.getMaxIdleTime(), "maxIdleTime must be specified");
+ logger.info("Setting {} connectionTimeout: {}, responseTimeout: {}, maxIdleTime: {}", logContext, connectionTimeout, responseTimeout, maxIdleTime);
+
+ final ConnectionProvider connectionProvider = ConnectionProvider.builder("custom")
+ .maxIdleTime(maxIdleTime)
+ .build();
+ final HttpClient httpClient = HttpClient.create(connectionProvider)
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout)
+ .responseTimeout(responseTimeout);
+ final ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
+
+ return WebClient.builder()
+ .clientConnector(connector)
+ .filter(filter)
+ .build();
+ }
+
}
diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/service/IProovRestApiService.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/service/IProovRestApiService.java
index 3f898458..fabc95b1 100644
--- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/service/IProovRestApiService.java
+++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/presencecheck/iproov/service/IProovRestApiService.java
@@ -229,6 +229,8 @@ private boolean doesUserExists(final String userId, final OwnerId id) {
.doOnError(e -> {
if (e instanceof final WebClientResponseException exception) {
logger.error("Get user - Error response body: {}, userId: {}, {}", exception.getResponseBodyAsString(), userId, id);
+ } else {
+ logger.error("Get user - Error, userId: {}, {}", userId, id, e);
}
})
.block(), false);
@@ -241,6 +243,8 @@ private void deleteUser(final String userId, final OwnerId id) {
.doOnError(e -> {
if (e instanceof final WebClientResponseException exception) {
logger.error("Delete user - Error response body: {}, userId: {}, {}", exception.getResponseBodyAsString(), userId, id);
+ } else {
+ logger.error("Get user - Error, userId: {}, {}", userId, id, e);
}
})
.block();
diff --git a/enrollment-server-onboarding/src/main/resources/application.properties b/enrollment-server-onboarding/src/main/resources/application.properties
index cedab3bd..40ca2799 100644
--- a/enrollment-server-onboarding/src/main/resources/application.properties
+++ b/enrollment-server-onboarding/src/main/resources/application.properties
@@ -175,6 +175,7 @@ enrollment-server-onboarding.presence-check.iproov.restClientConfig.proxyUsernam
enrollment-server-onboarding.presence-check.iproov.restClientConfig.proxyPassword=
enrollment-server-onboarding.presence-check.iproov.restClientConfig.connectionTimeout=10000
enrollment-server-onboarding.presence-check.iproov.restClientConfig.responseTimeout=60000
+enrollment-server-onboarding.presence-check.iproov.restClientConfig.maxIdleTime=200s
spring.security.oauth2.client.provider.app.token-uri=http://localhost:6060/oauth/token
diff --git a/enrollment-server-onboarding/src/test/resources/com/wultra/app/onboardingserver/task/cleaning/CleaningServiceTest.testTerminateExpiredOtpCodes.sql b/enrollment-server-onboarding/src/test/resources/com/wultra/app/onboardingserver/task/cleaning/CleaningServiceTest.testTerminateExpiredOtpCodes.sql
index fd980ed1..fa258467 100644
--- a/enrollment-server-onboarding/src/test/resources/com/wultra/app/onboardingserver/task/cleaning/CleaningServiceTest.testTerminateExpiredOtpCodes.sql
+++ b/enrollment-server-onboarding/src/test/resources/com/wultra/app/onboardingserver/task/cleaning/CleaningServiceTest.testTerminateExpiredOtpCodes.sql
@@ -1,7 +1,7 @@
INSERT INTO es_onboarding_process(id, identification_data, status, error_score, custom_data, timestamp_created) VALUES
('b4662611-df91-4053-bb3d-3970979baf5d', '{}', 'VERIFICATION_IN_PROGRESS', 0, '{}', now());
-INSERT INTO es_onboarding_otp(id, process_id, otp_code, failed_attempts, status, type, timestamp_created, timestamp_expiration) VALUES
- ('f50b8c04-649d-43a7-8079-4dbf9b0bbc72', 'b4662611-df91-4053-bb3d-3970979baf5d', '123', 0, 'ACTIVE', 'USER_VERIFICATION', now(), now()),
- ('6560a85d-7d97-44c0-bd29-04c57051aa57', 'b4662611-df91-4053-bb3d-3970979baf5d', '123', 0, 'ACTIVE', 'USER_VERIFICATION', now() - interval '301' second, now()), -- to be failed
- ('e4974ef6-135a-4ae1-be91-a2c0f674c8fd', 'b4662611-df91-4053-bb3d-3970979baf5d', '123', 0, 'VERIFIED', 'USER_VERIFICATION', now() - interval '301' second, now());
+INSERT INTO es_onboarding_otp(id, process_id, otp_code, failed_attempts, total_attempts, status, type, timestamp_created, timestamp_expiration) VALUES
+ ('f50b8c04-649d-43a7-8079-4dbf9b0bbc72', 'b4662611-df91-4053-bb3d-3970979baf5d', '123', 0, 0, 'ACTIVE', 'USER_VERIFICATION', now(), now()),
+ ('6560a85d-7d97-44c0-bd29-04c57051aa57', 'b4662611-df91-4053-bb3d-3970979baf5d', '123', 0, 0, 'ACTIVE', 'USER_VERIFICATION', now() - interval '301' second, now()), -- to be failed
+ ('e4974ef6-135a-4ae1-be91-a2c0f674c8fd', 'b4662611-df91-4053-bb3d-3970979baf5d', '123', 0, 0, 'VERIFIED', 'USER_VERIFICATION', now() - interval '301' second, now());
diff --git a/pom.xml b/pom.xml
index 51207631..7335be9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,7 +99,7 @@
1.5.0-SNAPSHOT
1.5.0-SNAPSHOT
- 1.73
+ 1.74