diff --git a/src/SocketLabs/InjectionApi/Core/ApiKeyParser.cs b/src/SocketLabs/InjectionApi/Core/ApiKeyParser.cs
new file mode 100644
index 0000000..d6a9edf
--- /dev/null
+++ b/src/SocketLabs/InjectionApi/Core/ApiKeyParser.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SocketLabs.InjectionApi.Core.Enum;
+using SocketLabs.InjectionApi.Core.Models;
+
+namespace SocketLabs.InjectionApi.Core
+{
+ ///
+ /// Parses a provided api key and provides a result
+ ///
+ public class ApiKeyParser : IApiKeyParser
+ {
+ ///
+ /// Parses the provided Api key.
+ ///
+ ///
+ /// An ApiKeyParseResult with the api key data and result code from the parse.
+ public ApiKeyParseResult Parse(string wholeApiKey)
+ {
+ var key = new ApiKey { IsValidFormat = false };
+ if (string.IsNullOrWhiteSpace(wholeApiKey))
+ return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidEmptyOrWhitespace };
+
+ //if (!wholeApiKey.StartsWith("SL.", StringComparison.InvariantCulture))
+ // return new ApiKeyParseResult {ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidMissingProperPrefix};
+
+ //extract public part
+ var maxCount = Math.Min(50, wholeApiKey.Length);
+ var publicPartEnd = wholeApiKey.IndexOf('.', startIndex: 0, maxCount); //don't check more than 50 chars
+ if (publicPartEnd == -1)
+ return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidUnableToExtractPublicPart };
+ var publicPart = wholeApiKey.Substring(0, publicPartEnd);
+
+
+ //now extract the private part
+ if (wholeApiKey.Length <= publicPartEnd + 1)
+ return new ApiKeyParseResult { ApiKey = null, ResultCode = ApiKeyParseResultCode.InvalidUnableToExtractSecretPart };
+ var privatePart = wholeApiKey.Substring(publicPartEnd + 1);
+
+ //success
+ return new ApiKeyParseResult
+ {
+ ApiKey = new ApiKey
+ {
+ PublicPart = publicPart,
+ PrivatePart = privatePart,
+ IsValidFormat = true,
+ },
+ ResultCode = ApiKeyParseResultCode.Success
+ };
+ }
+ }
+}
diff --git a/src/SocketLabs/InjectionApi/Core/Enum/ApiKeyParseResultCode.cs b/src/SocketLabs/InjectionApi/Core/Enum/ApiKeyParseResultCode.cs
new file mode 100644
index 0000000..aae2218
--- /dev/null
+++ b/src/SocketLabs/InjectionApi/Core/Enum/ApiKeyParseResultCode.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SocketLabs.InjectionApi.Core.Enum
+{
+ ///
+ /// A code describing the result of an attempt to parse an Api key.
+ ///
+ public enum ApiKeyParseResultCode
+ {
+
+ ///
+ /// No result could be produced.
+ ///
+ None,
+ ///
+ /// The key was found to be blank or invalid.
+ ///
+ InvalidEmptyOrWhitespace,
+ ///
+ /// The public portion of the key was unable to be parsed.
+ ///
+ InvalidUnableToExtractPublicPart,
+ ///
+ /// The secret portion of the key was unable to be parsed.
+ ///
+ InvalidUnableToExtractSecretPart,
+ ///
+ /// Key was successfully parsed.
+ ///
+ Success
+ }
+}
diff --git a/src/SocketLabs/InjectionApi/Core/IApiKeyParser.cs b/src/SocketLabs/InjectionApi/Core/IApiKeyParser.cs
new file mode 100644
index 0000000..64be894
--- /dev/null
+++ b/src/SocketLabs/InjectionApi/Core/IApiKeyParser.cs
@@ -0,0 +1,13 @@
+using SocketLabs.InjectionApi.Core.Enum;
+using SocketLabs.InjectionApi.Core.Models;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SocketLabs.InjectionApi.Core
+{
+ public interface IApiKeyParser
+ {
+ ApiKeyParseResult Parse(string wholeApiKey);
+ }
+}
diff --git a/src/SocketLabs/InjectionApi/Core/Models/ApiKey.cs b/src/SocketLabs/InjectionApi/Core/Models/ApiKey.cs
new file mode 100644
index 0000000..20b6dae
--- /dev/null
+++ b/src/SocketLabs/InjectionApi/Core/Models/ApiKey.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SocketLabs.InjectionApi.Core.Models
+{
+ ///
+ /// A class representing an Api Key
+ ///
+ public class ApiKey
+ {
+ ///
+ /// The public part of the Api Key.
+ ///
+ public string PublicPart { get; set; } = "";
+
+ ///
+ /// The private part of the Api Key
+ ///
+ public string PrivatePart { get; set; } = "";
+
+ ///
+ /// A boolean value describing the validity of the Api Key format
+ ///
+ public bool IsValidFormat { get; set; }
+ }
+}
diff --git a/src/SocketLabs/InjectionApi/Core/Models/ApiKeyParseResult.cs b/src/SocketLabs/InjectionApi/Core/Models/ApiKeyParseResult.cs
new file mode 100644
index 0000000..eec93bc
--- /dev/null
+++ b/src/SocketLabs/InjectionApi/Core/Models/ApiKeyParseResult.cs
@@ -0,0 +1,23 @@
+using SocketLabs.InjectionApi.Core.Enum;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SocketLabs.InjectionApi.Core.Models
+{
+ ///
+ /// The result of an Api Key Parse Attempt
+ ///
+ public class ApiKeyParseResult
+ {
+ ///
+ /// The object representing the parsed Api Key
+ ///
+ public ApiKey ApiKey { get; set; }
+
+ ///
+ /// A code describing the result of the attempt to parse the Api key.
+ ///
+ public ApiKeyParseResultCode ResultCode { get; set; }
+ }
+}
diff --git a/src/SocketLabs/InjectionApi/SocketLabsClient.cs b/src/SocketLabs/InjectionApi/SocketLabsClient.cs
index b3cda97..e46bcf1 100644
--- a/src/SocketLabs/InjectionApi/SocketLabsClient.cs
+++ b/src/SocketLabs/InjectionApi/SocketLabsClient.cs
@@ -1,11 +1,13 @@
using System;
using System.Net;
using System.Net.Http;
+using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
using SocketLabs.InjectionApi.Core;
+using SocketLabs.InjectionApi.Core.Enum;
using SocketLabs.InjectionApi.Message;
namespace SocketLabs.InjectionApi
@@ -35,8 +37,8 @@ public class SocketLabsClient : ISocketLabsClient, IDisposable
private string UserAgent { get; } = $"SocketLabs-csharp/{typeof(SocketLabsClient).GetTypeInfo().Assembly.GetName().Version}";
private readonly int _serverId;
- private readonly string _apiKey;
private readonly HttpClient _httpClient;
+ private string _apiKey;
///
@@ -228,6 +230,16 @@ public async Task SendAsync(IBasicMessage message, CancellationTok
validationResult = validator.ValidateMessage(message);
if (validationResult.Result != SendResult.Success) return validationResult;
+
+ var apiKeyParser = new ApiKeyParser();
+ var parseResult = apiKeyParser.Parse(_apiKey);
+
+ if (parseResult.ResultCode == ApiKeyParseResultCode.Success)
+ {
+ _httpClient.DefaultRequestHeaders.Authorization =
+ new AuthenticationHeaderValue("Bearer", _apiKey);
+ _apiKey = string.Empty;
+ }
var factory = new InjectionRequestFactory(_serverId, _apiKey);
var injectionRequest = factory.GenerateRequest(message);
@@ -282,6 +294,17 @@ public async Task SendAsync(IBulkMessage message, CancellationToke
validationResult = validator.ValidateMessage(message);
if (validationResult.Result != SendResult.Success) return validationResult;
+
+ var apiKeyParser = new ApiKeyParser();
+ var parseResult = apiKeyParser.Parse(_apiKey);
+
+ if (parseResult.ResultCode == ApiKeyParseResultCode.Success)
+ {
+ _httpClient.DefaultRequestHeaders.Authorization =
+ new AuthenticationHeaderValue("Bearer", _apiKey);
+ _apiKey = string.Empty;
+ }
+
var factory = new InjectionRequestFactory(_serverId, _apiKey);
var injectionRequest = factory.GenerateRequest(message);
var json = injectionRequest.GetAsJson();