passbolt-browser-extension 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/RELEASE_NOTES.md +50 -75
  3. package/doc/browser-extension-class-diagram.md +9 -0
  4. package/package.json +2 -2
  5. package/src/all/_locales/sl/messages.json +2 -2
  6. package/src/all/background_page/controller/resource/updateResourceLocalStorageByFolderParentIdController.js +70 -0
  7. package/src/all/background_page/controller/resource/updateResourceLocalStorageByFolderParentIdController.test.js +78 -0
  8. package/src/all/background_page/controller/share/shareOneFolderController.test.js +2 -1
  9. package/src/all/background_page/controller/share/shareResourcesController.test.js +1 -1
  10. package/src/all/background_page/event/resourceEvents.js +11 -0
  11. package/src/all/background_page/model/entity/resource/resourcesCollection.js +25 -0
  12. package/src/all/background_page/model/entity/resource/resourcesCollection.test.js +34 -0
  13. package/src/all/background_page/service/api/resource/resourceService.js +1 -0
  14. package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.js +52 -1
  15. package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.test.js +100 -0
  16. package/src/all/background_page/service/resource/findResourcesService.js +53 -19
  17. package/src/all/background_page/service/resource/findResourcesService.test.js +191 -0
  18. package/src/all/background_page/service/resourceType/updateResourceTypesService.test.js +1 -1
  19. package/src/all/background_page/service/share/shareResourceService.test.js +1 -1
  20. package/src/all/locales/de-DE/common.json +2 -2
  21. package/src/all/locales/es-ES/common.json +2 -2
  22. package/src/all/locales/fr-FR/common.json +5 -5
  23. package/src/all/locales/it-IT/common.json +2 -2
  24. package/src/all/locales/ja-JP/common.json +2 -2
  25. package/src/all/locales/ko-KR/common.json +2 -2
  26. package/src/all/locales/lt-LT/common.json +2 -2
  27. package/src/all/locales/nl-NL/common.json +2 -2
  28. package/src/all/locales/pl-PL/common.json +5 -5
  29. package/src/all/locales/pt-BR/common.json +2 -2
  30. package/src/all/locales/ro-RO/common.json +2 -2
  31. package/src/all/locales/ru-RU/common.json +2 -2
  32. package/src/all/locales/sl-SI/common.json +33 -33
  33. package/src/all/locales/sv-SE/common.json +2 -2
  34. package/src/all/locales/uk-UA/common.json +3 -3
  35. package/src/chrome/manifest.json +1 -1
  36. package/src/chrome-mv3/manifest.json +1 -1
  37. package/src/firefox/manifest.json +1 -1
@@ -371,4 +371,104 @@ describe("UpdateResourcesLocalStorage", () => {
371
371
  expect(expectLocalStorageResult[1]).toEqual(ResourceEntity.transformDtoFromV4toV5(resourceDto2));
372
372
  });
373
373
  });
