file_magic_sync.dart 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import 'dart:convert';
  2. import 'package:dio/dio.dart';
  3. import 'package:flutter_sodium/flutter_sodium.dart';
  4. import 'package:photos/core/event_bus.dart';
  5. import 'package:photos/core/network.dart';
  6. import 'package:photos/db/files_db.dart';
  7. import 'package:photos/events/files_updated_event.dart';
  8. import 'package:photos/models/file.dart';
  9. import 'package:photos/core/configuration.dart';
  10. import 'package:photos/models/file_magic_metadata.dart';
  11. import 'package:photos/services/remote_sync_service.dart';
  12. import 'crypto_util.dart';
  13. import 'file_download_util.dart';
  14. final _dio = Network.instance.getDio();
  15. FilesDB _filesDB = FilesDB.instance;
  16. Future<void> changeVisibility(List<File> files, int visibility) async {
  17. final params = <String, dynamic>{};
  18. params['metadataList'] = [];
  19. int ownerID = Configuration.instance.getUserID();
  20. for (final file in files) {
  21. if (file.uploadedFileID == null) {
  22. throw AssertionError("operation is only supported on backed up files");
  23. } else if (file.ownerID != ownerID) {
  24. throw AssertionError("can not modify memories not owned by you");
  25. }
  26. Map<String, dynamic> jsonToUpdate = jsonDecode(file.mMdEncodedJson);
  27. jsonToUpdate['visibility'] = visibility;
  28. // update the local information so that it's reflected on UI
  29. file.mMdEncodedJson = jsonEncode(jsonToUpdate);
  30. file.fileMagicMetadata = FileMagicMetadata.fromJson(jsonToUpdate);
  31. final fileKey = decryptFileKey(file);
  32. final encryptedMMd = await CryptoUtil.encryptChaCha(
  33. utf8.encode(jsonEncode(jsonToUpdate)), fileKey);
  34. params['metadataList'].add(UpdateMagicMetadata(
  35. id: file.uploadedFileID,
  36. data: MetadataPayload(
  37. version: file.mMdVersion,
  38. count: jsonToUpdate.length,
  39. data: Sodium.bin2base64(encryptedMMd.encryptedData),
  40. header: Sodium.bin2base64(encryptedMMd.header),
  41. )));
  42. }
  43. return _dio
  44. .post(
  45. Configuration.instance.getHttpEndpoint() + "/files/update-magic-metadata",
  46. data: params,
  47. options:
  48. Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}),
  49. )
  50. .then((value) async {
  51. // update the state of the selected file. Same file in other collection
  52. // should be eventually synced after remote sync has completed
  53. await _filesDB.insertMultiple(files);
  54. Bus.instance.fire(FilesUpdatedEvent(files));
  55. RemoteSyncService.instance.sync(silently: true);
  56. });
  57. }
  58. class UpdateMagicMetadata {
  59. int id;
  60. MetadataPayload data;
  61. UpdateMagicMetadata({this.id, this.data});
  62. UpdateMagicMetadata.fromJson(dynamic json) {
  63. id = json['id'];
  64. data = json['data'] != null ? MetadataPayload.fromJson(json['data']) : null;
  65. }
  66. Map<String, dynamic> toJson() {
  67. var map = <String, dynamic>{};
  68. map['id'] = id;
  69. if (data != null) {
  70. map['data'] = data.toJson();
  71. }
  72. return map;
  73. }
  74. }
  75. class MetadataPayload {
  76. int version;
  77. int count;
  78. String data;
  79. String header;
  80. MetadataPayload({this.version, this.count, this.data, this.header});
  81. MetadataPayload.fromJson(dynamic json) {
  82. version = json['version'];
  83. count = json['count'];
  84. data = json['data'];
  85. header = json['header'];
  86. }
  87. Map<String, dynamic> toJson() {
  88. var map = <String, dynamic>{};
  89. map['version'] = version;
  90. map['count'] = count;
  91. map['data'] = data;
  92. map['header'] = header;
  93. return map;
  94. }
  95. }