diff --git a/Fhi.HelseId/src/Fhi.HelseIdSelvbetjening.CLI/Commands/Extensions/CommandHandlerExtensions.cs b/Fhi.HelseId/src/Fhi.HelseIdSelvbetjening.CLI/Commands/Extensions/CommandHandlerExtensions.cs
index 508b35a..5439bf0 100644
--- a/Fhi.HelseId/src/Fhi.HelseIdSelvbetjening.CLI/Commands/Extensions/CommandHandlerExtensions.cs
+++ b/Fhi.HelseId/src/Fhi.HelseIdSelvbetjening.CLI/Commands/Extensions/CommandHandlerExtensions.cs
@@ -1,3 +1,4 @@
+using System.Text.Json;
using Fhi.HelseIdSelvbetjening.CLI.Services;
using Microsoft.Extensions.Logging;
@@ -25,7 +26,7 @@ public static string ResolveKeyValuePathOrString(
if (!string.IsNullOrWhiteSpace(directValue))
{
logger.LogInformation("{keyLabel} provided directly.", keyLabel);
- return directValue;
+ return UnescapeJson(directValue.Trim());
}
if (!string.IsNullOrWhiteSpace(filePath))
@@ -37,5 +38,21 @@ public static string ResolveKeyValuePathOrString(
logger.LogWarning("{keyLabel} not provided.", keyLabel);
return string.Empty;
}
+
+ ///
+ /// Unescapes JSON string escape sequences by deserializing the input as a JSON string value.
+ ///
+ ///
+ private static string UnescapeJson(string input)
+ {
+ try
+ {
+ return JsonSerializer.Deserialize($"\"{input}\"")!;
+ }
+ catch (JsonException)
+ {
+ return input;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Fhi.HelseId/tests/Fhi.HelseIdSelvbetjening.CLI.Tests/IntegrationTests/ReadClientSecretExpirationTests.cs b/Fhi.HelseId/tests/Fhi.HelseIdSelvbetjening.CLI.Tests/IntegrationTests/ReadClientSecretExpirationTests.cs
index 7de7093..de7c6c0 100644
--- a/Fhi.HelseId/tests/Fhi.HelseIdSelvbetjening.CLI.Tests/IntegrationTests/ReadClientSecretExpirationTests.cs
+++ b/Fhi.HelseId/tests/Fhi.HelseIdSelvbetjening.CLI.Tests/IntegrationTests/ReadClientSecretExpirationTests.cs
@@ -11,10 +11,19 @@ namespace Fhi.HelseIdSelvbetjening.CLI.IntegrationTests
{
public class ReadClientSecretExpirationTests
{
+ ///
+ /// Unicode escape sequence for the double quote character (").
+ /// The first JWKs from HelseId contained unicode escaped quotes.
+ ///
+ private const string UnicodeEscapedQuote = "\\u0022";
+
[TestCase("{\n \"kid\": \"test-kid\",\n \"kty\": \"RSA\",\n \"d\": \"test-d-value\",\n \"n\": \"test-n-value\",\n \"e\": \"AQAB\"\n}")]
[TestCase("{\"d\":\"test-kid\",\"e\":\"AQAB\",\"kid\":\"test-kid\",\"kty\":\"RSA\",\"n\":\"test-n-value\"}")]
[TestCase("{ \"kid\": \"test-kid\", \"kty\": \"RSA\", \"d\": \"test-data\", \"n\": \"test-modulus\", \"e\": \"AQAB\" }")]
- // [TestCase(@"{""kid"":""test-with-special-chars-!@#$%^&*()"",""d"":""data-with-quotes-\""and\""-backslashes-\\"",""n"":""modulus"",""e"":""AQAB""}")]
+ [TestCase(@"{""kid"":""test-kid"",""kty"":""RSA"",""d"":""test-with-special-chars-!@#$%^&*()"",""n"":""test-n-value"",""e"":""AQAB""}")]
+ [TestCase(@"{""kid"":""test-kid"",""kty"":""RSA"",""d"":""data-with-quotes-\""and\""-backslashes-\\"",""n"":""test-n-value"",""e"":""AQAB""}")]
+ [TestCase("{\\\"kid\\\":\\\"test-kid\\\",\\\"kty\\\":\\\"RSA\\\",\\\"d\\\":\\\"test-d-value\\\",\\\"n\\\":\\\"test-n-value\\\",\\\"e\\\":\\\"AQAB\\\"}")]
+ [TestCase("{" + UnicodeEscapedQuote + "kid" + UnicodeEscapedQuote + ":" + UnicodeEscapedQuote + "test-kid" + UnicodeEscapedQuote + "," + UnicodeEscapedQuote + "kty" + UnicodeEscapedQuote + ":" + UnicodeEscapedQuote + "RSA" + UnicodeEscapedQuote + "," + UnicodeEscapedQuote + "d" + UnicodeEscapedQuote + ":" + UnicodeEscapedQuote + "test-d-value" + UnicodeEscapedQuote + "," + UnicodeEscapedQuote + "n" + UnicodeEscapedQuote + ":" + UnicodeEscapedQuote + "test-n-value" + UnicodeEscapedQuote + "," + UnicodeEscapedQuote + "e" + UnicodeEscapedQuote + ":" + UnicodeEscapedQuote + "AQAB" + UnicodeEscapedQuote + "}")]
public async Task ReadClientSecretExpiration_ValidDirectJwkArgument_ExitCode0(string jwk)
{
var fakeLogProvider = new FakeLoggerProvider();
@@ -40,7 +49,7 @@ public async Task ReadClientSecretExpiration_ValidDirectJwkArgument_ExitCode0(st
using (Assert.EnterMultipleScope())
{
- Assert.That(exitCode, Is.EqualTo(0));
+ Assert.That(exitCode, Is.Zero);
Assert.That(fakeLogProvider.Collector?.LatestRecord.Message, Does.Contain(((DateTimeOffset)clientSecrets.FirstOrDefault()!.Expiration!).ToUnixTimeSeconds().ToString()));
var logs = fakeLogProvider.Collector?.GetSnapshot().Select(x => x.Message).ToList();
Assert.That(logs!, Does.Contain("Kid: test-kid"));