diff --git a/EnvelopeGenerator.Common/Constants.vb b/EnvelopeGenerator.Common/Constants.vb
index 487a8a7a..d47d5bce 100644
--- a/EnvelopeGenerator.Common/Constants.vb
+++ b/EnvelopeGenerator.Common/Constants.vb
@@ -99,6 +99,12 @@
DocumentShared
End Enum
+ Public Enum EncodeType
+ EnvelopeReceiver
+ EnvelopeReceiverReadOnly
+ Undefined
+ End Enum
+
#End Region
#Region "Constants"
diff --git a/EnvelopeGenerator.Extensions/DecodingExtensions.cs b/EnvelopeGenerator.Extensions/DecodingExtensions.cs
new file mode 100644
index 00000000..1fa41809
--- /dev/null
+++ b/EnvelopeGenerator.Extensions/DecodingExtensions.cs
@@ -0,0 +1,148 @@
+using System.Text;
+using static EnvelopeGenerator.Common.Constants;
+
+namespace EnvelopeGenerator.Extensions
+{
+ public static class DecodingExtensions
+ {
+ ///
+ /// Validates whether a given string is a correctly formatted Base-64 encoded string.
+ ///
+ ///
+ /// This method checks the string for proper Base-64 formatting, which includes validating
+ /// the length of the string (must be divisible by 4). It also checks each character to ensure
+ /// it belongs to the Base-64 character set (A-Z, a-z, 0-9, '+', '/', and '=' for padding).
+ /// The method ensures that padding characters ('=') only appear at the end of the string and
+ /// are in a valid configuration (either one '=' at the end if the string's length % 4 is 3,
+ /// or two '==' if the length % 4 is 2).
+ ///
+ /// The Base-64 encoded string to validate.
+ ///
+ /// true if the string is a valid Base-64 encoded string; otherwise, false.
+ ///
+ ///
+ ///
+ /// string testString = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnk=";
+ /// bool isValid = IsValidBase64String(testString);
+ /// Console.WriteLine(isValid); // Output: true
+ ///
+ ///
+ public static bool IsBase64String(this string input)
+ {
+ // Check if the string is null or empty
+ if (string.IsNullOrEmpty(input))
+ {
+ return false;
+ }
+
+ // Replace valid base-64 padding
+ input = input.Trim();
+ int mod4 = input.Length % 4;
+ if (mod4 > 0)
+ {
+ // Base-64 string lengths should be divisible by 4
+ return false;
+ }
+
+ // Check each character to ensure it is valid base-64
+ foreach (char c in input)
+ {
+ if (!char.IsLetterOrDigit(c) && c != '+' && c != '/' && c != '=')
+ {
+ // Invalid character detected
+ return false;
+ }
+ }
+
+ // Ensure no invalid padding scenarios exist
+ if (input.EndsWith("==") && (input.Length % 4 == 0) ||
+ input.EndsWith("=") && (input.Length % 4 == 3))
+ {
+ return true;
+ }
+
+ return input.IndexOf('=') == -1; // No padding allowed except at the end
+ }
+
+ public static bool TryDecode(this string encoded, out string[] decoded)
+ {
+ if (!encoded.IsBase64String())
+ {
+ decoded = Array.Empty();
+ return false;
+ }
+ byte[] bytes = Convert.FromBase64String(encoded);
+ string decodedString = Encoding.UTF8.GetString(bytes);
+ decoded = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
+ return true;
+ }
+
+ public static EncodeType GetEncodeType(this string[] decoded) => decoded.Length switch
+ {
+ 2 => EncodeType.EnvelopeReceiver,
+ 3 => long.TryParse(decoded[1], out var _) ? EncodeType.EnvelopeReceiverReadOnly : EncodeType.Undefined,
+ _ => EncodeType.Undefined,
+ };
+
+ public static (string? EnvelopeUuid, string? ReceiverSignature) ToEnvelopeReceiverId(this string[] decoded)
+ => decoded.GetEncodeType() == EncodeType.EnvelopeReceiver
+ ? (EnvelopeUuid: decoded[0], ReceiverSignature: decoded[1])
+ : throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. ");
+
+ public static long ToReadOnlyId(this string[] decoded)
+ => decoded.GetEncodeType() == EncodeType.EnvelopeReceiverReadOnly
+ ? long.Parse(decoded[1])
+ : throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. ");
+
+ ///
+ /// Decodes the envelope receiver ID and extracts the envelope UUID and receiver signature.
+ ///
+ /// The base64 encoded string containing the envelope UUID and receiver signature.
+ /// A tuple containing the envelope UUID and receiver signature.
+ public static (string? EnvelopeUuid, string? ReceiverSignature) DecodeEnvelopeReceiverId(this string envelopeReceiverId)
+ {
+ if (!envelopeReceiverId.IsBase64String())
+ {
+ return (null, null);
+ }
+ byte[] bytes = Convert.FromBase64String(envelopeReceiverId);
+ string decodedString = Encoding.UTF8.GetString(bytes);
+ string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
+
+ if (parts.Length > 1)
+ return (EnvelopeUuid: parts[0], ReceiverSignature: parts[1]);
+ else
+ return (string.Empty, string.Empty);
+ }
+
+ public static long? DecodeEnvelopeReceiverReadOnlyId(this string envelopeReceiverReadOnlyId)
+ {
+ if (!envelopeReceiverReadOnlyId.IsBase64String())
+ {
+ return null;
+ }
+ byte[] bytes = Convert.FromBase64String(envelopeReceiverReadOnlyId);
+ string decodedString = System.Text.Encoding.UTF8.GetString(bytes);
+ string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
+
+ if (parts.Length > 2)
+ return long.TryParse(parts[1], out long readOnlyId) ? readOnlyId : null;
+ else
+ return null;
+ }
+
+ ///
+ /// Gets the envelope UUID from the decoded envelope receiver ID.
+ ///
+ /// The base64 encoded string to decode.
+ /// The envelope UUID.
+ public static string? GetEnvelopeUuid(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().EnvelopeUuid;
+
+ ///
+ /// Gets the receiver signature from the decoded envelope receiver ID.
+ ///
+ /// The base64 encoded string to decode.
+ /// The receiver signature.
+ public static string? GetReceiverSignature(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().ReceiverSignature;
+ }
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.Extensions/EncodeType.cs b/EnvelopeGenerator.Extensions/EncodeType.cs
deleted file mode 100644
index 41c706a7..00000000
--- a/EnvelopeGenerator.Extensions/EncodeType.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace EnvelopeGenerator.Extensions
-{
- public enum EncodeType
- {
- EnvelopeReceiver,
- ReadOnly,
- Undefined
- }
-}
\ No newline at end of file
diff --git a/EnvelopeGenerator.Extensions/EncodingExtensions.cs b/EnvelopeGenerator.Extensions/EncodingExtensions.cs
index f35c07d5..f2e0a1f8 100644
--- a/EnvelopeGenerator.Extensions/EncodingExtensions.cs
+++ b/EnvelopeGenerator.Extensions/EncodingExtensions.cs
@@ -8,155 +8,6 @@ namespace EnvelopeGenerator.Extensions
///
public static class EncodingExtensions
{
- ///
- /// Validates whether a given string is a correctly formatted Base-64 encoded string.
- ///
- ///
- /// This method checks the string for proper Base-64 formatting, which includes validating
- /// the length of the string (must be divisible by 4). It also checks each character to ensure
- /// it belongs to the Base-64 character set (A-Z, a-z, 0-9, '+', '/', and '=' for padding).
- /// The method ensures that padding characters ('=') only appear at the end of the string and
- /// are in a valid configuration (either one '=' at the end if the string's length % 4 is 3,
- /// or two '==' if the length % 4 is 2).
- ///
- /// The Base-64 encoded string to validate.
- ///
- /// true if the string is a valid Base-64 encoded string; otherwise, false.
- ///
- ///
- ///
- /// string testString = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnk=";
- /// bool isValid = IsValidBase64String(testString);
- /// Console.WriteLine(isValid); // Output: true
- ///
- ///
- public static bool IsBase64String(this string input)
- {
- // Check if the string is null or empty
- if (string.IsNullOrEmpty(input))
- {
- return false;
- }
-
- // Replace valid base-64 padding
- input = input.Trim();
- int mod4 = input.Length % 4;
- if (mod4 > 0)
- {
- // Base-64 string lengths should be divisible by 4
- return false;
- }
-
- // Check each character to ensure it is valid base-64
- foreach (char c in input)
- {
- if (!char.IsLetterOrDigit(c) && c != '+' && c != '/' && c != '=')
- {
- // Invalid character detected
- return false;
- }
- }
-
- // Ensure no invalid padding scenarios exist
- if (input.EndsWith("==") && (input.Length % 4 == 0) ||
- input.EndsWith("=") && (input.Length % 4 == 3))
- {
- return true;
- }
-
- return input.IndexOf('=') == -1; // No padding allowed except at the end
- }
-
- public static bool TryDecode(this string encoded, out string[] decoded)
- {
- if (!encoded.IsBase64String())
- {
- decoded = Array.Empty();
- return false;
- }
- byte[] bytes = Convert.FromBase64String(encoded);
- string decodedString = Encoding.UTF8.GetString(bytes);
- decoded = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
- return true;
- }
-
- public static EncodeType GetEncodeType(this string[] decoded) => decoded.Length switch
- {
- 2 => EncodeType.EnvelopeReceiver,
- 3 => long.TryParse(decoded[1], out var _) ? EncodeType.ReadOnly : EncodeType.Undefined,
- _ => EncodeType.Undefined,
- };
-
- public static (string? EnvelopeUuid, string? ReceiverSignature) ToEnvelopeReceiverId(this string[] decoded)
- => decoded.GetEncodeType() == EncodeType.EnvelopeReceiver
- ? (EnvelopeUuid: decoded[0], ReceiverSignature: decoded[1])
- : throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. ");
-
- public static long ToReadOnlyId(this string[] decoded)
- => decoded.GetEncodeType() == EncodeType.ReadOnly
- ? long.Parse(decoded[1])
- : throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. ");
-
- ///
- /// Decodes the envelope receiver ID and extracts the envelope UUID and receiver signature.
- ///
- /// The base64 encoded string containing the envelope UUID and receiver signature.
- /// A tuple containing the envelope UUID and receiver signature.
- public static (string? EnvelopeUuid, string? ReceiverSignature) DecodeEnvelopeReceiverId(this string envelopeReceiverId)
- {
- if (!envelopeReceiverId.IsBase64String())
- {
- return (null, null);
- }
- byte[] bytes = Convert.FromBase64String(envelopeReceiverId);
- string decodedString = Encoding.UTF8.GetString(bytes);
- string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
-
- if (parts.Length > 1)
- return (EnvelopeUuid: parts[0], ReceiverSignature: parts[1]);
- else
- return (string.Empty, string.Empty);
- }
-
- public static long? DecodeEnvelopeReceiverReadOnlyId(this string envelopeReceiverReadOnlyId)
- {
- if (!envelopeReceiverReadOnlyId.IsBase64String())
- {
- return null;
- }
- byte[] bytes = Convert.FromBase64String(envelopeReceiverReadOnlyId);
- string decodedString = System.Text.Encoding.UTF8.GetString(bytes);
- string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
-
- if (parts.Length > 2)
- return long.TryParse(parts[1], out long readOnlyId) ? readOnlyId : null;
- else
- return null;
- }
-
- ///
- /// Gets the envelope UUID from the decoded envelope receiver ID.
- ///
- /// The base64 encoded string to decode.
- /// The envelope UUID.
- public static string? GetEnvelopeUuid(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().EnvelopeUuid;
-
- ///
- /// Gets the receiver signature from the decoded envelope receiver ID.
- ///
- /// The base64 encoded string to decode.
- /// The receiver signature.
- public static string? GetReceiverSignature(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().ReceiverSignature;
-
- public static string EncodeEnvelopeReceiverId(this (string envelopeUuid, string receiverSignature) input)
- {
- string combinedString = $"{input.envelopeUuid}::{input.receiverSignature}";
- byte[] bytes = Encoding.UTF8.GetBytes(combinedString);
- string base64String = Convert.ToBase64String(bytes);
-
- return base64String;
- }
-
public static string EncodeEnvelopeReceiverId(this long readOnlyId)
{
string combinedString = $"{Random.Shared.Next()}::{readOnlyId}::{Random.Shared.Next()}";
@@ -166,38 +17,13 @@ namespace EnvelopeGenerator.Extensions
return base64String;
}
- public static void LogEnvelopeError(this ILogger logger, string envelopeReceiverId, Exception? exception = null, string? message = null, params object?[] args)
+ public static string EncodeEnvelopeReceiverId(this (string envelopeUuid, string receiverSignature) input)
{
- var sb = new StringBuilder().AppendLine(envelopeReceiverId.DecodeEnvelopeReceiverId().ToTitle());
+ string combinedString = $"{input.envelopeUuid}::{input.receiverSignature}";
+ byte[] bytes = Encoding.UTF8.GetBytes(combinedString);
+ string base64String = Convert.ToBase64String(bytes);
- if (message is not null)
- sb.AppendLine(message);
-
- if(exception is null)
- logger.Log(LogLevel.Error, sb.ToString(), args);
- else
- logger.Log(LogLevel.Error, exception, sb.AppendLine(exception.Message).ToString(), args);
- }
-
- public static void LogEnvelopeError(this ILogger logger, string? uuid, string? signature = null, Exception? exception = null, string? message = null, params object?[] args)
- {
- var sb = new StringBuilder($"Envelope Uuid: {uuid}");
-
- if(signature is not null)
- sb.AppendLine().Append($"Receiver Signature: {signature}");
-
- if (message is not null)
- sb.AppendLine().Append(message);
-
- if (exception is null)
- logger.Log(LogLevel.Error, sb.ToString(), args);
- else
- logger.Log(LogLevel.Error, exception, sb.ToString(), args);
- }
-
- public static string ToTitle(this (string? UUID, string? Signature) envelopeReceiverTuple)
- {
- return $"UUID is {envelopeReceiverTuple.UUID} and signature is {envelopeReceiverTuple.Signature}";
+ return base64String;
}
}
}
\ No newline at end of file
diff --git a/EnvelopeGenerator.Extensions/EnvelopeGenerator.Extensions.csproj b/EnvelopeGenerator.Extensions/EnvelopeGenerator.Extensions.csproj
index 2f15281d..8467bc11 100644
--- a/EnvelopeGenerator.Extensions/EnvelopeGenerator.Extensions.csproj
+++ b/EnvelopeGenerator.Extensions/EnvelopeGenerator.Extensions.csproj
@@ -7,7 +7,13 @@
+
+
+
+
+
+
diff --git a/EnvelopeGenerator.Extensions/LoggerExtensions.cs b/EnvelopeGenerator.Extensions/LoggerExtensions.cs
new file mode 100644
index 00000000..b1c56974
--- /dev/null
+++ b/EnvelopeGenerator.Extensions/LoggerExtensions.cs
@@ -0,0 +1,42 @@
+using Microsoft.Extensions.Logging;
+using System.Text;
+
+namespace EnvelopeGenerator.Extensions
+{
+ public static class LoggerExtensions
+ {
+ public static void LogEnvelopeError(this ILogger logger, string envelopeReceiverId, Exception? exception = null, string? message = null, params object?[] args)
+ {
+ var sb = new StringBuilder().AppendLine(envelopeReceiverId.DecodeEnvelopeReceiverId().ToTitle());
+
+ if (message is not null)
+ sb.AppendLine(message);
+
+ if (exception is null)
+ logger.Log(LogLevel.Error, sb.ToString(), args);
+ else
+ logger.Log(LogLevel.Error, exception, sb.AppendLine(exception.Message).ToString(), args);
+ }
+
+ public static void LogEnvelopeError(this ILogger logger, string? uuid, string? signature = null, Exception? exception = null, string? message = null, params object?[] args)
+ {
+ var sb = new StringBuilder($"Envelope Uuid: {uuid}");
+
+ if (signature is not null)
+ sb.AppendLine().Append($"Receiver Signature: {signature}");
+
+ if (message is not null)
+ sb.AppendLine().Append(message);
+
+ if (exception is null)
+ logger.Log(LogLevel.Error, sb.ToString(), args);
+ else
+ logger.Log(LogLevel.Error, exception, sb.ToString(), args);
+ }
+
+ public static string ToTitle(this (string? UUID, string? Signature) envelopeReceiverTuple)
+ {
+ return $"UUID is {envelopeReceiverTuple.UUID} and signature is {envelopeReceiverTuple.Signature}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.Web/XSSExtensions.cs b/EnvelopeGenerator.Extensions/XSSExtensions.cs
similarity index 94%
rename from EnvelopeGenerator.Web/XSSExtensions.cs
rename to EnvelopeGenerator.Extensions/XSSExtensions.cs
index 9b414fd6..3649df9d 100644
--- a/EnvelopeGenerator.Web/XSSExtensions.cs
+++ b/EnvelopeGenerator.Extensions/XSSExtensions.cs
@@ -2,7 +2,7 @@
using Microsoft.Extensions.Localization;
using System.Text.Encodings.Web;
-namespace EnvelopeGenerator.Web
+namespace EnvelopeGenerator.Extensions
{
public static class XSSExtensions
{
diff --git a/EnvelopeGenerator.Web/Controllers/HomeController.cs b/EnvelopeGenerator.Web/Controllers/HomeController.cs
index b987067d..3cedf1ac 100644
--- a/EnvelopeGenerator.Web/Controllers/HomeController.cs
+++ b/EnvelopeGenerator.Web/Controllers/HomeController.cs
@@ -17,6 +17,7 @@ using EnvelopeGenerator.Application.Resources;
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
using EnvelopeGenerator.Domain.Entities;
using System.Text.RegularExpressions;
+using static EnvelopeGenerator.Common.Constants;
namespace EnvelopeGenerator.Web.Controllers
{
@@ -60,7 +61,7 @@ namespace EnvelopeGenerator.Web.Controllers
return this.ViewDocumentNotFound();
}
- if(decoded.GetEncodeType() == EncodeType.ReadOnly)
+ if(decoded.GetEncodeType() == EncodeType.EnvelopeReceiverReadOnly)
return Redirect($"{envelopeReceiverId}/ReadOnly");
ViewData["EnvelopeKey"] = envelopeReceiverId;
diff --git a/EnvelopeGenerator.Web/Views/_ViewImports.cshtml b/EnvelopeGenerator.Web/Views/_ViewImports.cshtml
index 1e3c2c8f..5a19cc58 100644
--- a/EnvelopeGenerator.Web/Views/_ViewImports.cshtml
+++ b/EnvelopeGenerator.Web/Views/_ViewImports.cshtml
@@ -1,6 +1,7 @@
@using EnvelopeGenerator.Web
@using EnvelopeGenerator.Web.Models
@using EnvelopeGenerator.Web.Sanitizers
+@using EnvelopeGenerator.Extensions
@using Microsoft.Extensions.Localization
@using EnvelopeGenerator.Application.Resources
@using Microsoft.Extensions.Options