diff --git a/SendsafelyAPI/ClientAPI.cs b/SendsafelyAPI/ClientAPI.cs
index bb634c3..7afe7c6 100644
--- a/SendsafelyAPI/ClientAPI.cs
+++ b/SendsafelyAPI/ClientAPI.cs
@@ -695,6 +695,32 @@ public String FinalizePackage(String packageId, String keycode)
return pu.FinalizePackage(packageId, keycode);
}
+ ///
+ /// Finalizes the package so it can be delivered to the recipients.
+ /// createPackage(). Additionally, the package must contain at least one file.
+ ///
+ /// The unique package id of the package to be finalized.
+ /// The keycode belonging to the package.
+ /// Determines whether package recipients permitted to reply to all recipients or just sender.
+ /// Thrown when the API has not been initialized.
+ /// Thrown when the API credentials are incorrect.
+ /// Thrown when the API failed to connect to the server.
+ /// Thrown when a non-existent or invalid package ID is used.
+ /// Thrown when the package limits has been exceeded.
+ /// Thrown when the package couldn't be finalized. The message will contain detailed information
+ /// Thrown when the keycode is null, empty or to short.
+ /// Will be thrown if the server returns an error message
+ ///
+ /// A link to access the package. This link can be sent to the recipients.
+ ///
+ public String FinalizePackage(String packageId, String keycode, bool allowReplyAll)
+ {
+ EnforceInitialized();
+
+ PackageUtility pu = new PackageUtility(connection);
+ return pu.FinalizePackage(packageId, keycode, allowReplyAll);
+ }
+
///
/// Finalizes an undisclosed package, which is a package without recipients. Anyone with access to the link can access the package.
///
diff --git a/SendsafelyAPI/Objects/FinalizePackageRequest.cs b/SendsafelyAPI/Objects/FinalizePackageRequest.cs
index f74c9f6..4c6cb19 100644
--- a/SendsafelyAPI/Objects/FinalizePackageRequest.cs
+++ b/SendsafelyAPI/Objects/FinalizePackageRequest.cs
@@ -10,7 +10,8 @@ class FinalizePackageRequest
{
private String _password;
private String _checksum;
- private bool undisclosedRecipients;
+ private bool undisclosedRecipients;
+ private bool allowReplyAll = false;
[JsonProperty(PropertyName = "password")]
public String Password { get; set; }
@@ -20,5 +21,8 @@ class FinalizePackageRequest
[JsonProperty(PropertyName = "undisclosedRecipients")]
public bool UndisclosedRecipients { get; set; }
+
+ [JsonProperty(PropertyName = "allowReplyAll")]
+ public bool AllowReplyAll { get; set; }
}
}
diff --git a/SendsafelyAPI/Objects/PackageDTO.cs b/SendsafelyAPI/Objects/PackageDTO.cs
index 9433b41..958e416 100644
--- a/SendsafelyAPI/Objects/PackageDTO.cs
+++ b/SendsafelyAPI/Objects/PackageDTO.cs
@@ -23,6 +23,7 @@ class PackageDTO
private String packageUserName;
private String packageState;
private List contactGroups;
+ private String _packageParentId;
[JsonProperty(PropertyName = "response")]
internal APIResponse Response
@@ -125,5 +126,11 @@ public List ContactGroups
get { return contactGroups; }
set { contactGroups = value; }
}
+ [JsonProperty(PropertyName = "packageParentId")]
+ public String PackageParentId
+ {
+ get { return _packageParentId; }
+ set { _packageParentId = value; }
+ }
}
}
diff --git a/SendsafelyAPI/Objects/PackageInformationResponse.cs b/SendsafelyAPI/Objects/PackageInformationResponse.cs
index 0c8b3f4..236aaa7 100644
--- a/SendsafelyAPI/Objects/PackageInformationResponse.cs
+++ b/SendsafelyAPI/Objects/PackageInformationResponse.cs
@@ -1,155 +1,170 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Newtonsoft.Json;
-
-namespace SendSafely.Objects
-{
- [JsonObject(MemberSerialization.OptIn)]
- class PackageInformationResponse
- {
- private String _packageId;
- private String _packageCode;
- private String _serverSecret;
- private APIResponse _response;
- private String _message;
- private bool _needsApprover;
- private String state;
- private List _recipients;
- private List _files;
- private List _approvers;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Newtonsoft.Json;
+
+namespace SendSafely.Objects
+{
+ [JsonObject(MemberSerialization.OptIn)]
+ class PackageInformationResponse
+ {
+ private String _packageId;
+ private String _packageCode;
+ private String _serverSecret;
+ private APIResponse _response;
+ private String _message;
+ private bool _needsApprover;
+ private String state;
+ private List _recipients;
+ private List _files;
+ private List _approvers;
private int _life;
- private DateTime _packageTimestamp;
- private String _packageSender;
- private String _rootDirectoryId;
- private String _label;
- private bool _isVDR;
- private List contactGroups;
-
- [JsonProperty(PropertyName = "response")]
- internal APIResponse Response
- {
- get { return _response; }
- set { _response = value; }
- }
-
- [JsonProperty(PropertyName = "packageId")]
- internal String PackageID
- {
- get { return _packageId; }
- set { _packageId = value; }
- }
-
- [JsonProperty(PropertyName = "packageCode")]
- internal String PackageCode
- {
- get { return _packageCode; }
- set { _packageCode = value; }
- }
-
- [JsonProperty(PropertyName = "serverSecret")]
- internal String ServerSecret
- {
- get { return _serverSecret; }
- set { _serverSecret = value; }
- }
-
- [JsonProperty(PropertyName = "message")]
- public String Message
- {
- get { return _message; }
- set { _message = value; }
- }
-
- [JsonProperty(PropertyName = "needsApproval")]
- public bool NeedsApprover
- {
- get { return _needsApprover; }
- set { _needsApprover = value; }
- }
-
- [JsonProperty(PropertyName = "recipients")]
- internal List Recipients
- {
- get { return _recipients; }
- set { _recipients = value; }
- }
-
- [JsonProperty(PropertyName = "files")]
- public List Files
- {
- get { return _files; }
- set { _files = value; }
- }
-
- [JsonProperty(PropertyName = "approverList")]
- public List Approvers
- {
- get { return _approvers; }
- set { _approvers = value; }
- }
-
- [JsonProperty(PropertyName = "life")]
- public int Life
- {
- get { return _life; }
- set { _life = value; }
- }
-
- [JsonProperty(PropertyName = "packageTimestamp")]
- public DateTime PackageTimestamp
- {
- get { return _packageTimestamp; }
- set { _packageTimestamp = value; }
- }
-
- [JsonProperty(PropertyName = "packageSender")]
- public String PackageSender
- {
- get { return _packageSender; }
- set { _packageSender = value; }
- }
-
- [JsonProperty(PropertyName = "rootDirectoryId")]
- public String RootDirectoryId
- {
- get { return _rootDirectoryId; }
- set { _rootDirectoryId = value; }
- }
-
- [JsonProperty(PropertyName = "label")]
- public String Label
- {
- get { return _label; }
- set { _label = value; }
- }
-
- [JsonProperty(PropertyName = "isVDR")]
- public Boolean IsVDR
- {
- get { return _isVDR; }
- set { _isVDR = value; }
- }
-
- ///
- /// A list of contact groups
- ///
- [JsonProperty(PropertyName = "contactGroups")]
- public List ContactGroups
- {
- get { return contactGroups; }
- set { contactGroups = value; }
- }
-
+ private DateTime _packageTimestamp;
+ private String _packageSender;
+ private String _rootDirectoryId;
+ private String _label;
+ private bool _isVDR;
+ private List contactGroups;
+ private bool _allowReplyAll;
+ private String _packageParentId;
+
+ [JsonProperty(PropertyName = "response")]
+ internal APIResponse Response
+ {
+ get { return _response; }
+ set { _response = value; }
+ }
+
+ [JsonProperty(PropertyName = "packageId")]
+ internal String PackageID
+ {
+ get { return _packageId; }
+ set { _packageId = value; }
+ }
+
+ [JsonProperty(PropertyName = "packageCode")]
+ internal String PackageCode
+ {
+ get { return _packageCode; }
+ set { _packageCode = value; }
+ }
+
+ [JsonProperty(PropertyName = "serverSecret")]
+ internal String ServerSecret
+ {
+ get { return _serverSecret; }
+ set { _serverSecret = value; }
+ }
+
+ [JsonProperty(PropertyName = "message")]
+ public String Message
+ {
+ get { return _message; }
+ set { _message = value; }
+ }
+
+ [JsonProperty(PropertyName = "needsApproval")]
+ public bool NeedsApprover
+ {
+ get { return _needsApprover; }
+ set { _needsApprover = value; }
+ }
+
+ [JsonProperty(PropertyName = "recipients")]
+ internal List Recipients
+ {
+ get { return _recipients; }
+ set { _recipients = value; }
+ }
+
+ [JsonProperty(PropertyName = "files")]
+ public List Files
+ {
+ get { return _files; }
+ set { _files = value; }
+ }
+
+ [JsonProperty(PropertyName = "approverList")]
+ public List Approvers
+ {
+ get { return _approvers; }
+ set { _approvers = value; }
+ }
+
+ [JsonProperty(PropertyName = "life")]
+ public int Life
+ {
+ get { return _life; }
+ set { _life = value; }
+ }
+
+ [JsonProperty(PropertyName = "packageTimestamp")]
+ public DateTime PackageTimestamp
+ {
+ get { return _packageTimestamp; }
+ set { _packageTimestamp = value; }
+ }
+
+ [JsonProperty(PropertyName = "packageSender")]
+ public String PackageSender
+ {
+ get { return _packageSender; }
+ set { _packageSender = value; }
+ }
+
+ [JsonProperty(PropertyName = "rootDirectoryId")]
+ public String RootDirectoryId
+ {
+ get { return _rootDirectoryId; }
+ set { _rootDirectoryId = value; }
+ }
+
+ [JsonProperty(PropertyName = "label")]
+ public String Label
+ {
+ get { return _label; }
+ set { _label = value; }
+ }
+
+ [JsonProperty(PropertyName = "isVDR")]
+ public Boolean IsVDR
+ {
+ get { return _isVDR; }
+ set { _isVDR = value; }
+ }
+
+ ///
+ /// A list of contact groups
+ ///
+ [JsonProperty(PropertyName = "contactGroups")]
+ public List ContactGroups
+ {
+ get { return contactGroups; }
+ set { contactGroups = value; }
+ }
+
///
/// a string of state
- ///
- [JsonProperty(PropertyName = "state")]
- public String State
- {
- get { return state; }
- set { state = value; }
- }
-
- }
-}
+ ///
+ [JsonProperty(PropertyName = "state")]
+ public String State
+ {
+ get { return state; }
+ set { state = value; }
+ }
+
+ [JsonProperty(PropertyName = "allowReplyAll")]
+ public Boolean AllowReplyAll
+ {
+ get { return _allowReplyAll; }
+ set { _allowReplyAll = value; }
+ }
+
+ [JsonProperty(PropertyName = "packageParentId")]
+ public String PackageParentId
+ {
+ get { return _packageParentId; }
+ set { _packageParentId = value; }
+ }
+ }
+}
diff --git a/SendsafelyAPI/PackageInformation.cs b/SendsafelyAPI/PackageInformation.cs
index 2376b30..2f1d64e 100644
--- a/SendsafelyAPI/PackageInformation.cs
+++ b/SendsafelyAPI/PackageInformation.cs
@@ -26,91 +26,93 @@ public class PackageInformation
private bool isWorkspace;
private DateTime packageTimestamp;
private String packageOwner;
- private List recipients;
- private List contactGroups;
-
- ///
- /// The package ID for the given package.
- ///
- public String PackageId
- {
- get { return packageId; }
- set { packageId = value; }
- }
-
- ///
- /// The package code for the given package. The package code is a part of the URL that must be sent to the recipients.
- ///
- public String PackageCode
- {
- get { return packageCode; }
- set { packageCode = value; }
- }
-
- ///
- /// The keycode for the package. This key should always be kept client side and never be sent to the server.
- /// The keycode makes up one part of the encryption key.
- ///
- public String KeyCode
- {
- get { return keyCode; }
- set { keyCode = value; }
- }
-
- ///
- /// The server secret makes together with the keycode up the encryption key. The server secret is specific
- /// to a package and passed from the server.
- ///
- public String ServerSecret
- {
- get { return serverSecret; }
- set { serverSecret = value; }
- }
-
- ///
- /// NeedsApprover will be true when a package needs to add at least one approver before the package can be finalized.
- /// If the package is finalized without the approver, an exception will be thrown.
- ///
- public bool NeedsApprover
- {
- get { return needsApprover; }
- set { needsApprover = value; }
- }
-
- ///
- /// A list of recipients that are currently attached to the package.
- ///
- public List Recipients
- {
- get { return recipients; }
- set { recipients = value; }
- }
-
- ///
- /// A list of files that are currently attached to the package.
- ///
- public List Files
- {
- get { return files; }
- set { files = value; }
- }
-
- ///
- /// A list of approvers that are currently attached to the package.
- ///
- public List Approvers
- {
- get { return approvers; }
- set { approvers = value; }
- }
-
- ///
- /// The current package life. The package life determines for how long the package
- /// should be available to the recipients. It's measured in days.
- ///
- public int Life
- {
- get { return life; }
+ private List recipients;
+ private List contactGroups;
+ private bool allowReplyAll;
+ private String packageParentId;
+
+ ///
+ /// The package ID for the given package.
+ ///
+ public String PackageId
+ {
+ get { return packageId; }
+ set { packageId = value; }
+ }
+
+ ///
+ /// The package code for the given package. The package code is a part of the URL that must be sent to the recipients.
+ ///
+ public String PackageCode
+ {
+ get { return packageCode; }
+ set { packageCode = value; }
+ }
+
+ ///
+ /// The keycode for the package. This key should always be kept client side and never be sent to the server.
+ /// The keycode makes up one part of the encryption key.
+ ///
+ public String KeyCode
+ {
+ get { return keyCode; }
+ set { keyCode = value; }
+ }
+
+ ///
+ /// The server secret makes together with the keycode up the encryption key. The server secret is specific
+ /// to a package and passed from the server.
+ ///
+ public String ServerSecret
+ {
+ get { return serverSecret; }
+ set { serverSecret = value; }
+ }
+
+ ///
+ /// NeedsApprover will be true when a package needs to add at least one approver before the package can be finalized.
+ /// If the package is finalized without the approver, an exception will be thrown.
+ ///
+ public bool NeedsApprover
+ {
+ get { return needsApprover; }
+ set { needsApprover = value; }
+ }
+
+ ///
+ /// A list of recipients that are currently attached to the package.
+ ///
+ public List Recipients
+ {
+ get { return recipients; }
+ set { recipients = value; }
+ }
+
+ ///
+ /// A list of files that are currently attached to the package.
+ ///
+ public List Files
+ {
+ get { return files; }
+ set { files = value; }
+ }
+
+ ///
+ /// A list of approvers that are currently attached to the package.
+ ///
+ public List Approvers
+ {
+ get { return approvers; }
+ set { approvers = value; }
+ }
+
+ ///
+ /// The current package life. The package life determines for how long the package
+ /// should be available to the recipients. It's measured in days.
+ ///
+ public int Life
+ {
+ get { return life; }
set { life = value; }
}
@@ -121,7 +123,7 @@ public int Life
public DateTime PackageTimestamp
{
get { return packageTimestamp; }
- set { packageTimestamp = value; }
+ set { packageTimestamp = value; }
}
///
@@ -149,42 +151,60 @@ public PackageStatus Status
{
get { return status; }
set { status = value; }
- }
-
+ }
+
///
/// The root directory of a workspace package.
- ///
- public String RootDirectoryId
- {
- get { return rootDirectoryId; }
- set { rootDirectoryId = value; }
- }
-
+ ///
+ public String RootDirectoryId
+ {
+ get { return rootDirectoryId; }
+ set { rootDirectoryId = value; }
+ }
+
///
/// The package descriptor.
- ///
- public String PackageDescriptor
- {
- get { return packageDescriptor; }
- set { packageDescriptor = value; }
- }
-
+ ///
+ public String PackageDescriptor
+ {
+ get { return packageDescriptor; }
+ set { packageDescriptor = value; }
+ }
+
///
/// The flag specifying the package is a workspace.
- ///
+ ///
public Boolean IsWorkspace
{
- get { return isWorkspace; }
+ get { return isWorkspace; }
set { isWorkspace = value; }
}
- ///
- /// A list of contact groups
- ///
- public List ContactGroups
- {
- get { return contactGroups; }
- set { contactGroups = value; }
- }
- }
-}
+ ///
+ /// A list of contact groups
+ ///
+ public List ContactGroups
+ {
+ get { return contactGroups; }
+ set { contactGroups = value; }
+ }
+
+ ///
+ /// Allow reply all, false if BCC recipients
+ ///
+ public Boolean AllowReplyAll
+ {
+ get { return allowReplyAll; }
+ set { allowReplyAll = value; }
+ }
+
+ ///
+ /// Package parent id
+ ///
+ public String PackageParentId
+ {
+ get { return packageParentId; }
+ set { packageParentId = value; }
+ }
+ }
+}
diff --git a/SendsafelyAPI/Properties/AssemblyInfo.cs b/SendsafelyAPI/Properties/AssemblyInfo.cs
index b214cc3..d7fe2b5 100644
--- a/SendsafelyAPI/Properties/AssemblyInfo.cs
+++ b/SendsafelyAPI/Properties/AssemblyInfo.cs
@@ -10,7 +10,7 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SendSafely Windows Client API")]
-[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,7 +32,7 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("3.0.4")]
-[assembly: AssemblyFileVersion("3.0.4")]
+[assembly: AssemblyVersion("3.0.5")]
+[assembly: AssemblyFileVersion("3.0.5")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("APITests")]
\ No newline at end of file
diff --git a/SendsafelyAPI/Utilities/PackageUtility.cs b/SendsafelyAPI/Utilities/PackageUtility.cs
index 39a2b1a..54e0c3a 100644
--- a/SendsafelyAPI/Utilities/PackageUtility.cs
+++ b/SendsafelyAPI/Utilities/PackageUtility.cs
@@ -576,6 +576,23 @@ public String FinalizePackage(String packageId, String keycode)
return FinalizePackage(packageInfo);
}
+ public String FinalizePackage(String packageId, String keycode, bool allowReplyAll)
+ {
+ if (packageId == null)
+ {
+ throw new InvalidPackageException("PackageId can not be null");
+ }
+ FinalizePackageRequest request = new FinalizePackageRequest();
+
+ request.AllowReplyAll = allowReplyAll;
+ // Add the keycode in case we don't have it
+ connection.AddKeycode(packageId, keycode);
+
+ // Get the updated package information.
+ PackageInformation packageInfo = GetPackageInformation(packageId);
+ return FinalizePackage(packageInfo, request);
+ }
+
public String FinalizePackage(PackageInformation packageInfo)
{
FinalizePackageRequest request = new FinalizePackageRequest();
@@ -1325,6 +1342,7 @@ private PackageInformation Convert(PackageDTO raw)
packageInfo.ServerSecret = raw.ServerSecret;
packageInfo.Approvers = raw.Approvers;
packageInfo.PackageTimestamp = raw.PackageUpdateTimestamp;
+ packageInfo.PackageParentId = raw.PackageParentId;
packageInfo.PackageOwner = raw.PackageUserName;
@@ -1385,6 +1403,7 @@ private PackageInformation Convert(PackageInformationResponse raw)
packageInfo.ContactGroups = raw.ContactGroups;
int stateValue = (int) Enum.Parse(typeof(PackageState), raw.State, true);
packageInfo.Status = ConvertStateToStatus(stateValue);
+ packageInfo.PackageParentId = raw.PackageParentId;
try
{