passbolt-browser-extension 5.3.2 → 5.4.1
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 +58 -1
- package/README.md +2 -2
- package/RELEASE_NOTES.md +8 -30
- package/crowdin.yml +1 -0
- package/package.json +4 -3
- package/src/all/_locales/cs/messages.json +10 -0
- package/src/all/background_page/controller/InformMenuController/InformMenuController.js +3 -3
- package/src/all/background_page/controller/auth/redirectPostLoginController.js +57 -0
- package/src/all/background_page/controller/auth/redirectPostLoginController.test.js +82 -0
- package/src/all/background_page/controller/auth/redirectToAdminWorkspaceController.js +50 -0
- package/src/all/background_page/controller/auth/redirectToAdminWorkspaceController.test.js +45 -0
- package/src/all/background_page/controller/comment/createCommentController.js +3 -3
- package/src/all/background_page/controller/comment/createCommentController.test.js +5 -5
- package/src/all/background_page/controller/comment/deleteCommentController.js +3 -3
- package/src/all/background_page/controller/comment/deleteCommentController.test.js +3 -3
- package/src/all/background_page/controller/comment/getCommentsByRessourceIdController.js +3 -3
- package/src/all/background_page/controller/comment/getCommentsByRessourceidController.test.js +2 -2
- package/src/all/background_page/controller/import/importResourcesFileController.test.js +23 -23
- package/src/all/background_page/controller/metadata/enableEncryptedMetadataForExistingInstanceController.js +54 -0
- package/src/all/background_page/controller/metadata/enableEncryptedMetadataForExistingInstanceController.test.js +54 -0
- package/src/all/background_page/controller/metadata/enableMetadataSetupSettingsController.js +54 -0
- package/src/all/background_page/controller/metadata/enableMetadataSetupSettingsController.test.js +64 -0
- package/src/all/background_page/controller/metadata/findAllNonDeletedMetadataKeysController.js +2 -3
- package/src/all/background_page/controller/metadata/findMetadataGettingStartedSettingsController.js +50 -0
- package/src/all/background_page/controller/metadata/findMetadataGettingStartedSettingsController.test.js +33 -0
- package/src/all/background_page/controller/metadata/findMetadataSetupSettingsController.js +50 -0
- package/src/all/background_page/controller/metadata/findMetadataSetupSettingsController.test.js +42 -0
- package/src/all/background_page/controller/metadata/keepCleartextMetadataForExistingInstanceController.js +51 -0
- package/src/all/background_page/controller/metadata/keepCleartextMetadataForExistingInstanceController.test.js +47 -0
- package/src/all/background_page/controller/permission/FindAcoPermissionsForDisplayController.js +1 -0
- package/src/all/background_page/controller/quickaccess/consumeInProgressCreationResourceController.js +53 -0
- package/src/all/background_page/controller/quickaccess/consumeInProgressCreationResourceController.test.js +40 -0
- package/src/all/background_page/controller/quickaccess/prepareResourceController.js +64 -0
- package/src/all/background_page/controller/quickaccess/prepareResourceController.test.js +73 -0
- package/src/all/background_page/controller/resource/resourceDeleteController.js +67 -0
- package/src/all/background_page/controller/resource/resourceDeleteController.test.js +114 -0
- package/src/all/background_page/controller/resourceLocalStorage/resourceUpdateLocalStorageController.js +1 -1
- package/src/all/background_page/controller/resourceLocalStorage/resourceUpdateLocalStorageController.test.js +5 -1
- package/src/all/background_page/controller/setup/signInSetupController.js +0 -10
- package/src/all/background_page/controller/setup/signInSetupController.test.js +11 -12
- package/src/all/background_page/controller/sso/saveSsoSettingsAsDraftController.test.data.js +1 -0
- package/src/all/background_page/controller/webIntegration/webIntegrationController.js +1 -1
- package/src/all/background_page/event/appEvents.js +47 -0
- package/src/all/background_page/event/authEvents.js +4 -8
- package/src/all/background_page/event/informMenuEvents.js +31 -0
- package/src/all/background_page/event/quickAccessEvents.js +18 -23
- package/src/all/background_page/event/recoverEvents.js +12 -0
- package/src/all/background_page/event/resourceEvents.js +4 -11
- package/src/all/background_page/event/setupEvents.js +55 -0
- package/src/all/background_page/model/comment/{commentModel.js → commentService.js} +6 -2
- package/src/all/background_page/model/comment/commentService.test.js +98 -0
- package/src/all/background_page/model/entity/actionLog/actionLogsCollection.js +3 -3
- package/src/all/background_page/model/entity/actionLog/permissionsUpdatedActionLogEntity.js +4 -0
- package/src/all/background_page/model/entity/import/importResourcesFileEntity.test.data.js +3 -3
- package/src/all/background_page/model/entity/organizationSettings/organizationSettingsEntity.test.data.js +4 -0
- package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionEntity.test.data.js +23 -0
- package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionEntity.test.js +18 -33
- package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionsCollection.js +71 -2
- package/src/all/background_page/model/entity/permission/actionLog/updatedPermissionsCollection.test.js +204 -0
- package/src/all/background_page/model/entity/permission/permissionsCollection.js +78 -0
- package/src/all/background_page/model/entity/permission/permissionsCollection.test.js +139 -7
- package/src/all/background_page/model/entity/plaintext/plaintextEntity.js +9 -0
- package/src/all/background_page/model/entity/resource/external/externalResourceEntity.js +65 -8
- package/src/all/background_page/model/entity/resource/external/externalResourceEntity.test.data.js +5 -4
- package/src/all/background_page/model/entity/resource/external/externalResourceEntity.test.js +72 -16
- package/src/all/background_page/model/entity/resource/external/externalResourcesCollection.test.js +2 -1
- package/src/all/background_page/model/entity/totp/externalTotpEntity.js +2 -2
- package/src/all/background_page/model/entity/totp/totpEntity.test.js +1 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csv1PasswordRowComposer.test.js +2 -2
- package/src/all/background_page/model/export/resources/csvRowComposer/csv1passwordRowComposer.js +5 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvBitWardenRowComposer.js +9 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvBitWardenRowComposer.test.js +6 -4
- package/src/all/background_page/model/export/resources/csvRowComposer/csvChromiumRowComposer.js +5 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvChromiumRowComposer.test.js +3 -2
- package/src/all/background_page/model/export/resources/csvRowComposer/csvDashlaneRowComposer.js +5 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvDashlaneRowComposer.test.js +2 -3
- package/src/all/background_page/model/export/resources/csvRowComposer/csvKdbxRowComposer.js +3 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvKdbxRowComposer.test.js +6 -4
- package/src/all/background_page/model/export/resources/csvRowComposer/csvLastPassRowComposer.js +5 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvLastPassRowComposer.test.js +2 -3
- package/src/all/background_page/model/export/resources/csvRowComposer/csvLogMeOnceRowComposer.js +5 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvLogMeOnceRowComposer.test.js +2 -3
- package/src/all/background_page/model/export/resources/csvRowComposer/csvMozillaPlatformRowComposer.js +6 -2
- package/src/all/background_page/model/export/resources/csvRowComposer/csvMozillaPlatformRowComposer.test.js +2 -2
- package/src/all/background_page/model/export/resources/csvRowComposer/csvNordpassRowComposer.js +5 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvNordpassRowComposer.test.js +2 -2
- package/src/all/background_page/model/export/resources/csvRowComposer/csvSafariRowComposer.js +5 -1
- package/src/all/background_page/model/export/resources/csvRowComposer/csvSafariRowComposer.test.js +2 -2
- package/src/all/background_page/model/export/resources/resourcesKdbxExporter.js +44 -2
- package/src/all/background_page/model/export/resources/resourcesKdbxExporter.test.js +24 -3
- package/src/all/background_page/model/import/resources/csvRowParser/abstractCsvRowParser.js +1 -1
- package/src/all/background_page/model/import/resources/csvRowParser/csv1PasswordRowParser.js +5 -3
- package/src/all/background_page/model/import/resources/csvRowParser/csv1PasswordRowParser.test.js +3 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvBitWardenRowParser.js +22 -3
- package/src/all/background_page/model/import/resources/csvRowParser/csvBitWardenRowParser.test.js +92 -4
- package/src/all/background_page/model/import/resources/csvRowParser/csvChromiumRowParser.js +4 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvChromiumRowParser.test.js +2 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvDashlaneRowParser.js +4 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvDashlaneRowParser.test.js +3 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvKdbxRowParser.js +5 -3
- package/src/all/background_page/model/import/resources/csvRowParser/csvKdbxRowParser.test.js +4 -4
- package/src/all/background_page/model/import/resources/csvRowParser/csvLastPassRowParser.js +4 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvLastPassRowParser.test.js +2 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvLogMeOnceRowParser.js +5 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvLogMeOnceRowParser.test.js +2 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvMozillaPlatformRowParser.js +5 -3
- package/src/all/background_page/model/import/resources/csvRowParser/csvMozillaPlatformRowParser.test.js +2 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvNordpassRowParser.js +4 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvNordpassRowParser.test.js +2 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvSafariRowParser.js +4 -2
- package/src/all/background_page/model/import/resources/csvRowParser/csvSafariRowParser.test.js +2 -2
- package/src/all/background_page/model/import/resources/kdbx/kdbx-custom-fields-with-uris.kdbx +0 -0
- package/src/all/background_page/model/import/resources/kdbx/kdbx-multiple-uris-with-33-entries.kdbx +0 -0
- package/src/all/background_page/model/import/resources/kdbx/kdbx-multiple-uris.kdbx +0 -0
- package/src/all/background_page/model/import/resources/kdbx/kdbx-with-protected-custom-fields.kdbx +0 -0
- package/src/all/background_page/model/import/resources/resourcesCsvImportParser.test.js +1 -1
- package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.js +124 -41
- package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.test.js +133 -1
- package/src/all/background_page/model/import/resourcesImportParser.test.js +0 -1
- package/src/all/background_page/model/resource/resourceModel.js +0 -68
- package/src/all/background_page/service/api/comment/commentApiService.test.js +1 -1
- package/src/all/background_page/service/api/metadata/metadataSetupSettingsApiService.js +40 -0
- package/src/all/background_page/service/api/metadata/metadataSetupSettingsApiService.test.js +54 -0
- package/src/all/background_page/service/api/setup/setupService.js +2 -2
- package/src/all/background_page/service/api/setup/setupService.test.js +132 -0
- package/src/all/background_page/service/local_storage/resourceLocalStorage.js +25 -1
- package/src/all/background_page/service/local_storage/resourceLocalStorage.test.js +54 -0
- package/src/all/background_page/service/metadata/configureMetadataSettingsService.js +100 -0
- package/src/all/background_page/service/metadata/configureMetadataSettingsService.test.js +265 -0
- package/src/all/background_page/service/metadata/createMetadataKeyService.js +1 -1
- package/src/all/background_page/service/metadata/decryptMetadataPrivateKeysService.js +3 -19
- package/src/all/background_page/service/metadata/decryptMetadataService.js +5 -3
- package/src/all/background_page/service/metadata/decryptMetadataService.test.js +31 -24
- package/src/all/background_page/service/metadata/encryptMetadataService.js +2 -18
- package/src/all/background_page/service/metadata/findAndUpdateMetadataKeysSessionStorageService.js +5 -2
- package/src/all/background_page/service/metadata/findAndUpdateMetadataKeysSessionStorageService.test.js +4 -6
- package/src/all/background_page/service/metadata/findMetadataKeysService.js +8 -12
- package/src/all/background_page/service/metadata/findMetadataKeysService.test.js +21 -47
- package/src/all/background_page/service/metadata/findMetadataSetupSettingsService.js +45 -0
- package/src/all/background_page/service/metadata/findMetadataSetupSettingsService.test.js +68 -0
- package/src/all/background_page/service/metadata/generateMetadataKeyService.js +1 -1
- package/src/all/background_page/service/metadata/verifyOrTrustMetadataKeyService.test.js +16 -0
- package/src/all/background_page/service/passphrase/getPassphraseService.js +13 -0
- package/src/all/background_page/service/permission/findPermissionsService.js +3 -1
- package/src/all/background_page/service/resource/delete/deleteResourceService.js +60 -0
- package/src/all/background_page/service/resource/delete/deleteResourceService.test.js +75 -0
- package/src/all/background_page/service/resource/export/exportResourcesService.js +22 -0
- package/src/all/background_page/service/resource/export/exportResourcesService.test.js +48 -1
- package/src/all/background_page/service/resource/import/ImportResourcesService.js +34 -3
- package/src/all/background_page/service/resource/import/ImportResourcesService.test.js +55 -13
- package/src/all/background_page/service/sessionKey/decryptSessionKeysBundlesService.js +2 -18
- package/src/all/background_page/service/sessionKey/encryptSessionKeysBundlesService.js +1 -17
- package/src/all/locales/cs-CZ/common.json +130 -0
- package/src/all/locales/de-DE/common.json +11 -5
- package/src/all/locales/en-UK/common.json +6 -0
- package/src/all/locales/es-ES/common.json +6 -0
- package/src/all/locales/fr-FR/common.json +6 -0
- package/src/all/locales/it-IT/common.json +6 -0
- package/src/all/locales/ja-JP/common.json +6 -0
- package/src/all/locales/ko-KR/common.json +6 -0
- package/src/all/locales/lt-LT/common.json +6 -0
- package/src/all/locales/nl-NL/common.json +6 -0
- package/src/all/locales/pl-PL/common.json +6 -0
- package/src/all/locales/pt-BR/common.json +6 -0
- package/src/all/locales/ro-RO/common.json +6 -0
- package/src/all/locales/ru-RU/common.json +6 -0
- package/src/all/locales/sl-SI/common.json +6 -0
- package/src/all/locales/sv-SE/common.json +6 -0
- package/src/all/locales/uk-UA/common.json +6 -0
- package/src/chrome/manifest.json +1 -1
- package/src/chrome-mv3/manifest.json +1 -1
- package/src/firefox/manifest.json +1 -1
- package/src/safari/manifest.json +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
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 AbstractService from "../abstract/abstractService";
|
|
16
|
+
import PassboltResponseEntity from "passbolt-styleguide/src/shared/models/entity/apiService/PassboltResponseEntity";
|
|
17
|
+
|
|
18
|
+
const METADATA_SETUP_RESOURCE_NAME = "metadata/setup/";
|
|
19
|
+
|
|
20
|
+
export default class MetadataSetupSettingsApiService extends AbstractService {
|
|
21
|
+
/**
|
|
22
|
+
* @constructor
|
|
23
|
+
* @param {ApiClientOptions} apiClientOptions
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
constructor(apiClientOptions) {
|
|
27
|
+
super(apiClientOptions, METADATA_SETUP_RESOURCE_NAME);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Find the metadata setup settings on the Passbolt API
|
|
32
|
+
*
|
|
33
|
+
* @returns {Promise<PassboltResponseEntity>} the api response
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
async find() {
|
|
37
|
+
const response = await this.apiClient.get("settings");
|
|
38
|
+
return new PassboltResponseEntity(response);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
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 {enableFetchMocks} from "jest-fetch-mock";
|
|
15
|
+
import {mockApiResponse} from '../../../../../../test/mocks/mockApiResponse';
|
|
16
|
+
import MetadataSetupSettingsApiService from "./metadataSetupSettingsApiService";
|
|
17
|
+
import {defaultApiClientOptions} from "passbolt-styleguide/src/shared/lib/apiClient/apiClientOptions.test.data";
|
|
18
|
+
import {enableMetadataSetupSettingsDto} from "passbolt-styleguide/src/shared/models/entity/metadata/metadataSetupSettingsEntity.test.data";
|
|
19
|
+
import PassboltResponseEntity from "passbolt-styleguide/src/shared/models/entity/apiService/PassboltResponseEntity";
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
jest.resetAllMocks();
|
|
23
|
+
enableFetchMocks();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("metadataSetupSettingsApiService", () => {
|
|
27
|
+
describe('::find', () => {
|
|
28
|
+
it("Should return a PassboltResponseEntity if everything goes well.", async() => {
|
|
29
|
+
expect.assertions(2);
|
|
30
|
+
|
|
31
|
+
const apiClientOptions = defaultApiClientOptions();
|
|
32
|
+
const service = new MetadataSetupSettingsApiService(apiClientOptions);
|
|
33
|
+
const expectedBodyResponse = enableMetadataSetupSettingsDto();
|
|
34
|
+
|
|
35
|
+
fetch.doMockOnceIf(/\/metadata\/setup\/settings\.json/, () => mockApiResponse(expectedBodyResponse));
|
|
36
|
+
|
|
37
|
+
const apiResult = await service.find();
|
|
38
|
+
|
|
39
|
+
expect(apiResult).toBeInstanceOf(PassboltResponseEntity);
|
|
40
|
+
expect(apiResult.body).toStrictEqual(expectedBodyResponse);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should throw an error if something goes wrong during the fetch", async() => {
|
|
44
|
+
expect.assertions(1);
|
|
45
|
+
|
|
46
|
+
const apiClientOptions = defaultApiClientOptions();
|
|
47
|
+
const service = new MetadataSetupSettingsApiService(apiClientOptions);
|
|
48
|
+
|
|
49
|
+
fetch.doMockOnceIf(/\/metadata\/setup\/settings\.json/, () => { throw new Error("Something went wrong"); });
|
|
50
|
+
|
|
51
|
+
await expect(() => service.find()).rejects.toThrowError();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -44,7 +44,7 @@ class SetupService extends AbstractService {
|
|
|
44
44
|
*/
|
|
45
45
|
async complete(userId, completeDto) {
|
|
46
46
|
this.assertValidId(userId);
|
|
47
|
-
const url =
|
|
47
|
+
const url = this.apiClient.buildUrl(`${this.apiClient.baseUrl}/complete/${userId}`, {});
|
|
48
48
|
const bodyString = this.apiClient.buildBody(completeDto);
|
|
49
49
|
return this.apiClient.fetchAndHandleResponse('POST', url, bodyString);
|
|
50
50
|
}
|
|
@@ -58,7 +58,7 @@ class SetupService extends AbstractService {
|
|
|
58
58
|
*/
|
|
59
59
|
async completeRecover(userId, completeDto) {
|
|
60
60
|
this.assertValidId(userId);
|
|
61
|
-
const url =
|
|
61
|
+
const url = this.apiClient.buildUrl(`${this.apiClient.baseUrl}/recover/complete/${userId}`, {});
|
|
62
62
|
const bodyString = this.apiClient.buildBody(completeDto);
|
|
63
63
|
return this.apiClient.fetchAndHandleResponse('POST', url, bodyString);
|
|
64
64
|
}
|
|
@@ -0,0 +1,132 @@
|
|
|
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 {v4 as uuidv4} from "uuid";
|
|
15
|
+
import {enableFetchMocks} from "jest-fetch-mock";
|
|
16
|
+
import {mockApiResponse, mockApiResponseError} from "passbolt-styleguide/test/mocks/mockApiResponse";
|
|
17
|
+
import PassboltApiFetchError from "passbolt-styleguide/src/shared/lib/Error/PassboltApiFetchError";
|
|
18
|
+
import PassboltServiceUnavailableError from "passbolt-styleguide/src/shared/lib/Error/PassboltServiceUnavailableError";
|
|
19
|
+
import SetupService from "./setupService";
|
|
20
|
+
import BuildApiClientOptionsService from "../../account/buildApiClientOptionsService";
|
|
21
|
+
import AccountEntity from "../../../model/entity/account/accountEntity";
|
|
22
|
+
import {defaultAccountDto} from "../../../model/entity/account/accountEntity.test.data";
|
|
23
|
+
import {initialAccountAccountRecoveryDto} from "../../../model/entity/account/accountAccountRecoveryEntity.test.data";
|
|
24
|
+
import {startAccountSetupDto} from "../../../model/entity/account/accountSetupEntity.test.data";
|
|
25
|
+
|
|
26
|
+
describe("SetupService", () => {
|
|
27
|
+
let service, apiClientOptions, userId,
|
|
28
|
+
accountRecoveryDto, setupCompleteDto;
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
enableFetchMocks();
|
|
32
|
+
fetch.resetMocks();
|
|
33
|
+
const account = new AccountEntity(defaultAccountDto());
|
|
34
|
+
apiClientOptions = BuildApiClientOptionsService.buildFromAccount(account);
|
|
35
|
+
service = new SetupService(apiClientOptions);
|
|
36
|
+
|
|
37
|
+
userId = uuidv4();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("::complete", () => {
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
setupCompleteDto = startAccountSetupDto();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("calls the complete API with correct URL", async() => {
|
|
46
|
+
expect.assertions(2);
|
|
47
|
+
|
|
48
|
+
fetch.doMockOnceIf(new RegExp(`/complete/${userId}`), () => mockApiResponse({success: true}));
|
|
49
|
+
|
|
50
|
+
await service.complete(userId, setupCompleteDto);
|
|
51
|
+
|
|
52
|
+
const lastCall = fetch.mock.calls[0];
|
|
53
|
+
const [url, options] = lastCall;
|
|
54
|
+
|
|
55
|
+
expect(url).toMatch(`/complete/${userId}.json`);
|
|
56
|
+
expect(options.method).toBe("POST");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("throws API error if API returns an error", async() => {
|
|
60
|
+
expect.assertions(1);
|
|
61
|
+
|
|
62
|
+
fetch.mockResponseOnce(async() => {
|
|
63
|
+
const mockResponse = await mockApiResponseError(400, "Invalid request", {});
|
|
64
|
+
return {
|
|
65
|
+
status: mockResponse.status,
|
|
66
|
+
body: mockResponse.body,
|
|
67
|
+
headers: {"Content-Type": "application/json"}
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await expect(service.complete(userId, setupCompleteDto)).rejects.toThrow(PassboltApiFetchError);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("throws service unavailable error on unexpected failure", async() => {
|
|
75
|
+
expect.assertions(1);
|
|
76
|
+
fetch.mockImplementationOnce(() => { throw new Error("Service Down"); });
|
|
77
|
+
|
|
78
|
+
await expect(() => service.complete(userId, setupCompleteDto)).rejects.toThrow(PassboltServiceUnavailableError);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("throws an error if userId is invalid", async() => {
|
|
82
|
+
expect.assertions(1);
|
|
83
|
+
await expect(() => service.complete("invalid-id", setupCompleteDto)).rejects.toThrow(Error);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("::completeRecover", () => {
|
|
88
|
+
beforeEach(() => {
|
|
89
|
+
accountRecoveryDto = initialAccountAccountRecoveryDto();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("calls the completeRecover API with correct URL", async() => {
|
|
93
|
+
expect.assertions(2);
|
|
94
|
+
|
|
95
|
+
fetch.doMockOnceIf(new RegExp(`/recover/complete/${userId}`), () => mockApiResponse({success: true}));
|
|
96
|
+
|
|
97
|
+
await service.completeRecover(userId, accountRecoveryDto);
|
|
98
|
+
|
|
99
|
+
const lastCall = fetch.mock.calls[0];
|
|
100
|
+
const [url, options] = lastCall;
|
|
101
|
+
|
|
102
|
+
expect(url).toMatch(`/recover/complete/${userId}.json`);
|
|
103
|
+
expect(options.method).toBe("POST");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("throws API error if API returns an error", async() => {
|
|
107
|
+
expect.assertions(1);
|
|
108
|
+
fetch.mockResponseOnce(async() => {
|
|
109
|
+
const mockResponse = await mockApiResponseError(400, "Invalid request", {});
|
|
110
|
+
return {
|
|
111
|
+
status: mockResponse.status,
|
|
112
|
+
body: mockResponse.body,
|
|
113
|
+
headers: {"Content-Type": "application/json"}
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
await expect(() => service.completeRecover(userId, accountRecoveryDto)).rejects.toThrow(PassboltApiFetchError);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("throws service unavailable error on unexpected failure", async() => {
|
|
121
|
+
expect.assertions(1);
|
|
122
|
+
fetch.mockImplementationOnce(() => { throw new Error("Service unavailable"); });
|
|
123
|
+
|
|
124
|
+
await expect(() => service.completeRecover(userId, accountRecoveryDto)).rejects.toThrow(PassboltServiceUnavailableError);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("throws an error if userId is invalid", async() => {
|
|
128
|
+
expect.assertions(1);
|
|
129
|
+
await expect(() => service.completeRecover("invalid-id", accountRecoveryDto)).rejects.toThrow(Error);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
@@ -15,7 +15,7 @@ import Log from "../../model/log";
|
|
|
15
15
|
import ResourcesCollection from "../../model/entity/resource/resourcesCollection";
|
|
16
16
|
import ResourceEntity from "../../model/entity/resource/resourceEntity";
|
|
17
17
|
import Lock from "../../utils/lock";
|
|
18
|
-
import {assertType, assertUuid} from "../../utils/assertions";
|
|
18
|
+
import {assertArrayUUID, assertType, assertUuid} from "../../utils/assertions";
|
|
19
19
|
import PasswordExpiryResourceEntity from "../../model/entity/passwordExpiry/passwordExpiryResourceEntity";
|
|
20
20
|
|
|
21
21
|
const lock = new Lock();
|
|
@@ -273,6 +273,30 @@ class ResourceLocalStorage {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Delete multiple resources in local storage by Id
|
|
278
|
+
* @param {Array<string>} resourceIds
|
|
279
|
+
*/
|
|
280
|
+
static async deleteResources(resourceIds) {
|
|
281
|
+
assertArrayUUID(resourceIds);
|
|
282
|
+
await lock.acquire();
|
|
283
|
+
try {
|
|
284
|
+
const resources = await ResourceLocalStorage.get() || [];
|
|
285
|
+
|
|
286
|
+
if (resources.length > 0 && resourceIds.length > 0) {
|
|
287
|
+
const setOfResourceIds = new Set(resourceIds);
|
|
288
|
+
|
|
289
|
+
const filteredResources = resources.filter(resource => !setOfResourceIds.has(resource.id));
|
|
290
|
+
|
|
291
|
+
await browser.storage.local.set({resources: filteredResources});
|
|
292
|
+
ResourceLocalStorage._cachedData = filteredResources;
|
|
293
|
+
}
|
|
294
|
+
} finally {
|
|
295
|
+
lock.release();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
276
300
|
/*
|
|
277
301
|
* =================================================
|
|
278
302
|
* Static methods
|
|
@@ -600,4 +600,58 @@ describe("ResourceLocalStorage", () => {
|
|
|
600
600
|
expect(ResourceLocalStorage._cachedData).toBeNull();
|
|
601
601
|
});
|
|
602
602
|
});
|
|
603
|
+
|
|
604
|
+
describe("::deleteResources", () => {
|
|
605
|
+
it("Should throw if no data passed as parameter", async() => {
|
|
606
|
+
expect.assertions(1);
|
|
607
|
+
const promise = ResourceLocalStorage.deleteResources();
|
|
608
|
+
await expect(promise).rejects.toThrow("The given parameter is not a valid array of uuid");
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
it("Should throw if the resourceIds parameter is not a valid entry", async() => {
|
|
612
|
+
expect.assertions(1);
|
|
613
|
+
const promise = ResourceLocalStorage.deleteResources(42);
|
|
614
|
+
await expect(promise).rejects.toThrow("he given parameter is not a valid array of uuid");
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
it("Should do nothing if the resource is not found in the local storage", async() => {
|
|
618
|
+
expect.assertions(2);
|
|
619
|
+
const resourceDto = defaultResourceDto();
|
|
620
|
+
const resourcesDtos = [resourceDto];
|
|
621
|
+
await browser.storage.local.set({[RESOURCES_LOCAL_STORAGE_KEY]: resourcesDtos});
|
|
622
|
+
await ResourceLocalStorage.deleteResources([uuidv4()]);
|
|
623
|
+
const localStorageData = await browser.storage.local.get([RESOURCES_LOCAL_STORAGE_KEY]);
|
|
624
|
+
expect(localStorageData[RESOURCES_LOCAL_STORAGE_KEY]).toEqual(expect.any(Array));
|
|
625
|
+
expect(localStorageData[RESOURCES_LOCAL_STORAGE_KEY]).toHaveLength(1);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
it("Should update the resources", async() => {
|
|
629
|
+
expect.assertions(3);
|
|
630
|
+
const resourceDto1 = defaultResourceDto();
|
|
631
|
+
const resourceDto2 = defaultResourceDto();
|
|
632
|
+
const resourceDto3 = defaultResourceDto();
|
|
633
|
+
const resourcesDtos = [resourceDto1, resourceDto2, resourceDto3];
|
|
634
|
+
await browser.storage.local.set({[RESOURCES_LOCAL_STORAGE_KEY]: resourcesDtos});
|
|
635
|
+
await ResourceLocalStorage.deleteResources([resourceDto1.id, resourceDto2.id]);
|
|
636
|
+
const localStorageData = await browser.storage.local.get([RESOURCES_LOCAL_STORAGE_KEY]);
|
|
637
|
+
expect(localStorageData[RESOURCES_LOCAL_STORAGE_KEY]).toEqual(expect.any(Array));
|
|
638
|
+
expect(localStorageData[RESOURCES_LOCAL_STORAGE_KEY]).toHaveLength(1);
|
|
639
|
+
expect(localStorageData[RESOURCES_LOCAL_STORAGE_KEY][0]).toEqual(resourceDto3);
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
it("Should update cache after deleting the resources", async() => {
|
|
643
|
+
expect.assertions(5);
|
|
644
|
+
const resourceDto1 = defaultResourceDto();
|
|
645
|
+
const resourceDto2 = defaultResourceDto();
|
|
646
|
+
const resourceDto3 = defaultResourceDto();
|
|
647
|
+
const resourcesDtos = [resourceDto1, resourceDto2, resourceDto3];
|
|
648
|
+
await browser.storage.local.set({[RESOURCES_LOCAL_STORAGE_KEY]: resourcesDtos});
|
|
649
|
+
expect(ResourceLocalStorage.hasCachedData()).toBeFalsy();
|
|
650
|
+
await ResourceLocalStorage.deleteResources([resourceDto1.id, resourceDto2.id]);
|
|
651
|
+
expect(ResourceLocalStorage.hasCachedData()).toBeTruthy();
|
|
652
|
+
expect(ResourceLocalStorage._cachedData).toEqual(expect.any(Array));
|
|
653
|
+
expect(ResourceLocalStorage._cachedData).toHaveLength(1);
|
|
654
|
+
expect(ResourceLocalStorage._cachedData[0]).toEqual(resourceDto3);
|
|
655
|
+
});
|
|
656
|
+
});
|
|
603
657
|
});
|
|
@@ -0,0 +1,100 @@
|
|
|
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 MetadataTypesSettingsEntity from "passbolt-styleguide/src/shared/models/entity/metadata/metadataTypesSettingsEntity";
|
|
15
|
+
import MetadataKeysSettingsEntity from "passbolt-styleguide/src/shared/models/entity/metadata/metadataKeysSettingsEntity";
|
|
16
|
+
import GenerateMetadataKeyService from "./generateMetadataKeyService";
|
|
17
|
+
import CreateMetadataKeyService from "./createMetadataKeyService";
|
|
18
|
+
import SaveMetadataSettingsService from "./saveMetadataSettingsService";
|
|
19
|
+
import {assertString} from "../../utils/assertions";
|
|
20
|
+
import FindMetadataGettingStartedSettingsService from "passbolt-styleguide/src/shared/services/metadata/findMetadataGettingStartedSettingsService";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The service aims to orchestrate the enablement of the metadata encryption.
|
|
24
|
+
*/
|
|
25
|
+
export default class ConfigureMetadataSettingsService {
|
|
26
|
+
/**
|
|
27
|
+
* @constructor
|
|
28
|
+
* @param {AccountEntity} account The user account
|
|
29
|
+
* @param {ApiClientOptions} apiClientOptions The api client options
|
|
30
|
+
*/
|
|
31
|
+
constructor(account, apiClientOptions) {
|
|
32
|
+
this.generateMetadataKeyService = new GenerateMetadataKeyService(account);
|
|
33
|
+
this.createMetadataKeyService = new CreateMetadataKeyService(account, apiClientOptions);
|
|
34
|
+
this.saveMetadaSettingsService = new SaveMetadataSettingsService(account, apiClientOptions);
|
|
35
|
+
this.findMetadataGettingStartedSettingsService = new FindMetadataGettingStartedSettingsService(apiClientOptions);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Enables metadata encryption with confuguration that matches a new instance.
|
|
40
|
+
* @param {string} passphrase
|
|
41
|
+
* @return {Promise<void>}
|
|
42
|
+
* @throws {TypeError} if the `passphrase` is not a valid string
|
|
43
|
+
*/
|
|
44
|
+
async enableEncryptedMetadataForNewInstance(passphrase) {
|
|
45
|
+
assertString(passphrase);
|
|
46
|
+
|
|
47
|
+
const gpgKeyPairEntity = await this.generateMetadataKeyService.generateKey(passphrase);
|
|
48
|
+
await this.createMetadataKeyService.create(gpgKeyPairEntity, passphrase);
|
|
49
|
+
|
|
50
|
+
const metadataKeySettings = MetadataKeysSettingsEntity.createFromDefault();
|
|
51
|
+
await this.saveMetadaSettingsService.saveKeysSettings(metadataKeySettings);
|
|
52
|
+
|
|
53
|
+
const metadataTypeSettings = MetadataTypesSettingsEntity.createFromV5Default();
|
|
54
|
+
await this.saveMetadaSettingsService.saveTypesSettings(metadataTypeSettings);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Enables metadata encryption with confuguration that matches an existing instance.
|
|
59
|
+
* @param {string} passphrase
|
|
60
|
+
* @return {Promise<void>}
|
|
61
|
+
* @throws {TypeError} if the `passphrase` is not a valid string
|
|
62
|
+
*/
|
|
63
|
+
async enableEncryptedMetadataForExistingInstance(passphrase) {
|
|
64
|
+
await this.assertProcessIsEnabled();
|
|
65
|
+
assertString(passphrase);
|
|
66
|
+
|
|
67
|
+
const gpgKeyPairEntity = await this.generateMetadataKeyService.generateKey(passphrase);
|
|
68
|
+
await this.createMetadataKeyService.create(gpgKeyPairEntity, passphrase);
|
|
69
|
+
|
|
70
|
+
const metadataKeySettings = MetadataKeysSettingsEntity.createFromDefault();
|
|
71
|
+
await this.saveMetadaSettingsService.saveKeysSettings(metadataKeySettings);
|
|
72
|
+
|
|
73
|
+
const metadataTypeSettings = MetadataTypesSettingsEntity.createFromV5Default({
|
|
74
|
+
allow_v4_v5_upgrade: true,
|
|
75
|
+
});
|
|
76
|
+
await this.saveMetadaSettingsService.saveTypesSettings(metadataTypeSettings);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Configure metadata settings to keep legacy metadata in cleartext.
|
|
81
|
+
* @return {Promise<void>}
|
|
82
|
+
*/
|
|
83
|
+
async keepCleartextMetadataForExistingInstance() {
|
|
84
|
+
await this.assertProcessIsEnabled();
|
|
85
|
+
const metadataTypeSettings = MetadataTypesSettingsEntity.createFromV4Default();
|
|
86
|
+
await this.saveMetadaSettingsService.saveTypesSettings(metadataTypeSettings);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Asserts that the process can be run before proceeding.
|
|
91
|
+
* @returns {Promise<void>}
|
|
92
|
+
* @throws {Error}
|
|
93
|
+
*/
|
|
94
|
+
async assertProcessIsEnabled() {
|
|
95
|
+
const gettingStartedEntity = await this.findMetadataGettingStartedSettingsService.findGettingStartedSettings();
|
|
96
|
+
if (!gettingStartedEntity.enabled) {
|
|
97
|
+
throw new Error("The metadata encryption strategy has been already chosen.");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|