mirror of
https://github.com/bitwarden/mobile
synced 2025-12-05 23:53:33 +00:00
* PM-1575 Added new models for Fido2Key
* PM-1575 Added discoverable passkeys and WIP non-discoverable ones
* PM-1575 Fix format
* PM-1575 Added non-discoverable passkeys to login UI
* PM-1575 Added copy application icon to Fido2Key UI
* PM-1575 Updated bwi font with the updated passkey icon
* PM-1575 For now just display Available for two-step login on non-discoverable passkey inside of a cipher login
* PM-1575 Fix non-discoverable passkey visibility
* PM-1575 remove Passkeys as a filter in the vault list
* PM-1575 Display error toast if there is a duplicate passkey when moving a cipher to an org
* Revert "PM-1575 Display error toast if there is a duplicate passkey when moving a cipher to an org"
This reverts commit 78e6353602.
* [PM-2378] Display error toast on duplicate Passkey when moving cipher to an organization (#2594)
* PM-2378 Display error toast if there is a duplicate passkey when moving a cipher to an org
* PM-3097 Fix issue when moving cipher with passkey to an org where the uniqueness should be taken into consideration on different passkeys types and also the Username (#2632)
* PM-3096 Fix non-discoverable passkey to be taken into account when encrypting a cipher which was causing the passkey to be removed when moving to an org (#2637)
217 lines
8.3 KiB
C#
217 lines
8.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Bit.Core.Enums;
|
|
using Bit.Core.Models.Data;
|
|
using Bit.Core.Models.View;
|
|
|
|
namespace Bit.Core.Models.Domain
|
|
{
|
|
public class Cipher : Domain
|
|
{
|
|
public Cipher() { }
|
|
|
|
public Cipher(CipherData obj, bool alreadyEncrypted = false, Dictionary<string, object> localData = null)
|
|
{
|
|
BuildDomainModel(this, obj, new HashSet<string>
|
|
{
|
|
"Id",
|
|
"OrganizationId",
|
|
"FolderId",
|
|
"Name",
|
|
"Notes"
|
|
}, alreadyEncrypted, new HashSet<string> { "Id", "OrganizationId", "FolderId" });
|
|
|
|
Type = obj.Type;
|
|
Favorite = obj.Favorite;
|
|
OrganizationUseTotp = obj.OrganizationUseTotp;
|
|
Edit = obj.Edit;
|
|
ViewPassword = obj.ViewPassword;
|
|
RevisionDate = obj.RevisionDate;
|
|
CreationDate = obj.CreationDate;
|
|
CollectionIds = obj.CollectionIds != null ? new HashSet<string>(obj.CollectionIds) : null;
|
|
LocalData = localData;
|
|
Reprompt = obj.Reprompt;
|
|
|
|
switch (Type)
|
|
{
|
|
case Enums.CipherType.Login:
|
|
Login = new Login(obj.Login, alreadyEncrypted);
|
|
break;
|
|
case Enums.CipherType.SecureNote:
|
|
SecureNote = new SecureNote(obj.SecureNote, alreadyEncrypted);
|
|
break;
|
|
case Enums.CipherType.Card:
|
|
Card = new Card(obj.Card, alreadyEncrypted);
|
|
break;
|
|
case Enums.CipherType.Identity:
|
|
Identity = new Identity(obj.Identity, alreadyEncrypted);
|
|
break;
|
|
case CipherType.Fido2Key:
|
|
Fido2Key = new Fido2Key(obj.Fido2Key, alreadyEncrypted);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Attachments = obj.Attachments?.Select(a => new Attachment(a, alreadyEncrypted)).ToList();
|
|
Fields = obj.Fields?.Select(f => new Field(f, alreadyEncrypted)).ToList();
|
|
PasswordHistory = obj.PasswordHistory?.Select(ph => new PasswordHistory(ph, alreadyEncrypted)).ToList();
|
|
DeletedDate = obj.DeletedDate;
|
|
}
|
|
|
|
public string Id { get; set; }
|
|
public string OrganizationId { get; set; }
|
|
public string FolderId { get; set; }
|
|
public EncString Name { get; set; }
|
|
public EncString Notes { get; set; }
|
|
public Enums.CipherType Type { get; set; }
|
|
public bool Favorite { get; set; }
|
|
public bool OrganizationUseTotp { get; set; }
|
|
public bool Edit { get; set; }
|
|
public bool ViewPassword { get; set; }
|
|
public DateTime RevisionDate { get; set; }
|
|
public DateTime CreationDate { get; set; }
|
|
public DateTime? DeletedDate { get; set; }
|
|
public Dictionary<string, object> LocalData { get; set; }
|
|
public Login Login { get; set; }
|
|
public Identity Identity { get; set; }
|
|
public Card Card { get; set; }
|
|
public SecureNote SecureNote { get; set; }
|
|
public Fido2Key Fido2Key { get; set; }
|
|
public List<Attachment> Attachments { get; set; }
|
|
public List<Field> Fields { get; set; }
|
|
public List<PasswordHistory> PasswordHistory { get; set; }
|
|
public HashSet<string> CollectionIds { get; set; }
|
|
public CipherRepromptType Reprompt { get; set; }
|
|
|
|
public async Task<CipherView> DecryptAsync()
|
|
{
|
|
var model = new CipherView(this);
|
|
await DecryptObjAsync(model, this, new HashSet<string>
|
|
{
|
|
"Name",
|
|
"Notes"
|
|
}, OrganizationId);
|
|
|
|
switch (Type)
|
|
{
|
|
case Enums.CipherType.Login:
|
|
model.Login = await Login.DecryptAsync(OrganizationId);
|
|
break;
|
|
case Enums.CipherType.SecureNote:
|
|
model.SecureNote = await SecureNote.DecryptAsync(OrganizationId);
|
|
break;
|
|
case Enums.CipherType.Card:
|
|
model.Card = await Card.DecryptAsync(OrganizationId);
|
|
break;
|
|
case Enums.CipherType.Identity:
|
|
model.Identity = await Identity.DecryptAsync(OrganizationId);
|
|
break;
|
|
case Enums.CipherType.Fido2Key:
|
|
model.Fido2Key = await Fido2Key.DecryptAsync(OrganizationId);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (Attachments?.Any() ?? false)
|
|
{
|
|
model.Attachments = new List<AttachmentView>();
|
|
var tasks = new List<Task>();
|
|
async Task decryptAndAddAttachmentAsync(Attachment attachment)
|
|
{
|
|
var decAttachment = await attachment.DecryptAsync(OrganizationId);
|
|
model.Attachments.Add(decAttachment);
|
|
}
|
|
foreach (var attachment in Attachments)
|
|
{
|
|
tasks.Add(decryptAndAddAttachmentAsync(attachment));
|
|
}
|
|
await Task.WhenAll(tasks);
|
|
}
|
|
if (Fields?.Any() ?? false)
|
|
{
|
|
model.Fields = new List<FieldView>();
|
|
var tasks = new List<Task>();
|
|
async Task decryptAndAddFieldAsync(Field field)
|
|
{
|
|
var decField = await field.DecryptAsync(OrganizationId);
|
|
model.Fields.Add(decField);
|
|
}
|
|
foreach (var field in Fields)
|
|
{
|
|
tasks.Add(decryptAndAddFieldAsync(field));
|
|
}
|
|
await Task.WhenAll(tasks);
|
|
}
|
|
if (PasswordHistory?.Any() ?? false)
|
|
{
|
|
model.PasswordHistory = new List<PasswordHistoryView>();
|
|
var tasks = new List<Task>();
|
|
async Task decryptAndAddHistoryAsync(PasswordHistory ph)
|
|
{
|
|
var decPh = await ph.DecryptAsync(OrganizationId);
|
|
model.PasswordHistory.Add(decPh);
|
|
}
|
|
foreach (var ph in PasswordHistory)
|
|
{
|
|
tasks.Add(decryptAndAddHistoryAsync(ph));
|
|
}
|
|
await Task.WhenAll(tasks);
|
|
}
|
|
return model;
|
|
}
|
|
|
|
public CipherData ToCipherData(string userId)
|
|
{
|
|
var c = new CipherData
|
|
{
|
|
Id = Id,
|
|
OrganizationId = OrganizationId,
|
|
FolderId = FolderId,
|
|
UserId = OrganizationId != null ? userId : null,
|
|
Edit = Edit,
|
|
OrganizationUseTotp = OrganizationUseTotp,
|
|
Favorite = Favorite,
|
|
RevisionDate = RevisionDate,
|
|
CreationDate = CreationDate,
|
|
Type = Type,
|
|
CollectionIds = CollectionIds.ToList(),
|
|
DeletedDate = DeletedDate,
|
|
Reprompt = Reprompt,
|
|
};
|
|
BuildDataModel(this, c, new HashSet<string>
|
|
{
|
|
"Name",
|
|
"Notes"
|
|
});
|
|
switch (c.Type)
|
|
{
|
|
case Enums.CipherType.Login:
|
|
c.Login = Login.ToLoginData();
|
|
break;
|
|
case Enums.CipherType.SecureNote:
|
|
c.SecureNote = SecureNote.ToSecureNoteData();
|
|
break;
|
|
case Enums.CipherType.Card:
|
|
c.Card = Card.ToCardData();
|
|
break;
|
|
case Enums.CipherType.Identity:
|
|
c.Identity = Identity.ToIdentityData();
|
|
break;
|
|
case Enums.CipherType.Fido2Key:
|
|
c.Fido2Key = Fido2Key.ToFido2KeyData();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
c.Fields = Fields?.Select(f => f.ToFieldData()).ToList();
|
|
c.Attachments = Attachments?.Select(a => a.ToAttachmentData()).ToList();
|
|
c.PasswordHistory = PasswordHistory?.Select(ph => ph.ToPasswordHistoryData()).ToList();
|
|
return c;
|
|
}
|
|
}
|
|
}
|