From f8e648aaba4adf1cfa650b745e9ec3d649ce5bd9 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 11 Jun 2024 11:37:39 +0200 Subject: [PATCH 1/9] Fix #1071: Configure timeouts for REST clients --- deploy/enrollment-server.xml | 4 ++ deploy/env.list.tmp | 2 + docs/Configuration-Properties.md | 20 ++++--- docs/onboarding/Configuration-Properties.md | 12 +++-- .../PowerAuthWebServiceConfiguration.java | 35 ++++++------ .../configuration/PushServiceConfig.java | 53 ------------------- .../src/main/resources/application.properties | 2 + .../PowerAuthWebServiceConfiguration.java | 35 ++++++------ .../configuration/PushServiceConfig.java | 27 ++++------ .../PushServiceConfigProperties.java | 39 ++++++++++++++ .../controller/api/InboxController.java | 2 +- .../api/PushRegistrationController.java | 2 +- .../impl/service/PushRegistrationService.java | 2 + .../util/ConditionalOnPropertyNotEmpty.java | 11 ++-- .../main/resources/application-dev.properties | 3 ++ .../src/main/resources/application.properties | 4 ++ 16 files changed, 135 insertions(+), 118 deletions(-) delete mode 100644 enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PushServiceConfig.java create mode 100644 enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfigProperties.java diff --git a/deploy/enrollment-server.xml b/deploy/enrollment-server.xml index 8a20f2b6..e0f823c9 100644 --- a/deploy/enrollment-server.xml +++ b/deploy/enrollment-server.xml @@ -19,11 +19,15 @@ + + + + diff --git a/deploy/env.list.tmp b/deploy/env.list.tmp index 8c4ed3da..8caef8af 100644 --- a/deploy/env.list.tmp +++ b/deploy/env.list.tmp @@ -1,4 +1,6 @@ ENROLLMENT_SERVER_POWERAUTH_SERVICE_URL=http://localhost:8080/powerauth-java-server/rest +ENROLLMENT_SERVER_POWERAUTH_SERVICE_RESPONSE_TIMEOUT=60s +ENROLLMENT_SERVER_POWERAUTH_SERVICE_MAX_IDLE_TIME=200s ENROLLMENT_SERVER_SECURITY_CLIENT_TOKEN= ENROLLMENT_SERVER_SECURITY_CLIENT_SECRET= ENROLLMENT_SERVER_PUSH_SERVER_URL= diff --git a/docs/Configuration-Properties.md b/docs/Configuration-Properties.md index af3040ed..e4d3d291 100644 --- a/docs/Configuration-Properties.md +++ b/docs/Configuration-Properties.md @@ -15,17 +15,21 @@ The Enrollment Server uses the following public configuration properties: ## PowerAuth Service Configuration -| Property | Default | Note | -|---|---|---| -| `powerauth.service.url` | `http://localhost:8080/powerauth-java-server/rest` | PowerAuth service REST API base URL. | -| `powerauth.service.security.clientToken` | `_empty_` | PowerAuth REST API authentication token. | -| `powerauth.service.security.clientSecret` | `_empty_` | PowerAuth REST API authentication secret / password. | +| Property | Default | Note | +|------------------------------------------------------|----------------------------------------------------|------------------------------------------------------| +| `powerauth.service.url` | `http://localhost:8080/powerauth-java-server/rest` | PowerAuth service REST API base URL. | +| `powerauth.service.restClientConfig.responseTimeout` | `60s` | PowerAuth REST API response timeout. | +| `powerauth.service.restClientConfig.maxIdleTime` | `200s` | PowerAuth REST API max idle time. | +| `powerauth.service.security.clientToken` | `_empty_` | PowerAuth REST API authentication token. | +| `powerauth.service.security.clientSecret` | `_empty_` | PowerAuth REST API authentication secret / password. | ## PowerAuth Push Service Configuration -| Property | Default | Note | -|---|---|---| -| `powerauth.push.service.url` | `http://localhost:8080/powerauth-push-server` | PowerAuth Push service REST API base URL. | +| Property | Default | Note | +|-----------------------------------------------------------|-----------------------------------------------|---------------------------------------------------| +| `powerauth.push.service.url` | `http://localhost:8080/powerauth-push-server` | PowerAuth Push service REST API base URL. | +| `powerauth.push.service.restClientConfig.responseTimeout` | `60s` | PowerAuth Push service REST API response timeout. | +| `powerauth.push.service.restClientConfig.maxIdleTime` | `200s` | PowerAuth Push service REST API max idle time. | ## Enrollment Server Configuration diff --git a/docs/onboarding/Configuration-Properties.md b/docs/onboarding/Configuration-Properties.md index d236dd43..497b9b1f 100644 --- a/docs/onboarding/Configuration-Properties.md +++ b/docs/onboarding/Configuration-Properties.md @@ -15,11 +15,13 @@ The Onboarding Server uses the following public configuration properties: ## PowerAuth Service Configuration -| Property | Default | Note | -|---|---|---| -| `powerauth.service.url` | `http://localhost:8080/powerauth-java-server/rest` | PowerAuth service REST API base URL. | -| `powerauth.service.security.clientToken` | `_empty_` | PowerAuth REST API authentication token. | -| `powerauth.service.security.clientSecret` | `_empty_` | PowerAuth REST API authentication secret / password. | +| Property | Default | Note | +|------------------------------------------------------|----------------------------------------------------|------------------------------------------------------| +| `powerauth.service.url` | `http://localhost:8080/powerauth-java-server/rest` | PowerAuth service REST API base URL. | +| `powerauth.service.restClientConfig.responseTimeout` | `60s` | PowerAuth REST API response timeout. | +| `powerauth.service.restClientConfig.maxIdleTime` | `200s` | PowerAuth REST API max idle time. | +| `powerauth.service.security.clientToken` | `_empty_` | PowerAuth REST API authentication token. | +| `powerauth.service.security.clientSecret` | `_empty_` | PowerAuth REST API authentication secret / password. | ## Onboarding Process Configuration diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PowerAuthWebServiceConfiguration.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PowerAuthWebServiceConfiguration.java index 61fe10be..26d06eaa 100644 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PowerAuthWebServiceConfiguration.java +++ b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PowerAuthWebServiceConfiguration.java @@ -29,6 +29,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import java.time.Duration; /** * PowerAuth service configuration class. @@ -50,6 +53,12 @@ public class PowerAuthWebServiceConfiguration { @Value("${powerauth.service.url}") private String powerAuthServiceUrl; + @Value("${powerauth.service.restClientConfig.responseTimeout}") + private Duration powerAuthServiceTimeout; + + @Value("${powerauth.service.restClientConfig.maxIdleTime}") + private Duration powerAuthServiceMaxIdleTime; + @Value("${powerauth.service.security.clientToken}") private String clientToken; @@ -57,22 +66,18 @@ public class PowerAuthWebServiceConfiguration { private String clientSecret; @Bean - public PowerAuthClient powerAuthClient() { - try { - // Endpoint security is on - if (clientToken != null && !clientToken.isEmpty()) { - PowerAuthRestClientConfiguration config = new PowerAuthRestClientConfiguration(); - config.setPowerAuthClientToken(clientToken); - config.setPowerAuthClientSecret(clientSecret); - return new PowerAuthRestClient(powerAuthServiceUrl, config); - } else { - return new PowerAuthRestClient(powerAuthServiceUrl); - } - } catch (PowerAuthClientException ex) { - // Log the error in case Rest client initialization failed - logger.error(ex.getMessage(), ex); - return null; + public PowerAuthClient powerAuthClient() throws PowerAuthClientException { + final PowerAuthRestClientConfiguration config = new PowerAuthRestClientConfiguration(); + config.setResponseTimeout(powerAuthServiceTimeout); + config.setMaxIdleTime(powerAuthServiceMaxIdleTime); + + if (StringUtils.hasText(clientToken)) { + logger.info("Configuring security for PowerAuthRestClient."); + config.setPowerAuthClientToken(clientToken); + config.setPowerAuthClientSecret(clientSecret); } + + return new PowerAuthRestClient(powerAuthServiceUrl, config); } } \ No newline at end of file diff --git a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PushServiceConfig.java b/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PushServiceConfig.java deleted file mode 100644 index 72f00db5..00000000 --- a/enrollment-server-onboarding/src/main/java/com/wultra/app/onboardingserver/configuration/PushServiceConfig.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * PowerAuth Enrollment Server - * Copyright (C) 2020 Wultra s.r.o. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.wultra.app.onboardingserver.configuration; - -import io.getlime.push.client.PushServerClient; -import io.getlime.push.client.PushServerClientException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Configuration regarding Push Service connectivity. - * - * @author Petr Dvorak, petr@wultra.com - */ -@Configuration -public class PushServiceConfig { - - private static final Logger logger = LoggerFactory.getLogger(PushServiceConfig.class); - - @Value("${powerauth.push.service.url:}") - private String powerAuthPushServiceUrl; - - @Bean - public PushServerClient pushServerClient() { - try { - return new PushServerClient(powerAuthPushServiceUrl); - } catch (PushServerClientException ex) { - // Log the error in case Rest client initialization failed - logger.error(ex.getMessage(), ex); - return null; - } - } - -} diff --git a/enrollment-server-onboarding/src/main/resources/application.properties b/enrollment-server-onboarding/src/main/resources/application.properties index 21597928..63bdddb7 100644 --- a/enrollment-server-onboarding/src/main/resources/application.properties +++ b/enrollment-server-onboarding/src/main/resources/application.properties @@ -59,6 +59,8 @@ springdoc.swagger-ui.disable-swagger-default-url=true # PowerAuth service configuration powerauth.service.url=http://localhost:8080/powerauth-java-server/rest +powerauth.service.restClientConfig.responseTimeout=60s +powerauth.service.restClientConfig.maxIdleTime=200s powerauth.service.security.clientToken= powerauth.service.security.clientSecret= diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PowerAuthWebServiceConfiguration.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PowerAuthWebServiceConfiguration.java index 2ae51d4e..823c780c 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PowerAuthWebServiceConfiguration.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PowerAuthWebServiceConfiguration.java @@ -29,6 +29,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import java.time.Duration; /** * PowerAuth service configuration class. @@ -48,6 +51,12 @@ public class PowerAuthWebServiceConfiguration { @Value("${powerauth.service.url}") private String powerAuthServiceUrl; + @Value("${powerauth.service.restClientConfig.responseTimeout}") + private Duration powerAuthServiceTimeout; + + @Value("${powerauth.service.restClientConfig.maxIdleTime}") + private Duration powerAuthServiceMaxIdleTime; + @Value("${powerauth.service.security.clientToken}") private String clientToken; @@ -55,22 +64,18 @@ public class PowerAuthWebServiceConfiguration { private String clientSecret; @Bean - public PowerAuthClient powerAuthClient() { - try { - // Endpoint security is on - if (clientToken != null && !clientToken.isEmpty()) { - PowerAuthRestClientConfiguration config = new PowerAuthRestClientConfiguration(); - config.setPowerAuthClientToken(clientToken); - config.setPowerAuthClientSecret(clientSecret); - return new PowerAuthRestClient(powerAuthServiceUrl, config); - } else { - return new PowerAuthRestClient(powerAuthServiceUrl); - } - } catch (PowerAuthClientException ex) { - // Log the error in case Rest client initialization failed - logger.error(ex.getMessage(), ex); - return null; + public PowerAuthClient powerAuthClient() throws PowerAuthClientException { + final PowerAuthRestClientConfiguration config = new PowerAuthRestClientConfiguration(); + config.setResponseTimeout(powerAuthServiceTimeout); + config.setMaxIdleTime(powerAuthServiceMaxIdleTime); + + if (StringUtils.hasText(clientToken)) { + logger.info("Configuring security for PowerAuthRestClient."); + config.setPowerAuthClientToken(clientToken); + config.setPowerAuthClientSecret(clientSecret); } + + return new PowerAuthRestClient(powerAuthServiceUrl, config); } } \ No newline at end of file diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfig.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfig.java index 7fb64585..cb3edb37 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfig.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfig.java @@ -18,11 +18,11 @@ package com.wultra.app.enrollmentserver.configuration; +import com.wultra.app.enrollmentserver.impl.util.ConditionalOnPropertyNotEmpty; +import com.wultra.core.rest.client.base.RestClientConfiguration; import io.getlime.push.client.PushServerClient; import io.getlime.push.client.PushServerClientException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -32,22 +32,17 @@ * @author Petr Dvorak, petr@wultra.com */ @Configuration +@Slf4j +@ConditionalOnPropertyNotEmpty("powerauth.push.service.url") public class PushServiceConfig { - private static final Logger logger = LoggerFactory.getLogger(PushServiceConfig.class); - - @Value("${powerauth.push.service.url:}") - private String powerAuthPushServiceUrl; - @Bean - public PushServerClient pushServerClient() { - try { - return new PushServerClient(powerAuthPushServiceUrl); - } catch (PushServerClientException ex) { - // Log the error in case Rest client initialization failed - logger.error(ex.getMessage(), ex); - return null; - } + public PushServerClient pushServerClient(final PushServiceConfigProperties pushServiceProperties) throws PushServerClientException { + final String url = pushServiceProperties.getUrl(); + logger.info("Configuring PushServerClient for URL: {}", url); + final RestClientConfiguration restClientConfig = pushServiceProperties.getRestClientConfig(); + restClientConfig.setBaseUrl(url); + return new PushServerClient(restClientConfig); } } diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfigProperties.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfigProperties.java new file mode 100644 index 00000000..e7eaa02f --- /dev/null +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/configuration/PushServiceConfigProperties.java @@ -0,0 +1,39 @@ +/* + * PowerAuth Enrollment Server + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.app.enrollmentserver.configuration; + +import com.wultra.core.rest.client.base.RestClientConfiguration; +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration properties for Push Server. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +@Configuration +@ConfigurationProperties(prefix = "powerauth.push.service") +@Getter @Setter +public class PushServiceConfigProperties { + + private String url; + + private RestClientConfiguration restClientConfig; +} diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/InboxController.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/InboxController.java index fa5df9da..b223d415 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/InboxController.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/InboxController.java @@ -52,7 +52,7 @@ * * @author Roman Strobl, roman.strobl@wultra.com */ -@ConditionalOnExpression("!'${powerauth.push.service.url}'.empty and ${enrollment-server.inbox.enabled}") +@ConditionalOnExpression("!'${powerauth.push.service.url:}'.empty and ${enrollment-server.inbox.enabled}") @RestController @RequestMapping(value = "api/inbox") @Slf4j diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/PushRegistrationController.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/PushRegistrationController.java index 6f1721c0..6804fc6b 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/PushRegistrationController.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/PushRegistrationController.java @@ -39,7 +39,7 @@ * * @author Petr Dvorak, petr@wultra.com */ -@ConditionalOnPropertyNotEmpty(value="powerauth.push.service.url") +@ConditionalOnPropertyNotEmpty("powerauth.push.service.url") @RestController @RequestMapping(value = "api/push") public class PushRegistrationController { diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/PushRegistrationService.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/PushRegistrationService.java index 2ba048a4..a3ee4a6f 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/PushRegistrationService.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/PushRegistrationService.java @@ -21,6 +21,7 @@ import com.wultra.app.enrollmentserver.api.model.enrollment.request.PushRegisterRequest; import com.wultra.app.enrollmentserver.errorhandling.InvalidRequestObjectException; import com.wultra.app.enrollmentserver.errorhandling.PushRegistrationFailedException; +import com.wultra.app.enrollmentserver.impl.util.ConditionalOnPropertyNotEmpty; import com.wultra.app.enrollmentserver.model.validator.PushRegisterRequestValidator; import io.getlime.core.rest.model.base.request.ObjectRequest; import io.getlime.core.rest.model.base.response.Response; @@ -39,6 +40,7 @@ * @author Petr Dvorak, petr@wultra.com */ @Service +@ConditionalOnPropertyNotEmpty("powerauth.push.service.url") public class PushRegistrationService { private static final Logger logger = LoggerFactory.getLogger(PushRegistrationService.class); diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/util/ConditionalOnPropertyNotEmpty.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/util/ConditionalOnPropertyNotEmpty.java index e96aa8c4..d0141890 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/util/ConditionalOnPropertyNotEmpty.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/util/ConditionalOnPropertyNotEmpty.java @@ -19,6 +19,7 @@ package com.wultra.app.enrollmentserver.impl.util; import org.apache.commons.lang3.StringUtils; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; @@ -49,10 +50,12 @@ class OnPropertyNotEmptyCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - Map attrs = metadata.getAnnotationAttributes(ConditionalOnPropertyNotEmpty.class.getName()); - String propertyName = (String) Objects.requireNonNull(attrs).get("value"); - String val = context.getEnvironment().getProperty(propertyName); - return StringUtils.isNotBlank(val); + final Map attrs = metadata.getAnnotationAttributes(ConditionalOnPropertyNotEmpty.class.getName()); + final String propertyName = (String) Objects.requireNonNull(attrs).get("value"); + final String val = context.getEnvironment().getProperty(propertyName); + final boolean result = StringUtils.isNotBlank(val); + LoggerFactory.getLogger(ConditionalOnPropertyNotEmpty.class).debug("Property: {}, not-empty: {}", propertyName, result); + return result; } } diff --git a/enrollment-server/src/main/resources/application-dev.properties b/enrollment-server/src/main/resources/application-dev.properties index 165c749e..5abdc192 100644 --- a/enrollment-server/src/main/resources/application-dev.properties +++ b/enrollment-server/src/main/resources/application-dev.properties @@ -7,3 +7,6 @@ enrollment-server.auth-type=BASIC_HTTP spring.security.user.name=admin spring.security.user.password={bcrypt}$2a$10$Im45aSJeMpove4pF8/ypB.ufkITjfjpFvby9AMkvy.hrOVixkfkxq + +logging.level.com.wultra=DEBUG +logging.level.io.getlime=DEBUG diff --git a/enrollment-server/src/main/resources/application.properties b/enrollment-server/src/main/resources/application.properties index c0cb052d..6433bec4 100644 --- a/enrollment-server/src/main/resources/application.properties +++ b/enrollment-server/src/main/resources/application.properties @@ -59,11 +59,15 @@ springdoc.swagger-ui.disable-swagger-default-url=true # PowerAuth service configuration powerauth.service.url=http://localhost:8080/powerauth-java-server/rest +powerauth.service.restClientConfig.responseTimeout=60s +powerauth.service.restClientConfig.maxIdleTime=200s powerauth.service.security.clientToken= powerauth.service.security.clientSecret= # PowerAuth Push Service configuration # powerauth.push.service.url=http://localhost:8080/powerauth-push-server +powerauth.push.service.restClientConfig.responseTimeout=60s +powerauth.push.service.restClientConfig.maxIdleTime=200s # Enrollment Server Configuration enrollment-server.mtoken.enabled=true From 762923b2483e8140df3740f4bbfcef1d6e176252 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 17 Jun 2024 08:46:11 +0200 Subject: [PATCH 2/9] Fix #1074: Tests are failing in parallel maven build --- .../provider/innovatrics/InnovatricsRestApiServiceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/enrollment-server-onboarding-provider-innovatrics/src/test/java/com/wultra/app/onboardingserver/provider/innovatrics/InnovatricsRestApiServiceTest.java b/enrollment-server-onboarding-provider-innovatrics/src/test/java/com/wultra/app/onboardingserver/provider/innovatrics/InnovatricsRestApiServiceTest.java index f6f06598..edee6114 100644 --- a/enrollment-server-onboarding-provider-innovatrics/src/test/java/com/wultra/app/onboardingserver/provider/innovatrics/InnovatricsRestApiServiceTest.java +++ b/enrollment-server-onboarding-provider-innovatrics/src/test/java/com/wultra/app/onboardingserver/provider/innovatrics/InnovatricsRestApiServiceTest.java @@ -51,7 +51,8 @@ @ActiveProfiles("test") class InnovatricsRestApiServiceTest { - static final int PORT = 52936; + // TODO (racansky, 2024-06-17) find the way how to set the same random port for mock server and property + static final int PORT = 52937; @Autowired private InnovatricsApiService tested; From ceca096d84c27f92b952ff52d402e315aca1aa98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Wed, 19 Jun 2024 07:03:38 +0200 Subject: [PATCH 3/9] Fix #1073: Add ui.templates to Operation Detail (#1076) * Fix #1073: Add ui.templates to Operation Detail --- .../converter/MobileTokenConverterTest.java | 104 ++++++++++++++++++ .../lib/mtoken/model/entity/UiExtensions.java | 39 ++++++- 2 files changed, 140 insertions(+), 3 deletions(-) diff --git a/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java b/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java index 16e32c57..3ef6f88e 100644 --- a/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java +++ b/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java @@ -169,6 +169,110 @@ void testConvertUiRiskFlagsXCF() throws Exception { assertEquals(PreApprovalScreen.ApprovalType.SLIDER, preApprovalScreen.getApprovalType()); } + @Test + void testConvertUiTemplates() throws Exception { + final OperationDetailResponse operationDetail = createOperationDetailResponse(); + + final OperationTemplateEntity operationTemplate = new OperationTemplateEntity(); + operationTemplate.setUi(""" + { + "flipButtons": false, + "blockApprovalOnCall": true, + "templates": { + "list": { + "title": null, + "message": "operation.amount", + "image": null, + "style": "POSITIVE" + }, + "history": null, + "detail": { + "style": null, + "headerSection": false, + "sections": [ + { + "style": "MONEY", + "cells": [ + { + "name": "operation.amount", + "visibleTitle": false, + "style": null, + "canCopy": true, + "collapsable": "NO" + }, + { + "name": "operation.conversion", + "style": null, + "canCopy": true, + "collapsable": "NO" + }, + { + "name": "operation.conversion2", + "visibleTitle": true, + "style": null, + "canCopy": false, + "collapsable": "COLLAPSED" + } + ] + } + ] + } + } + } + """); + + final Operation result = tested.convert(operationDetail, operationTemplate); + + final Map expectedPayload = new HashMap<>() {{ + put("list", new HashMap() {{ + put("title", null); + put("message", "operation.amount"); + put("image", null); + put("style", "POSITIVE"); + }}); + put("history", null); + put("detail", new HashMap() {{ + put("style", null); + put("headerSection", false); + put("sections", List.of( + Map.of( + "style", "MONEY", + "cells", List.of( + new HashMap() {{ + put("name", "operation.amount"); + put("visibleTitle", false); + put("style", null); + put("canCopy", true); + put("collapsable", "NO"); + }}, + new HashMap() {{ + put("name", "operation.conversion"); + put("style", null); + put("canCopy", true); + put("collapsable", "NO"); + }}, + new HashMap() {{ + put("name", "operation.conversion2"); + put("visibleTitle", true); + put("style", null); + put("canCopy", false); + put("collapsable", "COLLAPSED"); + }} + ) + ) + )); + }}); + }}; + + assertThat(result) + .isNotNull() + .extracting(Operation::getUi) + .isNotNull() + .extracting(UiExtensions::getTemplates) + .isNotNull() + .isEqualTo(expectedPayload); + } + @Test void testConvertUiPostApprovalMerchantRedirect() throws Exception { final OperationDetailResponse operationDetail = createOperationDetailResponse(); diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/UiExtensions.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/UiExtensions.java index 1f3e68e3..ec087d78 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/UiExtensions.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/UiExtensions.java @@ -17,8 +17,11 @@ */ package com.wultra.security.powerauth.lib.mtoken.model.entity; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.util.Map; + /** * Data object representing UI extensions displayed during the operation approval. * @@ -28,17 +31,27 @@ public class UiExtensions { /** - * Property that hints the mobile app that the "Approve" and "Reject" buttons should be flipped, - * raising the CTA priority of the "Reject" button over the "Approve" button. + * Property that hints the mobile app that the `Approve` and `Reject` buttons should be flipped, + * raising the CTA priority of the `Reject` button over the `Approve` button. */ + @Schema(description = """ + Property that hints the mobile app that the `Approve` and `Reject` buttons should be flipped, + raising the CTA priority of the `Reject` button over the `Approve` button. + """) private Boolean flipButtons; /** * Property that hints the mobile app that the operation approval should be blocked in case that - * there is an ongoing call on the device. The UI should still allow pressing the "Approve" button, + * there is an ongoing call on the device. The UI should still allow pressing the `Approve` button, * but instead of displaying a PIN code / biometric authentication, user should be presented with * a screen informing the user that the operation cannot be approved while the user is on the phone. */ + @Schema(description = """ + Property that hints the mobile app that the operation approval should be blocked in case that + there is an ongoing call on the device. The UI should still allow pressing the `Approve` button, + but instead of displaying a PIN code / biometric authentication, user should be presented with + a screen informing the user that the operation cannot be approved while the user is on the phone. + """) private Boolean blockApprovalOnCall; /** @@ -46,6 +59,11 @@ public class UiExtensions { * approval screen. The purpose of the screen could be to provide an additional warning before * approving an operation, or to display generic information related to the operation approval. */ + @Schema(description = """ + Property that defines a screen content that is displayed before the user sees the operation + approval screen. The purpose of the screen could be to provide an additional warning before + approving an operation, or to display generic information related to the operation approval. + """) private PreApprovalScreen preApprovalScreen; /** @@ -53,5 +71,20 @@ public class UiExtensions { * approval screen. The purpose of the screen could be to provide additional information after * approving an operation, or to provide an option to execute simple consecutive actions. */ + @Schema(description = """ + Property that defines a screen content that is displayed after the user sees the operation + approval screen. The purpose of the screen could be to provide additional information after + approving an operation, or to provide an option to execute simple consecutive actions. + """) private PostApprovalScreen postApprovalScreen; + + /** + * A mapping of additional data templates that can be sent to the app for further customization. + * For example, these templates can contain specific data fields and their corresponding form format to be displayed in the app. + */ + @Schema(description = """ + A mapping of additional data templates that can be sent to the app for further customization. + For example, these templates can contain specific data fields and their corresponding form format to be displayed in the app. + """) + private Map templates; } From bf39d1fa16f03bae0a6f3e5ae014ba9a00c023fe Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 19 Jun 2024 08:54:48 +0200 Subject: [PATCH 4/9] Fix #1081: Update ZenID swagger --- .../pom.xml | 1 + .../ZenidDocumentVerificationProvider.java | 2 +- .../src/main/resources/api/api-zenid.yaml | 2698 +++++++++++++++-- 3 files changed, 2379 insertions(+), 322 deletions(-) diff --git a/enrollment-server-onboarding-provider-zenid/pom.xml b/enrollment-server-onboarding-provider-zenid/pom.xml index e77100fc..bf55ad49 100644 --- a/enrollment-server-onboarding-provider-zenid/pom.xml +++ b/enrollment-server-onboarding-provider-zenid/pom.xml @@ -77,6 +77,7 @@ true false false + true native true diff --git a/enrollment-server-onboarding-provider-zenid/src/main/java/com/wultra/app/onboardingserver/provider/zenid/ZenidDocumentVerificationProvider.java b/enrollment-server-onboarding-provider-zenid/src/main/java/com/wultra/app/onboardingserver/provider/zenid/ZenidDocumentVerificationProvider.java index 1d583859..62342113 100644 --- a/enrollment-server-onboarding-provider-zenid/src/main/java/com/wultra/app/onboardingserver/provider/zenid/ZenidDocumentVerificationProvider.java +++ b/enrollment-server-onboarding-provider-zenid/src/main/java/com/wultra/app/onboardingserver/provider/zenid/ZenidDocumentVerificationProvider.java @@ -570,7 +570,7 @@ private String toExtractedData(OwnerId id, ZenidSharedMineAllResult minedData) t private DocumentVerificationStatus toStatus(ZenidWebInvestigateResponse.StateEnum stateEnum) { return switch (stateEnum) { - case DONE -> DocumentVerificationStatus.ACCEPTED; + case DONE, ARCHIVED -> DocumentVerificationStatus.ACCEPTED; case ERROR -> DocumentVerificationStatus.FAILED; case NOTDONE, OPERATOR -> DocumentVerificationStatus.IN_PROGRESS; case REJECTED -> DocumentVerificationStatus.REJECTED; diff --git a/enrollment-server-onboarding-provider-zenid/src/main/resources/api/api-zenid.yaml b/enrollment-server-onboarding-provider-zenid/src/main/resources/api/api-zenid.yaml index 78eff50e..1eca078f 100644 --- a/enrollment-server-onboarding-provider-zenid/src/main/resources/api/api-zenid.yaml +++ b/enrollment-server-onboarding-provider-zenid/src/main/resources/api/api-zenid.yaml @@ -2,7 +2,6 @@ swagger: '2.0' info: version: v1 title: ZenidWeb -host: raiffeisen.frauds.zenid.cz schemes: - https paths: @@ -10,10 +9,12 @@ paths: post: tags: - Api - summary: "This method uploads a sample for processing. Sample can be a single image or video file. This call gets file, normalize it (e.t. rotate etc) and OCR its content.\r\nThe file content can be sent in two different formats:\r\nRAW: send the file content as body of the request in binary form without alternations\r\nFORM: use the multipart form encoding and send the file content in file variable\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing,\r\nEmptyBody - no uploaded file." + summary: This method uploads a sample for processing. Sample can be a single image or video file. This call gets file, normalize it (e.t. rotate etc) and OCR its content. + description: "The file content can be sent in two different formats: \r\n* **RAW:** send the file content as body of the request in binary form without alternations, \r\n* **FORM:** use the multipart form encoding and send the file content in file variable.\r\n\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these)\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **EmptyBody** - no uploaded file." operationId: Api_UploadSample consumes: - multipart/form-data + - multipart/form-data produces: - application/json - text/json @@ -22,38 +23,30 @@ paths: parameters: - name: expectedSampleType in: query - description: >- - Expected type of sample. Set this if you know the type of sample - ahead to speed up processing. Required. + description: Expected type of sample. Set this if you know the type of sample ahead to speed up processing. Required. required: true type: string enum: - - Unknown - - Selfie - DocumentPicture + - Selfie - SelfieVideo - DocumentVideo - Archived + - Unknown - name: uploadSessionID in: query - description: >- - SessionID is GUID created by client to group multiple sample uploads - together + description: SessionID is GUID created by client to group multiple sample uploads together required: false type: string format: uuid - name: customData in: query - description: >- - Custom data to be associated with this sample. Sample can later be - located using customData. Any string. + description: Custom data to be associated with this sample. Sample can later be located using customData. Any string. required: false type: string - name: fileName in: query - description: >- - Name of the original file (for example DSC01.jpg). If form upload is - needed, then this is optional + description: Name of the original file (for example DSC01.jpg). If form upload is needed, then this is optional required: false type: string - name: country @@ -83,21 +76,186 @@ paths: - Se - Si - Bg + - Al + - Ad - Be + - By + - Ba + - Me - Ee - Ie - Cy + - Li - Lt - Lv - Lu - Mt + - Md + - Mc + - 'No' - Pt - Gr + - Sm + - Mk + - Rs + - Ch + - Tr + - Va + - Vn + - In + - Us + - Jp + - Pk + - Ng + - Br + - Bd + - Cn + - Id + - Mx + - Ol + - Ph + - Et + - Eg + - Cd + - Ir + - Th + - Tz + - Za + - Mm + - Co + - Kr + - Ke + - Ar + - Dz + - Sd + - Ug + - Iq + - Ca + - Ma + - Uz + - Sa + - Ye + - Pe + - Ao + - My + - Af + - Mz + - Gh + - Ci + - Np + - Ve + - Mg + - Au + - Kp + - Cm + - Ne + - Tw + - Ml + - Bf + - Lk + - Sy + - Mw + - Cl + - Kz + - Zm + - Ec + - So + - Sn + - Gt + - Td + - Kh + - Zw + - Ss + - Rw + - Gn + - Bi + - Bj + - Bo + - Tn + - Ht + - Jo + - Cu + - Do + - Az + - Il + - Tj + - Hn + - Ae + - Sl + - Tg + - La + - Kg + - Tm + - Ly + - Sv + - Ni + - Py + - Cg + - Sg + - Cf + - Lb + - Ps + - Cr + - Lr + - Nz + - Om + - Kw + - Mr + - Pa + - Er + - Ge + - Uy + - Mn + - Am + - Jm + - Qa + - Na + - Gm + - Bw + - Ls + - Ga + - Gw + - Xk + - Bh + - Gq + - Tt + - Tl + - Mu + - Sz + - Dj + - Fj + - Bt + - Km + - Gy + - Sb + - Sr + - Cv + - Bn + - Bz + - Bs + - Mv + - Vu + - Bb + - St + - Ws + - Lc + - Ki + - Gd + - Vc + - Fm + - Ag + - Sc + - To + - Dm + - Kn + - Mh + - Pw + - Nr + - Tv + - Pg - name: role in: query - description: >- - Expected role of the uploaded document (IDC, Passport, Drivers - licence) + description: Expected role of the uploaded document (IDC, Passport, Drivers licence) required: false type: string enum: @@ -112,43 +270,32 @@ paths: - Birth - Add - Ide + - Vis + - Exp - name: fileLastWriteTime in: query - description: >- - Last write time of the file uploaded. This can be determined using - javascript. Value is used for fraud detection (EXIF comparison) + description: Last write time of the file uploaded. This can be determined using javascript. Value is used for fraud detection (EXIF comparison) required: false type: string format: date-time - name: async in: query - description: >- - Set this true if you want this request to respond as soon as the - data are uploaded for processing, not waiting for result. + description: Set this true if you want this request to respond as soon as the data are uploaded for processing, not waiting for result. required: false type: boolean - name: callbackUrl in: query - description: >- - Set URL for call back here, if you want to receive JSON object with - response there. + description: Set URL for call back here, if you want to receive JSON object with response there. required: false type: string - name: searchForSubsamples in: query - description: >- - For videos, this makes ZenID extract static picture of the card from - the video of card. For document pictures, if single sample contains - multiple card pictures (for example multi-page PDF or scan with - multiple picture), set this to true to search for them and extract - as separate "subsamples" + description: For videos, this makes ZenID extract static picture of the card from the video of card. For document pictures, if single sample contains multiple card pictures (for example multi-page PDF or scan with multiple picture), set this to true to search for them and extract as separate "subsamples" required: false type: boolean - name: anonymizeImage in: query - description: >- - ZenID can optionally anonymize specific documents by blackening - certain fields. Set this to true to perform anonymization + description: ZenID can optionally anonymize specific documents by blackening certain fields. Set this to true to perform anonymization required: false type: boolean - name: documentCode @@ -157,15 +304,23 @@ paths: required: false type: string enum: + - IDC1 - IDC2 - DRV - - IDC1 - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 - SK_IDC_2008plus - SK_DRV_2004_08_09 - SK_DRV_2013 - SK_DRV_2015 - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 - SK_DRV_1993 - PL_IDC_2015 - DE_IDC_2010 @@ -239,7 +394,6 @@ paths: - BE_IDC_2020_21 - GR_PAS_2020 - PT_PAS_2006_09 - - PT_PAS_2017 - PT_IDC_2007_08_09_15 - SE_IDC_2012_21 - FI_IDC_2017_21 @@ -265,6 +419,62 @@ paths: - PL_PAS_2011 - PL_DRV_1999 - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 - name: pageCode in: query description: Side of the document to seek if you know it @@ -275,120 +485,546 @@ paths: - B - name: priorityQueueName in: query - description: >- - Setting this puts the request into a separate queue for processing, - ignoring standard queue. + description: Setting this puts the request into a separate queue for processing, ignoring standard queue. required: false type: string - name: profile in: query - description: >- - Optional name of profile. Use it to sort samples by different input - channels for example. - required: false - type: string - - name: processingMode - in: query - description: >- - Fast (default) or Slow. Slow process mode might fix some alignment - problems but is slower. + description: Optional name of profile. Use it to sort samples by different input channels for example. required: false type: string - enum: - - Fast - - Slow - - name: sdkSignature + - name: acceptableInput in: query - description: Optional SDK signature for pictures. Generated by SDK + description: Detailed specification of acceptable input document. Use this to specify for example multiple different documents as inputs. If this parameter is specified, then role, documentCode, pageCode and country are ignored required: false + schema: + $ref: '#/definitions/ZenidShared.AcceptableInput' type: string - name: File in: formData description: Upload samples file required: true type: file + - name: SdkSignature + in: formData + description: Optional SDK signature for pictures. Generated by SDK. This should be sent as a second file in form data. Another supported method is to append it to body of request if sent in binary form. + required: false + type: file responses: '200': description: OK schema: $ref: '#/definitions/ZenidWeb.UploadSampleResponse' - /api/investigateSamples: - get: + /api/sampleAndInvestigate: + post: tags: - Api - summary: "Investigation node. Investigation gets list of samples, combine mined data from them in one combined object (see MinedAllData), and validate it with set of validators.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing,\r\nUnknownSampleID - any of sampleIDs is not stored in DB.\r\nSampleInInvalidState - sample is in invalid state - for example it is waiting for operators or processing of sample ended with error\r\nInvalidSampleCombination - investigation must contain samples from single person/customer" - operationId: Api_InvestigateSamples - consumes: [] + summary: This method uploads and then investigates single sample. For normal use please use "investageSamples". Sample can be a single image or video file. This call gets file, normalize it (e.t. rotate etc) and OCR its content. + description: "The file content can be sent in two different formats:\r\n* **RAW:** send the file content as body of the request in binary form without alternations\r\n* **FORM:** use the multipart form encoding and send the file content in file variable\r\n\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **EmptyBody** - no uploaded file." + operationId: Api_UploadAndInvestigateSample + consumes: + - multipart/form-data + - multipart/form-data produces: - application/json - text/json - application/xml - text/xml parameters: - - name: sampleIDs + - name: expectedSampleType in: query - description: List of strings - sample IDs. Required. + description: Expected type of sample. Set this if you know the type of sample ahead to speed up processing. Required. required: true - type: array - items: - type: string - collectionFormat: multi - - name: profile + type: string + enum: + - DocumentPicture + - Selfie + - SelfieVideo + - DocumentVideo + - Archived + - Unknown + - name: uploadSessionID in: query - description: >- - Optional name of profile. Each profile defines settings for - validators. + description: SessionID is GUID created by client to group multiple sample uploads together required: false type: string + format: uuid - name: customData in: query - description: >- - Custom data to be associated with this sample. Sample can later be - located using customData. Any string. + description: Custom data to be associated with this sample. Sample can later be located using customData. Any string. + required: false + type: string + - name: fileName + in: query + description: Name of the original file (for example DSC01.jpg). If form upload is needed, then this is optional + required: false + type: string + - name: country + in: query + description: Expected country of the uploaded document (Cz, At, Sk...) + required: false + type: string + enum: + - Cz + - Sk + - At + - Hu + - Pl + - De + - Hr + - Ro + - Ru + - Ua + - It + - Dk + - Es + - Fi + - Fr + - Gb + - Is + - Nl + - Se + - Si + - Bg + - Al + - Ad + - Be + - By + - Ba + - Me + - Ee + - Ie + - Cy + - Li + - Lt + - Lv + - Lu + - Mt + - Md + - Mc + - 'No' + - Pt + - Gr + - Sm + - Mk + - Rs + - Ch + - Tr + - Va + - Vn + - In + - Us + - Jp + - Pk + - Ng + - Br + - Bd + - Cn + - Id + - Mx + - Ol + - Ph + - Et + - Eg + - Cd + - Ir + - Th + - Tz + - Za + - Mm + - Co + - Kr + - Ke + - Ar + - Dz + - Sd + - Ug + - Iq + - Ca + - Ma + - Uz + - Sa + - Ye + - Pe + - Ao + - My + - Af + - Mz + - Gh + - Ci + - Np + - Ve + - Mg + - Au + - Kp + - Cm + - Ne + - Tw + - Ml + - Bf + - Lk + - Sy + - Mw + - Cl + - Kz + - Zm + - Ec + - So + - Sn + - Gt + - Td + - Kh + - Zw + - Ss + - Rw + - Gn + - Bi + - Bj + - Bo + - Tn + - Ht + - Jo + - Cu + - Do + - Az + - Il + - Tj + - Hn + - Ae + - Sl + - Tg + - La + - Kg + - Tm + - Ly + - Sv + - Ni + - Py + - Cg + - Sg + - Cf + - Lb + - Ps + - Cr + - Lr + - Nz + - Om + - Kw + - Mr + - Pa + - Er + - Ge + - Uy + - Mn + - Am + - Jm + - Qa + - Na + - Gm + - Bw + - Ls + - Ga + - Gw + - Xk + - Bh + - Gq + - Tt + - Tl + - Mu + - Sz + - Dj + - Fj + - Bt + - Km + - Gy + - Sb + - Sr + - Cv + - Bn + - Bz + - Bs + - Mv + - Vu + - Bb + - St + - Ws + - Lc + - Ki + - Gd + - Vc + - Fm + - Ag + - Sc + - To + - Dm + - Kn + - Mh + - Pw + - Nr + - Tv + - Pg + - name: role + in: query + description: Expected role of the uploaded document (IDC, Passport, Drivers licence) + required: false + type: string + enum: + - Idc + - Pas + - Drv + - Res + - Gun + - Hic + - Std + - Car + - Birth + - Add + - Ide + - Vis + - Exp + - name: fileLastWriteTime + in: query + description: Last write time of the file uploaded. This can be determined using javascript. Value is used for fraud detection (EXIF comparison) required: false type: string + format: date-time - name: async in: query - description: >- - Set this true if you want this request to respond as soon as the - data are uploaded for processing, not waiting for result. + description: Set this true if you want this request to respond as soon as the data are uploaded for processing, not waiting for result. required: false type: boolean - name: callbackUrl in: query - description: >- - Set URL for call back here, if you want to receive JSON object with - response there. + description: Set URL for call back here, if you want to receive JSON object with response there. required: false type: string - - name: language + - name: searchForSubsamples in: query - description: Language of the output (Czech/English). + description: For videos, this makes ZenID extract static picture of the card from the video of card. For document pictures, if single sample contains multiple card pictures (for example multi-page PDF or scan with multiple picture), set this to true to search for them and extract as separate "subsamples" + required: false + type: boolean + - name: anonymizeImage + in: query + description: ZenID can optionally anonymize specific documents by blackening certain fields. Set this to true to perform anonymization + required: false + type: boolean + - name: documentCode + in: query + description: Code of the specific document if you know it required: false type: string enum: - - English - - Czech - - Polish - - German + - IDC1 + - IDC2 + - DRV + - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 + - SK_IDC_2008plus + - SK_DRV_2004_08_09 + - SK_DRV_2013 + - SK_DRV_2015 + - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 + - SK_DRV_1993 + - PL_IDC_2015 + - DE_IDC_2010 + - DE_IDC_2001 + - HR_IDC_2013_15 + - AT_IDE_2000 + - HU_IDC_2000_01_12 + - HU_IDC_2016 + - AT_IDC_2002_05_10 + - HU_ADD_2012 + - AT_PAS_2006_14 + - AT_DRV_2006 + - AT_DRV_2013 + - CZ_RES_2011_14 + - CZ_RES_2006_T + - CZ_RES_2006_07 + - CZ_GUN_2014 + - HU_PAS_2006_12 + - HU_DRV_2012_13 + - HU_DRV_2012_B + - EU_EHIC_2004_A + - Unknown + - CZ_GUN_2017 + - CZ_RES_2020 + - PL_IDC_2019 + - IT_PAS_2006_10 + - INT_ISIC_2008 + - DE_PAS + - DK_PAS + - ES_PAS + - FI_PAS + - FR_PAS + - GB_PAS + - IS_PAS + - NL_PAS + - RO_PAS + - SE_PAS + - PL_PAS + - PL_DRV_2013 + - CZ_BIRTH + - CZ_VEHICLE_I + - INT_ISIC_2019 + - SI_PAS + - SI_IDC + - SI_DRV + - EU_EHIC_2004_B + - PL_IDC_2001_02_13 + - IT_IDC_2016 + - HR_PAS_2009_15 + - HR_DRV_2013 + - HR_IDC_2003 + - SI_DRV_2009 + - BG_PAS_2010 + - BG_IDC_2010 + - BG_DRV_2010_13 + - HR_IDC_2021 + - AT_IDC_2021 + - DE_PAS_2007 + - DE_DRV_2013_21 + - DE_DRV_1999_01_04_11 + - FR_IDC_2021 + - FR_IDC_1988_94 + - ES_PAS_2003_06 + - ES_IDC_2015 + - ES_IDC_2006 + - IT_IDC_2004 + - RO_IDC_2001_06_09_17_21 + - NL_IDC_2014_17_21 + - BE_PAS_2014_17_19 + - BE_IDC_2013_15 + - BE_IDC_2020_21 + - GR_PAS_2020 + - PT_PAS_2006_09 + - PT_IDC_2007_08_09_15 + - SE_IDC_2012_21 + - FI_IDC_2017_21 + - IE_PAS_2006_13 + - LT_PAS_2008_09_11_19 + - LT_IDC_2009_12 + - LV_PAS_2015 + - LV_PAS_2007 + - LV_IDC_2012 + - LV_IDC_2019 + - EE_PAS_2014 + - EE_PAS_2021 + - EE_IDC_2011 + - EE_IDC_2018_21 + - CY_PAS_2010_20 + - CY_IDC_2000_08 + - CY_IDC_2015_20 + - LU_PAS_2015 + - LU_IDC_2014_21 + - LU_IDC_2008_13 + - MT_PAS_2008 + - MT_IDC_2014 + - PL_PAS_2011 + - PL_DRV_1999 + - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 + - name: pageCode + in: query + description: Side of the document to seek if you know it + required: false + type: string + enum: + - F + - B - name: priorityQueueName in: query - description: >- - Setting this puts the request into a separate queue for processing, - ignoring standard queue. + description: Setting this puts the request into a separate queue for processing, ignoring standard queue. + required: false + type: string + - name: profile + in: query + description: Optional name of profile. Use it to sort samples by different input channels for example. required: false type: string + - name: File + in: formData + description: Upload samples file + required: true + type: file + - name: SdkSignature + in: formData + description: Optional SDK signature for pictures. Generated by SDK. This should be sent as a second file in form data. Another supported method is to append it to body of request if sent in binary form. + required: false + type: file responses: '200': description: OK schema: $ref: '#/definitions/ZenidWeb.InvestigateResponse' - /api/investigateUploadSession: + /api/investigateSamples: get: tags: - Api - summary: "Investigation node. Investigation gets GUID, unique identifier, gets all samples tagged with this UploadSessionID, combine mined data from them in one combined object (see MinedAllData), and validate it with set of validators.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing,\r\nUnknownUploadSessionID - UploadSessionID is not known\r\nSampleInInvalidState - sample is in invalid state - for example it is waiting for operators or processing of sample ended with error\r\nInvalidSampleCombination - investigation must contain samples from single person/customer" - operationId: Api_InvestigateUploadSession + summary: "Investigation node. Investigation gets list of samples, combine mined data from them in one combined object (see MinedAllData), and validate it with set of validators.\r\nResult of validation is returned in ValidatorResult structure (detail info about validator result) and Rank (info about all input samples, overall score and basic info about failed validators)" + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **UnknownSampleID** - any of sampleIDs is not stored in DB.\r\n* **SampleInInvalidState** - sample is in invalid state - for example it is waiting for operators or processing of sample ended with error\r\n* **InvalidSampleCombination** - investigation must contain samples from single person/customer" + operationId: Api_InvestigateSamples consumes: [] produces: - application/json @@ -396,38 +1032,92 @@ paths: - application/xml - text/xml parameters: - - name: uploadSessionID + - name: sampleIDs in: query - description: User identification of list of samples. Required. + description: List of strings - sample IDs. Required. required: true - type: string - format: uuid + type: array + items: + type: string + collectionFormat: multi + - name: profile + in: query + description: Optional name of profile. Each profile defines settings for validators. + required: false + type: string + - name: customData + in: query + description: Custom data to be associated with this sample. Sample can later be located using customData. Any string. + required: false + type: string + - name: async + in: query + description: Set this true if you want this request to respond as soon as the data are uploaded for processing, not waiting for result. + required: false + type: boolean + - name: callbackUrl + in: query + description: Set URL for call back here, if you want to receive JSON object with response there. + required: false + type: string + - name: language + in: query + description: Language of the output (Czech/English). + required: false + type: string + enum: + - English + - Czech + - Polish + - German + - name: priorityQueueName + in: query + description: Setting this puts the request into a separate queue for processing, ignoring standard queue. + required: false + type: string + responses: + '200': + description: OK + schema: + $ref: '#/definitions/ZenidWeb.InvestigateResponse' + /api/investigateUploadSession: + get: + tags: + - Api + summary: "Investigation node. Investigation gets GUID, unique identifier, gets all samples tagged with this UploadSessionID, combine mined data from them in one combined object (see MinedAllData), and validate it with set of validators.\r\nResult of validation is returned in ValidatorResult structure (detail info about validator result) and Rank (info about all input samples, overall score and basic info about failed validators)" + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **UnknownUploadSessionID** - UploadSessionID is not known\r\n* **SampleInInvalidState** - sample is in invalid state - for example it is waiting for operators or processing of sample ended with error\r\n* **InvalidSampleCombination** - investigation must contain samples from single person/customer" + operationId: Api_InvestigateUploadSession + consumes: [] + produces: + - application/json + - text/json + - application/xml + - text/xml + parameters: + - name: uploadSessionID + in: query + description: User identification of list of samples. Required. + required: true + type: string + format: uuid - name: profile in: query - description: >- - Optional name of profile. Each profile defines settings for - validators. + description: Optional name of profile. Each profile defines settings for validators. required: false type: string - name: customData in: query - description: >- - Custom data to be associated with this sample. Sample can later be - located using customData. Any string. + description: Custom data to be associated with this sample. Sample can later be located using customData. Any string. required: false type: string - name: async in: query - description: >- - Set this true if you want this request to respond as soon as the - data are uploaded for processing, not waiting for result. + description: Set this true if you want this request to respond as soon as the data are uploaded for processing, not waiting for result. required: false type: boolean - name: callbackUrl in: query - description: >- - Set URL for call back here, if you want to receive JSON object with - response there. + description: Set URL for call back here, if you want to receive JSON object with response there. required: false type: string - name: language @@ -449,7 +1139,8 @@ paths: get: tags: - Api - summary: "Node for synchronizing samples - returns sample for given ID. This call can be used for synchronizing information about samples with external systems.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing,\r\nUnknownSampleID - if that ID is not used in DB for any sample." + summary: Node for synchronizing samples - returns sample for given ID. This call can be used for synchronizing information about samples with external systems. + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **UnknownSampleID** - if that ID is not used in DB for any sample." operationId: Api_GetSample consumes: [] produces: @@ -503,9 +1194,7 @@ paths: type: string - name: birthNumber in: query - description: >- - Birth Number (RČ in czech) of the person whose documents are - searched for + description: Birth Number (RČ in czech) of the person whose documents are searched for required: false type: string - name: birthDate @@ -516,9 +1205,7 @@ paths: format: date-time - name: deleteType in: query - description: >- - Set if you want delete only samples and investigations or face from - FaceDB or everything + description: Set if you want delete only samples and investigations or face from FaceDB or everything required: false type: string enum: @@ -534,9 +1221,7 @@ paths: get: tags: - Api - summary: >- - Deletes a sample. Also deletes an investigation in which this sample was - used + summary: Deletes a sample. Also deletes an investigation in which this sample was used operationId: Api_DeleteSample consumes: [] produces: @@ -559,7 +1244,8 @@ paths: get: tags: - Api - summary: "Node for synchronizing investigations - returns investigations for given ID. This call can be used for synchronizing information about samples with external systems.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing,\r\nUnknownSampleID - if Investigation ID is not stored in DB." + summary: "Node for synchronizing investigations - returns investigations for given ID. This call can be used for synchronizing information about samples with external systems.\r\nResult of validation is returned in ValidatorResult structure (detail info about validator result) Rank (info about all input samples, overall score and basic info about failed validators)" + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **UnknownSampleID** - if Investigation ID is not stored in DB." operationId: Api_GetInvestigation consumes: [] produces: @@ -583,7 +1269,8 @@ paths: get: tags: - Api - summary: "Get list of samples (newer than timestamp). This call can be used for synchronizing information about samples with external systems.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing,\r\nInvalidTimeStamp - error while decoding timestamp." + summary: Get list of samples (newer than timestamp). This call can be used for synchronizing information about samples with external systems. + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **InvalidTimeStamp** - error while decoding timestamp." operationId: Api_GetSamples consumes: [] produces: @@ -594,10 +1281,28 @@ paths: parameters: - name: timestamp in: query - description: if defined, list is limited to samples newer than given timestamp + description: if defined, list is limited to samples newer than given database timestamp. Set to 0 to get all samples. Database timestamp is returned by response required: false type: integer format: int64 + - name: sessionID + in: query + description: if defined, list is limited to samples which was uploaded with defined sessionID + required: false + type: string + format: uuid + - name: timePeriodStart + in: query + description: if defined, list is limited to samples which was uploaded after defined time + required: false + type: string + format: date-time + - name: timePeriodEnd + in: query + description: if defined, list is limited to samples which was uploaded before defined time + required: false + type: string + format: date-time responses: '200': description: OK @@ -607,7 +1312,8 @@ paths: get: tags: - Api - summary: "Get list of investigations (newer than timestamp). This call can be used for synchronizing information about samples with external systems.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing,\r\nInvalidTimeStamp - error while decoding timestamp." + summary: Get list of investigations (newer than timestamp). This call can be used for synchronizing information about samples with external systems. + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing,\r\n* **InvalidTimeStamp** - error while decoding timestamp." operationId: Api_GetInvestigations consumes: [] produces: @@ -618,12 +1324,16 @@ paths: parameters: - name: timestamp in: query - description: >- - if defined, list is limited to investigations newer than given - timestamp + description: if defined, list is limited to investigations newer than given timestamp required: false type: integer format: int64 + - name: sessionID + in: query + description: if defined, list is limited to investigations which contain samples uploaded with defined sessionID + required: false + type: string + format: uuid responses: '200': description: OK @@ -633,7 +1343,8 @@ paths: get: tags: - Api - summary: "Get list of names of profiles, defined in system. This call can be used for selecting profile in investigation.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing," + summary: Get list of names of profiles, defined in system. This call can be used for selecting profile in investigation. + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing," operationId: Api_GetProfiles consumes: [] produces: @@ -650,7 +1361,8 @@ paths: get: tags: - Api - summary: "Returns list of validators - their id and text description.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these): InternalServerError - problem while preprocessing or unknown problem while processing," + summary: Returns list of validators - their id and text description. + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing," operationId: Api_GetValidatorEnum consumes: [] produces: @@ -680,9 +1392,7 @@ paths: get: tags: - Api - summary: >- - Performs diagnostics test. Note depending on parameters, license might - be consumed + summary: Performs diagnostics test. Note depending on parameters, license might be consumed operationId: Api_Diagnostics consumes: [] produces: @@ -733,7 +1443,8 @@ paths: post: tags: - Api - summary: "Loads face image in the image repository (for comparing faces for validation).\r\nIn most cases, /api/sample with sampleType=Selfie should be used instead.\r\nWhile processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\nInternalServerError - problem while preprocessing or unknown problem while processing or disabled face database." + summary: "Loads face image in the image repository (for comparing faces for validation).\r\nIn most cases, /api/sample with sampleType=Selfie should be used instead." + description: "While processing, error could be identified.\r\nIn that case empty response with described ErrorCode and Description is returned (one of these):\r\n* **InternalServerError** - problem while preprocessing or unknown problem while processing or disabled face database." operationId: Api_UploadFace consumes: - multipart/form-data @@ -755,9 +1466,7 @@ paths: type: string - name: async in: query - description: >- - Set this true if you want this request to respond as soon as the - data are uploaded for processing, not waiting for result. + description: Set this true if you want this request to respond as soon as the data are uploaded for processing, not waiting for result. required: false type: boolean - name: callbackUrl @@ -779,7 +1488,8 @@ paths: post: tags: - Api - summary: "Verifies card validity using same means as existing CardRecalled validator\r\nIt takes a List of cards to verify - each with DocumentCode and card number and returns same list with Recalled status. Recalled status can be either True = recalled, False = not recalled, Null = could not determine/not supported document code." + summary: "Verifies card validity using same means as existing CardRecalled validator\r\nIt takes a List of cards to verify - each with DocumentCode and card number and returns same list with Recalled status." + description: Recalled status can be either True = recalled, False = not recalled, Null = could not determine/not supported document code. operationId: Api_VerifyCardsRecalled consumes: - application/json @@ -823,16 +1533,21 @@ definitions: SampleType: description: Real SampleType enum: - - Unknown - - Selfie - DocumentPicture + - Selfie - SelfieVideo - DocumentVideo - Archived + - Unknown type: string MinedData: $ref: '#/definitions/ZenidShared.MineAllResult' description: Structure of data, mined from sample - {ZenidShared.MineAllResult}. + RawFieldsOcr: + description: Raw OCR results of fields (not mined) + type: array + items: + $ref: '#/definitions/ZenidWeb.Classes.FieldOcrResult' State: description: State of the request - NotDone/Done/Error enum: @@ -841,6 +1556,7 @@ definitions: - Error - Operator - Rejected + - Archived type: string ProjectedImage: $ref: '#/definitions/ZenidShared.Hash' @@ -856,17 +1572,22 @@ definitions: type: string ImagePageCount: format: int32 - description: >- - Number of pages this document has (in case of PDF or TIFF). This can - be used in history URL /history/image/{hash}?page=1 + description: Number of pages this document has (in case of PDF or TIFF). This can be used in history URL /history/image/{hash}?page=1 type: integer + DocumentOutlineInOriginalImage: + description: Outline of the document in the original image in relative dimensions + type: array + items: + $ref: '#/definitions/System.Drawing.PointF' Subsamples: - description: >- - If subsample processing is enable, this list contains further images - extracted from the primary image, each with extra document image + description: If subsample processing is enable, this list contains further images extracted from the primary image, each with extra document image type: array items: $ref: '#/definitions/ZenidWeb.UploadSampleResponse' + UploadTime: + format: date-time + description: Time of the sample upload (server time) + type: string ErrorCode: description: If throght processing some error occurs, ErrorCode property is set. enum: @@ -880,10 +1601,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -913,9 +1638,7 @@ definitions: description: identification number for id card - set only on id cards DrivinglicenseNumber: $ref: '#/definitions/ZenidShared.MinedText' - description: >- - identification number for driving licence - set only on driving - licences + description: identification number for driving licence - set only on driving licences PassportNumber: $ref: '#/definitions/ZenidShared.MinedText' description: identification number for passport - set only on passports @@ -934,19 +1657,25 @@ definitions: $ref: '#/definitions/ZenidShared.MinedMrz' description: Machine readable zone DocumentCode: - description: >- - Code identificating document (when combining from more samples the - most probable version is set) + description: Set access point shouldnt be used anywhere. It is in DocumentCode property just because of xml serialization enum: + - IDC1 - IDC2 - DRV - - IDC1 - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 - SK_IDC_2008plus - SK_DRV_2004_08_09 - SK_DRV_2013 - SK_DRV_2015 - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 - SK_DRV_1993 - PL_IDC_2015 - DE_IDC_2010 @@ -1020,7 +1749,6 @@ definitions: - BE_IDC_2020_21 - GR_PAS_2020 - PT_PAS_2006_09 - - PT_PAS_2017 - PT_IDC_2007_08_09_15 - SE_IDC_2012_21 - FI_IDC_2017_21 @@ -1046,9 +1774,65 @@ definitions: - PL_PAS_2011 - PL_DRV_1999 - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 type: string DocumentCountry: - description: Country associated with this document type + description: "Country associated with this document type.\r\nSet access point shouldnt be used anywhere. It is in DocumentCountry property just because of xml serialization" enum: - Cz - Sk @@ -1071,21 +1855,186 @@ definitions: - Se - Si - Bg + - Al + - Ad - Be + - By + - Ba + - Me - Ee - Ie - Cy + - Li - Lt - Lv - Lu - Mt + - Md + - Mc + - 'No' - Pt - Gr + - Sm + - Mk + - Rs + - Ch + - Tr + - Va + - Vn + - In + - Us + - Jp + - Pk + - Ng + - Br + - Bd + - Cn + - Id + - Mx + - Ol + - Ph + - Et + - Eg + - Cd + - Ir + - Th + - Tz + - Za + - Mm + - Co + - Kr + - Ke + - Ar + - Dz + - Sd + - Ug + - Iq + - Ca + - Ma + - Uz + - Sa + - Ye + - Pe + - Ao + - My + - Af + - Mz + - Gh + - Ci + - Np + - Ve + - Mg + - Au + - Kp + - Cm + - Ne + - Tw + - Ml + - Bf + - Lk + - Sy + - Mw + - Cl + - Kz + - Zm + - Ec + - So + - Sn + - Gt + - Td + - Kh + - Zw + - Ss + - Rw + - Gn + - Bi + - Bj + - Bo + - Tn + - Ht + - Jo + - Cu + - Do + - Az + - Il + - Tj + - Hn + - Ae + - Sl + - Tg + - La + - Kg + - Tm + - Ly + - Sv + - Ni + - Py + - Cg + - Sg + - Cf + - Lb + - Ps + - Cr + - Lr + - Nz + - Om + - Kw + - Mr + - Pa + - Er + - Ge + - Uy + - Mn + - Am + - Jm + - Qa + - Na + - Gm + - Bw + - Ls + - Ga + - Gw + - Xk + - Bh + - Gq + - Tt + - Tl + - Mu + - Sz + - Dj + - Fj + - Bt + - Km + - Gy + - Sb + - Sr + - Cv + - Bn + - Bz + - Bs + - Mv + - Vu + - Bb + - St + - Ws + - Lc + - Ki + - Gd + - Vc + - Fm + - Ag + - Sc + - To + - Dm + - Kn + - Mh + - Pw + - Nr + - Tv + - Pg type: string DocumentRole: - description: >- - General role of this document (ID card vs Passport vs Driver license - etc) + description: "General role of this document (ID card vs Passport vs Driving license etc)\r\nSet access point shouldnt be used anywhere. It is in DocumentRole property just because of xml serialization" enum: - Idc - Pas @@ -1098,6 +2047,8 @@ definitions: - Birth - Add - Ide + - Vis + - Exp type: string PageCode: description: identification of page of document @@ -1111,12 +2062,17 @@ definitions: $ref: '#/definitions/ZenidShared.MinedText' CarNumber: $ref: '#/definitions/ZenidShared.MinedText' + VisaNumber: + $ref: '#/definitions/ZenidShared.MinedText' FirstNameOfParents: $ref: '#/definitions/ZenidShared.MinedText' ResidencyNumber: $ref: '#/definitions/ZenidShared.MinedText' ResidencyNumberPhoto: $ref: '#/definitions/ZenidShared.MinedText' + FathersName: + $ref: '#/definitions/ZenidShared.MinedText' + description: Patronymium in UA ResidencyPermitDescription: $ref: '#/definitions/ZenidShared.MinedText' ResidencyPermitCode: @@ -1133,10 +2089,150 @@ definitions: $ref: '#/definitions/ZenidShared.MinedText' HealthInsuranceCardNumber: $ref: '#/definitions/ZenidShared.MinedText' + HealthInsuranceNumber: + $ref: '#/definitions/ZenidShared.MinedText' InsuranceCompanyCode: $ref: '#/definitions/ZenidShared.MinedText' IssuingCountry: $ref: '#/definitions/ZenidShared.MinedText' + FathersBirthDate: + $ref: '#/definitions/ZenidShared.MinedDate' + FathersSurname: + $ref: '#/definitions/ZenidShared.MinedText' + FathersBirthNumber: + $ref: '#/definitions/ZenidShared.MinedText' + FathersBirthSurname: + $ref: '#/definitions/ZenidShared.MinedText' + MothersBirthDate: + $ref: '#/definitions/ZenidShared.MinedDate' + MothersSurname: + $ref: '#/definitions/ZenidShared.MinedText' + MothersBirthNumber: + $ref: '#/definitions/ZenidShared.MinedText' + MothersBirthSurname: + $ref: '#/definitions/ZenidShared.MinedText' + BirthCertificateNumber: + $ref: '#/definitions/ZenidShared.MinedText' + ZenidWeb.Classes.FieldOcrResult: + type: object + properties: + FieldId: + enum: + - A1 + - A2 + - A3 + - FirstName + - LastName + - Photo + - BirthDate + - BirthNumber + - Authority + - Mrz1 + - Mrz2 + - Mrz3 + - IdcardNumber + - Sex + - MaritalStatus + - BirthAddress + - BA1 + - BA2 + - IssueDate + - ExpiryDate + - PassportNumber + - DrivinglicenseNumber + - Barcode + - BirthLastName + - SpecialRemarks + - Height + - EyesColor + - Titles + - Authority1 + - Authority2 + - LastName1 + - LastName2TitlesAfter + - DrvCodes + - Signature + - OtherInfo + - MiniHologram + - MiniPhoto + - CarNumber + - LicenseTypes + - FirstNameOfParents + - BirthDateNumber + - DrivinglicenseNumber2 + - RDIFChipAccess + - Pseudonym + - ResidencyPermitDescription + - ResidencyPermitCode + - ResidencyNumber + - AuthorityAndIssueDate + - Nationality + - GunlicenseNumber + - Stamp + - Stamp2 + - SurnameAndName1 + - SurnameAndName2 + - SurnameAndName3 + - MothersSurnameAndName + - TemporaryAddress1 + - TemporaryAddress2 + - AddressStartingDate + - TemporaryAddressStartingDate + - TemporaryAddressEndingDate + - NameInNationalLanguage + - BirthDateAndAddress + - SpecialRemarks2 + - SpecialRemarks3 + - Unknown + - HealthInsuranceCardNumber + - InsuranceCompanyCode + - IssuingCountry + - ResidencyNumberPhoto + - IssueDateAndAuthority + - TitlesAfter + - PlaceOfIssue + - BirthAddressAndDate + - IssueDateAndPlaceOfIssue + - MothersSurname + - MothersName + - FathersSurname + - FathersName + - LastName2 + - A4 + - FirstName2 + - IssueAndExpiryDate + - FiscalNumber + - SocialNumber + - AlternativeName + - VisaNumber + - Duration + - Type + - Count + - NamesOfParents + - NamesOfParents2 + - HealthInsuranceNumber + - FathersBirthDate + - MothersBirthDate + - BirthCertificateNumber1 + - BirthCertificateNumber2 + - BirthCertificateNumber3 + - BirthCertificateNumber4 + - FathersBirthNumber + - MothersBirthNumber + - FathersSurnameBirthSurname + - MothersSurnameBirthSurname + - Authority3 + - Sex2 + type: string + Confidence: + format: int32 + type: integer + OrcResult: + type: string + OrcRawResult: + type: string + OutlineInProjectedImage: + $ref: '#/definitions/System.Nullable[System.Drawing.RectangleF]' ZenidShared.Hash: description: Simple MD5 hash wrapper with easy compare/text conversions type: object @@ -1146,6 +2242,18 @@ definitions: IsNull: type: boolean readOnly: true + System.Drawing.PointF: + type: object + properties: + IsEmpty: + type: boolean + readOnly: true + X: + format: float + type: number + 'Y': + format: float + type: number ZenidShared.MinedText: description: Identifies mined text - its value and confidence type: object @@ -1169,18 +2277,17 @@ definitions: A3: description: physical third row of address on card type: string + A4: + description: physical fourth row of address on card + type: string AdministrativeAreaLevel1: description: main admin. area - in CZ - kraj type: string AdministrativeAreaLevel2: - description: >- - secondary admin. area - in CZ - okres or towns behaves also as okres - - like Brno + description: secondary admin. area - in CZ - okres or towns behaves also as okres - like Brno type: string Locality: - description: >- - identification of town/city/village (if not already defined up - Brno, - Praha) / OSM: boundary=administrative+ admin_level=8 + description: 'identification of town/city/village (if not already defined up - Brno, Praha) / OSM: boundary=administrative+ admin_level=8' type: string Sublocality: description: "town-subdivision\r\nCZ - čtvrť/katastrální území (Neighborhood/Cadastral place) / OSM: boundary=administrative+ admin_level=10\r\nSK - čtvrť/katastrální území (Neighborhood/Cadastral place) / OSM: boundary=administrative+ admin_level=10\r\nDE - stadtteil without selfgovernment / OSM: boundary=administrative+ admin_level=10\r\nHU - admin-level 9\r\n \r\ntodo slovak: Valaská - Piesok is in addess, but Piesok is just place=village, no admin_level=10" @@ -1192,9 +2299,7 @@ definitions: description: in CZ - ulice type: string HouseNumber: - description: >- - descriptive house number in town - used in Czechia, Slovakia, Austria - (číslo popisné, číslo súpisné, Konskriptionsnummer) + description: descriptive house number in town - used in Czechia, Slovakia, Austria (číslo popisné, číslo súpisné, Konskriptionsnummer) type: string StreetNumber: description: descriptive number of house on the street - in CZ - číslo orientační @@ -1211,9 +2316,7 @@ definitions: format: int32 type: integer ZenidShared.MinedRc: - description: >- - Object containing mined information about birth-number - checksum, date, - sex... + description: Object containing mined information about birth-number - checksum, date, sex... type: object properties: BirthDate: @@ -1223,7 +2326,6 @@ definitions: Checksum: format: int32 type: integer - readOnly: true Sex: enum: - F @@ -1261,9 +2363,7 @@ definitions: format: int32 type: integer ZenidShared.MinedMaritalStatus: - description: >- - MinedMaritalStatus - test of field, its confidence and property - MaritalStatus (parsed text) + description: MinedMaritalStatus - test of field, its confidence and property MaritalStatus (parsed text) type: object properties: MaritalStatus: @@ -1285,27 +2385,21 @@ definitions: format: int32 type: integer ZenidShared.MinedPhoto: - description: >- - MinedPhoto - shows image data, and also two face-related values - - estimated age and sex. + description: MinedPhoto - shows image data, and also two face-related values - estimated age and sex. type: object properties: ImageData: $ref: '#/definitions/ZenidShared.LazyMatImage' - EstimatedAge: - format: double - type: number - EstimatedSex: - enum: - - F - - M - type: string + EyesInfo: + $ref: '#/definitions/ZenidShared.EyesInfo' HasOccludedMouth: type: boolean HasSunGlasses: type: boolean HasHeadWear: type: boolean + FromNfc: + type: boolean Text: type: string Confidence: @@ -1322,115 +2416,96 @@ definitions: Confidence: format: int32 type: integer + System.Nullable[System.Drawing.RectangleF]: + type: object + properties: + Location: + $ref: '#/definitions/System.Drawing.PointF' + Size: + type: string + X: + format: float + type: number + 'Y': + format: float + type: number + Width: + format: float + type: number + Height: + format: float + type: number + Left: + format: float + type: number + readOnly: true + Top: + format: float + type: number + readOnly: true + Right: + format: float + type: number + readOnly: true + Bottom: + format: float + type: number + readOnly: true + IsEmpty: + type: boolean + readOnly: true ZenidShared.LazyMatImage: type: object properties: ImageHash: $ref: '#/definitions/ZenidShared.Hash' + ZenidShared.EyesInfo: + type: object + properties: + BoxLeftTopRel: + $ref: '#/definitions/System.Drawing.PointF' + BoxRightBottomRel: + $ref: '#/definitions/System.Drawing.PointF' ZenidShared.Mrz: type: object properties: - Type: - enum: - - ID_v2000 - - ID_v2012 - - PAS_v2006 - - Unknown - - AUT_IDC2002 - - AUT_PAS2006 - - SVK_IDC2008 - - SVK_DL2013 - - SVK_PAS2008 - - POL_IDC2015 - - HRV_IDC2003 - - CZE_RES_2011_14 - - HUN_PAS_2006_12 - - HU_IDC_2000_01_12_16 - type: string - Subtype: - enum: - - OP - - R - - D - - S - - Default - - Unknown - type: string BirthDate: - description: >- - Inner Birth date string of MRZ. Low-level data, ignore it. Use - BirthDate from MineAllResult object. + description: Inner Birth date string of MRZ. Low-level data, ignore it. Use BirthDate from MineAllResult object. type: string BirthDateVerified: - description: >- - Inner flag, if MRZ BirthDate checksum is ok. Low-level check, ignore - it. Use Validators. + description: Inner flag, if MRZ BirthDate checksum is ok. Low-level check, ignore it. Use Validators. type: boolean DocumentNumber: - description: >- - Inner Document number string of MRZ. Low-level data, ignore it. Use - value from MineAllResult object. + description: Inner Document number string of MRZ. Low-level data, ignore it. Use value from MineAllResult object. type: string DocumentNumberVerified: - description: >- - Inner flag, if MRZ DocumentNumber checksum is ok. Low-level check, - ignore it. Use Validators. + description: Inner flag, if MRZ DocumentNumber checksum is ok. Low-level check, ignore it. Use Validators. type: boolean ExpiryDate: - description: >- - Inner Expiry date string of MRZ. Low-level data, ignore it. Use value - from MineAllResult object. + description: Inner Expiry date string of MRZ. Low-level data, ignore it. Use value from MineAllResult object. type: string ExpiryDateVerified: - description: >- - Inner flag, if MRZ ExpiryDate checksum is ok. Low-level check, ignore - it. Use Validators. + description: Inner flag, if MRZ ExpiryDate checksum is ok. Low-level check, ignore it. Use Validators. type: boolean GivenName: - description: >- - Inner Given name string of MRZ. Low-level data, ignore it. Use value - from MineAllResult object. + description: Inner Given name string of MRZ. Low-level data, ignore it. Use value from MineAllResult object. type: string ChecksumVerified: - description: >- - Inner flag, if checksum of MRZ itself is ok. Low-level check, ignore - it. Use Validators. + description: Inner flag, if checksum of MRZ itself is ok. Low-level check, ignore it. Use Validators. type: boolean ChecksumDigit: format: int32 description: Inner value of global MRZ checksum. type: integer LastName: - description: >- - Inner Last name string of MRZ. Low-level data, ignore it. Use value - from MineAllResult object. + description: Inner Last name string of MRZ. Low-level data, ignore it. Use value from MineAllResult object. type: string Nationality: - description: >- - Inner Nationality string of MRZ. Low-level data, ignore it. Use value - from MineAllResult object. + description: Inner Nationality string of MRZ. Low-level data, ignore it. Use value from MineAllResult object. type: string Sex: - description: >- - Inner Sex string of MRZ. Low-level data, ignore it. Use value from - MineAllResult object. + description: Inner Sex string of MRZ. Low-level data, ignore it. Use value from MineAllResult object. type: string - BirthNumber: - description: >- - Inner Birthnumber string of MRZ (used on Czech passports). Low-level - data, ignore it. Use value from MineAllResult object. - type: string - BirthNumberChecksum: - format: int32 - description: >- - Inner value of Birthnumber checksum in MRZ (on Czech passports). - Low-level check, ignore it. Use Validators. - type: integer - BirthNumberVerified: - description: >- - Inner flag, if MRZ BirthNumber checksum is ok (used on Czech - passports). Low-level check, ignore it. Use Validators. - type: boolean BirthdateChecksum: format: int32 description: Inner value of MRZ BirthDate checksum. @@ -1444,54 +2519,482 @@ definitions: description: Inner value of MRZ ExpiryDate checksum. type: integer IssueDate: - description: >- - Prefix of the MRZ (type of the MRZ + subtype (differs, some ID cards - have ID, other I_ or IO) + country issuer. Low-level data, can be - ignored. - type: string - IssueDateParsed: - format: date-time + description: Prefix of the MRZ (type of the MRZ + subtype (differs, some ID cards have ID, other I_ or IO) + country issuer. Low-level data, can be ignored. type: string - readOnly: true AdditionalData: - description: >- - Output of OptionalSubstructure dont fitting in IssueDate or - BirthNumber + description: Output of OptionalSubstructure dont fitting in IssueDate or BirthNumber + type: string + AdditionalData2: + description: Output of OptionalSubstructure dont fitting in IssueDate or BirthNumber (second line) + type: string + Issuer: + description: Issuer ISO identification type: string BirthDateParsed: format: date-time - description: >- - Inner machine-readable value of BirthDate (in DateTime structure). - Low-level data, use value from MineAllResult object. + description: Inner machine-readable value of BirthDate (in DateTime structure). Low-level data, use value from MineAllResult object. type: string - readOnly: true ExpiryDateParsed: format: date-time - description: >- - Inner machine-readable value of ExpiryDate (in DateTime structure). - Low-level data, use value from MineAllResult object. + description: Inner machine-readable value of ExpiryDate (in DateTime structure). Low-level data, use value from MineAllResult object. + type: string + IssueDateParsed: + format: date-time + type: string + MrzDefType: + enum: + - TD1_IDC + - TD2_IDC2000 + - TD3_PAS + - SKDRV + - None + - FrenchID1988 + - NLDRV + type: string + BirthNumber: + description: Inner Birthnumber string of MRZ (used on Czech passports). Low-level data, ignore it. Use value from MineAllResult object. + type: string + BirthNumberChecksum: + format: int32 + description: Inner value of Birthnumber checksum in MRZ (on Czech passports). Low-level check, ignore it. Use Validators. + type: integer + BirthNumberVerified: + description: Inner flag, if MRZ BirthNumber checksum is ok (used on Czech passports). Low-level check, ignore it. Use Validators. + type: boolean + SecondaryDocumentNumber: + description: "Some documents (passports) dont have any additional number. Some have PIN (birthnumber in object MRZ). Some have number of some other document, for example\r\ndocument of ID card. In that case this field is used." + type: string + SecondaryDocumentRole: + description: Role of secondary document. For some passports, that is Idc. + enum: + - Idc + - Pas + - Drv + - Res + - Gun + - Hic + - Std + - Car + - Birth + - Add + - Ide + - Vis + - Exp + type: string + SecondaryDocumentNumberChecksum: + format: int32 + type: integer + SecondaryDocumentNumberVerified: + description: Check, if number is verified. + type: boolean + ZenidShared.AcceptableInput: + type: object + properties: + PossibleDocuments: + type: array + items: + $ref: '#/definitions/ZenidShared.DocumentFilter' + ZenidShared.DocumentFilter: + type: object + properties: + Role: + enum: + - Idc + - Pas + - Drv + - Res + - Gun + - Hic + - Std + - Car + - Birth + - Add + - Ide + - Vis + - Exp + type: string + Country: + enum: + - Cz + - Sk + - At + - Hu + - Pl + - De + - Hr + - Ro + - Ru + - Ua + - It + - Dk + - Es + - Fi + - Fr + - Gb + - Is + - Nl + - Se + - Si + - Bg + - Al + - Ad + - Be + - By + - Ba + - Me + - Ee + - Ie + - Cy + - Li + - Lt + - Lv + - Lu + - Mt + - Md + - Mc + - 'No' + - Pt + - Gr + - Sm + - Mk + - Rs + - Ch + - Tr + - Va + - Vn + - In + - Us + - Jp + - Pk + - Ng + - Br + - Bd + - Cn + - Id + - Mx + - Ol + - Ph + - Et + - Eg + - Cd + - Ir + - Th + - Tz + - Za + - Mm + - Co + - Kr + - Ke + - Ar + - Dz + - Sd + - Ug + - Iq + - Ca + - Ma + - Uz + - Sa + - Ye + - Pe + - Ao + - My + - Af + - Mz + - Gh + - Ci + - Np + - Ve + - Mg + - Au + - Kp + - Cm + - Ne + - Tw + - Ml + - Bf + - Lk + - Sy + - Mw + - Cl + - Kz + - Zm + - Ec + - So + - Sn + - Gt + - Td + - Kh + - Zw + - Ss + - Rw + - Gn + - Bi + - Bj + - Bo + - Tn + - Ht + - Jo + - Cu + - Do + - Az + - Il + - Tj + - Hn + - Ae + - Sl + - Tg + - La + - Kg + - Tm + - Ly + - Sv + - Ni + - Py + - Cg + - Sg + - Cf + - Lb + - Ps + - Cr + - Lr + - Nz + - Om + - Kw + - Mr + - Pa + - Er + - Ge + - Uy + - Mn + - Am + - Jm + - Qa + - Na + - Gm + - Bw + - Ls + - Ga + - Gw + - Xk + - Bh + - Gq + - Tt + - Tl + - Mu + - Sz + - Dj + - Fj + - Bt + - Km + - Gy + - Sb + - Sr + - Cv + - Bn + - Bz + - Bs + - Mv + - Vu + - Bb + - St + - Ws + - Lc + - Ki + - Gd + - Vc + - Fm + - Ag + - Sc + - To + - Dm + - Kn + - Mh + - Pw + - Nr + - Tv + - Pg + type: string + Page: + enum: + - F + - B + type: string + DocumentCode: + enum: + - IDC1 + - IDC2 + - DRV + - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 + - SK_IDC_2008plus + - SK_DRV_2004_08_09 + - SK_DRV_2013 + - SK_DRV_2015 + - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 + - SK_DRV_1993 + - PL_IDC_2015 + - DE_IDC_2010 + - DE_IDC_2001 + - HR_IDC_2013_15 + - AT_IDE_2000 + - HU_IDC_2000_01_12 + - HU_IDC_2016 + - AT_IDC_2002_05_10 + - HU_ADD_2012 + - AT_PAS_2006_14 + - AT_DRV_2006 + - AT_DRV_2013 + - CZ_RES_2011_14 + - CZ_RES_2006_T + - CZ_RES_2006_07 + - CZ_GUN_2014 + - HU_PAS_2006_12 + - HU_DRV_2012_13 + - HU_DRV_2012_B + - EU_EHIC_2004_A + - Unknown + - CZ_GUN_2017 + - CZ_RES_2020 + - PL_IDC_2019 + - IT_PAS_2006_10 + - INT_ISIC_2008 + - DE_PAS + - DK_PAS + - ES_PAS + - FI_PAS + - FR_PAS + - GB_PAS + - IS_PAS + - NL_PAS + - RO_PAS + - SE_PAS + - PL_PAS + - PL_DRV_2013 + - CZ_BIRTH + - CZ_VEHICLE_I + - INT_ISIC_2019 + - SI_PAS + - SI_IDC + - SI_DRV + - EU_EHIC_2004_B + - PL_IDC_2001_02_13 + - IT_IDC_2016 + - HR_PAS_2009_15 + - HR_DRV_2013 + - HR_IDC_2003 + - SI_DRV_2009 + - BG_PAS_2010 + - BG_IDC_2010 + - BG_DRV_2010_13 + - HR_IDC_2021 + - AT_IDC_2021 + - DE_PAS_2007 + - DE_DRV_2013_21 + - DE_DRV_1999_01_04_11 + - FR_IDC_2021 + - FR_IDC_1988_94 + - ES_PAS_2003_06 + - ES_IDC_2015 + - ES_IDC_2006 + - IT_IDC_2004 + - RO_IDC_2001_06_09_17_21 + - NL_IDC_2014_17_21 + - BE_PAS_2014_17_19 + - BE_IDC_2013_15 + - BE_IDC_2020_21 + - GR_PAS_2020 + - PT_PAS_2006_09 + - PT_IDC_2007_08_09_15 + - SE_IDC_2012_21 + - FI_IDC_2017_21 + - IE_PAS_2006_13 + - LT_PAS_2008_09_11_19 + - LT_IDC_2009_12 + - LV_PAS_2015 + - LV_PAS_2007 + - LV_IDC_2012 + - LV_IDC_2019 + - EE_PAS_2014 + - EE_PAS_2021 + - EE_IDC_2011 + - EE_IDC_2018_21 + - CY_PAS_2010_20 + - CY_IDC_2000_08 + - CY_IDC_2015_20 + - LU_PAS_2015 + - LU_IDC_2014_21 + - LU_IDC_2008_13 + - MT_PAS_2008 + - MT_IDC_2014 + - PL_PAS_2011 + - PL_DRV_1999 + - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 type: string - readOnly: true - MrzLength: - $ref: '#/definitions/System.ValueTuple[System.Int32,System.Int32]' - readOnly: true - MrzDefType: - enum: - - TD1_IDC - - TD2_IDC2000 - - TD3_PAS - - SKDRV - - None + ModelID: type: string - System.ValueTuple[System.Int32,System.Int32]: - type: object - properties: - Item1: - format: int32 - type: integer - Item2: - format: int32 - type: integer ZenidWeb.InvestigateResponse: description: Response object for the investigation nodes. type: object @@ -1507,19 +3010,22 @@ definitions: $ref: '#/definitions/ZenidShared.MineAllResult' description: Structure of data, mined from sample - {ZenidShared.MineAllResult}. DocumentsData: - description: >- - If investigation covers multiple documents, each will have their own - entry here + description: If investigation covers multiple documents, each will have their own entry here type: array items: $ref: '#/definitions/ZenidShared.MineAllResult' InvestigationUrl: description: URL of the investigation detail type: string + Rank: + $ref: '#/definitions/RecogLib.RankDetail' + description: Rank of investigation result (A (OK), B (Warning), F (Fail)) + Time: + format: date-time + description: Time of investigation (server time) + type: string ValidatorResults: - description: >- - Result of the all validators - List of - {ZenidWeb.InvestigationValidatorResponse} + description: Result of the all validators - List of {ZenidWeb.InvestigationValidatorResponse} type: array items: $ref: '#/definitions/ZenidWeb.InvestigationValidatorResponse' @@ -1531,6 +3037,7 @@ definitions: - Error - Operator - Rejected + - Archived type: string ErrorCode: description: If throght processing some error occurs, ErrorCode property is set. @@ -1545,13 +3052,34 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true + RecogLib.RankDetail: + type: object + properties: + Overall: + enum: + - A + - B + - F + type: string + Samples: + type: array + items: + $ref: '#/definitions/RecogLib.SampleOverview' + Conditions: + type: array + items: + $ref: '#/definitions/RecogLib.RankCondition' ZenidWeb.InvestigationValidatorResponse: type: object properties: @@ -1567,9 +3095,7 @@ definitions: type: integer AcceptScore: format: int32 - description: >- - Accept score - if score is higher than accept score, Validator - response OK is set to true + description: Accept score - if score is higher than accept score, Validator response OK is set to true type: integer Issues: description: Description of the issues of validation (why score is lower) @@ -1578,6 +3104,228 @@ definitions: $ref: '#/definitions/ZenidWeb.InvestigationIssueResponse' Ok: type: boolean + RecogLib.SampleOverview: + type: object + properties: + SampleType: + enum: + - DocumentPicture + - Selfie + - SelfieVideo + - DocumentVideo + - Archived + - Unknown + type: string + Page: + enum: + - F + - B + type: string + Rank: + description: Rank B or F indicates problems and it is recommended to take image again and re-upload + enum: + - A + - B + - F + type: string + DocumentCode: + enum: + - IDC1 + - IDC2 + - DRV + - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 + - SK_IDC_2008plus + - SK_DRV_2004_08_09 + - SK_DRV_2013 + - SK_DRV_2015 + - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 + - SK_DRV_1993 + - PL_IDC_2015 + - DE_IDC_2010 + - DE_IDC_2001 + - HR_IDC_2013_15 + - AT_IDE_2000 + - HU_IDC_2000_01_12 + - HU_IDC_2016 + - AT_IDC_2002_05_10 + - HU_ADD_2012 + - AT_PAS_2006_14 + - AT_DRV_2006 + - AT_DRV_2013 + - CZ_RES_2011_14 + - CZ_RES_2006_T + - CZ_RES_2006_07 + - CZ_GUN_2014 + - HU_PAS_2006_12 + - HU_DRV_2012_13 + - HU_DRV_2012_B + - EU_EHIC_2004_A + - Unknown + - CZ_GUN_2017 + - CZ_RES_2020 + - PL_IDC_2019 + - IT_PAS_2006_10 + - INT_ISIC_2008 + - DE_PAS + - DK_PAS + - ES_PAS + - FI_PAS + - FR_PAS + - GB_PAS + - IS_PAS + - NL_PAS + - RO_PAS + - SE_PAS + - PL_PAS + - PL_DRV_2013 + - CZ_BIRTH + - CZ_VEHICLE_I + - INT_ISIC_2019 + - SI_PAS + - SI_IDC + - SI_DRV + - EU_EHIC_2004_B + - PL_IDC_2001_02_13 + - IT_IDC_2016 + - HR_PAS_2009_15 + - HR_DRV_2013 + - HR_IDC_2003 + - SI_DRV_2009 + - BG_PAS_2010 + - BG_IDC_2010 + - BG_DRV_2010_13 + - HR_IDC_2021 + - AT_IDC_2021 + - DE_PAS_2007 + - DE_DRV_2013_21 + - DE_DRV_1999_01_04_11 + - FR_IDC_2021 + - FR_IDC_1988_94 + - ES_PAS_2003_06 + - ES_IDC_2015 + - ES_IDC_2006 + - IT_IDC_2004 + - RO_IDC_2001_06_09_17_21 + - NL_IDC_2014_17_21 + - BE_PAS_2014_17_19 + - BE_IDC_2013_15 + - BE_IDC_2020_21 + - GR_PAS_2020 + - PT_PAS_2006_09 + - PT_IDC_2007_08_09_15 + - SE_IDC_2012_21 + - FI_IDC_2017_21 + - IE_PAS_2006_13 + - LT_PAS_2008_09_11_19 + - LT_IDC_2009_12 + - LV_PAS_2015 + - LV_PAS_2007 + - LV_IDC_2012 + - LV_IDC_2019 + - EE_PAS_2014 + - EE_PAS_2021 + - EE_IDC_2011 + - EE_IDC_2018_21 + - CY_PAS_2010_20 + - CY_IDC_2000_08 + - CY_IDC_2015_20 + - LU_PAS_2015 + - LU_IDC_2014_21 + - LU_IDC_2008_13 + - MT_PAS_2008 + - MT_IDC_2014 + - PL_PAS_2011 + - PL_DRV_1999 + - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 + type: string + SampleID: + description: If SampleID is undefined, it means that validators require sample, but it miss + type: string + RecogLib.RankCondition: + type: object + properties: + Result: + enum: + - A + - B + - F + type: string + ConditionParamJson: + type: string + Type: + enum: + - FailedMrzAndNoBlurNoLowConfidence + - FailedMrzAndFontShape + - ExpirationAndFontShape + - BarcodeAndNoBlur + - BarcodeAndMrzMismatch + - Simple + - FontFailedNoBlur + type: string ZenidWeb.InvestigationIssueResponse: type: object properties: @@ -1590,15 +3338,23 @@ definitions: DocumentCode: description: Document code of sample, where issue is present enum: + - IDC1 - IDC2 - DRV - - IDC1 - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 - SK_IDC_2008plus - SK_DRV_2004_08_09 - SK_DRV_2013 - SK_DRV_2015 - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 - SK_DRV_1993 - PL_IDC_2015 - DE_IDC_2010 @@ -1672,7 +3428,6 @@ definitions: - BE_IDC_2020_21 - GR_PAS_2020 - PT_PAS_2006_09 - - PT_PAS_2017 - PT_IDC_2007_08_09_15 - SE_IDC_2012_21 - FI_IDC_2017_21 @@ -1698,6 +3453,62 @@ definitions: - PL_PAS_2011 - PL_DRV_1999 - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 type: string FieldID: description: FieldID wher issue is present @@ -1788,6 +3599,25 @@ definitions: - FiscalNumber - SocialNumber - AlternativeName + - VisaNumber + - Duration + - Type + - Count + - NamesOfParents + - NamesOfParents2 + - HealthInsuranceNumber + - FathersBirthDate + - MothersBirthDate + - BirthCertificateNumber1 + - BirthCertificateNumber2 + - BirthCertificateNumber3 + - BirthCertificateNumber4 + - FathersBirthNumber + - MothersBirthNumber + - FathersSurnameBirthSurname + - MothersSurnameBirthSurname + - Authority3 + - Sex2 type: string SampleID: description: ID of the identification issue @@ -1801,12 +3631,12 @@ definitions: SampleType: description: Type of sample enum: - - Unknown - - Selfie - DocumentPicture + - Selfie - SelfieVideo - DocumentVideo - Archived + - Unknown type: string ZenidWeb.DeletePersonResponse: type: object @@ -1819,6 +3649,9 @@ definitions: type: array items: type: string + DeletedFacesWithoutCorrespondingSampleCount: + format: int32 + type: integer ErrorCode: description: If throght processing some error occurs, ErrorCode property is set. enum: @@ -1832,10 +3665,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -1855,10 +3692,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -1867,9 +3708,7 @@ definitions: type: object properties: Results: - description: >- - List of declarations of samples - ID, CustomData, UploadSessionID, - State + description: List of declarations of samples - ID, CustomData, UploadSessionID, State type: array items: $ref: '#/definitions/ZenidWeb.ListSamplesResponse.SampleItem' @@ -1890,10 +3729,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -1904,9 +3747,7 @@ definitions: description: DB ID of given sample. type: string ParentSampleID: - description: >- - If the sample is subsample image created from primary one, this is the - ID of primary image + description: If the sample is subsample image created from primary one, this is the ID of primary image type: string CustomData: description: CustomData attribute (copied from Request) @@ -1924,6 +3765,7 @@ definitions: - Error - Operator - Rejected + - Archived type: string ZenidWeb.ListInvestigationsResponse: description: Return value of api/investigation @@ -1951,10 +3793,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -1977,6 +3823,7 @@ definitions: - Error - Operator - Rejected + - Archived type: string ZenidWeb.ListProfilesResponse: description: Return value of api/profiles @@ -2000,10 +3847,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -2026,15 +3877,23 @@ definitions: type: array items: enum: + - IDC1 - IDC2 - DRV - - IDC1 - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 - SK_IDC_2008plus - SK_DRV_2004_08_09 - SK_DRV_2013 - SK_DRV_2015 - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 - SK_DRV_1993 - PL_IDC_2015 - DE_IDC_2010 @@ -2108,7 +3967,6 @@ definitions: - BE_IDC_2020_21 - GR_PAS_2020 - PT_PAS_2006_09 - - PT_PAS_2017 - PT_IDC_2007_08_09_15 - SE_IDC_2012_21 - FI_IDC_2017_21 @@ -2134,6 +3992,62 @@ definitions: - PL_PAS_2011 - PL_DRV_1999 - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 type: string ErrorCode: description: If throght processing some error occurs, ErrorCode property is set. @@ -2148,10 +4062,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -2195,10 +4113,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -2234,10 +4156,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -2253,15 +4179,23 @@ definitions: properties: DocumentCode: enum: + - IDC1 - IDC2 - DRV - - IDC1 - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 - SK_IDC_2008plus - SK_DRV_2004_08_09 - SK_DRV_2013 - SK_DRV_2015 - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 - SK_DRV_1993 - PL_IDC_2015 - DE_IDC_2010 @@ -2335,7 +4269,6 @@ definitions: - BE_IDC_2020_21 - GR_PAS_2020 - PT_PAS_2006_09 - - PT_PAS_2017 - PT_IDC_2007_08_09_15 - SE_IDC_2012_21 - FI_IDC_2017_21 @@ -2361,6 +4294,62 @@ definitions: - PL_PAS_2011 - PL_DRV_1999 - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 type: string CardNumber: type: string @@ -2384,10 +4373,14 @@ definitions: - AccessDenied - UnknownPerson - InvalidInputData + - InitSDKRecreatesSessionError type: string ErrorText: description: Error text type: string + ProcessingTimeMs: + format: int64 + type: integer MessageType: type: string readOnly: true @@ -2398,15 +4391,23 @@ definitions: type: boolean DocumentCode: enum: + - IDC1 - IDC2 - DRV - - IDC1 - PAS + - EU_VIS_2019 + - CZ_BIRTH_A2 + - CZ_BIRTH_A3 + - CZ_BIRTH_A4 + - CZ_RES_2020_A2 - SK_IDC_2008plus - SK_DRV_2004_08_09 - SK_DRV_2013 - SK_DRV_2015 - SK_PAS_2008_14 + - SK_RES_2011 + - SK_RES_2020 + - SK_IDC_2022 - SK_DRV_1993 - PL_IDC_2015 - DE_IDC_2010 @@ -2480,7 +4481,6 @@ definitions: - BE_IDC_2020_21 - GR_PAS_2020 - PT_PAS_2006_09 - - PT_PAS_2017 - PT_IDC_2007_08_09_15 - SE_IDC_2012_21 - FI_IDC_2017_21 @@ -2506,6 +4506,62 @@ definitions: - PL_PAS_2011 - PL_DRV_1999 - LT_IDC_2021 + - UA_PAS_2007_15 + - UA_IDC_2017 + - UA_DRV_2016 + - UA_DRV_2005 + - UA_DRV_2021 + - EU_EHIC_2004_C + - VN_PAS_2005 + - NL_DRV_2006 + - NL_DRV_2013 + - NL_DRV_2014 + - AL_PAS_2009 + - BA_PAS_2014 + - CH_PAS_2010 + - ME_PAS_2008 + - MK_PAS_2007 + - RS_PAS_2008 + - NO_PAS_2011_15 + - NO_PAS_2020 + - GB_PAS_2010_11_15_19 + - BY_PAS_2006 + - BY_PAS_2021 + - MD_PAS_2011_14_18 + - IS_PAS_2006 + - IN_PAS_2000_13 + - TR_PAS_2010 + - TR_PAS_2018 + - RO_IDC_2021sep + - PL_DRV_1999_A2 + - DE_IDC_2010_A2 + - DE_IDC_2010_A3 + - PL_DRV_2013_A2 + - AT_IDC_2002_05_10_A2 + - CY_IDC_2015_20_A2 + - CY_IDC_2000_08_A2 + - CY_PAS_2010_20_A2 + - ES_PAS_2003_06_A2 + - LU_IDC_2008_13_A2 + - NL_IDC_2014_17_21_A2 + - SE_IDC_2022 + - SE_PAS_2022 + - DK_PAS_2021 + - CH_PAS_2022 + - VN_PAS_2022 + - ME_PAS_2008_A2 + - OL_IDC_2022 + - SM_PAS_2006 + - AD_PAS_2017 + - BE_PAS_2022 + - RU_PAS_2006_10 + - TR_PAS_2023 + - DO_IDC_2014 + - LI_PAS_2006 + - VA_PAS_2013 + - US_PAS_2006 + - JP_PAS_2013 + - PK_PAS_2022 type: string CardNumber: type: string From 83aafb9776a2701896c960fdcb7bfcb76718bc75 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 19 Jun 2024 09:46:52 +0200 Subject: [PATCH 5/9] Fix #1083: Add migration-guides 1.8.0 --- docs/Migration-Instructions.md | 1 + docs/PowerAuth-Enrollment-Server-1.8.0.md | 5 +++++ docs/onboarding/Migration-Instructions.md | 2 ++ .../PowerAuth-Enrollment-Onboarding-Server-1.7.0.md | 5 +++++ .../PowerAuth-Enrollment-Onboarding-Server-1.8.0.md | 5 +++++ 5 files changed, 18 insertions(+) create mode 100644 docs/PowerAuth-Enrollment-Server-1.8.0.md create mode 100644 docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.7.0.md create mode 100644 docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.8.0.md diff --git a/docs/Migration-Instructions.md b/docs/Migration-Instructions.md index 740c7d30..280af0e2 100644 --- a/docs/Migration-Instructions.md +++ b/docs/Migration-Instructions.md @@ -2,6 +2,7 @@ This page contains PowerAuth Enrollment Server migration instructions. +- [PowerAuth Enrollment Server 1.8.0](./PowerAuth-Enrollment-Server-1.8.0.md) - [PowerAuth Enrollment Server 1.7.0](./PowerAuth-Enrollment-Server-1.7.0.md) - [PowerAuth Enrollment Server 1.6.0](./PowerAuth-Enrollment-Server-1.6.0.md) - [PowerAuth Enrollment Server 1.5.0](./PowerAuth-Enrollment-Server-1.5.0.md) diff --git a/docs/PowerAuth-Enrollment-Server-1.8.0.md b/docs/PowerAuth-Enrollment-Server-1.8.0.md new file mode 100644 index 00000000..e13ce0bd --- /dev/null +++ b/docs/PowerAuth-Enrollment-Server-1.8.0.md @@ -0,0 +1,5 @@ +# Migration from 1.7.x to 1.8.x + +This guide contains instructions for migration from PowerAuth Enrollment Server version `1.7.x` to version `1.8.0`. + +No migration steps nor database changes are required. diff --git a/docs/onboarding/Migration-Instructions.md b/docs/onboarding/Migration-Instructions.md index 9c502ee3..8b7a2275 100644 --- a/docs/onboarding/Migration-Instructions.md +++ b/docs/onboarding/Migration-Instructions.md @@ -2,5 +2,7 @@ This page contains PowerAuth Enrollment Onboarding Server migration instructions. +- [PowerAuth Enrollment Onboarding Server 1.8.0](./PowerAuth-Enrollment-Onboarding-Server-1.8.0.md) +- [PowerAuth Enrollment Onboarding Server 1.7.0](./PowerAuth-Enrollment-Onboarding-Server-1.7.0.md) - [PowerAuth Enrollment Onboarding Server 1.6.0](./PowerAuth-Enrollment-Onboarding-Server-1.6.0.md) - [PowerAuth Enrollment Onboarding Server 1.5.0](./PowerAuth-Enrollment-Onboarding-Server-1.5.0.md) diff --git a/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.7.0.md b/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.7.0.md new file mode 100644 index 00000000..e6c12d4e --- /dev/null +++ b/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.7.0.md @@ -0,0 +1,5 @@ +# Migration from 1.6.x to 1.7.x + +This guide contains instructions for migration from PowerAuth Enrollment Onboarding Server version `1.6.x` to version `1.7.0`. + +No migration steps nor database changes are required. diff --git a/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.8.0.md b/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.8.0.md new file mode 100644 index 00000000..bfca22d0 --- /dev/null +++ b/docs/onboarding/PowerAuth-Enrollment-Onboarding-Server-1.8.0.md @@ -0,0 +1,5 @@ +# Migration from 1.7.x to 1.8.x + +This guide contains instructions for migration from PowerAuth Enrollment Onboarding Server version `1.7.x` to version `1.8.0`. + +No migration steps nor database changes are required. From a52899f875e20f7b30cd8976d422c18f341de760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Wed, 19 Jun 2024 11:49:39 +0200 Subject: [PATCH 6/9] Fix #1079: Refactor MobileTokenConverter#prepareFormData (#1080) * Fix #1079: Refactor MobileTokenConverter#prepareFormData - Change forEach with a side-effect into collect --- .../converter/MobileTokenConverter.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java index 98b574cb..09e52cea 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java @@ -19,6 +19,7 @@ package com.wultra.app.enrollmentserver.impl.service.converter; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.wultra.app.enrollmentserver.database.entity.OperationTemplateEntity; import com.wultra.app.enrollmentserver.database.entity.OperationTemplateParam; @@ -130,15 +131,17 @@ private FormData prepareFormData( } final String attributes = operationTemplate.getAttributes(); - if (attributes != null) { - final OperationTemplateParam[] operationTemplateParams = objectMapper.readValue(attributes, OperationTemplateParam[].class); - if (operationTemplateParams != null) { - final List formDataAttributes = formData.getAttributes(); - for (OperationTemplateParam templateParam : operationTemplateParams) { - buildAttribute(templateParam, parameters) - .ifPresent(formDataAttributes::add); - } - } + if (attributes == null) { + return formData; + } + + final List operationTemplateParams = objectMapper.readValue(attributes, new TypeReference<>(){}); + if (operationTemplateParams != null) { + final List formDataAttributes = operationTemplateParams.stream() + .map(templateParam -> buildAttribute(templateParam, parameters)) + .flatMap(Optional::stream) + .toList(); + formData.setAttributes(formDataAttributes); } return formData; } From 784dd41564780e4cc5a08f09c194e151df1d85ef Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 19 Jun 2024 15:28:24 +0200 Subject: [PATCH 7/9] Fix #1086: Consider omitting Attribute discriminator --- mtoken-model/pom.xml | 13 ++ .../entity/attributes/AlertAttribute.java | 7 +- .../entity/attributes/AmountAttribute.java | 5 +- .../attributes/AmountConversionAttribute.java | 7 +- .../model/entity/attributes/Attribute.java | 57 --------- .../entity/attributes/HeadingAttribute.java | 7 +- .../entity/attributes/ImageAttribute.java | 5 +- .../entity/attributes/KeyValueAttribute.java | 14 +-- .../entity/attributes/NoteAttribute.java | 7 +- .../entity/attributes/PartyAttribute.java | 7 +- .../AmountConversionAttributeTest.java | 117 ++++++++++++++++++ 11 files changed, 152 insertions(+), 94 deletions(-) create mode 100644 mtoken-model/src/test/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttributeTest.java diff --git a/mtoken-model/pom.xml b/mtoken-model/pom.xml index 8bd5bd94..e9460220 100644 --- a/mtoken-model/pom.xml +++ b/mtoken-model/pom.xml @@ -43,6 +43,19 @@ io.swagger.core.v3 swagger-annotations-jakarta + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.fasterxml.jackson.core + jackson-databind + test + diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AlertAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AlertAttribute.java index e5b344f7..f2d68754 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AlertAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AlertAttribute.java @@ -71,10 +71,10 @@ public enum AlertType { private String message; /** - * Default constructor. + * No-arg constructor. */ - public AlertAttribute() { - super(Type.ALERT); + private AlertAttribute() { + super(); } /** @@ -86,7 +86,6 @@ public AlertAttribute() { * @param message Alert message. */ public AlertAttribute(String id, AlertType alertType, String label, String title, String message) { - this(); this.id = id; this.alertType = alertType; this.label = label; diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountAttribute.java index c3238e3f..28bd60a5 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountAttribute.java @@ -45,12 +45,11 @@ public class AmountAttribute extends Attribute { /** * No-arg constructor. */ - AmountAttribute() { - super(Type.AMOUNT); + private AmountAttribute() { + super(); } protected AmountAttribute(final Builder builder) { - this(); this.id = builder.id; this.label = builder.label; this.amount = builder.amount; diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttribute.java index bbcd31eb..130468cb 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttribute.java @@ -60,12 +60,11 @@ public class AmountConversionAttribute extends Attribute { /** * No-arg constructor. */ - AmountConversionAttribute() { - super(Type.AMOUNT_CONVERSION); + private AmountConversionAttribute() { + super(); } - protected AmountConversionAttribute(final Builder builder) { - this(); + private AmountConversionAttribute(final Builder builder) { this.dynamic = builder.dynamic; this.id = builder.id; this.label = builder.label; diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/Attribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/Attribute.java index 7f7d9838..033114bd 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/Attribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/Attribute.java @@ -17,7 +17,6 @@ */ package com.wultra.security.powerauth.lib.mtoken.model.entity.attributes; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; @@ -43,59 +42,6 @@ }) public class Attribute { - /** - * Attribute type. - */ - public enum Type { - - /** - * Amount attribute type - represents amount and currency. - */ - AMOUNT, - - /** - * Amount conversion attribute type - represents amount and currency conversion. - */ - AMOUNT_CONVERSION, - - /** - * Key-value attribute type - represents generic single-line key value. - */ - KEY_VALUE, - - /** - * Note, a multi-line key-value attribute. - */ - NOTE, - - /** - * Heading attribute type, represents a visual separator. - */ - HEADING, - - /** - * Alert attribute type, represents an alert of success (green), info (blue), warning (orange), and error (red). - */ - ALERT, - - /** - * Information about third-party subject. - */ - PARTY_INFO, - - /** - * Image attribute type - represents an image as a URL to the thumbnail and the higher resolution. - */ - IMAGE - } - - /** - * Type of the attribute. - */ - // JsonIgnore added, otherwise type was serialized twice - @JsonIgnore - protected Type type; - /** * ID of the attribute. */ @@ -106,7 +52,4 @@ public enum Type { */ protected String label; - public Attribute(Type type) { - this.type = type; - } } diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/HeadingAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/HeadingAttribute.java index ed004803..cc786110 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/HeadingAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/HeadingAttribute.java @@ -32,10 +32,10 @@ public class HeadingAttribute extends Attribute { private int level; /** - * Default constructor. + * No-arg constructor. */ - public HeadingAttribute() { - super(Type.HEADING); + private HeadingAttribute() { + super(); } /** @@ -44,7 +44,6 @@ public HeadingAttribute() { * @param label Heading text. */ public HeadingAttribute(String id, String label, int level) { - this(); this.id = id; this.label = label; this.level = level; diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/ImageAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/ImageAttribute.java index 6f3e120c..c6a20c31 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/ImageAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/ImageAttribute.java @@ -43,8 +43,8 @@ public class ImageAttribute extends Attribute { /** * No-arg constructor. */ - public ImageAttribute() { - super(Type.IMAGE); + private ImageAttribute() { + super(); } /** @@ -55,7 +55,6 @@ public ImageAttribute() { * @param originalUrl URL to the original image in higher resolution. May be {@code null}. */ public ImageAttribute(String id, String label, String thumbnailUrl, String originalUrl) { - this(); this.id = id; this.label = label; this.thumbnailUrl = thumbnailUrl; diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/KeyValueAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/KeyValueAttribute.java index 3e470dc9..9223963b 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/KeyValueAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/KeyValueAttribute.java @@ -36,17 +36,10 @@ public class KeyValueAttribute extends Attribute { protected String value; /** - * Default constructor. + * No-arg constructor. */ - public KeyValueAttribute() { - super(Type.KEY_VALUE); - } - - /** - * Protected constructor for easier subclassing. - */ - protected KeyValueAttribute(Type type) { - super(type); + private KeyValueAttribute() { + super(); } /** @@ -56,7 +49,6 @@ protected KeyValueAttribute(Type type) { * @param value Value. */ public KeyValueAttribute(String id, String label, String value) { - this(); this.id = id; this.label = label; this.value = value; diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/NoteAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/NoteAttribute.java index 6fdc64c1..a44d97f4 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/NoteAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/NoteAttribute.java @@ -33,10 +33,10 @@ public class NoteAttribute extends Attribute { private String note; /** - * Default constructor. + * No-arg constructor. */ - public NoteAttribute() { - super(Type.NOTE); + private NoteAttribute() { + super(); } /** @@ -46,7 +46,6 @@ public NoteAttribute() { * @param note Note. */ public NoteAttribute(String id, String label, String note) { - this(); this.id = id; this.label = label; this.note = note; diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/PartyAttribute.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/PartyAttribute.java index de90a73a..c82bdcf3 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/PartyAttribute.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/PartyAttribute.java @@ -33,10 +33,10 @@ public class PartyAttribute extends Attribute { private PartyInfo partyInfo; /** - * Default constructor. + * No-arg constructor. */ - public PartyAttribute() { - super(Type.PARTY_INFO); + private PartyAttribute() { + super(); } /** @@ -46,7 +46,6 @@ public PartyAttribute() { * @param partyInfo Party information. */ public PartyAttribute(String id, String label, PartyInfo partyInfo) { - this(); this.id = id; this.label = label; this.partyInfo = partyInfo; diff --git a/mtoken-model/src/test/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttributeTest.java b/mtoken-model/src/test/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttributeTest.java new file mode 100644 index 00000000..935fc515 --- /dev/null +++ b/mtoken-model/src/test/java/com/wultra/security/powerauth/lib/mtoken/model/entity/attributes/AmountConversionAttributeTest.java @@ -0,0 +1,117 @@ +/* + * PowerAuth Mobile Token Model + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.lib.mtoken.model.entity.attributes; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Test for {@link AmountConversionAttribute}. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +class AmountConversionAttributeTest { + + @Test + void testSerializeToJson() throws Exception { + final String expectedResult = """ + { + "type" : "AMOUNT_CONVERSION", + "id" : "operation.amountConversion", + "label" : "Amount Conversion", + "dynamic" : true, + "sourceAmount" : 1.26, + "sourceCurrency" : "ETH", + "sourceAmountFormatted" : "1.26", + "sourceCurrencyFormatted" : "ETH", + "sourceValueFormatted" : "1.26 ETH", + "targetAmount" : 1710.98, + "targetCurrency" : "USD", + "targetAmountFormatted" : "1,710.98", + "targetCurrencyFormatted" : "$", + "targetValueFormatted" : "$1,710.98" + }"""; + + final Attribute tested = AmountConversionAttribute.builder() + .id("operation.amountConversion") + .label("Amount Conversion") + .dynamic(true) + .sourceAmount(new BigDecimal("1.26")) + .sourceAmountFormatted("1.26") + .sourceCurrency("ETH") + .sourceCurrencyFormatted("ETH") + .sourceValueFormatted("1.26 ETH") + .targetAmount(new BigDecimal("1710.98")) + .targetAmountFormatted("1,710.98") + .targetCurrency("USD") + .targetCurrencyFormatted("$") + .targetValueFormatted("$1,710.98") + .build(); + + final String result = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(tested); + + assertEquals(expectedResult, result); + } + + @Test + void testDeserializeFromJson() throws Exception { + final String input = """ + { + "type" : "AMOUNT_CONVERSION", + "id" : "operation.amountConversion", + "label" : "Amount Conversion", + "dynamic" : true, + "sourceAmount" : 1.26, + "sourceCurrency" : "ETH", + "sourceAmountFormatted" : "1.26", + "sourceCurrencyFormatted" : "ETH", + "sourceValueFormatted" : "1.26 ETH", + "targetAmount" : 1710.98, + "targetCurrency" : "USD", + "targetAmountFormatted" : "1,710.98", + "targetCurrencyFormatted" : "$", + "targetValueFormatted" : "$1,710.98" + }"""; + + final Attribute expectedResult = AmountConversionAttribute.builder() + .id("operation.amountConversion") + .label("Amount Conversion") + .dynamic(true) + .sourceAmount(new BigDecimal("1.26")) + .sourceAmountFormatted("1.26") + .sourceCurrency("ETH") + .sourceCurrencyFormatted("ETH") + .sourceValueFormatted("1.26 ETH") + .targetAmount(new BigDecimal("1710.98")) + .targetAmountFormatted("1,710.98") + .targetCurrency("USD") + .targetCurrencyFormatted("$") + .targetValueFormatted("$1,710.98") + .build(); + + final Attribute result = new ObjectMapper().readValue(input, Attribute.class); + + assertNotNull(result); + assertEquals(expectedResult, result); + } +} From b2c8ef7fc2026036eaea06db88af36bc43f7f8c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 05:19:15 +0000 Subject: [PATCH 8/9] Bump org.springframework.boot:spring-boot-starter-parent Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-parent dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96d1a041..5e03a6d6 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ org.springframework.boot spring-boot-starter-parent - 3.3.0 + 3.3.1 From 6025666c7a234830d82df4b77bb4f59ada5114f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Fri, 21 Jun 2024 08:06:16 +0200 Subject: [PATCH 9/9] Fix #1077: Add optional texts to the operation template for - success - failure - reject (#1085) * Fix #1077: Add optional texts to the operation template for - success - failure - reject --- docs-private/Developer-How-To-Start.md | 23 +++++++ docs/Database-Structure.md | 19 +++--- docs/Operation-Form-Data.md | 8 ++- docs/PowerAuth-Enrollment-Server-1.8.0.md | 16 ++++- .../1.8.x/20240620-add-resultTexts.xml | 18 ++++++ .../1.8.x/db.changelog-version.xml | 8 +++ .../enrollment-server/db.changelog-module.xml | 1 + .../enrollment/migration_1.7.0_1.8.0.sql | 3 + .../enrollment/migration_1.7.0_1.8.0.sql | 3 + .../response/TemplateListResponse.java | 3 +- .../resources/application-test.properties | 2 + .../api/admin/AdminControllerTest.sql | 26 ++++++++ .../controller/api/admin/AdminController.java | 15 +++++ .../entity/OperationTemplateEntity.java | 17 +++--- .../converter/MobileTokenConverter.java | 49 ++++++++++----- .../api/admin/AdminControllerTest.java | 60 +++++++++++++++++++ .../converter/MobileTokenConverterTest.java | 36 +++++++++++ .../lib/mtoken/model/entity/FormData.java | 2 + .../lib/mtoken/model/entity/ResultTexts.java | 37 ++++++++++++ 19 files changed, 311 insertions(+), 35 deletions(-) create mode 100644 docs/db/changelog/changesets/enrollment-server/1.8.x/20240620-add-resultTexts.xml create mode 100644 docs/db/changelog/changesets/enrollment-server/1.8.x/db.changelog-version.xml create mode 100644 docs/sql/oracle/enrollment/migration_1.7.0_1.8.0.sql create mode 100644 docs/sql/postgresql/enrollment/migration_1.7.0_1.8.0.sql create mode 100644 enrollment-server-api-model/src/main/resources/application-test.properties create mode 100644 enrollment-server-api-model/src/main/resources/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.sql create mode 100644 enrollment-server/src/test/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.java create mode 100644 mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/ResultTexts.java diff --git a/docs-private/Developer-How-To-Start.md b/docs-private/Developer-How-To-Start.md index 1ca53619..f4bb0de6 100644 --- a/docs-private/Developer-How-To-Start.md +++ b/docs-private/Developer-How-To-Start.md @@ -22,6 +22,29 @@ Others (like URL, username, password) depend on your environment. liquibase --changelog-file=./docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml --url=jdbc:postgresql://localhost:5432/powerauth --username=powerauth status ``` +To generate SQL script run this command. + + +#### Oracle + +```shell +liquibase --changeLogFile=./docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml --output-file=./docs/sql/oracle/generated-oracle-script.sql updateSQL --url=offline:oracle +``` + + +#### MS SQL + +```shell +liquibase --changeLogFile=./docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml --output-file=./docs/sql/mssql/generated-mssql-script.sql updateSQL --url=offline:mssql +``` + + +#### PostgreSQL + +```shell +liquibase --changeLogFile=./docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml --output-file=./docs/sql/postgresql/generated-postgresql-script.sql updateSQL --url=offline:postgresql +``` + ### Docker diff --git a/docs/Database-Structure.md b/docs/Database-Structure.md index f4037859..a80c4a01 100644 --- a/docs/Database-Structure.md +++ b/docs/Database-Structure.md @@ -29,14 +29,15 @@ For more information, see [Operation Extensions](Operation-Extensions.md) and [C #### Schema -| Name | Type | Info | Note | -|---------------|----------------|------------------------|------------------------------------------------------------------------------------------| -| `id` | `BIGINT` | `NOT NULL PRIMARY KEY` | Autogenerated record identifier. | -| `placeholder` | `VARCHAR(255)` | `NOT NULL` | Operation type at PowerAuth server. | -| `language` | `VARCHAR(8)` | `NOT NULL` | Language of the template. | -| `title` | `VARCHAR(255)` | `NOT NULL` | Title of the operation. | -| `message` | `TEXT` | `NOT NULL` | Message for the user related to the operation. | -| `attributes` | `TEXT` | | Structured custom form data attributes as JSON. | -| `ui` | `TEXT` | | JSON configuration which may affect behavior or visual aspect of the mobile application. | +| Name | Type | Info | Note | +|----------------|----------------|------------------------|------------------------------------------------------------------------------------------| +| `id` | `BIGINT` | `NOT NULL PRIMARY KEY` | Autogenerated record identifier. | +| `placeholder` | `VARCHAR(255)` | `NOT NULL` | Operation type at PowerAuth server. | +| `language` | `VARCHAR(8)` | `NOT NULL` | Language of the template. | +| `title` | `VARCHAR(255)` | `NOT NULL` | Title of the operation. | +| `message` | `TEXT` | `NOT NULL` | Message for the user related to the operation. | +| `result_texts` | `TEXT` | | Customized texts to display for `success`, `failure`, or `reject` operations as JSON. | +| `attributes` | `TEXT` | | Structured custom form data attributes as JSON. | +| `ui` | `TEXT` | | JSON configuration which may affect behavior or visual aspect of the mobile application. | diff --git a/docs/Operation-Form-Data.md b/docs/Operation-Form-Data.md index 7a4ab8d3..efb54967 100644 --- a/docs/Operation-Form-Data.md +++ b/docs/Operation-Form-Data.md @@ -4,11 +4,17 @@ When creating an operation, you can customize the operation form data. This cust ## Standard Operation Form Data Attributes -Following attributes are required to be specified for each operation: +Following attributes are **required** to be specified for each operation: - `title` - title of the operation - `message` - message for the user related to the operation +Following attributes are **optional** to be specified for each operation: + +- `resultTexts.success` - Customized text to display for _success_ operation. If not provided, the default message will be used. +- `resultTexts.failure` - Customized text to display for _failure_ operation. If not provided, the default message will be used. +- `resultTexts.reject` - Customized text to display for _reject_ operation. If not provided, the default message will be used. + ## Custom Operation Form Data Attributes Following structured custom form data attributes are available: diff --git a/docs/PowerAuth-Enrollment-Server-1.8.0.md b/docs/PowerAuth-Enrollment-Server-1.8.0.md index e13ce0bd..d01b423c 100644 --- a/docs/PowerAuth-Enrollment-Server-1.8.0.md +++ b/docs/PowerAuth-Enrollment-Server-1.8.0.md @@ -2,4 +2,18 @@ This guide contains instructions for migration from PowerAuth Enrollment Server version `1.7.x` to version `1.8.0`. -No migration steps nor database changes are required. + +## Database Changes + +For convenience, you can use liquibase for your database migration. + +For manual changes use SQL scripts: + +- [PostgreSQL script](./sql/postgresql/enrollment/migration_1.7.0_1.8.0.sql) +- [Oracle script](./sql/oracle/enrollment/migration_1.7.0_1.8.0.sql) + + +### Add Column result_texts + +A column `result_texts` has been added to the table `es_operation_template`. +It is an optional JSON representing customized texts to display for `success`, `failure`, or `reject` operations. diff --git a/docs/db/changelog/changesets/enrollment-server/1.8.x/20240620-add-resultTexts.xml b/docs/db/changelog/changesets/enrollment-server/1.8.x/20240620-add-resultTexts.xml new file mode 100644 index 00000000..69e59180 --- /dev/null +++ b/docs/db/changelog/changesets/enrollment-server/1.8.x/20240620-add-resultTexts.xml @@ -0,0 +1,18 @@ + + + + + + + + + + Add result_texts column + + + + + + diff --git a/docs/db/changelog/changesets/enrollment-server/1.8.x/db.changelog-version.xml b/docs/db/changelog/changesets/enrollment-server/1.8.x/db.changelog-version.xml new file mode 100644 index 00000000..35df0daa --- /dev/null +++ b/docs/db/changelog/changesets/enrollment-server/1.8.x/db.changelog-version.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml b/docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml index b3ebdeab..20a3429e 100644 --- a/docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml +++ b/docs/db/changelog/changesets/enrollment-server/db.changelog-module.xml @@ -10,5 +10,6 @@ + \ No newline at end of file diff --git a/docs/sql/oracle/enrollment/migration_1.7.0_1.8.0.sql b/docs/sql/oracle/enrollment/migration_1.7.0_1.8.0.sql new file mode 100644 index 00000000..c6028397 --- /dev/null +++ b/docs/sql/oracle/enrollment/migration_1.7.0_1.8.0.sql @@ -0,0 +1,3 @@ +-- Changeset enrollment-server/1.8.x/20240620-add-resultTexts.xml::1::Lubos Racansky +-- Add result_texts column +ALTER TABLE es_operation_template ADD result_texts CLOB; diff --git a/docs/sql/postgresql/enrollment/migration_1.7.0_1.8.0.sql b/docs/sql/postgresql/enrollment/migration_1.7.0_1.8.0.sql new file mode 100644 index 00000000..50039b3c --- /dev/null +++ b/docs/sql/postgresql/enrollment/migration_1.7.0_1.8.0.sql @@ -0,0 +1,3 @@ +-- Changeset enrollment-server/1.8.x/20240620-add-resultTexts.xml::1::Lubos Racansky +-- Add result_texts column +ALTER TABLE es_operation_template ADD result_texts TEXT; diff --git a/enrollment-server-api-model/src/main/java/com/wultra/app/enrollmentserver/api/model/enrollment/response/TemplateListResponse.java b/enrollment-server-api-model/src/main/java/com/wultra/app/enrollmentserver/api/model/enrollment/response/TemplateListResponse.java index 248f0e42..a420b92d 100644 --- a/enrollment-server-api-model/src/main/java/com/wultra/app/enrollmentserver/api/model/enrollment/response/TemplateListResponse.java +++ b/enrollment-server-api-model/src/main/java/com/wultra/app/enrollmentserver/api/model/enrollment/response/TemplateListResponse.java @@ -23,6 +23,7 @@ import java.io.Serial; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Template list response. @@ -36,6 +37,6 @@ public class TemplateListResponse extends ArrayList attributes, String language) { + public record TemplateDetail(String name, String title, String message, List attributes, String language, Map resultTexts) { } } diff --git a/enrollment-server-api-model/src/main/resources/application-test.properties b/enrollment-server-api-model/src/main/resources/application-test.properties new file mode 100644 index 00000000..e42e9b9f --- /dev/null +++ b/enrollment-server-api-model/src/main/resources/application-test.properties @@ -0,0 +1,2 @@ +spring.datasource.url=jdbc:h2:mem:testdb +spring.jpa.hibernate.ddl-auto=create diff --git a/enrollment-server-api-model/src/main/resources/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.sql b/enrollment-server-api-model/src/main/resources/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.sql new file mode 100644 index 00000000..488955e6 --- /dev/null +++ b/enrollment-server-api-model/src/main/resources/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.sql @@ -0,0 +1,26 @@ +insert into public.es_operation_template (id, placeholder, language, title, message, attributes, ui, result_texts) +values + (1, 'authorize_payment', 'en', 'Payment Approval', 'Please confirm the payment', '[ + { + "id": "operation.amount", + "type": "AMOUNT", + "text": "Amount", + "params": { + "amount": "amount", + "currency": "currency" + } + }, + { + "id": "operation.account", + "type": "KEY_VALUE", + "text": "To Account", + "params": { + "value": "iban" + } + } +]', null, + '{ + "success": "Payment of ${amount} ${currency} was confirmed", + "reject": "Payment was rejected", + "failure": "Payment approval failed" +}'); diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminController.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminController.java index b1a9e883..d771ad40 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminController.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminController.java @@ -33,6 +33,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; +import java.util.Map; /** * Admin controller. @@ -71,9 +72,23 @@ private TemplateListResponse.TemplateDetail convert(final OperationTemplateEntit .message(source.getMessage()) .language(source.getLanguage()) .attributes(convert(source.getAttributes())) + .resultTexts(convertResultTexts(source.getResultTexts())) .build(); } + private Map convertResultTexts(final String source) { + if (!StringUtils.hasText(source)) { + return null; + } + + try { + return objectMapper.readValue(source, new TypeReference<>() {}); + } catch (JsonProcessingException e) { + logger.warn("Unable to convert resultTexts, returning an empty collection", e); + return Map.of(); + } + } + private List convert(final String source) { if (!StringUtils.hasText(source)) { return null; diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/database/entity/OperationTemplateEntity.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/database/entity/OperationTemplateEntity.java index c4a9c935..c26287fd 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/database/entity/OperationTemplateEntity.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/database/entity/OperationTemplateEntity.java @@ -66,23 +66,26 @@ public class OperationTemplateEntity implements Serializable { @Column(name = "ui") private String ui; - @Column(name = "attributes") + @Column(name = "attributes", columnDefinition = "text") private String attributes; + /** + * Customized texts to display for {@code success}, {@code failure}, or {@code reject} operations. + * If not provided (either as individual properties or for the entire object), default messages will be used. + */ + @Column(name = "result_texts", columnDefinition = "text") + private String resultTexts; + @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof final OperationTemplateEntity that)) return false; return Objects.equals(placeholder, that.placeholder) - && Objects.equals(language, that.language) - && Objects.equals(title, that.title) - && Objects.equals(message, that.message) - && Objects.equals(ui, that.ui) - && Objects.equals(attributes, that.attributes); + && Objects.equals(language, that.language); } @Override public int hashCode() { - return Objects.hash(placeholder, language, title, message, ui, attributes); + return Objects.hash(placeholder, language); } } diff --git a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java index 09e52cea..d832ebc4 100644 --- a/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java +++ b/enrollment-server/src/main/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverter.java @@ -39,6 +39,7 @@ import java.math.BigDecimal; import java.util.*; +import java.util.function.UnaryOperator; import static java.util.stream.Collectors.toMap; @@ -92,9 +93,9 @@ private AllowedSignatureType convert(List signatureType) { public Operation convert(OperationDetailResponse operationDetail, OperationTemplateEntity operationTemplate) throws MobileTokenConfigurationException { try { final Map parameters = operationDetail.getParameters(); - final StringSubstitutor sub = createStringSubstitutor(parameters); - final UiExtensions uiExtensions = convertUiExtension(operationDetail, operationTemplate, sub); - final FormData formData = prepareFormData(operationTemplate, parameters, sub); + final UnaryOperator substitutor = createStringSubstitutor(parameters); + final UiExtensions uiExtensions = convertUiExtension(operationDetail, operationTemplate, substitutor); + final FormData formData = prepareFormData(operationTemplate, parameters, substitutor); final Operation operation = new Operation(); operation.setId(operationDetail.getId()); @@ -119,16 +120,12 @@ public Operation convert(OperationDetailResponse operationDetail, OperationTempl private FormData prepareFormData( final OperationTemplateEntity operationTemplate, final Map parameters, - final StringSubstitutor sub) throws JsonProcessingException { + final UnaryOperator substitutor) throws JsonProcessingException { final FormData formData = new FormData(); - if (sub != null) { - formData.setTitle(sub.replace(operationTemplate.getTitle())); - formData.setMessage(sub.replace(operationTemplate.getMessage())); - } else { - formData.setTitle(operationTemplate.getTitle()); - formData.setMessage(operationTemplate.getMessage()); - } + formData.setTitle(substitutor.apply(operationTemplate.getTitle())); + formData.setMessage(substitutor.apply(operationTemplate.getMessage())); + formData.setResultTexts(convert(substitutor.apply(operationTemplate.getResultTexts()))); final String attributes = operationTemplate.getAttributes(); if (attributes == null) { @@ -146,24 +143,31 @@ private FormData prepareFormData( return formData; } - private static StringSubstitutor createStringSubstitutor(final Map parameters) { - if (CollectionUtils.isEmpty(parameters)) { + private ResultTexts convert(final String source) throws JsonProcessingException { + if (!StringUtils.hasText(source)) { return null; + } + return objectMapper.readValue(source, ResultTexts.class); + } + + private static UnaryOperator createStringSubstitutor(final Map parameters) { + if (CollectionUtils.isEmpty(parameters)) { + return UnaryOperator.identity(); } else { final Map escapedParameters = parameters.entrySet().stream() .filter(entry -> entry.getValue() != null) .collect(toMap(Map.Entry::getKey, it -> StringEscapeUtils.escapeJson(it.getValue()))); - return new StringSubstitutor(escapedParameters); + return new StringSubstitutorWrapper(escapedParameters); } } private UiExtensions convertUiExtension( final OperationDetailResponse operationDetail, final OperationTemplateEntity operationTemplate, - final StringSubstitutor substitutor) throws JsonProcessingException { + final UnaryOperator substitutor) throws JsonProcessingException { if (StringUtils.hasText(operationTemplate.getUi())) { - final String uiJsonString = substitutor == null ? operationTemplate.getUi() : substitutor.replace(operationTemplate.getUi()); + final String uiJsonString = substitutor.apply(operationTemplate.getUi()); logger.debug("Deserializing ui: '{}' of OperationTemplate ID: {} to UiExtensions", uiJsonString, operationTemplate.getId()); return deserializeUiExtensions(uiJsonString, operationDetail); } else if (StringUtils.hasText(operationDetail.getRiskFlags())) { @@ -414,4 +418,17 @@ private static String fetchTemplateParamValueNullable(final OperationTemplatePar } private record AmountFormatted(BigDecimal amountRaw, String amountFormatted, String valueFormatted) {} + + private static class StringSubstitutorWrapper implements UnaryOperator { + private final StringSubstitutor substitutor; + + StringSubstitutorWrapper(final Map escapedParameters) { + substitutor = new StringSubstitutor(escapedParameters); + } + + @Override + public String apply(final String source) { + return substitutor.replace(source); + } + } } diff --git a/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.java b/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.java new file mode 100644 index 00000000..2d616217 --- /dev/null +++ b/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/controller/api/admin/AdminControllerTest.java @@ -0,0 +1,60 @@ +/* + * PowerAuth Enrollment Server + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.app.enrollmentserver.controller.api.admin; + +import com.wultra.app.enrollmentserver.EnrollmentServerTestApplication; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Test for {@link AdminController}. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +@SpringBootTest(classes = EnrollmentServerTestApplication.class, properties = "enrollment-server.admin.enabled=true") +@AutoConfigureMockMvc +@ActiveProfiles("test") +@Sql +class AdminControllerTest { + + @Autowired + private MockMvc mvc; + + @Test + void testGetTemplates() throws Exception { + mvc.perform(get("/api/admin/template") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.status", is("OK"))) + .andExpect(jsonPath("$.responseObject.*", hasSize(1))) + .andExpect(jsonPath("$.responseObject[0].title", is("Payment Approval"))) + .andExpect(jsonPath("$.responseObject[0].resultTexts.success", is("Payment of ${amount} ${currency} was confirmed"))); + } +} diff --git a/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java b/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java index 3ef6f88e..aa9e8c1b 100644 --- a/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java +++ b/enrollment-server/src/test/java/com/wultra/app/enrollmentserver/impl/service/converter/MobileTokenConverterTest.java @@ -575,6 +575,8 @@ void testConvertAttributes() throws Exception { LocaleContextHolder.setLocale(new Locale("en")); final Operation result = tested.convert(operationDetail, operationTemplate); + assertNull(result.getFormData().getResultTexts()); + final List attributes = result.getFormData().getAttributes(); assertEquals(9, attributes.size()); @@ -881,6 +883,40 @@ void testCreateStringSubstitutorWithNullValue() throws MobileTokenConfigurationE assertEquals("operation.amount", attributes.get(0).getId()); } + @Test + void testConvertFormData() throws Exception { + final OperationDetailResponse operationDetail = createOperationDetailResponse(); + operationDetail.setParameters(Map.ofEntries( + Map.entry("amount", "13.7"), + Map.entry("currency", "EUR"), + Map.entry("iban", "AT483200000012345864") + )); + + final OperationTemplateEntity operationTemplate = new OperationTemplateEntity(); + operationTemplate.setTitle("Payment to ${iban}"); + operationTemplate.setMessage("Pay ${amount} ${currency}"); + operationTemplate.setResultTexts(""" + { + "success": "Payment of ${amount} ${currency} was confirmed", + "reject": "Payment was rejected", + "failure": "Payment approval failed" + } + """); + + final Operation result = tested.convert(operationDetail, operationTemplate); + + final FormData formData = result.getFormData(); + + assertEquals("Payment to AT483200000012345864", formData.getTitle()); + assertEquals("Pay 13.7 EUR", formData.getMessage()); + + final ResultTexts resultTexts = formData.getResultTexts(); + assertNotNull(resultTexts); + assertEquals("Payment of 13.7 EUR was confirmed", resultTexts.getSuccess()); + assertEquals("Payment was rejected", resultTexts.getReject()); + assertEquals("Payment approval failed", resultTexts.getFailure()); + } + private static OperationDetailResponse createOperationDetailResponse() { final OperationDetailResponse operationDetail = new OperationDetailResponse(); operationDetail.setSignatureType(List.of(SignatureType.KNOWLEDGE)); diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/FormData.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/FormData.java index 47e4ec77..6e18a134 100644 --- a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/FormData.java +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/FormData.java @@ -39,4 +39,6 @@ public class FormData { @NotNull private List attributes = new ArrayList<>(); + private ResultTexts resultTexts; + } diff --git a/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/ResultTexts.java b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/ResultTexts.java new file mode 100644 index 00000000..abc2528b --- /dev/null +++ b/mtoken-model/src/main/java/com/wultra/security/powerauth/lib/mtoken/model/entity/ResultTexts.java @@ -0,0 +1,37 @@ +/* + * PowerAuth Mobile Token Model + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.lib.mtoken.model.entity; + +import lombok.Data; + +/** + * Customized texts to display for {@code success}, {@code failure}, or {@code reject} operations. + * If not provided (either as individual properties or for the entire object), default messages will be used. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +@Data +public class ResultTexts { + + private String success; + + private String failure; + + private String reject; + +}