374
+
375
+ describe("::findAndUpdateAllByParentFolderId", () => {
376
+ let service;
377
+
378
+ beforeEach(() => {
379
+ service = new FindAndUpdateResourcesLocalStorage(account, apiClientOptions);
380
+ jest.spyOn(ResourceTypeService.prototype, "findAll").mockImplementation(() => resourceTypesCollectionDto());
381
+ });
382
+
383
+ it("should extract the id from the resource collection", async() => {
384
+ expect.assertions(2);
385
+
386
+ const parentFolderId = uuidv4();
387
+
388
+ const resourcesDto = multipleResourceDtos();
389
+ jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => resourcesDto);
390
+ jest.spyOn(service.findResourcesServices, "findAllByParentFolderIdForLocalStorage");
391
+
392
+ await service.findAndUpdateAllByParentFolderId(parentFolderId);
393
+
394
+ expect(service.findResourcesServices.findAllByParentFolderIdForLocalStorage).toHaveBeenCalledTimes(1);
395
+ expect(service.findResourcesServices.findAllByParentFolderIdForLocalStorage).toHaveBeenCalledWith(parentFolderId);
396
+ });
397
+
398
+ it("should assert its parameter", async() => {
399
+ expect.assertions(1);
400
+ await expect(() => service.findAndUpdateAllByParentFolderId("test")).rejects.toThrow();
401
+ });
402
+
403
+ it("should update the local storage resource collection by removing deleted resources, moving resources and updating resources data", async() => {
404
+ expect.assertions(8);
405
+
406
+ const parentFolderId = uuidv4();
407
+ const otherParentFolderId = uuidv4();
408
+
409
+ /*
410
+ * Resources collection in local storage:
411
+ * Resource0.folderParentId = null;
412
+ * Resource1.folderParentId = parentFolderId; // on API it should be modified only
413
+ * Resource2.folderParentId = parentFolderId; // on API it should be moved
414
+ * Resource3.folderParentId = parentFolderId; // on API it should be removed
415
+ */
416
+
417
+ const resourcesDto = multipleResourceDtos();
418
+ resourcesDto[1].folder_parent_id = parentFolderId;
419
+ resourcesDto[2].folder_parent_id = parentFolderId;
420
+ resourcesDto[3].folder_parent_id = parentFolderId;
421
+
422
+ delete resourcesDto[0].name;
423
+ delete resourcesDto[1].name;
424
+ delete resourcesDto[2].name;
425
+ delete resourcesDto[3].name;
426
+
427
+ const localStorageResourceCollection = new ResourcesCollection(resourcesDto);
428
+ await ResourceLocalStorage.set(localStorageResourceCollection);
429
+
430
+ // the resources in the folder on the API does not have resource2 anymore but resources1 remains and is changed.
431
+ const apiResourcesDtoInFolder = [
432
+ {...resourcesDto[1]},
433
+ ];
434
+ apiResourcesDtoInFolder[0].metadata.name = "Resource1 - UPDATED";
435
+ apiResourcesDtoInFolder[0].modified = (new Date()).toISOString();
436
+
437
+ // resource2 on the API will be return and updated, resource3 will never be sent back as it is deleted
438
+ const allIdsApiResourcesDto = [
439
+ {...resourcesDto[2]},
440
+ ];
441
+ allIdsApiResourcesDto[0].folder_parent_id = otherParentFolderId;
442
+
443
+ async function mockedFindAllApi(_, filter) {
444
+ const isParentFolderSearchRequest = Boolean(filter["has-parent"]);
445
+
446
+ return isParentFolderSearchRequest
447
+ ? apiResourcesDtoInFolder
448
+ : allIdsApiResourcesDto;
449
+ }
450
+
451
+ jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(mockedFindAllApi);
452
+
453
+ await service.findAndUpdateAllByParentFolderId(parentFolderId);
454
+
455
+ const updatedResourceLocalStorage = new ResourcesCollection(await ResourceLocalStorage.get());
456
+
457
+ expect(updatedResourceLocalStorage).toHaveLength(3); //1 resource should be removed compared to the original data
458
+ const resource0 = updatedResourceLocalStorage.getFirstById(resourcesDto[0].id);
459
+ expect(resource0.toDto(ResourceEntity.ALL_CONTAIN_OPTIONS)).toStrictEqual(resourcesDto[0]); //this resource should remain unchanged
460
+
461
+ const updatedResource1 = updatedResourceLocalStorage.getFirstById(resourcesDto[1].id); // this resource should have been updated but not moved
462
+ expect(updatedResource1.metadata.name).toStrictEqual("Resource1 - UPDATED");
463
+ expect(updatedResource1.modified).toStrictEqual(apiResourcesDtoInFolder[0].modified);
464
+ expect(updatedResource1.folderParentId).toStrictEqual(parentFolderId);
465
+
466
+ const updatedResource2 = updatedResourceLocalStorage.getFirstById(resourcesDto[2].id); // this resource should not have changed per say but only moved
467
+ expect(updatedResource2.modified).toStrictEqual(resourcesDto[2].modified);
468
+ expect(updatedResource2.folderParentId).toStrictEqual(otherParentFolderId);
469
+
470
+ const updatedResource3 = updatedResourceLocalStorage.getFirstById(resourcesDto[3].id); // this resource should have been removed
471
+ expect(updatedResource3).toBeUndefined();
472
+ });
473
+ });
374
474
  });
