Skip to content

Commit 3ee55b3

Browse files
authored
feat: Support login_required, password, suppress_nofitications, verification_phone_number and additional_info fields in sign request (#1250)
1 parent d26bd4f commit 3ee55b3

File tree

6 files changed

+179
-6
lines changed

6 files changed

+179
-6
lines changed

src/intTest/java/com/box/sdk/BoxSignRequestIT.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,16 @@ public void createListAndCancelSignRequest() throws InterruptedException {
6262
files.add(new BoxSignRequestFile(file2.getID()));
6363

6464
String signerEmail = "user@example.com";
65+
Boolean signerLoginRequired = false;
66+
String signerPassword = "password";
67+
Boolean signerSuppressNotifications = false;
68+
String signerVerficationPhoneNumber = "+16314578901";
69+
6570
List<BoxSignRequestSigner> signers = new ArrayList<>();
66-
BoxSignRequestSigner newSigner = new BoxSignRequestSigner(signerEmail).setInPerson(false);
71+
BoxSignRequestSigner newSigner = new BoxSignRequestSigner(signerEmail).setInPerson(false)
72+
.setLoginRequired(signerLoginRequired).setPassword(signerPassword)
73+
.setSuppressNotifications(signerSuppressNotifications)
74+
.setVerificationPhoneNumber(signerVerficationPhoneNumber);
6775
signers.add(newSigner);
6876

6977
signedFileFolder = uniqueFolder.createFolder("Folder - signRequestIntegrationTest").getResource();
@@ -114,6 +122,9 @@ public void createListAndCancelSignRequest() throws InterruptedException {
114122
assertEquals(file2.getID(), file2Info.getID());
115123
assertEquals(signerEmail, signer.getEmail());
116124
assertEquals(signRequestIdCreate, signRequestInfoGetByID.getID());
125+
assertEquals(signerLoginRequired, signer.getLoginRequired());
126+
assertEquals(signerSuppressNotifications, signer.getSuppressNotifications());
127+
assertEquals(signerVerficationPhoneNumber, signer.getVerificationPhoneNumber());
117128

118129
// Resend sign request
119130
retry(signRequestGetByID::resend, 5, 500);
@@ -152,7 +163,7 @@ public void createListAndCancelSignRequest() throws InterruptedException {
152163
}
153164

154165
@Test
155-
public void createignRequestForGroup() throws InterruptedException {
166+
public void createSignRequestForGroup() throws InterruptedException {
156167
// Test Setup
157168
BoxAPIConnection api = jwtApiForServiceAccount();
158169
BoxFolder uniqueFolder = getUniqueFolder(api);

src/main/java/com/box/sdk/BoxSignRequestSigner.java

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public class BoxSignRequestSigner extends BoxJSONObject {
2727
private String declinedRedirectUrl;
2828
private String iframeableEmedUrl;
2929
private String signerGroupId;
30+
private Boolean loginRequired;
31+
private String password;
32+
private Boolean suppressNotifications;
33+
private String verificationPhoneNumber;
3034
private BoxAPIConnection api;
3135

3236
/**
@@ -295,6 +299,93 @@ public BoxSignRequestSigner setSignerGroupId(String signerGroupId) {
295299
return this;
296300
}
297301

302+
/**
303+
* If set to true, signer will need to login to a Box account before signing the request.
304+
* If the signer does not have an existing account, they will have an option to create a free Box account.
305+
*
306+
* @return true if login is required for the signer, otherwise false.
307+
*/
308+
public Boolean getLoginRequired() {
309+
return this.loginRequired;
310+
}
311+
312+
/**
313+
* If set to true, signer will need to login to a Box account before signing the request.
314+
* If the signer does not have an existing account, they will have an option to create a free Box account.
315+
*
316+
* @param loginRequired indicates if login is required for the signer.
317+
* @return this BoxSignRequestSigner object for chaining.
318+
*/
319+
public BoxSignRequestSigner setLoginRequired(Boolean loginRequired) {
320+
this.loginRequired = loginRequired;
321+
return this;
322+
}
323+
324+
/**
325+
* If set, the signer is required to enter the password before they are able to sign a document.
326+
* This field is write only.
327+
*
328+
* @return password required for the signer to access the sign request.
329+
*/
330+
public String getPassword() {
331+
return this.password;
332+
}
333+
334+
/**
335+
* Sets the password required for the signer to access the sign request.
336+
*
337+
* @param password required for the signer to access the sign request.
338+
* @return this BoxSignRequestSigner object for chaining.
339+
*/
340+
public BoxSignRequestSigner setPassword(String password) {
341+
this.password = password;
342+
return this;
343+
}
344+
345+
/**
346+
* Gets the flag that suppresses email notifications for the signer.
347+
*
348+
* @return true if email notifications are suppressed for the signer, otherwise false.
349+
*/
350+
public Boolean getSuppressNotifications() {
351+
return this.suppressNotifications;
352+
}
353+
354+
/**
355+
* Sets the flag that suppresses email notifications for the signer.
356+
*
357+
* @param suppressNotifications indicates if email notifications are suppressed for the signer.
358+
* @return this BoxSignRequestSigner object for chaining.
359+
*/
360+
public BoxSignRequestSigner setSuppressNotifications(Boolean suppressNotifications) {
361+
this.suppressNotifications = suppressNotifications;
362+
return this;
363+
}
364+
365+
/**
366+
* Gets the phone number used for verification.
367+
* If set, this phone number is be used to verify the signer via two factor authentication
368+
* before they are able to sign the document.
369+
*
370+
* @return phone number used for verification.
371+
*/
372+
public String getVerificationPhoneNumber() {
373+
return this.verificationPhoneNumber;
374+
}
375+
376+
/**
377+
* Sets the phone number used for verification.
378+
* If set, this phone number is be used to verify the signer via two factor authentication
379+
* before they are able to sign the document.
380+
*
381+
* @param verificationPhoneNumber phone number used for verification.
382+
* @return this BoxSignRequestSigner object for chaining.
383+
*/
384+
public BoxSignRequestSigner setVerificationPhoneNumber(String verificationPhoneNumber) {
385+
this.verificationPhoneNumber = verificationPhoneNumber;
386+
return this;
387+
}
388+
298389
/**
299390
* {@inheritDoc}
300391
*/
@@ -352,6 +443,14 @@ void parseJSONMember(JsonObject.Member member) {
352443
case "signer_group_id":
353444
this.signerGroupId = value.asString();
354445
break;
446+
case "login_required":
447+
this.loginRequired = value.asBoolean();
448+
break;
449+
case "suppress_notifications":
450+
this.suppressNotifications = value.asBoolean();
451+
break;
452+
case "verification_phone_number":
453+
this.verificationPhoneNumber = value.asString();
355454
default:
356455
return;
357456
}
@@ -375,6 +474,10 @@ public JsonObject getJSONObject() {
375474
JsonUtils.addIfNotNull(jsonObj, "redirect_url", this.redirectUrl);
376475
JsonUtils.addIfNotNull(jsonObj, "declined_redirect_url", this.declinedRedirectUrl);
377476
JsonUtils.addIfNotNull(jsonObj, "signer_group_id", this.signerGroupId);
477+
JsonUtils.addIfNotNull(jsonObj, "login_required", this.loginRequired);
478+
JsonUtils.addIfNotNull(jsonObj, "password", this.password);
479+
JsonUtils.addIfNotNull(jsonObj, "suppress_notifications", this.suppressNotifications);
480+
JsonUtils.addIfNotNull(jsonObj, "verification_phone_number", this.verificationPhoneNumber);
378481
return jsonObj;
379482
}
380483

@@ -554,6 +657,7 @@ static BoxSignRequestInputContentType fromJSONString(String jsonValue) {
554657
public class BoxSignerDecision extends BoxJSONObject {
555658
private BoxSignRequestSignerDecisionType type;
556659
private Date finalizedAt;
660+
private String additionalInfo;
557661

558662
/**
559663
* Constructs a BoxSignerDecision object using an already parsed JSON object.
@@ -582,6 +686,15 @@ public Date getFinalizedAt() {
582686
return this.finalizedAt;
583687
}
584688

689+
/**
690+
* Gets the additional info about the decision, such as the decline reason from the signer.
691+
*
692+
* @return additional information about the decision.
693+
*/
694+
public String getAdditionalInfo() {
695+
return this.additionalInfo;
696+
}
697+
585698
/**
586699
* {@inheritDoc}
587700
*/
@@ -594,6 +707,8 @@ void parseJSONMember(JsonObject.Member member) {
594707
this.type = BoxSignRequestSignerDecisionType.fromJSONString(value.asString());
595708
} else if (memberName.equals("finalized_at")) {
596709
this.finalizedAt = BoxDateFormat.parse(value.asString());
710+
} else if (memberName.equals("additional_info")) {
711+
this.additionalInfo = value.asString();
597712
}
598713
} catch (Exception e) {
599714
throw new BoxDeserializationException(memberName, value.toString(), e);

src/main/java/com/box/sdk/BoxWebHook.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,26 @@ public enum Trigger {
497497
* Triggered when {@link BoxFile} is expired.
498498
*/
499499
SIGN_REQUEST_EXPIRED("SIGN_REQUEST.EXPIRED",
500+
BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
501+
/**
502+
* Triggered when a signer's email is bounced.
503+
*/
504+
SIGN_REQUEST_SIGNER_EMAIL_BOUNCED("SIGN_REQUEST.SIGNER_EMAIL_BOUNCED",
505+
BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
506+
/**
507+
* Triggered when the signature request is signed.
508+
*/
509+
SIGN_REQUEST_SIGNER_SIGNED("SIGN_REQUEST.SIGNER_SIGNED",
510+
BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
511+
/**
512+
* Triggered when the signature is requested from the signer.
513+
*/
514+
SIGN_REQUEST_SIGNATURE_REQUESTED("SIGN_REQUEST.SIGNATURE_REQUESTED",
515+
BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class)),
516+
/**
517+
* Triggered when the signature request could not be processed.
518+
*/
519+
SIGN_REQUEST_ERROR_FINALIZING("SIGN_REQUEST.ERROR_FINALIZING",
500520
BoxResource.getResourceType(BoxFolder.class), BoxResource.getResourceType(BoxFile.class));
501521

502522
/**

src/test/Fixtures/BoxSignRequest/CreateSignRequest200.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"has_viewed_document": true,
1818
"signer_decision": {
1919
"type": "signed",
20-
"finalized_at": "2021-04-26T08:12:13.982Z"
20+
"finalized_at": "2021-04-26T08:12:13.982Z",
21+
"additional_info": "Requesting changes before signing."
2122
},
2223
"inputs": [
2324
{
@@ -33,7 +34,10 @@
3334
"embed_url": "https://example.com",
3435
"redirect_url": "https://box.com/redirect_url_signer_1",
3536
"declined_redirect_url": "https://box.com/declined_redirect_url_signer_1",
36-
"iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4"
37+
"iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4",
38+
"suppress_notifications": true,
39+
"login_required": true,
40+
"verification_phone_number": "1234567890"
3741
}
3842
],
3943
"source_files": [

src/test/Fixtures/BoxSignRequest/GetSignRequest200.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"has_viewed_document": true,
1818
"signer_decision": {
1919
"type": "signed",
20-
"finalized_at": "2021-04-26T08:12:13.982Z"
20+
"finalized_at": "2021-04-26T08:12:13.982Z",
21+
"additional_info": "Requesting changes before signing."
2122
},
2223
"inputs": [
2324
{
@@ -51,7 +52,10 @@
5152
"embed_url": "https://example.com",
5253
"redirect_url": "https://box.com/redirect_url_signer_1",
5354
"declined_redirect_url": "https://box.com/declined_redirect_url_signer_1",
54-
"iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4"
55+
"iframeable_embed_url": "https://app.box.com/embed/sign/document/gfhr4222-a331-494b-808b-79bc7f3992a3/f14d7098-a331-494b-808b-79bc7f3992a4",
56+
"suppress_notifications": true,
57+
"login_required": true,
58+
"verification_phone_number": "1234567890"
5559
}
5660
],
5761
"source_files": [

src/test/java/com/box/sdk/BoxSignRequestTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public void createSignRequestSucceeds() {
5050

5151
final String signerRedirectUrl = "https://box.com/redirect_url_signer_1";
5252
final String signerDeclinedRedirectUrl = "https://box.com/declined_redirect_url_signer_1";
53+
final Boolean signerLoginRequired = true;
54+
final String signerPassword = "password";
55+
final Boolean signerSuppressNotifications = true;
56+
final String signerVerficationPhoneNumber = "1234567890";
5357

5458
String result = TestUtils.getFixture("BoxSignRequest/CreateSignRequest200");
5559

@@ -65,6 +69,10 @@ public void createSignRequestSucceeds() {
6569
List<BoxSignRequestSigner> signers = new ArrayList<>();
6670
BoxSignRequestSigner newSigner = new BoxSignRequestSigner("signer@mail.com");
6771
newSigner.setEmbedUrlExternalUserId("1234");
72+
newSigner.setLoginRequired(signerLoginRequired);
73+
newSigner.setPassword(signerPassword);
74+
newSigner.setSuppressNotifications(signerSuppressNotifications);
75+
newSigner.setVerificationPhoneNumber(signerVerficationPhoneNumber);
6876
signers.add(newSigner);
6977

7078
String parentFolderId = "55555";
@@ -81,6 +89,9 @@ public void createSignRequestSucceeds() {
8189
assertEquals(signerRedirectUrl, signer.getRedirectUrl());
8290
assertEquals(iframeableEmedUrl, signer.getIframeableEmedUrl());
8391
assertEquals(signerDeclinedRedirectUrl, signer.getDeclinedRedirectUrl());
92+
assertEquals(signerLoginRequired, signer.getLoginRequired());
93+
assertEquals(signerSuppressNotifications, signer.getSuppressNotifications());
94+
assertEquals(signerVerficationPhoneNumber, signer.getVerificationPhoneNumber());
8495

8596
assertEquals(prepareUrl, signRequestInfo.getPrepareUrl());
8697
assertEquals(redirectUrl, signRequestInfo.getRedirectUrl());
@@ -109,6 +120,10 @@ public void getSignRequestInfoSucceeds() {
109120

110121
final String signerRedirectUrl = "https://box.com/redirect_url_signer_1";
111122
final String signerDeclinedRedirectUrl = "https://box.com/declined_redirect_url_signer_1";
123+
final Boolean signerLoginRequired = true;
124+
final Boolean signerSuppressNotifications = true;
125+
final String signerVerficationPhoneNumber = "1234567890";
126+
final String signerDecisionAdditionalInfo = "Requesting changes before signing.";
112127

113128
final String templateId = "93153068-5420-467b-b8ef-aaaaaaaaaaa";
114129

@@ -130,6 +145,10 @@ public void getSignRequestInfoSucceeds() {
130145
assertEquals(signerRedirectUrl, signer.getRedirectUrl());
131146
assertEquals(signerDeclinedRedirectUrl, signer.getDeclinedRedirectUrl());
132147
assertEquals(iframeableEmedUrl, signer.getIframeableEmedUrl());
148+
assertEquals(signerLoginRequired, signer.getLoginRequired());
149+
assertEquals(signerSuppressNotifications, signer.getSuppressNotifications());
150+
assertEquals(signerVerficationPhoneNumber, signer.getVerificationPhoneNumber());
151+
assertEquals(signerDecisionAdditionalInfo, signer.getSignerDecision().getAdditionalInfo());
133152

134153
assertEquals(prepareUrl, signRequestInfo.getPrepareUrl());
135154
assertEquals(redirectUrl, signRequestInfo.getRedirectUrl());

0 commit comments

Comments
 (0)