From ece60e0614ea0dbd2344c5270506068d05036f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pe=C5=A1ek?= Date: Mon, 30 Sep 2024 14:07:48 +0200 Subject: [PATCH] Fix #1596: Update Callback Management API (#1679) --- docs/PowerAuth-Server-1.9.0.md | 11 +++++++ docs/WebServices-Methods.md | 15 ++++++++++ powerauth-client-model/pom.xml | 4 +++ .../client/model/entity/CallbackUrl.java | 14 +++++++++ .../request/CreateCallbackUrlRequest.java | 25 ++++++++++++++++ .../request/UpdateCallbackUrlRequest.java | 27 +++++++++++++++++ .../response/CreateCallbackUrlResponse.java | 14 +++++++++ .../response/UpdateCallbackUrlResponse.java | 16 ++++++++++ .../controller/RESTControllerAdvice.java | 2 +- .../api/ApplicationCallbackController.java | 5 ++-- .../behavior/tasks/CallbackUrlBehavior.java | 29 +++++++++++-------- .../api/PowerAuthControllerTest.java | 1 + .../tasks/CallbackUrlBehaviorTest.java | 2 ++ 13 files changed, 150 insertions(+), 15 deletions(-) diff --git a/docs/PowerAuth-Server-1.9.0.md b/docs/PowerAuth-Server-1.9.0.md index 1bd29bb4b..617d6fe09 100644 --- a/docs/PowerAuth-Server-1.9.0.md +++ b/docs/PowerAuth-Server-1.9.0.md @@ -78,6 +78,17 @@ The parameter `activationOtpValidation` is deprecated. Use the `activationOtp` parameter during activation init or activation commit to control the OTP check. Use the `commitPhase` parameter for specifying when the activation should be committed. +### New Attributes in Callback URL Management API + +The Callback URL Management API supports configuration of retry policy and retention period for each Callback URL +configuration. These changes impact both the request and response bodies of `/rest/v3/application/callback/create` +and `/rest/v3/application/callback/update` endpoints and response body of `/rest/v3/application/callback/list` endpoint. + +Following attributes have been added: +- `retentionPeriod` defines the duration after which a completed callback event is automatically removed from database. +- `initialBackoff` defines the initial delay before retry attempt following a callback event failure, if retries are enabled. +- `maxAttempts` defines the maximum number of attempts to send a callback event. + ### ECDSA Signature Verification in JOSE Format The method `POST /rest/v3/signature/ecdsa/verify` now supports validation of ECDSA signature in JOSE format, thanks to added `signatureFormat` request attribute (`DER` as a default value, or `JOSE`). diff --git a/docs/WebServices-Methods.md b/docs/WebServices-Methods.md index 9a6d7e50d..6b27d5f61 100644 --- a/docs/WebServices-Methods.md +++ b/docs/WebServices-Methods.md @@ -1394,6 +1394,9 @@ REST endpoint: `POST /rest/v3/application/callback/create` | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. See possible attributes bellow. | | `String` | `authentication` | Callback HTTP request authentication configuration. | +| `Duration` | `retentionPeriod` | Duration in ISO 8601 duration format after which a completed callback event is automatically removed from database. | +| `Duration` | `initialBackoff` | Initial delay in ISO 8601 duration format before retry attempt following a callback event failure, if retries are enabled. | +| `Integer` | `maxAttempts` | Maximum number of attempts to send a callback event. | When creating a callback URL of type `ACTIVATION_STATUS_CHANGE`, following `attributes` can be used: @@ -1466,6 +1469,9 @@ The `authentication` parameter contains a JSON-based configuration for client TL | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | | `String` | `authentication` | Callback HTTP request authentication configuration. | +| `Duration` | `retentionPeriod` | Duration in ISO 8601 duration format after which a completed callback event is automatically removed from database. | +| `Duration` | `initialBackoff` | Initial delay in ISO 8601 duration format before retry attempt following a callback event failure, if retries are enabled. | +| `Integer` | `maxAttempts` | Maximum number of attempts to send a callback event. | ### Method 'updateCallbackUrl' @@ -1486,6 +1492,9 @@ REST endpoint: `POST /rest/v3/application/callback/update` | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. See possible attributes bellow. | | `String` | `authentication` | Callback HTTP request authentication configuration. | +| `Duration` | `retentionPeriod` | Duration in ISO 8601 duration format after which a completed callback event is automatically removed from database. | +| `Duration` | `initialBackoff` | Initial delay in ISO 8601 duration format before retry attempt following a callback event failure, if retries are enabled. | +| `Integer` | `maxAttempts` | Maximum number of attempts to send a callback event. | When configuring a callback URL of type `ACTIVATION_STATUS_CHANGE`, following `attributes` can be used: @@ -1560,6 +1569,9 @@ The `authentication` parameter contains a JSON-based configuration for client TL | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | | `String` | `authentication` | Callback HTTP request authentication configuration. | +| `Duration` | `retentionPeriod` | Duration in ISO 8601 duration format after which a completed callback event is automatically removed from database. | +| `Duration` | `initialBackoff` | Initial delay in ISO 8601 duration format before retry attempt following a callback event failure, if retries are enabled. | +| `Integer` | `maxAttempts` | Maximum number of attempts to send a callback event. | ### Method 'getCallbackUrlList' @@ -1594,6 +1606,9 @@ REST endpoint: `POST /rest/v3/application/callback/list` | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | | `String` | `authentication` | Callback HTTP request authentication configuration. | +| `Duration` | `retentionPeriod` | Duration in ISO 8601 duration format after which a completed callback event is automatically removed from database. | +| `Duration` | `initialBackoff` | Initial delay in ISO 8601 duration format before retry attempt following a callback event failure, if retries are enabled. | +| `Integer` | `maxAttempts` | Maximum number of attempts to send a callback event. | ### Method 'removeCallbackUrl' diff --git a/powerauth-client-model/pom.xml b/powerauth-client-model/pom.xml index 56abff639..d1d69c24c 100644 --- a/powerauth-client-model/pom.xml +++ b/powerauth-client-model/pom.xml @@ -40,6 +40,10 @@ org.springframework spring-core + + org.springframework.boot + spring-boot-starter-validation + com.fasterxml.jackson.core jackson-annotations diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/entity/CallbackUrl.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/entity/CallbackUrl.java index 14a25629b..c4e18c551 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/entity/CallbackUrl.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/entity/CallbackUrl.java @@ -17,8 +17,11 @@ */ package com.wultra.security.powerauth.client.model.entity; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -38,4 +41,15 @@ public class CallbackUrl { private List attributes = new ArrayList<>(); private HttpAuthenticationPublic authentication = new HttpAuthenticationPublic(); + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(type = "string", format = "ISO 8601 Duration", example = "P30D") + private Duration retentionPeriod; + + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(type = "string", format = "ISO 8601 Duration", example = "PT2.5S") + private Duration initialBackoff; + + @Schema(type = "integer", example = "1") + private Integer maxAttempts; + } diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/CreateCallbackUrlRequest.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/CreateCallbackUrlRequest.java index 308628d4c..762f4cfd2 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/CreateCallbackUrlRequest.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/CreateCallbackUrlRequest.java @@ -19,8 +19,13 @@ package com.wultra.security.powerauth.client.model.request; import com.wultra.security.powerauth.client.model.entity.HttpAuthenticationPrivate; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; import lombok.Data; +import org.hibernate.validator.constraints.time.DurationMin; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -32,11 +37,31 @@ @Data public class CreateCallbackUrlRequest { + @NotBlank private String applicationId; + + @NotBlank private String name; + + @NotBlank private String type; + + @NotBlank private String callbackUrl; + private List attributes = new ArrayList<>(); private HttpAuthenticationPrivate authentication = new HttpAuthenticationPrivate(); + @DurationMin(message = "Duration must be positive or zero") + @Schema(type = "string", format = "ISO 8601 Duration", example = "P30D") + private Duration retentionPeriod; + + @DurationMin(message = "Duration must be positive or zero") + @Schema(type = "string", format = "ISO 8601 Duration", example = "PT2.5S") + private Duration initialBackoff; + + @Min(1) + @Schema(type = "integer", example = "1") + private Integer maxAttempts; + } diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/UpdateCallbackUrlRequest.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/UpdateCallbackUrlRequest.java index 03745b4a1..d1ee279dd 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/UpdateCallbackUrlRequest.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/request/UpdateCallbackUrlRequest.java @@ -19,8 +19,13 @@ package com.wultra.security.powerauth.client.model.request; import com.wultra.security.powerauth.client.model.entity.HttpAuthenticationPrivate; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; import lombok.Data; +import org.hibernate.validator.constraints.time.DurationMin; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -32,12 +37,34 @@ @Data public class UpdateCallbackUrlRequest { + @NotBlank private String id; + + @NotBlank private String applicationId; + + @NotBlank private String name; + + @NotBlank private String type; + + @NotBlank private String callbackUrl; + private List attributes = new ArrayList<>(); private HttpAuthenticationPrivate authentication = new HttpAuthenticationPrivate(); + @DurationMin(message = "Duration must be positive or zero") + @Schema(type = "string", format = "ISO 8601 Duration", example = "P30D") + private Duration retentionPeriod; + + @DurationMin(message = "Duration must be positive or zero") + @Schema(type = "string", format = "ISO 8601 Duration", example = "PT2.5S") + private Duration initialBackoff; + + @Min(1) + @Schema(type = "integer", example = "1") + private Integer maxAttempts; + } diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/CreateCallbackUrlResponse.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/CreateCallbackUrlResponse.java index 338d9309e..9a02bbc31 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/CreateCallbackUrlResponse.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/CreateCallbackUrlResponse.java @@ -18,9 +18,12 @@ package com.wultra.security.powerauth.client.model.response; +import com.fasterxml.jackson.annotation.JsonFormat; import com.wultra.security.powerauth.client.model.entity.HttpAuthenticationPublic; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -39,4 +42,15 @@ public class CreateCallbackUrlResponse { private List attributes = new ArrayList<>(); private HttpAuthenticationPublic authentication = new HttpAuthenticationPublic(); + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(type = "string", format = "ISO 8601 Duration", example = "P30D") + private Duration retentionPeriod; + + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(type = "string", format = "ISO 8601 Duration", example = "PT2.5S") + private Duration initialBackoff; + + @Schema(type = "integer", example = "1") + private Integer maxAttempts; + } diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/UpdateCallbackUrlResponse.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/UpdateCallbackUrlResponse.java index 983aef312..8963d05cc 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/UpdateCallbackUrlResponse.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/model/response/UpdateCallbackUrlResponse.java @@ -18,9 +18,14 @@ package com.wultra.security.powerauth.client.model.response; +import com.fasterxml.jackson.annotation.JsonFormat; import com.wultra.security.powerauth.client.model.entity.HttpAuthenticationPublic; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; import lombok.Data; +import org.hibernate.validator.constraints.time.DurationMin; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -40,4 +45,15 @@ public class UpdateCallbackUrlResponse { private List attributes = new ArrayList<>(); private HttpAuthenticationPublic authentication = new HttpAuthenticationPublic(); + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(type = "string", format = "ISO 8601 Duration", example = "P30D") + private Duration retentionPeriod; + + @JsonFormat(shape = JsonFormat.Shape.STRING) + @Schema(type = "string", format = "ISO 8601 Duration", example = "PT2.5S") + private Duration initialBackoff; + + @Schema(type = "integer", example = "1") + private Integer maxAttempts; + } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTControllerAdvice.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTControllerAdvice.java index f7d072a1b..c2f5cfd58 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTControllerAdvice.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTControllerAdvice.java @@ -144,7 +144,7 @@ public class RESTControllerAdvice { */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler - public @ResponseBody ObjectResponse returnActivationRecoveryError(final MethodArgumentNotValidException ex) { + public @ResponseBody ObjectResponse returnInvalidRequestError(final MethodArgumentNotValidException ex) { logger.error("Error occurred while processing the request: {}", ex.getMessage()); logger.debug("Exception details:", ex); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/api/ApplicationCallbackController.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/api/ApplicationCallbackController.java index f05a6a74b..470a46276 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/api/ApplicationCallbackController.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/api/ApplicationCallbackController.java @@ -30,6 +30,7 @@ import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.app.server.service.behavior.tasks.CallbackUrlBehavior; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; @@ -63,7 +64,7 @@ public ApplicationCallbackController(CallbackUrlBehavior service) { * @throws Exception In case the service throws exception. */ @PostMapping("/create") - public ObjectResponse createCallbackUrl(@RequestBody ObjectRequest request) throws Exception { + public ObjectResponse createCallbackUrl(@Valid @RequestBody ObjectRequest request) throws Exception { logger.info("CreateCallbackUrlRequest received: {}", request); final ObjectResponse response = new ObjectResponse<>(service.createCallbackUrl(request.getRequestObject())); logger.info("CreateCallbackUrlRequest succeeded: {}", response); @@ -78,7 +79,7 @@ public ObjectResponse createCallbackUrl(@RequestBody * @throws Exception In case the service throws exception. */ @PostMapping("/update") - public ObjectResponse updateCallbackUrl(@RequestBody ObjectRequest request) throws Exception { + public ObjectResponse updateCallbackUrl(@Valid @RequestBody ObjectRequest request) throws Exception { logger.info("UpdateCallbackUrlRequest received: {}", request); final ObjectResponse response = new ObjectResponse<>(service.updateCallbackUrl(request.getRequestObject())); logger.info("UpdateCallbackUrlRequest succeeded: {}", response); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehavior.java index 4db69d58d..3393fac94 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehavior.java @@ -81,12 +81,6 @@ public class CallbackUrlBehavior { @Transactional public CreateCallbackUrlResponse createCallbackUrl(CreateCallbackUrlRequest request) throws GenericServiceException { try { - if (request.getName() == null) { - logger.warn("Invalid request parameter name in method createCallbackUrl"); - // Rollback is not required, error occurs before writing to database - throw localizationProvider.buildExceptionForCode(ServiceError.INVALID_REQUEST); - } - // Check the URL format try { new URL(request.getCallbackUrl()); @@ -116,7 +110,11 @@ public CreateCallbackUrlResponse createCallbackUrl(CreateCallbackUrlRequest requ final EncryptableString encrypted = callbackUrlAuthenticationCryptor.encrypt(request.getAuthentication(), entity.getApplication().getId()); entity.setAuthentication(encrypted.encryptedData()); entity.setEncryptionMode(encrypted.encryptionMode()); + entity.setRetentionPeriod(request.getRetentionPeriod()); + entity.setInitialBackoff(request.getInitialBackoff()); + entity.setMaxAttempts(request.getMaxAttempts()); callbackUrlRepository.save(entity); + final CreateCallbackUrlResponse response = new CreateCallbackUrlResponse(); response.setId(entity.getId()); response.setApplicationId(entity.getApplication().getId()); @@ -126,6 +124,9 @@ public CreateCallbackUrlResponse createCallbackUrl(CreateCallbackUrlRequest requ response.getAttributes().addAll(entity.getAttributes()); } response.setAuthentication(callbackUrlAuthenticationCryptor.decryptToPublic(entity)); + response.setRetentionPeriod(entity.getRetentionPeriod()); + response.setInitialBackoff(entity.getInitialBackoff()); + response.setMaxAttempts(entity.getMaxAttempts()); return response; } catch (GenericServiceException ex) { // already logged @@ -147,12 +148,6 @@ public CreateCallbackUrlResponse createCallbackUrl(CreateCallbackUrlRequest requ */ public UpdateCallbackUrlResponse updateCallbackUrl(UpdateCallbackUrlRequest request) throws GenericServiceException { try { - if (request.getId() == null || request.getApplicationId() == null || request.getName() == null || request.getAttributes() == null) { - logger.warn("Invalid request in method updateCallbackUrl"); - // Rollback is not required, error occurs before writing to database - throw localizationProvider.buildExceptionForCode(ServiceError.INVALID_REQUEST); - } - final CallbackUrlEntity entity = callbackUrlRepository.findById(request.getId()) .filter(it -> it.getApplication().getId().equals(request.getApplicationId())) .orElseThrow(() -> { @@ -175,6 +170,7 @@ public UpdateCallbackUrlResponse updateCallbackUrl(UpdateCallbackUrlRequest requ entity.setName(request.getName()); entity.setCallbackUrl(request.getCallbackUrl()); entity.setAttributes(request.getAttributes()); + entity.setType(CallbackUrlType.valueOf(request.getType())); // Retain existing passwords in case new password is not set final HttpAuthenticationPrivate authRequest = request.getAuthentication(); final CallbackUrlAuthentication authExisting = callbackUrlAuthenticationCryptor.decrypt(entity); @@ -202,6 +198,9 @@ public UpdateCallbackUrlResponse updateCallbackUrl(UpdateCallbackUrlRequest requ final EncryptableString encrypted = callbackUrlAuthenticationCryptor.encrypt(authRequest, entity.getApplication().getId()); entity.setAuthentication(encrypted.encryptedData()); entity.setEncryptionMode(encrypted.encryptionMode()); + entity.setRetentionPeriod(request.getRetentionPeriod()); + entity.setInitialBackoff(request.getInitialBackoff()); + entity.setMaxAttempts(request.getMaxAttempts()); callbackUrlRepository.save(entity); final UpdateCallbackUrlResponse response = new UpdateCallbackUrlResponse(); @@ -214,6 +213,9 @@ public UpdateCallbackUrlResponse updateCallbackUrl(UpdateCallbackUrlRequest requ response.getAttributes().addAll(entity.getAttributes()); } response.setAuthentication(callbackUrlAuthenticationCryptor.decryptToPublic(entity)); + response.setRetentionPeriod(entity.getRetentionPeriod()); + response.setInitialBackoff(entity.getInitialBackoff()); + response.setMaxAttempts(entity.getMaxAttempts()); return response; } catch (GenericServiceException ex) { // already logged @@ -248,6 +250,9 @@ public GetCallbackUrlListResponse getCallbackUrlList(GetCallbackUrlListRequest r item.getAttributes().addAll(callbackUrl.getAttributes()); } item.setAuthentication(callbackUrlAuthenticationCryptor.decryptToPublic(callbackUrl)); + item.setRetentionPeriod(callbackUrl.getRetentionPeriod()); + item.setInitialBackoff(callbackUrl.getInitialBackoff()); + item.setMaxAttempts(callbackUrl.getMaxAttempts()); response.getCallbackUrlList().add(item); } return response; diff --git a/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/controller/api/PowerAuthControllerTest.java b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/controller/api/PowerAuthControllerTest.java index 6a3e933b0..43c845286 100644 --- a/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/controller/api/PowerAuthControllerTest.java +++ b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/controller/api/PowerAuthControllerTest.java @@ -524,6 +524,7 @@ void testCallbackUpdate() throws Exception { updateCallbackUrlRequest.setId(callbackUrlResponse.getId()); updateCallbackUrlRequest.setApplicationId(config.getApplicationId()); updateCallbackUrlRequest.setAuthentication(null); + updateCallbackUrlRequest.setType(CallbackUrlType.ACTIVATION_STATUS_CHANGE.toString()); final UpdateCallbackUrlResponse updateCallbackUrlResponse = powerAuthClient.updateCallbackUrl(updateCallbackUrlRequest); assertEquals(callbackAttributes, updateCallbackUrlResponse.getAttributes()); diff --git a/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehaviorTest.java b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehaviorTest.java index ddd107e74..f16dfad58 100644 --- a/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehaviorTest.java +++ b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/CallbackUrlBehaviorTest.java @@ -19,6 +19,7 @@ import com.wultra.security.powerauth.client.model.request.UpdateCallbackUrlRequest; import io.getlime.security.powerauth.app.server.database.model.entity.CallbackUrlEntity; +import io.getlime.security.powerauth.app.server.database.model.enumeration.CallbackUrlType; import io.getlime.security.powerauth.app.server.service.exceptions.GenericServiceException; import io.getlime.security.powerauth.app.server.service.model.ServiceError; import jakarta.persistence.EntityManager; @@ -63,6 +64,7 @@ void updateCallbackUrlTest() throws Exception { request.setCallbackUrl("http://localhost:8080"); request.setAuthentication(null); request.setName("new-name"); + request.setType(CallbackUrlType.OPERATION_STATUS_CHANGE.toString()); tested.updateCallbackUrl(request); final CallbackUrlEntity updated = entityManager.find(CallbackUrlEntity.class, "cafec169-28a6-490c-a1d5-c012b9e3c044");