diff --git a/src/intTest/java/com/box/sdk/BoxSignRequestIT.java b/src/intTest/java/com/box/sdk/BoxSignRequestIT.java index 23e03bd8f..88afc0665 100644 --- a/src/intTest/java/com/box/sdk/BoxSignRequestIT.java +++ b/src/intTest/java/com/box/sdk/BoxSignRequestIT.java @@ -62,8 +62,16 @@ public void createListAndCancelSignRequest() throws InterruptedException { files.add(new BoxSignRequestFile(file2.getID())); String signerEmail = "user@example.com"; + Boolean signerLoginRequired = false; + String signerPassword = "password"; + Boolean signerSuppressNotifications = false; + String signerVerficationPhoneNumber = "+16314578901"; + List signers = new ArrayList<>(); - BoxSignRequestSigner newSigner = new BoxSignRequestSigner(signerEmail).setInPerson(false); + BoxSignRequestSigner newSigner = new BoxSignRequestSigner(signerEmail).setInPerson(false) + .setLoginRequired(signerLoginRequired).setPassword(signerPassword) + .setSuppressNotifications(signerSuppressNotifications) + .setVerificationPhoneNumber(signerVerficationPhoneNumber); signers.add(newSigner); signedFileFolder = uniqueFolder.createFolder("Folder - signRequestIntegrationTest").getResource(); @@ -114,6 +122,9 @@ public void createListAndCancelSignRequest() throws InterruptedException { assertEquals(file2.getID(), file2Info.getID()); assertEquals(signerEmail, signer.getEmail()); assertEquals(signRequestIdCreate, signRequestInfoGetByID.getID()); + assertEquals(signerLoginRequired, signer.getLoginRequired()); + assertEquals(signerSuppressNotifications, signer.getSuppressNotifications()); + assertEquals(signerVerficationPhoneNumber, signer.getVerificationPhoneNumber()); // Resend sign request retry(signRequestGetByID::resend, 5, 500); @@ -152,7 +163,7 @@ public void createListAndCancelSignRequest() throws InterruptedException { } @Test - public void createignRequestForGroup() throws InterruptedException { + public void createSignRequestForGroup() throws InterruptedException { // Test Setup BoxAPIConnection api = jwtApiForServiceAccount(); BoxFolder uniqueFolder = getUniqueFolder(api); diff --git a/src/main/java/com/box/sdk/BoxSignRequestSigner.java b/src/main/java/com/box/sdk/BoxSignRequestSigner.java index 112a76e84..d68d949f8 100644 --- a/src/main/java/com/box/sdk/BoxSignRequestSigner.java +++ b/src/main/java/com/box/sdk/BoxSignRequestSigner.java @@ -27,6 +27,10 @@ public class BoxSignRequestSigner extends BoxJSONObject { private String declinedRedirectUrl; private String iframeableEmedUrl; private String signerGroupId; + private Boolean loginRequired; + private String password; + private Boolean suppressNotifications; + private String verificationPhoneNumber; private BoxAPIConnection api; /** @@ -295,6 +299,93 @@ public BoxSignRequestSigner setSignerGroupId(String signerGroupId) { return this; } + /** + * If set to true, signer will need to login to a Box account before signing the request. + * If the signer does not have an existing account, they will have an option to create a free Box account. + * + * @return true if login is required for the signer, otherwise false. + */ + public Boolean getLoginRequired() { + return this.loginRequired; + } + + /** + * If set to true, signer will need to login to a Box account before signing the request. + * If the signer does not have an existing account, they will have an option to create a free Box account. + * + * @param loginRequired indicates if login is required for the signer. + * @return this BoxSignRequestSigner object for chaining. + */ + public BoxSignRequestSigner setLoginRequired(Boolean loginRequired) { + this.loginRequired = loginRequired; + return this; + } + + /** + * If set, the signer is required to enter the password before they are able to sign a document. + * This field is write only. + * + * @return password required for the signer to access the sign request. + */ + public String getPassword() { + return this.password; + } + + /** + * Sets the password required for the signer to access the sign request. + * + * @param password required for the signer to access the sign request. + * @return this BoxSignRequestSigner object for chaining. + */ + public BoxSignRequestSigner setPassword(String password) { + this.password = password; + return this; + } + + /** + * Gets the flag that suppresses email notifications for the signer. + * + * @return true if email notifications are suppressed for the signer, otherwise false. + */ + public Boolean getSuppressNotifications() { + return this.suppressNotifications; + } + + /** + * Sets the flag that suppresses email notifications for the signer. + * + * @param suppressNotifications indicates if email notifications are suppressed for the signer. + * @return this BoxSignRequestSigner object for chaining. + */ + public BoxSignRequestSigner setSuppressNotifications(Boolean suppressNotifications) { + this.suppressNotifications = suppressNotifications; + return this; + } + + /** + * Gets the phone number used for verification. + * If set, this phone number is be used to verify the signer via two factor authentication + * before they are able to sign the document. + * + * @return phone number used for verification. + */ + public String getVerificationPhoneNumber() { + return this.verificationPhoneNumber; + } + + /** + * Sets the phone number used for verification. + * If set, this phone number is be used to verify the signer via two factor authentication + * before they are able to sign the document. + * + * @param verificationPhoneNumber phone number used for verification. + * @return this BoxSignRequestSigner object for chaining. + */ + public BoxSignRequestSigner setVerificationPhoneNumber(String verificationPhoneNumber) { + this.verificationPhoneNumber = verificationPhoneNumber; + return this; + } + /** * {@inheritDoc} */ @@ -352,6 +443,14 @@ void parseJSONMember(JsonObject.Member member) { case "signer_group_id": this.signerGroupId = value.asString(); break; + case "login_required": + this.loginRequired = value.asBoolean(); + break; + case "suppress_notifications": + this.suppressNotifications = value.asBoolean(); + break; + case "verification_phone_number": + this.verificationPhoneNumber = value.asString(); default: return; } @@ -375,6 +474,10 @@ public JsonObject getJSONObject() { JsonUtils.addIfNotNull(jsonObj, "redirect_url", this.redirectUrl); JsonUtils.addIfNotNull(jsonObj, "declined_redirect_url", this.declinedRedirectUrl); JsonUtils.addIfNotNull(jsonObj, "signer_group_id", this.signerGroupId); + JsonUtils.addIfNotNull(jsonObj, "login_required", this.loginRequired); + JsonUtils.addIfNotNull(jsonObj, "password", this.password); + JsonUtils.addIfNotNull(jsonObj, "suppress_notifications", this.suppressNotifications); + JsonUtils.addIfNotNull(jsonObj, "verification_phone_number", this.verificationPhoneNumber); return jsonObj; } @@ -554,6 +657,7 @@ static BoxSignRequestInputContentType fromJSONString(String jsonValue) { public class BoxSignerDecision extends BoxJSONObject { private BoxSignRequestSignerDecisionType type; private Date finalizedAt; + private String additionalInfo; /** * Constructs a BoxSignerDecision object using an already parsed JSON object. @@ -582,6 +686,15 @@ public Date getFinalizedAt() { return this.finalizedAt; } + /** + * Gets the additional info about the decision, such as the decline reason from the signer. + * + * @return additional information about the decision. + */ + public String getAdditionalInfo() { + return this.additionalInfo; + } + /** * {@inheritDoc} */ @@ -594,6 +707,8 @@ void parseJSONMember(JsonObject.Member member) { this.type = BoxSignRequestSignerDecisionType.fromJSONString(value.asString()); } else if (memberName.equals("finalized_at")) { this.finalizedAt = BoxDateFormat.parse(value.asString()); + } else if (memberName.equals("additional_info")) { + this.additionalInfo = value.asString(); } } catch (Exception e) { throw new BoxDeserializationException(memberName, value.toString(), e); diff --git a/src/main/java/com/box/sdk/BoxWebHook.java b/src/main/java/com/box/sdk/BoxWebHook.java index 8d951cb85..1025675b7 100644 --- a/src/main/java/com/box/sdk/BoxWebHook.java +++ b/src/main/java/com/box/sdk/BoxWebHook.java @@ -497,6 +497,26 @@ public enum Trigger { * Triggered when {@link BoxFile} is expired. */ SIGN_REQUEST_EXPIRED("SIGN_REQUEST.EXPIRED", + BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), + /** + * Triggered when a signer's email is bounced. + */ + SIGN_REQUEST_SIGNER_EMAIL_BOUNCED("SIGN_REQUEST.SIGNER_EMAIL_BOUNCED", + BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), + /** + * Triggered when the signature request is signed. + */ + SIGN_REQUEST_SIGNER_SIGNED("SIGN_REQUEST.SIGNER_SIGNED", + BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), + /** + * Triggered when the signature is requested from the signer. + */ + SIGN_REQUEST_SIGNATURE_REQUESTED("SIGN_REQUEST.SIGNATURE_REQUESTED", + BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)), + /** + * Triggered when the signature request could not be processed. + */ + SIGN_REQUEST_ERROR_FINALIZING("SIGN_REQUEST.ERROR_FINALIZING", BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)); /** diff --git a/src/test/Fixtures/BoxSignRequest/CreateSignRequest200.json b/src/test/Fixtures/BoxSignRequest/CreateSignRequest200.json index dca84dd2f..9720d605b 100644 --- a/src/test/Fixtures/BoxSignRequest/CreateSignRequest200.json +++ b/src/test/Fixtures/BoxSignRequest/CreateSignRequest200.json @@ -17,7 +17,8 @@ "has_viewed_document": true, "signer_decision": { "type": "signed", - "finalized_at": "2021-04-26T08:12:13.982Z" + "finalized_at": "2021-04-26T08:12:13.982Z", + "additional_info": "Requesting changes before signing." }, "inputs": [ { @@ -33,7 +34,10 @@ "embed_url": "https://example.com", "redirect_url": "https://box.com/redirect_url_signer_1", "declined_redirect_url": "https://box.com/declined_redirect_url_signer_1", - "iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4" + "iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4", + "suppress_notifications": true, + "login_required": true, + "verification_phone_number": "1234567890" } ], "source_files": [ diff --git a/src/test/Fixtures/BoxSignRequest/GetSignRequest200.json b/src/test/Fixtures/BoxSignRequest/GetSignRequest200.json index 7c8fe3c88..a4e899599 100644 --- a/src/test/Fixtures/BoxSignRequest/GetSignRequest200.json +++ b/src/test/Fixtures/BoxSignRequest/GetSignRequest200.json @@ -17,7 +17,8 @@ "has_viewed_document": true, "signer_decision": { "type": "signed", - "finalized_at": "2021-04-26T08:12:13.982Z" + "finalized_at": "2021-04-26T08:12:13.982Z", + "additional_info": "Requesting changes before signing." }, "inputs": [ { @@ -51,7 +52,10 @@ "embed_url": "https://example.com", "redirect_url": "https://box.com/redirect_url_signer_1", "declined_redirect_url": "https://box.com/declined_redirect_url_signer_1", - "iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4" + "iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4", + "suppress_notifications": true, + "login_required": true, + "verification_phone_number": "1234567890" } ], "source_files": [ diff --git a/src/test/java/com/box/sdk/BoxSignRequestTest.java b/src/test/java/com/box/sdk/BoxSignRequestTest.java index 2ca64ec0f..3107fb6fc 100644 --- a/src/test/java/com/box/sdk/BoxSignRequestTest.java +++ b/src/test/java/com/box/sdk/BoxSignRequestTest.java @@ -50,6 +50,10 @@ public void createSignRequestSucceeds() { final String signerRedirectUrl = "https://box.com/redirect_url_signer_1"; final String signerDeclinedRedirectUrl = "https://box.com/declined_redirect_url_signer_1"; + final Boolean signerLoginRequired = true; + final String signerPassword = "password"; + final Boolean signerSuppressNotifications = true; + final String signerVerficationPhoneNumber = "1234567890"; String result = TestUtils.getFixture("BoxSignRequest/CreateSignRequest200"); @@ -65,6 +69,10 @@ public void createSignRequestSucceeds() { List signers = new ArrayList<>(); BoxSignRequestSigner newSigner = new BoxSignRequestSigner("signer@mail.com"); newSigner.setEmbedUrlExternalUserId("1234"); + newSigner.setLoginRequired(signerLoginRequired); + newSigner.setPassword(signerPassword); + newSigner.setSuppressNotifications(signerSuppressNotifications); + newSigner.setVerificationPhoneNumber(signerVerficationPhoneNumber); signers.add(newSigner); String parentFolderId = "55555"; @@ -81,6 +89,9 @@ public void createSignRequestSucceeds() { assertEquals(signerRedirectUrl, signer.getRedirectUrl()); assertEquals(iframeableEmedUrl, signer.getIframeableEmedUrl()); assertEquals(signerDeclinedRedirectUrl, signer.getDeclinedRedirectUrl()); + assertEquals(signerLoginRequired, signer.getLoginRequired()); + assertEquals(signerSuppressNotifications, signer.getSuppressNotifications()); + assertEquals(signerVerficationPhoneNumber, signer.getVerificationPhoneNumber()); assertEquals(prepareUrl, signRequestInfo.getPrepareUrl()); assertEquals(redirectUrl, signRequestInfo.getRedirectUrl()); @@ -109,6 +120,10 @@ public void getSignRequestInfoSucceeds() { final String signerRedirectUrl = "https://box.com/redirect_url_signer_1"; final String signerDeclinedRedirectUrl = "https://box.com/declined_redirect_url_signer_1"; + final Boolean signerLoginRequired = true; + final Boolean signerSuppressNotifications = true; + final String signerVerficationPhoneNumber = "1234567890"; + final String signerDecisionAdditionalInfo = "Requesting changes before signing."; final String templateId = "93153068-5420-467b-b8ef-aaaaaaaaaaa"; @@ -130,6 +145,10 @@ public void getSignRequestInfoSucceeds() { assertEquals(signerRedirectUrl, signer.getRedirectUrl()); assertEquals(signerDeclinedRedirectUrl, signer.getDeclinedRedirectUrl()); assertEquals(iframeableEmedUrl, signer.getIframeableEmedUrl()); + assertEquals(signerLoginRequired, signer.getLoginRequired()); + assertEquals(signerSuppressNotifications, signer.getSuppressNotifications()); + assertEquals(signerVerficationPhoneNumber, signer.getVerificationPhoneNumber()); + assertEquals(signerDecisionAdditionalInfo, signer.getSignerDecision().getAdditionalInfo()); assertEquals(prepareUrl, signRequestInfo.getPrepareUrl()); assertEquals(redirectUrl, signRequestInfo.getRedirectUrl());