diff --git a/src/WalletFramework.Oid4Vc/Oid4Vci/Implementations/SdJwtRecordExtensions.cs b/src/WalletFramework.Oid4Vc/Oid4Vci/Implementations/SdJwtRecordExtensions.cs index 52ed4bd4..7ab8843b 100644 --- a/src/WalletFramework.Oid4Vc/Oid4Vci/Implementations/SdJwtRecordExtensions.cs +++ b/src/WalletFramework.Oid4Vc/Oid4Vci/Implementations/SdJwtRecordExtensions.cs @@ -1,10 +1,12 @@ using System.Drawing; +using Microsoft.IdentityModel.Tokens; using SD_JWT.Models; using WalletFramework.Core.Cryptography.Models; using WalletFramework.Core.Functional; using WalletFramework.Oid4Vc.Oid4Vci.CredConfiguration.Models.SdJwt; using WalletFramework.Oid4Vc.Oid4Vci.Issuer.Models; using WalletFramework.SdJwtVc.Models.Credential; +using WalletFramework.SdJwtVc.Models.Credential.Attributes; using WalletFramework.SdJwtVc.Models.Records; namespace WalletFramework.Oid4Vc.Oid4Vci.Implementations; @@ -19,9 +21,22 @@ public static SdJwtRecord ToRecord( { var claims = configuration .Claims? - .Select(pair => (pair.Key, pair.Value)) - .ToDictionary(pair => pair.Key, pair => pair.Value); + .SelectMany(claimMetadata => + { + var claimMetadatas = new Dictionary { { claimMetadata.Key, claimMetadata.Value } }; + if (!claimMetadata.Value.NestedClaims.IsNullOrEmpty()) + { + foreach (var nested in claimMetadata.Value.NestedClaims!) + { + claimMetadatas.Add(claimMetadata.Key + "." + nested.Key, nested.Value?.ToObject()!); + } + } + + return claimMetadatas; + }) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + var display = configuration .CredentialConfiguration .Display @@ -52,7 +67,7 @@ public static SdJwtRecord ToRecord( .ToDictionary( issuerDisplay => issuerDisplay.Locale.ToNullable()?.ToString(), issuerDisplay => issuerDisplay.Name.ToNullable()?.ToString()); - + var record = new SdJwtRecord( sdJwtDoc, claims!, diff --git a/src/WalletFramework.Oid4Vc/Oid4Vci/Models/Metadata/Credential/Attributes/OidClaim.cs b/src/WalletFramework.Oid4Vc/Oid4Vci/Models/Metadata/Credential/Attributes/OidClaim.cs index b39b5146..4f93eda4 100644 --- a/src/WalletFramework.Oid4Vc/Oid4Vci/Models/Metadata/Credential/Attributes/OidClaim.cs +++ b/src/WalletFramework.Oid4Vc/Oid4Vci/Models/Metadata/Credential/Attributes/OidClaim.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace WalletFramework.Oid4Vc.Oid4Vci.Models.Metadata.Credential.Attributes; @@ -30,4 +31,8 @@ public class OidClaim /// [JsonProperty("mandatory", NullValueHandling = NullValueHandling.Ignore)] public string? Mandatory { get; set; } -} \ No newline at end of file + + [JsonProperty("nested_claims", NullValueHandling = NullValueHandling.Ignore)] + [JsonExtensionData] + public Dictionary? NestedClaims { get; set; } +} diff --git a/src/WalletFramework.SdJwtVc/Models/Credential/Attributes/ClaimMetadata.cs b/src/WalletFramework.SdJwtVc/Models/Credential/Attributes/ClaimMetadata.cs index 4845b9a6..062afc7b 100644 --- a/src/WalletFramework.SdJwtVc/Models/Credential/Attributes/ClaimMetadata.cs +++ b/src/WalletFramework.SdJwtVc/Models/Credential/Attributes/ClaimMetadata.cs @@ -1,34 +1,38 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; -namespace WalletFramework.SdJwtVc.Models.Credential.Attributes -{ +namespace WalletFramework.SdJwtVc.Models.Credential.Attributes; + +/// +/// Represents the specifics about a claim. +/// +public class ClaimMetadata { /// - /// Represents the specifics about a claim. + /// Gets or sets the list of display properties associated with a specific credential attribute. /// - public class ClaimMetadata - { - /// - /// Gets or sets the list of display properties associated with a specific credential attribute. - /// - /// - /// The list of display properties. Each display property provides information on how the credential attribute should - /// be displayed. - /// - [JsonProperty("display", NullValueHandling = NullValueHandling.Ignore)] - public List? Display { get; set; } + /// + /// The list of display properties. Each display property provides information on how the credential attribute should + /// be displayed. + /// + [JsonProperty("display", NullValueHandling = NullValueHandling.Ignore)] + public List? Display { get; set; } - /// - /// String value determining type of value of the claim. A non-exhaustive list of valid values defined by this - /// specification are string, number, and image media types such as image/jpeg. - /// - [JsonProperty("value_type", NullValueHandling = NullValueHandling.Ignore)] - public string? ValueType { get; set; } - - /// - /// String value determining type of value of the claim. A non-exhaustive list of valid values defined by this - /// specification are string, number, and image media types such as image/jpeg. - /// - [JsonProperty("mandatory", NullValueHandling = NullValueHandling.Ignore)] - public string? Mandatory { get; set; } - } + /// + /// String value determining type of value of the claim. A non-exhaustive list of valid values defined by this + /// specification are string, number, and image media types such as image/jpeg. + /// + [JsonProperty("value_type", NullValueHandling = NullValueHandling.Ignore)] + public string? ValueType { get; set; } + + /// + /// String value determining type of value of the claim. A non-exhaustive list of valid values defined by this + /// specification are string, number, and image media types such as image/jpeg. + /// + [JsonProperty("mandatory", NullValueHandling = NullValueHandling.Ignore)] + public string? Mandatory { get; set; } + + [JsonProperty("nested_claims", NullValueHandling = NullValueHandling.Ignore)] + [JsonExtensionData] + public Dictionary? NestedClaims { get; set; } } +