Example #1
0
        public static RecordExtra ExtractRecordExtra(this PasswordRecord record, RecordExtra existingExtra = null)
        {
            IDictionary <string, RecordExtraFile> extraFiles = null;

            if (existingExtra != null && existingExtra.files != null && existingExtra.files.Length > 0)
            {
                extraFiles = new Dictionary <string, RecordExtraFile>();
                foreach (var f in existingExtra.files)
                {
                    extraFiles.Add(f.id, f);
                }
            }
            return(new RecordExtra
            {
                files = record.Attachments?.Select(x =>
                {
                    RecordExtraFile extraFile;
                    if (extraFiles != null)
                    {
                        if (extraFiles.TryGetValue(x.Id, out extraFile))
                        {
                            return extraFile;
                        }
                    }
                    extraFile = new RecordExtraFile
                    {
                        id = x.Id,
                        key = x.Key,
                        name = x.Name,
                        title = x.Title ?? x.Name,
                        size = x.Size,
                        type = x.Type
                    };
                    if (x.Thumbnails != null && x.Thumbnails.Length > 0)
                    {
                        extraFile.thumbs = x.Thumbnails.Select(y =>
                                                               new RecordExtraFileThumb
                        {
                            id = y.Id,
                            size = y.Size,
                            type = y.Type
                        })
                                           .ToArray();
                    }
                    return extraFile;
                }).ToArray(),
                ExtensionData = existingExtra?.ExtensionData
            });
        }
Example #2
0
        public async Task SaveRecord(PasswordRecord record, bool skipData = false, bool skipExtra = true)
        {
            SyncDownRecord existingRecord = null;

            if (!string.IsNullOrEmpty(record.Uid))
            {
                records.TryGetValue(record.Uid, out existingRecord);
            }
            var updateRecord = new RecordUpdateRecord();

            byte[] recordKey = null;
            if (existingRecord != null)
            {
                updateRecord.recordUid = existingRecord.recordUid;
                recordKey = existingRecord.unencryptedRecordKey;
                if (metaData.TryGetValue(existingRecord.recordUid, out SyncDownRecordMetaData sdrmd))
                {
                    if (sdrmd.recordKeyType == 2)
                    {
                        updateRecord.recordKey = CryptoUtils.EncryptAesV1(recordKey, Auth.DataKey).Base64UrlEncode();
                    }
                }
                updateRecord.revision = existingRecord.revision;
                ResolveRecordAccessPath(updateRecord);
            }
            else
            {
                updateRecord.recordUid = CryptoUtils.GenerateUid();
                recordKey = CryptoUtils.GenerateEncryptionKey();
                updateRecord.recordKey = CryptoUtils.EncryptAesV1(recordKey, Auth.DataKey).Base64UrlEncode();
                updateRecord.revision  = 0;
            }
            var settings = new DataContractJsonSerializerSettings
            {
                UseSimpleDictionaryFormat = true
            };

            if (!skipData)
            {
                var        dataSerializer = new DataContractJsonSerializer(typeof(RecordData), settings);
                RecordData existingData   = null;
                if (existingRecord != null)
                {
                    try
                    {
                        var unencrypted_data = CryptoUtils.DecryptAesV1(existingRecord.data.Base64UrlDecode(), existingRecord.unencryptedRecordKey);
                        using (var ms = new MemoryStream(unencrypted_data))
                        {
                            existingData = (RecordData)dataSerializer.ReadObject(ms);
                        }
                    }
                    catch (Exception e)
                    {
                        Trace.TraceError("Decrypt Record: UID: {0}, {1}: \"{2}\"", existingRecord.recordUid, e.GetType().Name, e.Message);
                    }
                }
                var data = record.ExtractRecordData(existingData);
                using (var ms = new MemoryStream())
                {
                    dataSerializer.WriteObject(ms, data);
                    updateRecord.data = CryptoUtils.EncryptAesV1(ms.ToArray(), recordKey).Base64UrlEncode();
                }
            }
            if (!skipExtra)
            {
                var         extraSerializer = new DataContractJsonSerializer(typeof(RecordExtra), settings);
                RecordExtra existingExtra   = null;
                if (existingRecord != null)
                {
                    try
                    {
                        var unencrypted_extra = CryptoUtils.DecryptAesV1(existingRecord.extra.Base64UrlDecode(), existingRecord.unencryptedRecordKey);
                        using (var ms = new MemoryStream(unencrypted_extra))
                        {
                            existingExtra = (RecordExtra)extraSerializer.ReadObject(ms);
                        }
                    }
                    catch (Exception e)
                    {
                        Trace.TraceError("Decrypt Record: UID: {0}, {1}: \"{2}\"", existingRecord.recordUid, e.GetType().Name, e.Message);
                    }
                }
                var extra = record.ExtractRecordExtra(existingExtra);
                using (var ms = new MemoryStream())
                {
                    extraSerializer.WriteObject(ms, extra);
                    updateRecord.extra = CryptoUtils.EncryptAesV1(ms.ToArray(), recordKey).Base64UrlEncode();
                }
                var udata = new RecordUpdateUData();
                var ids   = new HashSet <string>();
                if (record.Attachments != null)
                {
                    foreach (var atta in record.Attachments)
                    {
                        ids.Add(atta.Id);
                        if (atta.Thumbnails != null)
                        {
                            foreach (var thumb in atta.Thumbnails)
                            {
                                ids.Add(thumb.Id);
                            }
                        }
                    }
                }
                udata.fileIds      = ids.ToArray();
                updateRecord.udata = udata;
            }

            var command = new RecordUpdateCommand();

            if (existingRecord != null)
            {
                command.updateRecords = new RecordUpdateRecord[] { updateRecord };
            }
            else
            {
                command.addRecords = new RecordUpdateRecord[] { updateRecord };
            }

            var rs = await Auth.ExecuteAuthCommand <RecordUpdateCommand, RecordUpdateResponse>(command);

            await this.SyncDown();
        }