passbolt-browser-extension 5.2.0 → 5.3.2
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.
- package/CHANGELOG.md +79 -1
- package/Gruntfile.js +1 -1
- package/RELEASE_NOTES.md +27 -71
- package/doc/browser-extension-class-diagram.md +9 -0
- package/package.json +5 -5
- package/src/all/_locales/sl/messages.json +2 -2
- package/src/all/background_page/controller/clipboard/cancelClipboardContentFlushController.js +51 -0
- package/src/all/background_page/controller/clipboard/cancelClipboardContentFlushController.test.js +46 -0
- package/src/all/background_page/controller/clipboard/copyTemporarilyToClipboardController.js +53 -0
- package/src/all/background_page/controller/clipboard/copyTemporarilyToClipboardController.test.js +47 -0
- package/src/all/background_page/controller/clipboard/{clipboardController.js → copyToClipboardController.js} +8 -8
- package/src/all/background_page/controller/clipboard/copyToClipboardController.test.js +47 -0
- package/src/all/background_page/controller/extension/getExtensionVersionController.test.js +1 -1
- package/src/all/background_page/controller/metadata/getOrFindMetadataKeysSettingsController.js +53 -0
- package/src/all/background_page/controller/metadata/getOrFindMetadataKeysSettingsController.test.js +106 -0
- package/src/all/background_page/controller/resource/updateResourceLocalStorageByFolderParentIdController.js +70 -0
- package/src/all/background_page/controller/resource/updateResourceLocalStorageByFolderParentIdController.test.js +78 -0
- package/src/all/background_page/controller/share/shareOneFolderController.test.js +2 -1
- package/src/all/background_page/controller/share/shareResourcesController.test.js +1 -1
- package/src/all/background_page/controller/user/deleteDryRunUserController.js +73 -0
- package/src/all/background_page/controller/user/deleteDryRunUserController.test.js +129 -0
- package/src/all/background_page/controller/user/deleteUserController.js +76 -0
- package/src/all/background_page/controller/user/deleteUserController.test.js +141 -0
- package/src/all/background_page/event/actionLogEvents.js +5 -12
- package/src/all/background_page/event/appEvents.js +33 -0
- package/src/all/background_page/event/findAllForActionLogController.js +58 -0
- package/src/all/background_page/event/findAllForActionLogController.test.js +43 -0
- package/src/all/background_page/event/quickAccessEvents.js +32 -0
- package/src/all/background_page/event/resourceEvents.js +11 -0
- package/src/all/background_page/event/userEvents.js +7 -20
- package/src/all/background_page/event/webIntegrationEvents.js +11 -0
- package/src/all/background_page/model/actionLog/{actionLogModel.js → findActionLogService.js} +25 -5
- package/src/all/background_page/model/actionLog/findActionLogService.test.js +61 -0
- package/src/all/background_page/model/comment/commentModel.js +5 -5
- package/src/all/background_page/model/entity/actionLog/actionLogsCollection.test.data.js +18 -0
- package/src/all/background_page/model/entity/actionLog/defaultActionLogEntity.test.data.js +34 -0
- package/src/all/background_page/model/entity/resource/resourcesCollection.js +25 -0
- package/src/all/background_page/model/entity/resource/resourcesCollection.test.js +34 -0
- package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.test.js +0 -1
- package/src/all/background_page/model/user/userModel.js +0 -60
- package/src/all/background_page/pagemod/appPagemod.js +0 -2
- package/src/all/background_page/pagemod/appPagemod.test.js +2 -6
- package/src/all/background_page/service/alarm/globalAlarmService.js +2 -0
- package/src/all/background_page/service/api/actionLog/{actionLogService.js → actionLogApiService.js} +5 -4
- package/src/all/background_page/service/api/actionLog/actionLogApiService.test.js +55 -0
- package/src/all/background_page/service/api/comment/{commentService.js → commentApiService.js} +6 -7
- package/src/all/background_page/service/api/comment/commentApiService.test.js +122 -0
- package/src/all/background_page/service/api/resource/resourceService.js +1 -0
- package/src/all/background_page/service/auth/postLogoutService.js +2 -0
- package/src/all/background_page/service/auth/postLogoutService.test.js +4 -1
- package/src/all/background_page/service/browser/browserService.js +22 -0
- package/src/all/background_page/service/clipboard/clipboardProviderService.js +40 -0
- package/src/all/background_page/service/clipboard/clipboardProviderService.test.js +61 -0
- package/src/all/background_page/service/clipboard/copyToClipboardService.js +123 -0
- package/src/all/background_page/service/clipboard/copyToClipboardService.test.js +174 -0
- package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.js +52 -1
- package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.test.js +100 -0
- package/src/all/background_page/service/resource/findResourcesService.js +53 -19
- package/src/all/background_page/service/resource/findResourcesService.test.js +191 -0
- package/src/all/background_page/service/resourceType/updateResourceTypesService.test.js +1 -1
- package/src/all/background_page/service/share/shareResourceService.test.js +1 -1
- package/src/all/background_page/service/user/deleteUserService.js +97 -0
- package/src/all/background_page/service/user/deleteUserService.test.js +178 -0
- package/src/all/locales/de-DE/common.json +2 -2
- package/src/all/locales/es-ES/common.json +2 -2
- package/src/all/locales/fr-FR/common.json +5 -5
- package/src/all/locales/it-IT/common.json +2 -2
- package/src/all/locales/ja-JP/common.json +2 -2
- package/src/all/locales/ko-KR/common.json +2 -2
- package/src/all/locales/lt-LT/common.json +2 -2
- package/src/all/locales/nl-NL/common.json +2 -2
- package/src/all/locales/pl-PL/common.json +5 -5
- package/src/all/locales/pt-BR/common.json +2 -2
- package/src/all/locales/ro-RO/common.json +2 -2
- package/src/all/locales/ru-RU/common.json +2 -2
- package/src/all/locales/sl-SI/common.json +33 -33
- package/src/all/locales/sv-SE/common.json +2 -2
- package/src/all/locales/uk-UA/common.json +3 -3
- package/src/chrome/manifest.json +1 -1
- package/src/chrome/polyfill/clipboard/edgeBackgroundPageClipboardService.js +31 -0
- package/src/chrome/polyfill/clipboard/edgeBackgroundPageClipboardService.test.js +51 -0
- package/src/chrome-mv3/index.js +3 -3
- package/src/chrome-mv3/manifest.json +1 -1
- package/src/chrome-mv3/offscreens/{fetch.html → offscreen.html} +1 -1
- package/src/chrome-mv3/offscreens/{fetch.js → offscreen.js} +2 -2
- package/src/chrome-mv3/offscreens/service/clipboard/writeClipobardOffscreenService.js +54 -0
- package/src/chrome-mv3/offscreens/service/clipboard/writeClipobardOffscreenService.test.js +56 -0
- package/src/chrome-mv3/offscreens/service/network/fetchOffscreenService.js +36 -44
- package/src/chrome-mv3/offscreens/service/network/fetchOffscreenService.test.data.js +0 -1
- package/src/chrome-mv3/offscreens/service/network/fetchOffscreenService.test.js +90 -120
- package/src/chrome-mv3/offscreens/service/offscreen/handleOffscreenRequestService.js +85 -0
- package/src/chrome-mv3/offscreens/service/offscreen/handleOffscreenRequestService.test.js +99 -0
- package/src/chrome-mv3/polyfill/clipboardOffscreenPolyfill.js +19 -0
- package/src/chrome-mv3/serviceWorker/service/clipboard/requestClipboardOffscreenService.js +51 -0
- package/src/chrome-mv3/serviceWorker/service/clipboard/requestClipboardOffscreenService.test.js +70 -0
- package/src/chrome-mv3/serviceWorker/service/clipboard/responseClipboardOffscreenService.js +25 -0
- package/src/chrome-mv3/serviceWorker/service/clipboard/responseClipboardOffscreenService.test.data.js +21 -0
- package/src/chrome-mv3/serviceWorker/service/clipboard/responseClipboardOffscreenService.test.js +33 -0
- package/src/chrome-mv3/serviceWorker/service/network/requestFetchOffscreenService.js +25 -50
- package/src/chrome-mv3/serviceWorker/service/network/requestFetchOffscreenService.test.js +16 -39
- package/src/chrome-mv3/serviceWorker/service/network/responseFetchOffscreenService.js +14 -45
- package/src/chrome-mv3/serviceWorker/service/network/responseFetchOffscreenService.test.js +5 -37
- package/src/chrome-mv3/serviceWorker/service/offscreen/createOffscreenDocumentService.js +43 -0
- package/src/chrome-mv3/serviceWorker/service/offscreen/createOffscreenDocumentService.test.js +48 -0
- package/src/chrome-mv3/serviceWorker/service/offscreen/handleOffscreenResponseService.js +119 -0
- package/src/chrome-mv3/serviceWorker/service/offscreen/handleOffscreenResponseService.test.js +159 -0
- package/src/firefox/manifest.json +1 -1
- package/src/safari/manifest.json +1 -1
- package/test/jest.setup.js +4 -0
- package/test/mocks/mockNavigatorClipboard.js +40 -0
- package/test/mocks/mockWebExtensionPolyfill.js +2 -1
- package/{webpack-offscreens.fetch.config.js → webpack-offscreens.config.js} +1 -1
- package/webpack.service-worker.config.js +1 -0
- package/src/all/background_page/controller/clipboard/clipboardController.test.js +0 -68
- package/src/all/background_page/event/clipboardEvents.js +0 -28
|
@@ -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(
|
|
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/
|
|
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";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) Passbolt SA (https://www.passbolt.com)
|
|
4
|
+
*
|
|
5
|
+
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
|
6
|
+
* For full copyright and license information, please see the LICENSE.txt
|
|
7
|
+
* Redistributions of files must retain the above copyright notice.
|
|
8
|
+
*
|
|
9
|
+
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
|
|
10
|
+
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
|
11
|
+
* @link https://www.passbolt.com Passbolt(tm)
|
|
12
|
+
* @since 5.4.0
|
|
13
|
+
*/
|
|
14
|
+
import UserService from "../api/user/userService";
|
|
15
|
+
import {assertType, assertUuid} from "../../utils/assertions";
|
|
16
|
+
import DeleteDryRunError from "../../error/deleteDryRunError";
|
|
17
|
+
import PassboltApiFetchError from "passbolt-styleguide/src/shared/lib/Error/PassboltApiFetchError";
|
|
18
|
+
import UserDeleteTransferEntity from "../../model/entity/user/transfer/userDeleteTransferEntity";
|
|
19
|
+
import UserLocalStorage from "../local_storage/userLocalStorage";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The service aims to delete user from the API.
|
|
23
|
+
*/
|
|
24
|
+
export default class DeleteUserService {
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {AccountEntity} account The user account
|
|
28
|
+
* @param {ApiClientOptions} apiClientOptions The api client options
|
|
29
|
+
*/
|
|
30
|
+
constructor(account, apiClientOptions) {
|
|
31
|
+
this.account = account;
|
|
32
|
+
this.userServiceApi = new UserService(apiClientOptions);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Delete dry run a user.
|
|
37
|
+
* Check if a user can be deleted.
|
|
38
|
+
*
|
|
39
|
+
* A user can not be deleted if:
|
|
40
|
+
* - they are the only owner of a shared resource
|
|
41
|
+
* - they are the only group manager of a group that owns a shared resource
|
|
42
|
+
* In such case ownership transfer is required.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} userId The user id.
|
|
45
|
+
* @returns {Promise<void>}
|
|
46
|
+
* @throws {DeleteDryRunError} if the data should be transferred to someone.
|
|
47
|
+
* @throws {Error} if the data returned by the API is not a PassboltApiFetchError with error code 400 and groups, resources or folders to transfer.
|
|
48
|
+
*/
|
|
49
|
+
async deleteDryRun(userId) {
|
|
50
|
+
assertUuid(userId, "The parameter \"userId\" should be a UUID");
|
|
51
|
+
try {
|
|
52
|
+
await this.userServiceApi.delete(userId, {}, true);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
await this.handleError(error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Delete a user and transfer ownership if needed.
|
|
60
|
+
* @param {string} userId The user id.
|
|
61
|
+
* @param {UserDeleteTransferEntity} [transfer] optional ownership transfer information if needed.
|
|
62
|
+
* @returns {Promise<void>}
|
|
63
|
+
* @throws {DeleteDryRunError} if some permissions must be transferred.
|
|
64
|
+
* @throws {Error} if the data returned by the API is not a PassboltApiFetchError with error code 400 and groups, resources or folders to transfer.
|
|
65
|
+
*/
|
|
66
|
+
async delete(userId, transfer) {
|
|
67
|
+
assertUuid(userId, "The parameter \"userId\" should be a UUID");
|
|
68
|
+
if (transfer !== null) {
|
|
69
|
+
assertType(transfer, UserDeleteTransferEntity, 'The `transfer` parameter should be a UserDeleteTransferEntity.');
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const deleteData = transfer ? transfer.toDto() : {};
|
|
73
|
+
await this.userServiceApi.delete(userId, deleteData);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
await this.handleError(error);
|
|
76
|
+
}
|
|
77
|
+
// Update local storage
|
|
78
|
+
await UserLocalStorage.delete(userId);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @private
|
|
83
|
+
* @param {object} error The error
|
|
84
|
+
* @throws {DeleteDryRunError} if some permissions must be transferred.
|
|
85
|
+
* @throws {Error} if the data returned by the API is not a PassboltApiFetchError with error code 400 and groups, resources or folders to transfer.
|
|
86
|
+
*/
|
|
87
|
+
async handleError(error) {
|
|
88
|
+
if (error instanceof PassboltApiFetchError && error.data.code === 400 && error.data.body.errors) {
|
|
89
|
+
/*
|
|
90
|
+
* recast generic 400 error into a delete dry run error
|
|
91
|
+
* allowing validation of the returned entities and reuse down the line to transfer permissions
|
|
92
|
+
*/
|
|
93
|
+
throw new DeleteDryRunError(error.message, error.data.body.errors);
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passbolt ~ Open source password manager for teams
|
|
3
|
+
* Copyright (c) Passbolt SA (https://www.passbolt.com)
|
|
4
|
+
*
|
|
5
|
+
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
|
6
|
+
* For full copyright and license information, please see the LICENSE.txt
|
|
7
|
+
* Redistributions of files must retain the above copyright notice.
|
|
8
|
+
*
|
|
9
|
+
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
|
|
10
|
+
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
|
11
|
+
* @link https://www.passbolt.com Passbolt(tm)
|
|
12
|
+
* @since 5.4.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import AccountEntity from "../../model/entity/account/accountEntity";
|
|
16
|
+
import {defaultAccountDto} from "../../model/entity/account/accountEntity.test.data";
|
|
17
|
+
import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
|
|
18
|
+
import DeleteUserService from "./deleteUserService";
|
|
19
|
+
import {v4 as uuidv4} from "uuid";
|
|
20
|
+
import DeleteDryRunError from "../../error/deleteDryRunError";
|
|
21
|
+
import PassboltApiFetchError from "passbolt-styleguide/src/shared/lib/Error/PassboltApiFetchError";
|
|
22
|
+
import UserDeleteTransferEntity from "../../model/entity/user/transfer/userDeleteTransferEntity";
|
|
23
|
+
import {defaultUserDeleteTransferDto} from "passbolt-styleguide/src/shared/models/entity/user/userDeleteTransferEntity.test.data";
|
|
24
|
+
import {defaultResourceDto} from "passbolt-styleguide/src/shared/models/entity/resource/resourceEntity.test.data";
|
|
25
|
+
import UserLocalStorage from "../local_storage/userLocalStorage";
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
jest.clearAllMocks();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe("DeleteUserService", () => {
|
|
32
|
+
let deleteUserService, apiClientOptions;
|
|
33
|
+
const account = new AccountEntity(defaultAccountDto());
|
|
34
|
+
|
|
35
|
+
beforeEach(async() => {
|
|
36
|
+
apiClientOptions = defaultApiClientOptions();
|
|
37
|
+
deleteUserService = new DeleteUserService(account, apiClientOptions);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("::deleteDryRun", () => {
|
|
41
|
+
it("Do not need to transfer ownership.", async() => {
|
|
42
|
+
expect.assertions(1);
|
|
43
|
+
|
|
44
|
+
const usersId = uuidv4();
|
|
45
|
+
jest.spyOn(deleteUserService.userServiceApi, "delete").mockImplementationOnce(() => {});
|
|
46
|
+
|
|
47
|
+
await deleteUserService.deleteDryRun(usersId);
|
|
48
|
+
|
|
49
|
+
expect(deleteUserService.userServiceApi.delete).toHaveBeenCalledWith(usersId, {}, true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("Need to transfer ownership.", async() => {
|
|
53
|
+
expect.assertions(1);
|
|
54
|
+
|
|
55
|
+
const usersId = uuidv4();
|
|
56
|
+
const resourceDto = defaultResourceDto();
|
|
57
|
+
const error = {
|
|
58
|
+
code: 400,
|
|
59
|
+
body: {
|
|
60
|
+
errors: {
|
|
61
|
+
resources: {
|
|
62
|
+
sole_owner: [resourceDto]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
jest.spyOn(deleteUserService.userServiceApi, "delete").mockImplementationOnce(() => { throw new PassboltApiFetchError("Error", error); });
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
await deleteUserService.deleteDryRun(usersId);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
expect(error).toBeInstanceOf(DeleteDryRunError);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("throw any error not handled.", async() => {
|
|
77
|
+
expect.assertions(1);
|
|
78
|
+
|
|
79
|
+
const usersId = uuidv4();
|
|
80
|
+
const error = {
|
|
81
|
+
code: 404,
|
|
82
|
+
};
|
|
83
|
+
jest.spyOn(deleteUserService.userServiceApi, "delete").mockImplementationOnce(() => { throw new PassboltApiFetchError("Error", error); });
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
await deleteUserService.deleteDryRun(usersId);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
expect(error).toBeInstanceOf(PassboltApiFetchError);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("throws if user id is not an uuid.", async() => {
|
|
93
|
+
expect.assertions(1);
|
|
94
|
+
|
|
95
|
+
const promise = deleteUserService.deleteDryRun({});
|
|
96
|
+
|
|
97
|
+
expect(promise).rejects.toThrow(Error("The parameter \"userId\" should be a UUID"));
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe("::delete", () => {
|
|
102
|
+
it("delete a user with no transfer.", async() => {
|
|
103
|
+
expect.assertions(2);
|
|
104
|
+
|
|
105
|
+
const usersId = uuidv4();
|
|
106
|
+
jest.spyOn(deleteUserService.userServiceApi, "delete").mockImplementationOnce(() => {});
|
|
107
|
+
jest.spyOn(UserLocalStorage, "delete").mockImplementationOnce(() => {});
|
|
108
|
+
|
|
109
|
+
await deleteUserService.delete(usersId, null);
|
|
110
|
+
|
|
111
|
+
expect(deleteUserService.userServiceApi.delete).toHaveBeenCalledWith(usersId, {});
|
|
112
|
+
expect(UserLocalStorage.delete).toHaveBeenCalledWith(usersId);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("delete a user with transfer.", async() => {
|
|
116
|
+
expect.assertions(2);
|
|
117
|
+
|
|
118
|
+
const usersId = uuidv4();
|
|
119
|
+
const dto = defaultUserDeleteTransferDto();
|
|
120
|
+
const userDeleteTransfer = new UserDeleteTransferEntity(dto);
|
|
121
|
+
jest.spyOn(deleteUserService.userServiceApi, "delete").mockImplementationOnce(() => {});
|
|
122
|
+
jest.spyOn(UserLocalStorage, "delete").mockImplementationOnce(() => {});
|
|
123
|
+
|
|
124
|
+
await deleteUserService.delete(usersId, userDeleteTransfer);
|
|
125
|
+
|
|
126
|
+
expect(deleteUserService.userServiceApi.delete).toHaveBeenCalledWith(usersId, dto);
|
|
127
|
+
expect(UserLocalStorage.delete).toHaveBeenCalledWith(usersId);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("delete a user with an error and need to transfer ownership.", async() => {
|
|
131
|
+
expect.assertions(1);
|
|
132
|
+
|
|
133
|
+
const usersId = uuidv4();
|
|
134
|
+
const resourceDto = defaultResourceDto();
|
|
135
|
+
const error = {
|
|
136
|
+
code: 400,
|
|
137
|
+
body: {
|
|
138
|
+
errors: {
|
|
139
|
+
resources: {
|
|
140
|
+
sole_owner: [resourceDto]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
jest.spyOn(deleteUserService.userServiceApi, "delete").mockImplementationOnce(() => { throw new PassboltApiFetchError("Error", error); });
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
await deleteUserService.delete(usersId, null);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
expect(error).toBeInstanceOf(DeleteDryRunError);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("delete a user with an unexpected error.", async() => {
|
|
155
|
+
expect.assertions(1);
|
|
156
|
+
|
|
157
|
+
const usersId = uuidv4();
|
|
158
|
+
const error = {
|
|
159
|
+
code: 404,
|
|
160
|
+
};
|
|
161
|
+
jest.spyOn(deleteUserService.userServiceApi, "delete").mockImplementationOnce(() => { throw new PassboltApiFetchError("Error", error); });
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
await deleteUserService.delete(usersId, null);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
expect(error).toBeInstanceOf(PassboltApiFetchError);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("throws if user id is not an uuid.", async() => {
|
|
171
|
+
expect.assertions(1);
|
|
172
|
+
|
|
173
|
+
const promise = deleteUserService.delete({});
|
|
174
|
+
|
|
175
|
+
expect(promise).rejects.toThrow(Error("The parameter \"userId\" should be a UUID"));
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
@@ -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.": "
|
|
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.": "
|
|
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.": "
|
|
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.": "
|
|
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.": "
|
|
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.": "
|
|
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.",
|