|
7 | 7 | using Bit.Core.Vault.Entities;
|
8 | 8 | using Bit.Core.Vault.Enums;
|
9 | 9 | using Bit.Core.Vault.Models.Data;
|
10 |
| -using NS = Newtonsoft.Json; |
11 |
| -using NSL = Newtonsoft.Json.Linq; |
12 | 10 |
|
13 | 11 | namespace Bit.Api.Vault.Models.Request;
|
14 | 12 |
|
@@ -40,11 +38,26 @@ public class CipherRequestModel
|
40 | 38 | // TODO: Rename to Attachments whenever the above is finally removed.
|
41 | 39 | public Dictionary<string, CipherAttachmentModel> Attachments2 { get; set; }
|
42 | 40 |
|
| 41 | + [Obsolete("Use Data instead.")] |
43 | 42 | public CipherLoginModel Login { get; set; }
|
| 43 | + |
| 44 | + [Obsolete("Use Data instead.")] |
44 | 45 | public CipherCardModel Card { get; set; }
|
| 46 | + |
| 47 | + [Obsolete("Use Data instead.")] |
45 | 48 | public CipherIdentityModel Identity { get; set; }
|
| 49 | + |
| 50 | + [Obsolete("Use Data instead.")] |
46 | 51 | public CipherSecureNoteModel SecureNote { get; set; }
|
| 52 | + |
| 53 | + [Obsolete("Use Data instead.")] |
47 | 54 | public CipherSSHKeyModel SSHKey { get; set; }
|
| 55 | + |
| 56 | + /// <summary> |
| 57 | + /// JSON string containing cipher-specific data |
| 58 | + /// </summary> |
| 59 | + [StringLength(500000)] |
| 60 | + public string Data { get; set; } |
48 | 61 | public DateTime? LastKnownRevisionDate { get; set; } = null;
|
49 | 62 | public DateTime? ArchivedDate { get; set; }
|
50 | 63 |
|
@@ -73,29 +86,42 @@ public CipherDetails ToCipherDetails(CipherDetails existingCipher)
|
73 | 86 |
|
74 | 87 | public Cipher ToCipher(Cipher existingCipher)
|
75 | 88 | {
|
76 |
| - switch (existingCipher.Type) |
| 89 | + // If Data field is provided, use it directly |
| 90 | + if (!string.IsNullOrWhiteSpace(Data)) |
| 91 | + { |
| 92 | + existingCipher.Data = Data; |
| 93 | + } |
| 94 | + else |
77 | 95 | {
|
78 |
| - case CipherType.Login: |
79 |
| - var loginObj = NSL.JObject.FromObject(ToCipherLoginData(), |
80 |
| - new NS.JsonSerializer { NullValueHandling = NS.NullValueHandling.Ignore }); |
81 |
| - // TODO: Switch to JsonNode in .NET 6 https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-use-dom-utf8jsonreader-utf8jsonwriter?pivots=dotnet-6-0 |
82 |
| - loginObj[nameof(CipherLoginData.Uri)]?.Parent?.Remove(); |
83 |
| - existingCipher.Data = loginObj.ToString(NS.Formatting.None); |
84 |
| - break; |
85 |
| - case CipherType.Card: |
86 |
| - existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull); |
87 |
| - break; |
88 |
| - case CipherType.Identity: |
89 |
| - existingCipher.Data = JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull); |
90 |
| - break; |
91 |
| - case CipherType.SecureNote: |
92 |
| - existingCipher.Data = JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull); |
93 |
| - break; |
94 |
| - case CipherType.SSHKey: |
95 |
| - existingCipher.Data = JsonSerializer.Serialize(ToCipherSSHKeyData(), JsonHelpers.IgnoreWritingNull); |
96 |
| - break; |
97 |
| - default: |
98 |
| - throw new ArgumentException("Unsupported type: " + nameof(Type) + "."); |
| 96 | + // Fallback to structured fields |
| 97 | + switch (existingCipher.Type) |
| 98 | + { |
| 99 | + case CipherType.Login: |
| 100 | + var loginData = ToCipherLoginData(); |
| 101 | + var loginJson = JsonSerializer.Serialize(loginData, JsonHelpers.IgnoreWritingNull); |
| 102 | + var loginObj = JsonDocument.Parse(loginJson); |
| 103 | + var loginDict = JsonSerializer.Deserialize<Dictionary<string, object>>(loginJson); |
| 104 | + loginDict?.Remove(nameof(CipherLoginData.Uri)); |
| 105 | + |
| 106 | + existingCipher.Data = JsonSerializer.Serialize(loginDict, JsonHelpers.IgnoreWritingNull); |
| 107 | + break; |
| 108 | + case CipherType.Card: |
| 109 | + existingCipher.Data = JsonSerializer.Serialize(ToCipherCardData(), JsonHelpers.IgnoreWritingNull); |
| 110 | + break; |
| 111 | + case CipherType.Identity: |
| 112 | + existingCipher.Data = |
| 113 | + JsonSerializer.Serialize(ToCipherIdentityData(), JsonHelpers.IgnoreWritingNull); |
| 114 | + break; |
| 115 | + case CipherType.SecureNote: |
| 116 | + existingCipher.Data = |
| 117 | + JsonSerializer.Serialize(ToCipherSecureNoteData(), JsonHelpers.IgnoreWritingNull); |
| 118 | + break; |
| 119 | + case CipherType.SSHKey: |
| 120 | + existingCipher.Data = JsonSerializer.Serialize(ToCipherSSHKeyData(), JsonHelpers.IgnoreWritingNull); |
| 121 | + break; |
| 122 | + default: |
| 123 | + throw new ArgumentException("Unsupported type: " + nameof(Type) + "."); |
| 124 | + } |
99 | 125 | }
|
100 | 126 |
|
101 | 127 | existingCipher.Reprompt = Reprompt;
|
|
0 commit comments