From 57f41ee7bc3ecd8086dfe2737e9c8936c9f0668b Mon Sep 17 00:00:00 2001 From: jaasen-livefront Date: Fri, 4 Apr 2025 14:04:34 -0700 Subject: [PATCH] fix serialization issues --- .../Services/Implementations/CipherService.cs | 78 +++++++++++++++---- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/src/Core/Vault/Services/Implementations/CipherService.cs b/src/Core/Vault/Services/Implementations/CipherService.cs index 7dd6250e5f..a89c7cf2d5 100644 --- a/src/Core/Vault/Services/Implementations/CipherService.cs +++ b/src/Core/Vault/Services/Implementations/CipherService.cs @@ -986,31 +986,75 @@ public class CipherService : ICipherService // Check if user is a "hidden password" user if (!cipherPermissions.TryGetValue(cipher.Id, out var permission) || !(permission.ViewPassword && permission.Edit)) { - var existingCipherData = JsonSerializer.Deserialize(existingCipher.Data); - var newCipherData = JsonSerializer.Deserialize(cipher.Data); + var existingCipherData = DeserializeCipherData(existingCipher); + var newCipherData = DeserializeCipherData(cipher); + // "hidden password" users may not add cipher key encryption if (existingCipher.Key == null && cipher.Key != null) { throw new BadRequestException("You do not have permission to add cipher key encryption."); } - if (newCipherData?.Fields != null) - { - // Keep only non-hidden fields from the new cipher - var nonHiddenFields = newCipherData.Fields.Where(f => f.Type != FieldType.Hidden).ToList(); - // Get hidden fields from the existing cipher - var hiddenFields = existingCipherData.Fields?.Where(f => f.Type == FieldType.Hidden) ?? []; - // Replace the hidden fields in new cipher data with the existing ones - newCipherData.Fields = nonHiddenFields.Concat(hiddenFields); - cipher.Data = JsonSerializer.Serialize(newCipherData); - } - if (cipher.Type == CipherType.Login) + // Keep only non-hidden fileds from the new cipher + var nonHiddenFields = newCipherData.Fields?.Where(f => f.Type != FieldType.Hidden) ?? []; + // Get hidden fields from the existing cipher + var hiddenFields = existingCipherData.Fields?.Where(f => f.Type == FieldType.Hidden) ?? []; + // Replace the hidden fields in new cipher data with the existing ones + newCipherData.Fields = nonHiddenFields.Concat(hiddenFields); + cipher.Data = SerializeCipherData(newCipherData); + if (existingCipherData is CipherLoginData existingLoginData && newCipherData is CipherLoginData newLoginCipherData) { // "hidden password" users may not change passwords, TOTP codes, or passkeys, so we need to set them back to the original values - newCipherData.Fido2Credentials = existingCipherData.Fido2Credentials; - newCipherData.Totp = existingCipherData.Totp; - newCipherData.Password = existingCipherData.Password; - cipher.Data = JsonSerializer.Serialize(newCipherData); + newLoginCipherData.Fido2Credentials = existingLoginData.Fido2Credentials; + newLoginCipherData.Totp = existingLoginData.Totp; + newLoginCipherData.Password = existingLoginData.Password; + cipher.Data = SerializeCipherData(newLoginCipherData); } } } + + private string SerializeCipherData(CipherData data) + { + if (data is CipherLoginData cipherLoginData) + { + return JsonSerializer.Serialize(cipherLoginData); + } + if (data is CipherIdentityData cipherIdentityData) + { + return JsonSerializer.Serialize(cipherIdentityData); + } + if (data is CipherCardData cipherCardData) + { + return JsonSerializer.Serialize(cipherCardData); + } + if (data is CipherSecureNoteData cipherSecureNoteData) + { + return JsonSerializer.Serialize(cipherSecureNoteData); + } + + return null; + } + + private CipherData DeserializeCipherData(Cipher cipher) + { + if (cipher.Type == CipherType.Login) + { + return JsonSerializer.Deserialize(cipher.Data); + } + + if (cipher.Type == CipherType.Identity) + { + return JsonSerializer.Deserialize(cipher.Data); + } + + if (cipher.Type == CipherType.Card) + { + return JsonSerializer.Deserialize(cipher.Data); + } + + if (cipher.Type == CipherType.SecureNote) + { + return JsonSerializer.Deserialize(cipher.Data); + } + return null; + } }