/// <summary> /// Instantiates <see cref="VaultData"/> instance. /// </summary> /// <param name="clientKey"><see cref="IKeeperStorage"/> encryption key.</param> /// <param name="storage">Vault storage.</param> public VaultData(byte[] clientKey, IKeeperStorage storage) { ClientKey = clientKey; Storage = storage; rootFolder = new FolderNode { FolderUid = "", Name = "My Vault", FolderType = FolderType.UserFolder }; }
public bool TryGetFolder(string folderUid, out FolderNode node) { return(keeperFolders.TryGetValue(folderUid, out node)); }
internal void BuildFolders() { var folderMap = new Dictionary <string, IFolder>(); foreach (var folder in Storage.Folders.GetAll()) { folderMap[folder.FolderUid] = folder; } var uids = new HashSet <string>(); // check shared folder exists. foreach (var folder in folderMap.Values) { if (folder.FolderType == "user_folder") { continue; } if (string.IsNullOrEmpty(folder.SharedFolderUid)) { continue; } if (!keeperSharedFolders.ContainsKey(folder.SharedFolderUid)) { uids.Add(folder.FolderUid); } } if (uids.Count > 0) { Storage.FolderRecords.DeleteLinksForObjects(uids); Storage.Folders.DeleteUids(uids); foreach (var folderUid in uids) { folderMap.Remove(folderUid); } } keeperFolders.Clear(); rootFolder.Records.Clear(); rootFolder.Subfolders.Clear(); foreach (var folder in folderMap.Values) { var node = new FolderNode { FolderUid = folder.FolderUid, ParentUid = folder.ParentUid }; try { byte[] data = null; if (folder.FolderType == "user_folder") { node.FolderType = FolderType.UserFolder; var key = CryptoUtils.DecryptAesV1(folder.FolderKey.Base64UrlDecode(), ClientKey); data = CryptoUtils.DecryptAesV1(folder.Data.Base64UrlDecode(), key); } else { node.SharedFolderUid = folder.SharedFolderUid; node.FolderType = folder.FolderType == "shared_folder_folder" ? FolderType.SharedFolderFolder : FolderType.SharedFolder; if (keeperSharedFolders.TryGetValue(folder.SharedFolderUid, out var sf)) { if (node.FolderType == FolderType.SharedFolderFolder) { if (string.IsNullOrEmpty(node.ParentUid)) { node.ParentUid = node.SharedFolderUid; } var key = CryptoUtils.DecryptAesV1(folder.FolderKey.Base64UrlDecode(), sf.SharedFolderKey); data = CryptoUtils.DecryptAesV1(folder.Data.Base64UrlDecode(), key); } else { node.Name = sf.Name; } } else { Trace.TraceError( $"Missing Shared Folder UID {folder.SharedFolderUid} for Folder UID {folder.FolderUid}"); } } if (data != null) { var serializer = new DataContractJsonSerializer(typeof(FolderData)); using (var stream = new MemoryStream(data)) { var folderData = serializer.ReadObject(stream) as FolderData; node.Name = folderData?.name; } } } catch (Exception e) { Trace.TraceError(e.Message); } if (string.IsNullOrEmpty(node.Name)) { node.Name = node.FolderUid; } keeperFolders.TryAdd(node.FolderUid, node); } foreach (var folderUid in keeperFolders.Keys) { if (keeperFolders.TryGetValue(folderUid, out FolderNode node)) { FolderNode parent; if (string.IsNullOrEmpty(node.ParentUid)) { parent = rootFolder; } else { if (!keeperFolders.TryGetValue(node.ParentUid, out parent)) { parent = rootFolder; } } parent.Subfolders.Add(folderUid); } } foreach (var link in Storage.FolderRecords.GetAllLinks()) { FolderNode node; if (string.IsNullOrEmpty(link.FolderUid)) { node = rootFolder; } else { if (!keeperFolders.TryGetValue(link.FolderUid, out node)) { node = rootFolder; } } node.Records.Add(link.RecordUid); } }
public static async Task <PasswordRecord> AddRecordToFolder(this VaultOnline vault, PasswordRecord record, string folderUid = null) { FolderNode node = null; if (!string.IsNullOrEmpty(folderUid)) { vault.TryGetFolder(folderUid, out node); } record.Uid = CryptoUtils.GenerateUid(); record.RecordKey = CryptoUtils.GenerateEncryptionKey(); var recordAdd = new RecordAddCommand { RecordUid = record.Uid, RecordKey = CryptoUtils.EncryptAesV1(record.RecordKey, vault.Auth.AuthContext.DataKey).Base64UrlEncode(), RecordType = "password" }; if (node == null) { recordAdd.FolderType = "user_folder"; } else { switch (node.FolderType) { case FolderType.UserFolder: recordAdd.FolderType = "user_folder"; recordAdd.FolderUid = node.FolderUid; break; case FolderType.SharedFolder: case FolderType.SharedFolderFolder: recordAdd.FolderUid = node.FolderUid; recordAdd.FolderType = node.FolderType == FolderType.SharedFolder ? "shared_folder" : "shared_folder_folder"; if (vault.TryGetSharedFolder(node.SharedFolderUid, out var sf)) { recordAdd.FolderKey = CryptoUtils.EncryptAesV1(record.RecordKey, sf.SharedFolderKey) .Base64UrlEncode(); } if (string.IsNullOrEmpty(recordAdd.FolderKey)) { throw new Exception($"Cannot resolve shared folder for folder UID: {folderUid}"); } break; } } var dataSerializer = new DataContractJsonSerializer(typeof(RecordData), JsonUtils.JsonSettings); var data = record.ExtractRecordData(); using (var ms = new MemoryStream()) { dataSerializer.WriteObject(ms, data); recordAdd.Data = CryptoUtils.EncryptAesV1(ms.ToArray(), record.RecordKey).Base64UrlEncode(); } await vault.Auth.ExecuteAuthCommand(recordAdd); await vault.ScheduleSyncDown(TimeSpan.FromSeconds(0)); return(vault.TryGetRecord(record.Uid, out var r) ? r : record); }