@@ -46,18 +46,9 @@ export default class FindResourcesService {
46
46
  * @returns {Promise<ResourcesCollection>}
47
47
  * @private
48
48
  */
49
- async findAll(contains, filters, ignoreInvalidEntity) {
50
- //Assert contains
51
- const supportedOptions = ResourceService.getSupportedContainOptions();
52
- const supportedFilter = ResourceService.getSupportedFiltersOptions();
53
-
54
- if (contains && !Object.keys(contains).every(option => supportedOptions.includes(option))) {
55
- throw new Error("Unsupported contains parameter used, please check supported contains");
56
- }
57
-
58
- if (filters && !Object.keys(filters).every(filter => supportedFilter.includes(filter))) {
59
- throw new Error("Unsupported filter parameter used, please check supported filters");
60
- }
49
+ async findAll(contains, filters, ignoreInvalidEntity = false) {
50
+ this.assertContains(contains);
51
+ this.assertFilters(filters);
61
52
 
62
53
  const resourcesDto = await this.resourceService.findAll(contains, filters);
63
54
  return new ResourcesCollection(resourcesDto, {clone: false, ignoreInvalidEntity: ignoreInvalidEntity});
@@ -69,7 +60,7 @@ export default class FindResourcesService {
69
60
  * @param {Array<string>} resourcesIds
70
61
  * @returns {Promise<ResourcesCollection>}
71
62
  */
72
- async findAllByIds(resourcesIds, contains = {}) {
63
+ async findAllByIds(resourcesIds, contains = {}, ignoreInvalidEntity = false) {
73
64
  assertArrayUUID(resourcesIds);
74
65
 
75
66
  // We split the requests in chunks in order to avoid any too long url error.
@@ -78,7 +69,7 @@ export default class FindResourcesService {
78
69
  const filter = {
79
70
  "has-id": resourceIds
80
71
  };
81
- return async() => await this.findAll(contains, filter);
72
+ return async() => await this.findAll(contains, filter, ignoreInvalidEntity);
82
73
  });
83
74
 
84
75
  // @todo Later (tm). The Collection should provide this capability, ensuring that validation build rules are executed and performance is guaranteed.
@@ -196,12 +187,8 @@ export default class FindResourcesService {
196
187
  */
197
188
  async findOneById(resourceId, contains = {}) {
198
189
  assertUuid(resourceId);
199
- //Assert contains
200
- const supportedOptions = ResourceService.getSupportedContainOptions();
190
+ this.assertContains(contains);
201
191
 
202
- if (contains && !Object.keys(contains).every(option => supportedOptions.includes(option))) {
203
- throw new Error("Unsupported contains parameter used, please check supported contains");
204
- }
205
192
  const resourcesDto = await this.resourceService.get(resourceId, contains);
206
193
 
207
194
  return new ResourceEntity(resourcesDto);
@@ -224,4 +211,51 @@ export default class FindResourcesService {
224
211
  const resource = this.findOneById(resourceId, contains);
225
212
  return resource;
226
213
  }
214
+
215
+ /**
216
+ * Find all the resources matching the given ids for the local storage.
217
+ * All entities that cannot be validated will be ignored and excluded from the resulting collection.
218
+ * @param {Array<uuid>} resourceIds
219
+ * @returns {Promise<ResourcesCollection>}
220
+ */
221
+ async findAllByIdsForLocalStorage(resourceIds) {
222
+ assertArrayUUID(resourceIds);
223
+ return await this.findAllByIds(resourceIds, ResourceLocalStorage.DEFAULT_CONTAIN, true);
224
+ }
225
+
226
+ /**
227
+ * Find all the resources having the given parentFolderId as direct ancestor for the local storage
228
+ * All entities that cannot be validated will be ignored and excluded from the resulting collection.
229
+ * @param {uuid} parentFolderId
230
+ * @returns {Promise<ResourcesCollection>}
231
+ */
232
+ async findAllByParentFolderIdForLocalStorage(parentFolderId) {
233
+ assertUuid(parentFolderId);
234
+ const filters = {"has-parent": parentFolderId};
235
+ return await this.findAll(ResourceLocalStorage.DEFAULT_CONTAIN, filters, true);
236
+ }
237
+
238
+ /**
239
+ * Assert the contains to ensure they match the supported ones.
240
+ * @param {object} contains
241
+ * @private
242
+ */
243
+ assertContains(contains) {
244
+ const supportedOptions = ResourceService.getSupportedContainOptions();
245
+ if (contains && !Object.keys(contains).every(option => supportedOptions.includes(option))) {
246
+ throw new Error("Unsupported contains parameter used, please check supported contains");
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Assert the filters to ensure they match the supported ones.
252
+ * @param {object} filters
253
+ * @private
254
+ */
255
+ assertFilters(filters) {
256
+ const supportedFilter = ResourceService.getSupportedFiltersOptions();
257
+ if (filters && !Object.keys(filters).every(filter => supportedFilter.includes(filter))) {
258
+ throw new Error("Unsupported filter parameter used, please check supported filters");
259
+ }
260
+ }
227
261
  }
@@ -590,4 +590,195 @@ describe("FindResourcesService", () => {
590
590
  await expect(promise).rejects.toThrowError("API error");
591
591
  });
592
592
  });
593
+
594
+ describe("::findAllByIdsForLocalStorage", () => {
595
+ let service, expectedContains;
596
+
597
+ beforeEach(() => {
598
+ service = new FindResourcesService(account, apiClientOptions);
599
+ expectedContains = {
600
+ permission: true,
601
+ favorite: true,
602
+ tag: true
603
+ };
604
+ });
605
+
606
+ it("should retrieve all resources by their ids", async() => {
607
+ expect.assertions(3);
608
+
609
+ const ressourcesDto = multipleResourceDtos();
610
+ const resourcesIds = ressourcesDto.map(r => r.id);
611
+
612
+ jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => ressourcesDto);
613
+
614
+ const result = await service.findAllByIdsForLocalStorage(resourcesIds);
615
+
616
+ const resourcesIdsFilter = {"has-id": resourcesIds};
617
+
618
+ expect(result).toEqual(new ResourcesCollection(ressourcesDto));
619
+ expect(ResourceService.prototype.findAll).toHaveBeenCalledTimes(1);
620
+ expect(ResourceService.prototype.findAll).toHaveBeenCalledWith(expectedContains, resourcesIdsFilter);
621
+ });
622
+
623
+ it("should assert the given ids", async() => {
624
+ expect.assertions(1);
625
+
626
+ const resourcesIds = [uuidv4(), "test"];
627
+ await expect(() => service.findAllByIdsForLocalStorage(resourcesIds)).rejects.toThrowError();
628
+ });
629
+ });
630
+
631
+ describe("::findAllByParentFolderIdForLocalStorage", () => {
632
+ let service, expectedContains, expectedFilters;
633
+ const parentFolderId = uuidv4();
634
+
635
+ beforeEach(() => {
636
+ service = new FindResourcesService(account, apiClientOptions);
637
+ expectedContains = {
638
+ permission: true,
639
+ favorite: true,
640
+ tag: true
641
+ };
642
+
643
+ expectedFilters = {
644
+ 'has-parent': parentFolderId
645
+ };
646
+ });
647
+
648
+ it("should retrieve all resources by parent folder id", async() => {
649
+ expect.assertions(3);
650
+
651
+ const ressourcesDto = multipleResourceDtos();
652
+
653
+ jest.spyOn(ResourceService.prototype, "findAll").mockImplementation(() => ressourcesDto);
654
+
655
+ const result = await service.findAllByParentFolderIdForLocalStorage(parentFolderId);
656
+
657
+ expect(result).toEqual(new ResourcesCollection(ressourcesDto));
658
+ expect(ResourceService.prototype.findAll).toHaveBeenCalledTimes(1);
659
+ expect(ResourceService.prototype.findAll).toHaveBeenCalledWith(expectedContains, expectedFilters);
660
+ });
661
+
662
+ it("should assert the given id", async() => {
663
+ expect.assertions(1);
664
+ await expect(() => service.findAllByParentFolderIdForLocalStorage("test")).rejects.toThrowError();
665
+ });
666
+ });
667
+
668
+ describe("::assertContains", () => {
669
+ it("should not throw errors if all given contains are fine", () => {
670
+ expect.assertions(1);
671
+
672
+ const service = new FindResourcesService(account, apiClientOptions);
673
+ const allContains = {
674
+ 'creator': true,
675
+ 'favorite': true,
676
+ 'modifier': true,
677
+ 'secret': true,
678
+ 'permission': true,
679
+ 'permissions': true,
680
+ 'permissions.user.profile': true,
681
+ 'permissions.group': true,
682
+ 'tag': true,
683
+ 'resource-type': true,
684
+ };
685
+
686
+ expect(() => service.assertContains(allContains)).not.toThrow();
687
+ });
688
+
689
+ it("should not throw errors if the contain has 1 element only", () => {
690
+ expect.assertions(1);
691
+
692
+ const service = new FindResourcesService(account, apiClientOptions);
693
+ const contains = {'permissions.user.profile': true};
694
+
695
+ expect(() => service.assertContains(contains)).not.toThrow();
696
+ });
697
+
698
+ it("should not throw errors if the contain is empty", () => {
699
+ expect.assertions(1);
700
+
701
+ const service = new FindResourcesService(account, apiClientOptions);
702
+ const contains = {};
703
+
704
+ expect(() => service.assertContains(contains)).not.toThrow();
705
+ });
706
+
707
+ it("should throw an error if at least of the contain is wrong", () => {
708
+ expect.assertions(1);
709
+
710
+ const service = new FindResourcesService(account, apiClientOptions);
711
+ const allContains = {
712
+ 'creator': true,
713
+ 'favorite': true,
714
+ 'modifier': true,
715
+ 'secret': true,
716
+ 'permission': true,
717
+ 'permissions': true,
718
+ 'permissions.user.profile': true,
719
+ 'permissions.group': true,
720
+ 'tag': true,
721
+ 'resource-type': true,
722
+ 'resource-type-wrong': true,
723
+ };
724
+
725
+ expect(() => service.assertContains(allContains)).toThrow();
726
+ });
727
+ });
728
+
729
+
730
+ describe("::assertFilters", () => {
731
+ it("should not throw errors if all given filters are fine", () => {
732
+ expect.assertions(1);
733
+
734
+ const service = new FindResourcesService(account, apiClientOptions);
735
+ const allFilters = {
736
+ 'is-favorite': true,
737
+ 'is-shared-with-group': uuidv4(),
738
+ 'is-owned-by-me': true,
739
+ 'is-shared-with-me': true,
740
+ 'has-id': uuidv4(),
741
+ 'has-tag': uuidv4(),
742
+ "has-parent": uuidv4(),
743
+ };
744
+
745
+ expect(() => service.assertFilters(allFilters)).not.toThrow();
746
+ });
747
+
748
+ it("should not throw errors if the contain has 1 element only", () => {
749
+ expect.assertions(1);
750
+
751
+ const service = new FindResourcesService(account, apiClientOptions);
752
+ const contains = {'is-shared-with-me': true};
753
+
754
+ expect(() => service.assertFilters(contains)).not.toThrow();
755
+ });
756
+
757
+ it("should not throw errors if the filters is empty", () => {
758
+ expect.assertions(1);
759
+
760
+ const service = new FindResourcesService(account, apiClientOptions);
761
+ const contains = {};
762
+
763
+ expect(() => service.assertFilters(contains)).not.toThrow();
764
+ });
765
+
766
+ it("should throw an error if at least of the filters is wrong", () => {
767
+ expect.assertions(1);
768
+
769
+ const service = new FindResourcesService(account, apiClientOptions);
770
+ const allContains = {
771
+ 'is-favorite': true,
772
+ 'is-shared-with-group': uuidv4(),
773
+ 'is-owned-by-me': true,
774
+ 'is-shared-with-me': true,
775
+ 'has-id': uuidv4(),
776
+ 'has-tag': uuidv4(),
777
+ "has-parent": uuidv4(),
778
+ "has-parent-wrong": uuidv4(),
779
+ };
780
+
781
+ expect(() => service.assertFilters(allContains)).toThrow();
782
+ });
783
+ });
593
784
  });
@@ -152,7 +152,7 @@ describe("UpdateResourceTypesService", () => {
152
152
 
153
153
  await service.updateAllDeletedStatus(resourcesTypesCollection);
154
154
 
155
- expect(service.resourceTypeService.delete).toHaveBeenCalledTimes(4);
155
+ expect(service.resourceTypeService.delete).toHaveBeenCalledTimes(5);
156
156
  expect(service.resourceTypeService.undelete).toHaveBeenCalledTimes(4);
157
157
 
158
158
  expect(service.resourceTypeService.delete).toHaveBeenCalledWith(resourceTypesDto[0].id);
@@ -51,7 +51,7 @@ import ResourcesCollection from "../../model/entity/resource/resourcesCollection
51
51
  import MetadataKeysSessionStorage from "../session_storage/metadataKeysSessionStorage";
52
52
  import PermissionChangesCollection from "../../model/entity/permission/change/permissionChangesCollection";
53
53
  import expect from "expect";
54
- import MockPort from "passbolt-styleguide/test/mocks/mockPort";
54
+ import MockPort from "passbolt-styleguide/src/react-extension/test/mock/MockPort";
55
55
  import ProgressService from "../progress/progressService";
56
56
  import {METADATA_KEY_TYPE_METADATA_KEY, METADATA_KEY_TYPE_USER_KEY} from "../../model/entity/resource/resourceEntity";
57
57
  import ResourceTypeModel from "../../model/resourceType/resourceTypeModel";
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "Der Server-Schlüssel ist abgelaufen.",
106
106
  "The service is unavailable": "Der Dienst ist nicht verfügbar",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Dies ist kein gültiges Kennwort",
111
111
  "This key does not match any account.": "Dieser Schlüssel stimmt mit keinem Konto überein.",
112
112
  "This key is already used by another user.": "Dieser Schlüssel wird bereits von einem anderen Benutzer verwendet.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "La clave del servidor ha caducado.",
106
106
  "The service is unavailable": "El servicio no está disponible",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "El ID de clave de la verificación de resultado debe ser un objeto ID de clave válido.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "La firma verificationResult debe ser un Promise<openpgp.Signature> verificado válido.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "El verificationResult debe ser un Promise<boolean> verificado válido.",
110
110
  "This is not a valid passphrase": "Esta no es una contraseña válida",
111
111
  "This key does not match any account.": "Esta clave no coincide con ninguna cuenta.",
112
112
  "This key is already used by another user.": "Esta clave ya está siendo usada por otro usuario.",
@@ -73,7 +73,7 @@
73
73
  "Synchronizing keyring": "Synchronisation du porte-clés",
74
74
  "Synchronizing keys": "Synchronisation des clés en cours",
75
75
  "Tagging passwords {{taggedCount}}/{{total}}": "Étiquetage des mots de passe {{taggedCount}}/{{total}}",
76
- "The encryption key used to share metadata between users could not be verified and is considered untrusted.": "The encryption key used to share metadata between users could not be verified and is considered untrusted.",
76
+ "The encryption key used to share metadata between users could not be verified and is considered untrusted.": "La clé de chiffrement utilisée pour partager les métadonnées entre les utilisateurs n'a pas pu être vérifiée et est considérée comme n'étant pas fiable.",
77
77
  "The external service is unavailable": "Le service externe est indisponible",
78
78
  "The external service raised an error": "Le service externe a généré une erreur",
79
79
  "The folder cannot be moved inside itself.": "Le dossier ne peut pas être déplacé à l'intérieur de lui-même.",
@@ -92,7 +92,7 @@
92
92
  "The message should be decrypted.": "Le message doit être déchiffré.",
93
93
  "The message should be of type string.": "Le message doit être de type string.",
94
94
  "The message should contain at least one session key.": "Le message doit contenir au moins une clé de session.",
95
- "The operation has been aborted to maintain security integrity.": "The operation has been aborted to maintain security integrity.",
95
+ "The operation has been aborted to maintain security integrity.": "L'opération a été interrompue afin de maintenir l'intégrité de la sécurité.",
96
96
  "The private key should be a valid openpgp key.": "La clé privée doit être une clé OpenPGP valide.",
97
97
  "The private key should be decrypted.": "La clé privée doit être déchiffrée.",
98
98
  "The private key should be encrypted.": "La clé privée doit être chiffrée.",
@@ -104,9 +104,9 @@
104
104
  "The server key has changed.": "La clé du serveur a été modifiée.",
105
105
  "The server key is expired.": "La clé du serveur est expirée.",
106
106
  "The service is unavailable": "Le service est indisponible",
107
- "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
107
+ "The verificationResult keyID should be a valid keyID Object.": "L'identifiant de la clé verificationResult devrait être un objet d'identifiant de clé valide.",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "La signature verificationResult devrait être une Promise<openpgp.Signature> vérifiée valide.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Ce n'est pas une phrase de passe valide",
111
111
  "This key does not match any account.": "Cette clé ne correspond à aucun compte.",
112
112
  "This key is already used by another user.": "Cette clé est déjà utilisée par un autre utilisateur.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "La chiave del server è scaduta.",
106
106
  "The service is unavailable": "Il servizio non è disponibile",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Questa non è una frase segreta valida",
111
111
  "This key does not match any account.": "Questa chiave non corrisponde a nessun account.",
112
112
  "This key is already used by another user.": "Questa chiave è già utilizzata da un altro utente.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "サーバーキーの有効期限が切れています。",
106
106
  "The service is unavailable": "サービスはご利用いただけません",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "これは有効なパスフレーズではありません",
111
111
  "This key does not match any account.": "この鍵はどのアカウントとも一致しません。",
112
112
  "This key is already used by another user.": "この鍵はすでに他のユーザーが使用しています。",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "서버키가 만료되었습니다.",
106
106
  "The service is unavailable": "서버키를 사용할 수 없습니다.",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "validationResult keyID는 유효한 keyID 개체여야 합니다.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "verificationResult 서명은 유효하게 검증된 Promise<openpgp.Signature>이어야 합니다.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "verificationResult의 verified는 유효하게 검증된 Promise<boolean>이어야 합니다.",
110
110
  "This is not a valid passphrase": "유효하지 않은 비밀문구",
111
111
  "This key does not match any account.": "키가 맞는 계정이 없습니다.",
112
112
  "This key is already used by another user.": "키를 다른 사용자가 이미 사용 중입니다.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "Serverio raktas nebegalioja.",
106
106
  "The service is unavailable": "Paslauga yra nepasiekiama",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Tai nėra tinkama slaptafrazė",
111
111
  "This key does not match any account.": "Šis raktas neatitinka jokios paskyros.",
112
112
  "This key is already used by another user.": "Šį raktą jau naudoja kitas vartotojas.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "De serversleutel is verlopen.",
106
106
  "The service is unavailable": "Deze service is niet beschikbaar",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Dit is geen geldige wachtwoordzin",
111
111
  "This key does not match any account.": "Deze sleutel komt niet overeen met een account.",
112
112
  "This key is already used by another user.": "Deze sleutel wordt al gebruikt door een andere gebruiker.",
@@ -73,7 +73,7 @@
73
73
  "Synchronizing keyring": "Synchronizacja kluczy",
74
74
  "Synchronizing keys": "Synchronizowanie kluczy",
75
75
  "Tagging passwords {{taggedCount}}/{{total}}": "Tagowanie haseł {{taggedCount}}/{{total}}",
76
- "The encryption key used to share metadata between users could not be verified and is considered untrusted.": "The encryption key used to share metadata between users could not be verified and is considered untrusted.",
76
+ "The encryption key used to share metadata between users could not be verified and is considered untrusted.": "Nie udało się zweryfikować klucza szyfrowania do udostępniania metadanych pomiędzy użytkownikami i jest uważany za niezaufany.",
77
77
  "The external service is unavailable": "Usługa zewnętrzna jest niedostępna",
78
78
  "The external service raised an error": "Usługa zewnętrzna spowodowała błąd",
79
79
  "The folder cannot be moved inside itself.": "Folder nie może być przeniesiony do siebie samego.",
@@ -92,7 +92,7 @@
92
92
  "The message should be decrypted.": "Wiadomość powinna zostać odszyfrowana.",
93
93
  "The message should be of type string.": "Wiadomość powinna być ciągiem.",
94
94
  "The message should contain at least one session key.": "Wiadomość powinna zawierać przynajmniej jeden klucz sesji.",
95
- "The operation has been aborted to maintain security integrity.": "The operation has been aborted to maintain security integrity.",
95
+ "The operation has been aborted to maintain security integrity.": "To działanie zostało przerwane, aby utrzymać integralność zabezpieczeń.",
96
96
  "The private key should be a valid openpgp key.": "Klucz prywatny powinien być prawidłowym kluczem openpgp.",
97
97
  "The private key should be decrypted.": "Klucz prywatny powinien być odszyfrowany.",
98
98
  "The private key should be encrypted.": "Klucz prywatny powinien być zaszyfrowany.",
@@ -104,9 +104,9 @@
104
104
  "The server key has changed.": "Klucz serwera został zmieniony.",
105
105
  "The server key is expired.": "Klucz serwera wygasł.",
106
106
  "The service is unavailable": "Usługa jest niedostępna",
107
- "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
107
+ "The verificationResult keyID should be a valid keyID Object.": "KeyID dla verificationResult powinien być prawidłowym obiektem keyID.",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "To nie jest prawidłowe hasło dostępu",
111
111
  "This key does not match any account.": "Ten klucz nie pasuje do żadnego konta.",
112
112
  "This key is already used by another user.": "Ten klucz jest już używany przez innego użytkownika.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "A chave do servidor expirou.",
106
106
  "The service is unavailable": "O serviço está indisponível",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Esta não é uma senha válida",
111
111
  "This key does not match any account.": "Esta chave não corresponde a nenhuma conta.",
112
112
  "This key is already used by another user.": "Essa chave já está sendo usada por outro usuário.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "Cheia serverului a expirat.",
106
106
  "The service is unavailable": "Serviciul nu este disponibil",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Aceasta nu este o parolă validă",
111
111
  "This key does not match any account.": "Această cheie nu se potrivește cu niciun cont.",
112
112
  "This key is already used by another user.": "Această cheie este deja folosită de un alt utilizator.",
@@ -105,8 +105,8 @@
105
105
  "The server key is expired.": "Срок действия ключа сервера истёк.",
106
106
  "The service is unavailable": "Сервис недоступен",
107
107
  "The verificationResult keyID should be a valid keyID Object.": "The verificationResult keyID should be a valid keyID Object.",
108
- "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "",
109
- "The verificationResult verified should be a valid verified Promise<boolean>.": "",
108
+ "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.": "The verificationResult signature should be a valid verified Promise<openpgp.Signature>.",
109
+ "The verificationResult verified should be a valid verified Promise<boolean>.": "The verificationResult verified should be a valid verified Promise<boolean>.",
110
110
  "This is not a valid passphrase": "Это недействительная парольная фраза",
111
111
  "This key does not match any account.": "Этот ключ не соответствует ни одной учетной записи.",
112
112
  "This key is already used by another user.": "Этот ключ уже используется другим пользователем.",