diff --git a/CHANGELOG.md b/CHANGELOG.md
index da7cb609b..e9275f25f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# DocuSign C# Client Changelog
+## [v8.0.0-rc2] - eSignature API v2.1-24.2.00.00 - 2024-07-23
+### Changed
+- Introduced async versions of `ApiClient` authorization methods.
+- Corrected SDK metadata.
+- Updated the SDK release version.
## [v8.0.0-rc1] - eSignature API v2.1-24.2.00.00 - 2024-07-02
### Breaking Changes
diff --git a/LICENSE b/LICENSE
index b1136e304..847de507f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License
-Copyright (c) 2021 - DocuSign, Inc. (https://www.docusign.com)
+Copyright (c) 2021 - Docusign, Inc. (https://www.docusign.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 3558ff8fb..d92bd91cc 100755
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ This client SDK is provided as open source, which enables you to customize its f
### Version Information
- **API version**: v2.1
-- **Latest SDK version (Including prerelease)**: 8.0.0-rc1
+- **Latest SDK version (Including prerelease)**: 8.0.0-rc2
### Requirements
diff --git a/sdk/.doxygenconfig b/sdk/.doxygenconfig
index 9fc90763f..9eb3c8a6e 100644
--- a/sdk/.doxygenconfig
+++ b/sdk/.doxygenconfig
@@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
-PROJECT_NAME = "DocuSign CSharp Docs"
+PROJECT_NAME = "Docusign CSharp Docs"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
diff --git a/sdk/DocuSign.eSign.sln b/sdk/DocuSign.eSign.sln
index f8853d4d3..2145b3734 100644
--- a/sdk/DocuSign.eSign.sln
+++ b/sdk/DocuSign.eSign.sln
@@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
VisualStudioVersion = 12.0.0.0
MinimumVisualStudioVersion = 10.0.0.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocuSign.eSign", "src\DocuSign.eSign\DocuSign.eSign.csproj", "{6832F73B-2498-44E8-A8A5-5DD858B47089}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocuSign.eSign", "src\DocuSign.eSign\DocuSign.eSign.csproj", "{0DD2EBA2-97AB-491E-911A-01F064CA09E7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -10,10 +10,10 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6832F73B-2498-44E8-A8A5-5DD858B47089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6832F73B-2498-44E8-A8A5-5DD858B47089}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6832F73B-2498-44E8-A8A5-5DD858B47089}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6832F73B-2498-44E8-A8A5-5DD858B47089}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0DD2EBA2-97AB-491E-911A-01F064CA09E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0DD2EBA2-97AB-491E-911A-01F064CA09E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0DD2EBA2-97AB-491E-911A-01F064CA09E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0DD2EBA2-97AB-491E-911A-01F064CA09E7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/sdk/src/DocuSign.eSign/Client/Auth/OAuth.cs b/sdk/src/DocuSign.eSign/Client/Auth/OAuth.cs
index eb5af0c44..39a2cd396 100644
--- a/sdk/src/DocuSign.eSign/Client/Auth/OAuth.cs
+++ b/sdk/src/DocuSign.eSign/Client/Auth/OAuth.cs
@@ -54,7 +54,7 @@ public class OAuth
*
* UserInfo model with the following properties:
*
sub: the user ID GUID.
- *
accounts: this is list of DocuSign accounts associated with the current user.
+ *
accounts: this is list of Docusign accounts associated with the current user.
*
name: the user's full name.
*
givenName: the user's given name.
*
familyName: the user's family name.
@@ -73,7 +73,7 @@ public class UserInfo : IEquatable, IValidatableObject
/// isDefault: whether this is the default account, when the user has access to multiple accounts.
/// accountName: the human-readable name of the account.
/// baseUri: the base URI associated with this account.
- /// It also tells which DocuSign data center the account is hosted on.
+ /// It also tells which Docusign data center the account is hosted on.
///
[DataContract]
public class Account : IEquatable, IValidatableObject
@@ -235,8 +235,8 @@ public IEnumerable Validate(ValidationContext validationContex
///
/// Organization model with the following properties:
- /// organizationId: the organization ID GUID if DocuSign Org Admin is enabled.
- /// links: this is list of organization direct links associated with the DocuSign account.
+ /// organizationId: the organization ID GUID if Docusign Org Admin is enabled.
+ /// links: this is list of organization direct links associated with the Docusign account.
///
[DataContract]
public class Organization : IEquatable, IValidatableObject
diff --git a/sdk/src/DocuSign.eSign/Client/Configuration.cs b/sdk/src/DocuSign.eSign/Client/Configuration.cs
index fec7d14d2..072c5b0ad 100644
--- a/sdk/src/DocuSign.eSign/Client/Configuration.cs
+++ b/sdk/src/DocuSign.eSign/Client/Configuration.cs
@@ -26,7 +26,7 @@ public class Configuration
/// Version of the package.
///
/// Version of the package.
- public const string Version = "8.0.0-rc1";
+ public const string Version = "8.0.0-rc2";
///
/// Identifier for ISO 8601 DateTime Format
diff --git a/sdk/src/DocuSign.eSign/Client/DocuSignClient.cs b/sdk/src/DocuSign.eSign/Client/DocuSignClient.cs
index 73936138e..a3d373bbd 100644
--- a/sdk/src/DocuSign.eSign/Client/DocuSignClient.cs
+++ b/sdk/src/DocuSign.eSign/Client/DocuSignClient.cs
@@ -34,7 +34,7 @@
namespace DocuSign.eSign.Client
{
///
- /// DocuSignClient is mainly responsible for facilitating HTTP calls to the DocuSign APIs.
+ /// DocuSignClient is mainly responsible for facilitating HTTP calls to the Docusign APIs.
///
public class DocuSignClient
{
@@ -739,17 +739,58 @@ public void SetOAuthBasePath(string oauthBaseUri = null)
}
}
+ private static T TryCatchWrapper(Func func)
+ {
+ try
+ {
+ return func.Invoke();
+ }
+ catch (AggregateException ae)
+ {
+ foreach (var e in ae.InnerExceptions)
+ {
+ throw e;
+ }
+
+ // This line is technically unreachable, but necessary for the compiler to be happy.
+ throw;
+ }
+ catch (Exception e)
+ {
+
+ throw e;
+ }
+ }
+
///
/// GenerateAccessToken will exchange the authorization code for an access token and refresh tokens.
///
/// OAuth2 client ID: Identifies the client making the request.
- /// the secret key you generated when you set up the integration in DocuSign Admin console.
+ /// the secret key you generated when you set up the integration in Docusign Admin console.
/// The authorization code that you received from the GetAuthorizationUri callback.
/// OAuth.OAuthToken object.
/// ApiException if the HTTP call status is different than 2xx.
/// IOException if there is a problem while parsing the reponse object.
///
public OAuth.OAuthToken GenerateAccessToken(string clientId, string clientSecret, string code)
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ return TryCatchWrapper(() => GenerateAccessTokenAsync(clientId, clientSecret, code, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
+ }
+
+ ///
+ /// GenerateAccessTokenAsync will exchange the authorization code for an access token and refresh tokens.
+ ///
+ /// OAuth2 client ID: Identifies the client making the request.
+ /// the secret key you generated when you set up the integration in Docusign Admin console.
+ /// The authorization code that you received from the GetAuthorizationUri callback.
+ /// A CancellationToken which can be used to propagate notification that operations should be canceled.
+ ///
+ /// Task<OAuth.OAuthToken> object.
+ /// ApiException if the HTTP call status is different than 2xx.
+ /// IOException if there is a problem while parsing the reponse object.
+ ///
+ public async Task GenerateAccessTokenAsync(string clientId, string clientSecret, string code, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret) || string.IsNullOrEmpty(code))
{
@@ -777,20 +818,13 @@ public OAuth.OAuthToken GenerateAccessToken(string clientId, string clientSecret
foreach (var item in formParams)
request.AddPostParameter(item.Key, item.Value);
- DocuSignResponse response = RestClient.SendRequest(request);
+ DocuSignResponse response = await RestClient.SendRequestAsync(request, cancellationToken);
if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode < HttpStatusCode.BadRequest)
{
OAuth.OAuthToken tokenObj = JsonConvert.DeserializeObject(response.Content);
// Add the token to this ApiClient
string authHeader = "Bearer " + tokenObj.access_token;
- if (!this.Configuration.DefaultHeader.ContainsKey("Authorization"))
- {
- this.Configuration.DefaultHeader.Add("Authorization", authHeader);
- }
- else
- {
- this.Configuration.DefaultHeader["Authorization"] = authHeader;
- }
+ this.Configuration.DefaultHeader["Authorization"] = authHeader;
return tokenObj;
}
else
@@ -800,11 +834,23 @@ public OAuth.OAuthToken GenerateAccessToken(string clientId, string clientSecret
}
///
- /// Get User Info method takes the accessToken to retrieve User Account Data.
+ /// GetUserInfo method takes the accessToken to retrieve User Account Data.
///
///
/// The User Info model.
public OAuth.UserInfo GetUserInfo(string accessToken)
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ return TryCatchWrapper(() => GetUserInfoAsync(accessToken, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
+ }
+
+ ///
+ /// GetUserInfoAsync method takes the accessToken to retrieve User Account Data.
+ ///
+ ///
+ /// A CancellationToken which can be used to propagate notification that operations should be canceled.
+ /// The User Info model.
+ public async Task GetUserInfoAsync(string accessToken, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(accessToken))
{
@@ -817,7 +863,7 @@ public OAuth.UserInfo GetUserInfo(string accessToken)
localVarHeaderParams.Add("Authorization", "Bearer " + accessToken);
DocuSignRequest request = PrepareOAuthRequest(oAuthBasePath, $"oauth/userinfo", HttpMethod.Get, localVarHeaderParams.ToList(), localVarFormParams.ToList());
- DocuSignResponse response = RestClient.SendRequest(request);
+ DocuSignResponse response = await RestClient.SendRequestAsync(request, cancellationToken);
if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode < HttpStatusCode.BadRequest)
{
@@ -861,12 +907,12 @@ protected static RSA CreateRSAKeyFromPem(string key)
}
///
- /// Request JWT User Token
- /// Configures the current instance of ApiClient with a fresh OAuth JWT access token from DocuSign
+ /// RequestJWTUserToken
+ /// Configures the current instance of ApiClient with a fresh OAuth JWT access token from Docusign
///
- /// DocuSign OAuth Client Id(AKA Integrator Key)
- /// DocuSign user Id to be impersonated(This is a UUID)
- /// DocuSign OAuth base path
+ /// Docusign OAuth Client Id(AKA Integrator Key)
+ /// Docusign user Id to be impersonated(This is a UUID)
+ /// Docusign OAuth base path
///
///
///
@@ -877,11 +923,34 @@ protected static RSA CreateRSAKeyFromPem(string key)
///
/// The JWT user token
public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, string oauthBasePath, Stream privateKeyStream, int expiresInHours, List scopes = null)
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ return TryCatchWrapper(() => RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyStream, expiresInHours, scopes, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
+ }
+
+ ///
+ /// RequestJWTUserTokenAsync
+ /// Configures the current instance of ApiClient with a fresh OAuth JWT access token from Docusign
+ ///
+ /// Docusign OAuth Client Id(AKA Integrator Key)
+ /// Docusign user Id to be impersonated(This is a UUID)
+ /// Docusign OAuth base path
+ ///
+ ///
+ ///
+ /// The Stream of the RSA private key
+ /// Number of hours remaining before the JWT assertion is considered as invalid
+ /// Optional. The list of requested scopes may include (but not limited to)
+ /// A CancellationToken which can be used to propagate notification that operations should be canceled.
+ ///
+ ///
+ /// The JWT user token
+ public Task RequestJWTUserTokenAsync(string clientId, string userId, string oauthBasePath, Stream privateKeyStream, int expiresInHours, List scopes = null, CancellationToken cancellationToken = default)
{
if (privateKeyStream != null && privateKeyStream.CanRead && privateKeyStream.Length > 0)
{
byte[] privateKeyBytes = ReadAsBytes(privateKeyStream);
- return this.RequestJWTUserToken(clientId, userId, oauthBasePath, privateKeyBytes, expiresInHours, scopes);
+ return this.RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyBytes, expiresInHours, scopes, cancellationToken);
}
else
{
@@ -890,12 +959,12 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
}
///
- /// Request JWT User Token
- /// Configures the current instance of ApiClient with a fresh OAuth JWT access token from DocuSign
+ /// RequestJWTUserToken
+ /// Configures the current instance of ApiClient with a fresh OAuth JWT access token from Docusign
///
- /// DocuSign OAuth Client Id(AKA Integrator Key)
- /// DocuSign user Id to be impersonated(This is a UUID)
- /// DocuSign OAuth base path
+ /// Docusign OAuth Client Id(AKA Integrator Key)
+ /// Docusign user Id to be impersonated(This is a UUID)
+ /// Docusign OAuth base path
///
///
///
@@ -906,6 +975,29 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
///
/// The JWT user token
public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, string oauthBasePath, byte[] privateKeyBytes, int expiresInHours, List scopes = null)
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ return TryCatchWrapper(() => RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyBytes, expiresInHours, scopes, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
+ }
+
+ ///
+ /// RequestJWTUserTokenAsync
+ /// Configures the current instance of ApiClient with a fresh OAuth JWT access token from Docusign
+ ///
+ /// Docusign OAuth Client Id(AKA Integrator Key)
+ /// Docusign user Id to be impersonated(This is a UUID)
+ /// Docusign OAuth base path
+ ///
+ ///
+ ///
+ /// The byte contents of the RSA private key
+ /// Number of hours remaining before the JWT assertion is considered as invalid
+ /// Optional. The list of requested scopes may include (but not limited to) You can also pass any advanced scope.
+ /// A CancellationToken which can be used to propagate notification that operations should be canceled.
+ ///
+ ///
+ /// The JWT user token
+ public async Task RequestJWTUserTokenAsync(string clientId, string userId, string oauthBasePath, byte[] privateKeyBytes, int expiresInHours, List scopes = null, CancellationToken cancellationToken = default)
{
string privateKey = Encoding.UTF8.GetString(privateKeyBytes);
@@ -956,19 +1048,13 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
};
DocuSignRequest request = PrepareOAuthRequest(oauthBasePath, $"oauth/token", HttpMethod.Post, Configuration.DefaultHeader?.ToList(), localVarFormParams.ToList());
- DocuSignResponse response = RestClient.SendRequest(request);
+ DocuSignResponse response = await RestClient.SendRequestAsync(request, cancellationToken);
if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode < HttpStatusCode.BadRequest)
{
OAuth.OAuthToken tokenInfo = JsonConvert.DeserializeObject(response.Content);
- if (!this.Configuration.DefaultHeader.ContainsKey("Authorization"))
- {
- this.Configuration.DefaultHeader.Add("Authorization", string.Format("{0} {1}", tokenInfo.token_type, tokenInfo.access_token));
- }
- else
- {
- this.Configuration.DefaultHeader["Authorization"] = string.Format("{0} {1}", tokenInfo.token_type, tokenInfo.access_token);
- }
+ this.Configuration.DefaultHeader["Authorization"] = string.Format("{0} {1}", tokenInfo.token_type, tokenInfo.access_token);
+
return tokenInfo;
}
else
@@ -978,10 +1064,10 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
}
///
- /// *RESERVED FOR PARTNERS* Request JWT Application Token
+ /// *RESERVED FOR PARTNERS* RequestJWTApplicationToken
///
- /// DocuSign OAuth Client Id(AKA Integrator Key)
- /// DocuSign OAuth base path
+ /// Docusign OAuth Client Id(AKA Integrator Key)
+ /// Docusign OAuth base path
///
///
///
@@ -992,6 +1078,27 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
///
/// The JWT application token
public OAuth.OAuthToken RequestJWTApplicationToken(string clientId, string oauthBasePath, byte[] privateKeyBytes, int expiresInHours, List scopes = null)
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ return TryCatchWrapper(() => RequestJWTApplicationTokenAsync(clientId, oAuthBasePath, privateKeyBytes, expiresInHours, scopes, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
+ }
+
+ ///
+ /// *RESERVED FOR PARTNERS* RequestJWTApplicationTokenAsync
+ ///
+ /// Docusign OAuth Client Id(AKA Integrator Key)
+ /// Docusign OAuth base path
+ ///
+ ///
+ ///
+ /// The byte contents of the RSA private key
+ /// Number of hours remaining before the JWT assertion is considered as invalid
+ /// Optional. The list of requested scopes may include (but not limited to) You can also pass any advanced scope.
+ /// A CancellationToken which can be used to propagate notification that operations should be canceled.
+ ///
+ ///
+ /// The JWT application token
+ public async Task RequestJWTApplicationTokenAsync(string clientId, string oauthBasePath, byte[] privateKeyBytes, int expiresInHours, List scopes = null, CancellationToken cancellationToken = default)
{
string privateKey = Encoding.UTF8.GetString(privateKeyBytes);
@@ -1029,19 +1136,12 @@ public OAuth.OAuthToken RequestJWTApplicationToken(string clientId, string oauth
};
DocuSignRequest request = PrepareOAuthRequest(oauthBasePath, $"oauth/token", HttpMethod.Post, Configuration.DefaultHeader?.ToList(), localVarFormParams.ToList());
- DocuSignResponse response = RestClient.SendRequest(request);
+ DocuSignResponse response = await RestClient.SendRequestAsync(request, cancellationToken);
if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode < HttpStatusCode.BadRequest)
{
OAuth.OAuthToken tokenInfo = JsonConvert.DeserializeObject(response.Content);
- if (!this.Configuration.DefaultHeader.ContainsKey("Authorization"))
- {
- this.Configuration.DefaultHeader.Add("Authorization", string.Format("{0} {1}", tokenInfo.token_type, tokenInfo.access_token));
- }
- else
- {
- this.Configuration.DefaultHeader["Authorization"] = string.Format("{0} {1}", tokenInfo.token_type, tokenInfo.access_token);
- }
+ this.Configuration.DefaultHeader["Authorization"] = string.Format("{0} {1}", tokenInfo.token_type, tokenInfo.access_token);
return tokenInfo;
}
else
diff --git a/sdk/src/DocuSign.eSign/DocuSign.eSign.csproj b/sdk/src/DocuSign.eSign/DocuSign.eSign.csproj
index c23d11cbe..d00929b19 100644
--- a/sdk/src/DocuSign.eSign/DocuSign.eSign.csproj
+++ b/sdk/src/DocuSign.eSign/DocuSign.eSign.csproj
@@ -7,7 +7,7 @@
The Docusign NuGet package makes integrating Docusign into your apps and websites a super fast and painless process. The library is open sourced on GitHub, look for the docusign-esign-csharp-client repository. Join the eSign revolution!
DocuSign Inc.
DocuSign
- Copyright © DocuSign 2024
+ Copyright © Docusign 2024
DocuSign.eSign
DocuSign
Library
@@ -16,17 +16,17 @@
DocuSign.eSign
DocuSign.eSign
en-US
- 8.0.0-rc1
+ 8.0.0-rc2
true
true
- DocuSign.eSign;REST;eSign;docusign;eSignature;api
- https://s.gravatar.com/avatar/4a8c033df6baa902f730d514d5574c33
- https://github.com/docusign/docusign-csharp-client
- https://github.com/docusign/docusign-csharp-client/blob/master/LICENSE
- https://github.com/docusign/docusign-csharp-client
+ Docusign.eSign;REST;eSign;docusign;eSignature;api
+ icon.png
+ https://github.com/docusign/docusign-esign-csharp-client
+ https://github.com/docusign/docusign-esign-csharp-client/blob/master/LICENSE
+ https://github.com/docusign/docusign-esign-csharp-client
git
- [v8.0.0-rc1] - ESignature API v2.1-24.2.00.00 - 7/2/2024
+ [v8.0.0-rc2] - ESignature API v2.1-24.2.00.00 - 7/23/2024
NET462
diff --git a/sdk/src/DocuSign.eSign/Properties/AssemblyInfo.cs b/sdk/src/DocuSign.eSign/Properties/AssemblyInfo.cs
index 28b6e24dc..00080a37b 100644
--- a/sdk/src/DocuSign.eSign/Properties/AssemblyInfo.cs
+++ b/sdk/src/DocuSign.eSign/Properties/AssemblyInfo.cs
@@ -22,5 +22,5 @@
// [assembly: AssemblyVersion("1.0.*")]
internal class AssemblyInformation
{
- public const string AssemblyInformationalVersion = "8.0.0-rc1";
+ public const string AssemblyInformationalVersion = "8.0.0-rc2";
}
\ No newline at end of file
diff --git a/sdk/src/DocuSign.eSign/icon.png b/sdk/src/DocuSign.eSign/icon.png
new file mode 100644
index 000000000..739fd6acf
Binary files /dev/null and b/sdk/src/DocuSign.eSign/icon.png differ