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.
Files changed (115) hide show
  1. package/CHANGELOG.md +79 -1
  2. package/Gruntfile.js +1 -1
  3. package/RELEASE_NOTES.md +27 -71
  4. package/doc/browser-extension-class-diagram.md +9 -0
  5. package/package.json +5 -5
  6. package/src/all/_locales/sl/messages.json +2 -2
  7. package/src/all/background_page/controller/clipboard/cancelClipboardContentFlushController.js +51 -0
  8. package/src/all/background_page/controller/clipboard/cancelClipboardContentFlushController.test.js +46 -0
  9. package/src/all/background_page/controller/clipboard/copyTemporarilyToClipboardController.js +53 -0
  10. package/src/all/background_page/controller/clipboard/copyTemporarilyToClipboardController.test.js +47 -0
  11. package/src/all/background_page/controller/clipboard/{clipboardController.js → copyToClipboardController.js} +8 -8
  12. package/src/all/background_page/controller/clipboard/copyToClipboardController.test.js +47 -0
  13. package/src/all/background_page/controller/extension/getExtensionVersionController.test.js +1 -1
  14. package/src/all/background_page/controller/metadata/getOrFindMetadataKeysSettingsController.js +53 -0
  15. package/src/all/background_page/controller/metadata/getOrFindMetadataKeysSettingsController.test.js +106 -0
  16. package/src/all/background_page/controller/resource/updateResourceLocalStorageByFolderParentIdController.js +70 -0
  17. package/src/all/background_page/controller/resource/updateResourceLocalStorageByFolderParentIdController.test.js +78 -0
  18. package/src/all/background_page/controller/share/shareOneFolderController.test.js +2 -1
  19. package/src/all/background_page/controller/share/shareResourcesController.test.js +1 -1
  20. package/src/all/background_page/controller/user/deleteDryRunUserController.js +73 -0
  21. package/src/all/background_page/controller/user/deleteDryRunUserController.test.js +129 -0
  22. package/src/all/background_page/controller/user/deleteUserController.js +76 -0
  23. package/src/all/background_page/controller/user/deleteUserController.test.js +141 -0
  24. package/src/all/background_page/event/actionLogEvents.js +5 -12
  25. package/src/all/background_page/event/appEvents.js +33 -0
  26. package/src/all/background_page/event/findAllForActionLogController.js +58 -0
  27. package/src/all/background_page/event/findAllForActionLogController.test.js +43 -0
  28. package/src/all/background_page/event/quickAccessEvents.js +32 -0
  29. package/src/all/background_page/event/resourceEvents.js +11 -0
  30. package/src/all/background_page/event/userEvents.js +7 -20
  31. package/src/all/background_page/event/webIntegrationEvents.js +11 -0
  32. package/src/all/background_page/model/actionLog/{actionLogModel.js → findActionLogService.js} +25 -5
  33. package/src/all/background_page/model/actionLog/findActionLogService.test.js +61 -0
  34. package/src/all/background_page/model/comment/commentModel.js +5 -5
  35. package/src/all/background_page/model/entity/actionLog/actionLogsCollection.test.data.js +18 -0
  36. package/src/all/background_page/model/entity/actionLog/defaultActionLogEntity.test.data.js +34 -0
  37. package/src/all/background_page/model/entity/resource/resourcesCollection.js +25 -0
  38. package/src/all/background_page/model/entity/resource/resourcesCollection.test.js +34 -0
  39. package/src/all/background_page/model/import/resources/resourcesKdbxImportParser.test.js +0 -1
  40. package/src/all/background_page/model/user/userModel.js +0 -60
  41. package/src/all/background_page/pagemod/appPagemod.js +0 -2
  42. package/src/all/background_page/pagemod/appPagemod.test.js +2 -6
  43. package/src/all/background_page/service/alarm/globalAlarmService.js +2 -0
  44. package/src/all/background_page/service/api/actionLog/{actionLogService.js → actionLogApiService.js} +5 -4
  45. package/src/all/background_page/service/api/actionLog/actionLogApiService.test.js +55 -0
  46. package/src/all/background_page/service/api/comment/{commentService.js → commentApiService.js} +6 -7
  47. package/src/all/background_page/service/api/comment/commentApiService.test.js +122 -0
  48. package/src/all/background_page/service/api/resource/resourceService.js +1 -0
  49. package/src/all/background_page/service/auth/postLogoutService.js +2 -0
  50. package/src/all/background_page/service/auth/postLogoutService.test.js +4 -1
  51. package/src/all/background_page/service/browser/browserService.js +22 -0
  52. package/src/all/background_page/service/clipboard/clipboardProviderService.js +40 -0
  53. package/src/all/background_page/service/clipboard/clipboardProviderService.test.js +61 -0
  54. package/src/all/background_page/service/clipboard/copyToClipboardService.js +123 -0
  55. package/src/all/background_page/service/clipboard/copyToClipboardService.test.js +174 -0
  56. package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.js +52 -1
  57. package/src/all/background_page/service/resource/findAndUpdateResourcesLocalStorageService.test.js +100 -0
  58. package/src/all/background_page/service/resource/findResourcesService.js +53 -19
  59. package/src/all/background_page/service/resource/findResourcesService.test.js +191 -0
  60. package/src/all/background_page/service/resourceType/updateResourceTypesService.test.js +1 -1
  61. package/src/all/background_page/service/share/shareResourceService.test.js +1 -1
  62. package/src/all/background_page/service/user/deleteUserService.js +97 -0
  63. package/src/all/background_page/service/user/deleteUserService.test.js +178 -0
  64. package/src/all/locales/de-DE/common.json +2 -2
  65. package/src/all/locales/es-ES/common.json +2 -2
  66. package/src/all/locales/fr-FR/common.json +5 -5
  67. package/src/all/locales/it-IT/common.json +2 -2
  68. package/src/all/locales/ja-JP/common.json +2 -2
  69. package/src/all/locales/ko-KR/common.json +2 -2
  70. package/src/all/locales/lt-LT/common.json +2 -2
  71. package/src/all/locales/nl-NL/common.json +2 -2
  72. package/src/all/locales/pl-PL/common.json +5 -5
  73. package/src/all/locales/pt-BR/common.json +2 -2
  74. package/src/all/locales/ro-RO/common.json +2 -2
  75. package/src/all/locales/ru-RU/common.json +2 -2
  76. package/src/all/locales/sl-SI/common.json +33 -33
  77. package/src/all/locales/sv-SE/common.json +2 -2
  78. package/src/all/locales/uk-UA/common.json +3 -3
  79. package/src/chrome/manifest.json +1 -1
  80. package/src/chrome/polyfill/clipboard/edgeBackgroundPageClipboardService.js +31 -0
  81. package/src/chrome/polyfill/clipboard/edgeBackgroundPageClipboardService.test.js +51 -0
  82. package/src/chrome-mv3/index.js +3 -3
  83. package/src/chrome-mv3/manifest.json +1 -1
  84. package/src/chrome-mv3/offscreens/{fetch.html → offscreen.html} +1 -1
  85. package/src/chrome-mv3/offscreens/{fetch.js → offscreen.js} +2 -2
  86. package/src/chrome-mv3/offscreens/service/clipboard/writeClipobardOffscreenService.js +54 -0
  87. package/src/chrome-mv3/offscreens/service/clipboard/writeClipobardOffscreenService.test.js +56 -0
  88. package/src/chrome-mv3/offscreens/service/network/fetchOffscreenService.js +36 -44
  89. package/src/chrome-mv3/offscreens/service/network/fetchOffscreenService.test.data.js +0 -1
  90. package/src/chrome-mv3/offscreens/service/network/fetchOffscreenService.test.js +90 -120
  91. package/src/chrome-mv3/offscreens/service/offscreen/handleOffscreenRequestService.js +85 -0
  92. package/src/chrome-mv3/offscreens/service/offscreen/handleOffscreenRequestService.test.js +99 -0
  93. package/src/chrome-mv3/polyfill/clipboardOffscreenPolyfill.js +19 -0
  94. package/src/chrome-mv3/serviceWorker/service/clipboard/requestClipboardOffscreenService.js +51 -0
  95. package/src/chrome-mv3/serviceWorker/service/clipboard/requestClipboardOffscreenService.test.js +70 -0
  96. package/src/chrome-mv3/serviceWorker/service/clipboard/responseClipboardOffscreenService.js +25 -0
  97. package/src/chrome-mv3/serviceWorker/service/clipboard/responseClipboardOffscreenService.test.data.js +21 -0
  98. package/src/chrome-mv3/serviceWorker/service/clipboard/responseClipboardOffscreenService.test.js +33 -0
  99. package/src/chrome-mv3/serviceWorker/service/network/requestFetchOffscreenService.js +25 -50
  100. package/src/chrome-mv3/serviceWorker/service/network/requestFetchOffscreenService.test.js +16 -39
  101. package/src/chrome-mv3/serviceWorker/service/network/responseFetchOffscreenService.js +14 -45
  102. package/src/chrome-mv3/serviceWorker/service/network/responseFetchOffscreenService.test.js +5 -37
  103. package/src/chrome-mv3/serviceWorker/service/offscreen/createOffscreenDocumentService.js +43 -0
  104. package/src/chrome-mv3/serviceWorker/service/offscreen/createOffscreenDocumentService.test.js +48 -0
  105. package/src/chrome-mv3/serviceWorker/service/offscreen/handleOffscreenResponseService.js +119 -0
  106. package/src/chrome-mv3/serviceWorker/service/offscreen/handleOffscreenResponseService.test.js +159 -0
  107. package/src/firefox/manifest.json +1 -1
  108. package/src/safari/manifest.json +1 -1
  109. package/test/jest.setup.js +4 -0
  110. package/test/mocks/mockNavigatorClipboard.js +40 -0
  111. package/test/mocks/mockWebExtensionPolyfill.js +2 -1
  112. package/{webpack-offscreens.fetch.config.js → webpack-offscreens.config.js} +1 -1
  113. package/webpack.service-worker.config.js +1 -0
  114. package/src/all/background_page/controller/clipboard/clipboardController.test.js +0 -68
  115. package/src/all/background_page/event/clipboardEvents.js +0 -28
@@ -0,0 +1,119 @@
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.3.2
13
+ */
14
+ import {assertUuid} from "../../../../all/background_page/utils/assertions";
15
+ import {SEND_MESSAGE_TARGET_CLIPBOARD_WRITE_OFFSCREEN_RESPONSE_HANDLER} from "../../../offscreens/service/clipboard/writeClipobardOffscreenService";
16
+ import {
17
+ SEND_MESSAGE_TARGET_FETCH_OFFSCREEN_POLLING_HANDLER,
18
+ SEND_MESSAGE_TARGET_FETCH_OFFSCREEN_RESPONSE_HANDLER
19
+ } from "../../../offscreens/service/network/fetchOffscreenService";
20
+ import {SEND_MESSAGE_TARGET_OFFSCREEN_ERROR_RESPONSE_HANDLER} from "../../../offscreens/service/offscreen/handleOffscreenRequestService";
21
+ import ResponseClipboardOffscreenService from "../clipboard/responseClipboardOffscreenService";
22
+ import ResponseFetchOffscreenService from "../network/responseFetchOffscreenService";
23
+
24
+ export default class HandleOffscreenResponseService {
25
+ /**
26
+ * @type {object}
27
+ * @private
28
+ */
29
+ static _offscreenResponsePromisesCallbacks = {};
30
+
31
+ /**
32
+ * @type {Map<string, function>}
33
+ * @private
34
+ */
35
+ static REPONSE_HANDLE_MAP = {
36
+ [SEND_MESSAGE_TARGET_FETCH_OFFSCREEN_RESPONSE_HANDLER]: ResponseFetchOffscreenService.handleFetchResponse,
37
+ [SEND_MESSAGE_TARGET_CLIPBOARD_WRITE_OFFSCREEN_RESPONSE_HANDLER]: ResponseClipboardOffscreenService.handleClipboardResponse,
38
+ [SEND_MESSAGE_TARGET_OFFSCREEN_ERROR_RESPONSE_HANDLER]: HandleOffscreenResponseService.handleOffscreenError,
39
+ };
40
+
41
+ /**
42
+ * Handle offscreen response.
43
+ * @param {object} message Browser runtime.onMessage listener message.
44
+ */
45
+ static handleOffscreenResponse(message) {
46
+ if (message.target === SEND_MESSAGE_TARGET_FETCH_OFFSCREEN_POLLING_HANDLER) {
47
+ //it's a polling message that is only here to keep the offscreen document alive.
48
+ return;
49
+ }
50
+
51
+ const responseHandler = HandleOffscreenResponseService.REPONSE_HANDLE_MAP[message.target];
52
+ if (!responseHandler) {
53
+ console.debug("HandleOffscreenResponseService received response not specific to offscreen.");
54
+ return;
55
+ }
56
+
57
+ HandleOffscreenResponseService._assertOffscreenResponse(message);
58
+ const promise = HandleOffscreenResponseService._consumeRequestPromiseCallbacksOrFail(message.id);
59
+
60
+ responseHandler(message, promise);
61
+ }
62
+
63
+ /**
64
+ * Handles generic offscreen error message.
65
+ * @param {object} message
66
+ * @param {{resolve: function, reject: function}} promise
67
+ * @private
68
+ */
69
+ static handleOffscreenError(message, promise) {
70
+ const error = new Error("Something went wrong while processing an offscreen request");
71
+
72
+ const errorCauseString = message?.data?.error;
73
+ if (errorCauseString) {
74
+ const cause = JSON.parse(errorCauseString);
75
+ error.cause = new Error();
76
+ error.cause.name = cause.name;
77
+ error.cause.message = cause.message;
78
+ error.cause.stack = cause.stack;
79
+ }
80
+
81
+ promise.reject(error);
82
+ }
83
+
84
+ /**
85
+ * Sets a new promise response callback for a given offscreen request id.
86
+ * @param {string} id
87
+ * @param {{resolve: function, reject: function}} promise
88
+ */
89
+ static setResponseCallback(id, promise) {
90
+ HandleOffscreenResponseService._offscreenResponsePromisesCallbacks[id] = promise;
91
+ }
92
+
93
+ /**
94
+ * Asserts that the given message is a valid offscreen response message.
95
+ * @param {object} message
96
+ * @throws {Error} if message.id is not a valid UUID
97
+ * @private
98
+ */
99
+ static _assertOffscreenResponse(message) {
100
+ assertUuid(message.id, "HandleOffscreenResponseService: message.id should be a valid uuid.");
101
+ }
102
+
103
+ /**
104
+ * Consume the offscreen request promise callbacks or fail.
105
+ * @param {string} id The identifier of the offscreen fetch request.
106
+ * @returns {Promise}
107
+ * @throws {Error} If no request promise callbacks can be found for the given offscreen fetch request id.
108
+ * @private
109
+ */
110
+ static _consumeRequestPromiseCallbacksOrFail(id) {
111
+ const offscreenRequestPromiseCallback = HandleOffscreenResponseService._offscreenResponsePromisesCallbacks[id];
112
+ if (!offscreenRequestPromiseCallback) {
113
+ throw new Error("HandleOffscreenResponseService: No request promise callbacks found for the given offscreen fetch request id.");
114
+ }
115
+ delete HandleOffscreenResponseService._offscreenResponsePromisesCallbacks[id];
116
+
117
+ return offscreenRequestPromiseCallback;
118
+ }
119
+ }
@@ -0,0 +1,159 @@
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.3.2
13
+ */
14
+
15
+ import {SEND_MESSAGE_TARGET_CLIPBOARD_WRITE_OFFSCREEN_RESPONSE_HANDLER} from "../../../offscreens/service/clipboard/writeClipobardOffscreenService";
16
+ import {SEND_MESSAGE_TARGET_FETCH_OFFSCREEN_RESPONSE_HANDLER} from "../../../offscreens/service/network/fetchOffscreenService";
17
+ import {defaultCallbacks} from "../network/responseFetchOffscreenService.test.data";
18
+ import HandleOffscreenResponseService from "./handleOffscreenResponseService";
19
+ import {v4 as uuidv4} from "uuid";
20
+
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ });
24
+
25
+ describe("HandleOffscreenResponseService", () => {
26
+ let fetchFunction, clipboardWriteFunction;
27
+
28
+ beforeEach(() => {
29
+ jest.clearAllMocks();
30
+ fetchFunction = jest.spyOn(HandleOffscreenResponseService.REPONSE_HANDLE_MAP, SEND_MESSAGE_TARGET_FETCH_OFFSCREEN_RESPONSE_HANDLER).mockImplementation(() => {});
31
+ clipboardWriteFunction = jest.spyOn(HandleOffscreenResponseService.REPONSE_HANDLE_MAP, SEND_MESSAGE_TARGET_CLIPBOARD_WRITE_OFFSCREEN_RESPONSE_HANDLER).mockImplementation(() => {});
32
+ });
33
+
34
+ describe("::handleOffscreenResponse", () => {
35
+ it("should handle fetch response and dispatch to the right service", () => {
36
+ expect.assertions(3);
37
+
38
+ const message = {
39
+ id: uuidv4(),
40
+ target: "service-worker-fetch-offscreen-response-handler"
41
+ };
42
+ const promises = defaultCallbacks();
43
+ HandleOffscreenResponseService.setResponseCallback(message.id, promises);
44
+
45
+ HandleOffscreenResponseService.handleOffscreenResponse(message);
46
+
47
+ expect(fetchFunction).toHaveBeenCalledTimes(1);
48
+ expect(fetchFunction).toHaveBeenCalledWith(message, promises);
49
+ expect(clipboardWriteFunction).not.toHaveBeenCalled();
50
+ });
51
+
52
+ it("should handle fetch polling response and dispatch to the right service", () => {
53
+ expect.assertions(2);
54
+
55
+ const message = {
56
+ target: "service-worker-fetch-offscreen-polling-handler"
57
+ };
58
+
59
+ HandleOffscreenResponseService.handleOffscreenResponse(message);
60
+
61
+ expect(fetchFunction).not.toHaveBeenCalled();
62
+ expect(clipboardWriteFunction).not.toHaveBeenCalled();
63
+ });
64
+
65
+ it("should handle clipboard writeText and dispatch to the right service", () => {
66
+ expect.assertions(3);
67
+
68
+ const message = {
69
+ id: uuidv4(),
70
+ target: "service-worker-clipboard-write-text-offscreen-response-handler"
71
+ };
72
+ const promises = defaultCallbacks();
73
+ HandleOffscreenResponseService.setResponseCallback(message.id, promises);
74
+
75
+ HandleOffscreenResponseService.handleOffscreenResponse(message);
76
+
77
+ expect(clipboardWriteFunction).toHaveBeenCalledTimes(1);
78
+ expect(clipboardWriteFunction).toHaveBeenCalledWith(message, promises);
79
+ expect(fetchFunction).not.toHaveBeenCalled();
80
+ });
81
+
82
+ it("should handle offscreen error message", () => {
83
+ expect.assertions(2);
84
+
85
+ const error = new Error("It went really bad somehow");
86
+ const expectedError = new Error("Something went wrong while processing an offscreen request");
87
+ expectedError.cause = error;
88
+
89
+ const message = {
90
+ id: uuidv4(),
91
+ target: "service-worker-offscreen-error-response-handler",
92
+ data: {error: JSON.stringify(error, Object.getOwnPropertyNames(error))},
93
+ };
94
+
95
+ const promises = defaultCallbacks();
96
+
97
+ HandleOffscreenResponseService.setResponseCallback(message.id, promises);
98
+ HandleOffscreenResponseService.handleOffscreenResponse(message);
99
+
100
+ expect(promises.reject).toHaveBeenCalledTimes(1);
101
+ expect(promises.reject).toHaveBeenCalledWith(expectedError);
102
+ });
103
+
104
+ it("should ignore message with unknown target", () => {
105
+ expect.assertions(2);
106
+
107
+ const message = {target: "???"};
108
+
109
+ HandleOffscreenResponseService.handleOffscreenResponse(message);
110
+
111
+ expect(clipboardWriteFunction).not.toHaveBeenCalled();
112
+ expect(fetchFunction).not.toHaveBeenCalled();
113
+ });
114
+ });
115
+
116
+ describe("::_consumeRequestPromiseCallbacksOrFail", () => {
117
+ it("should consume the response handler associated to the given id", () => {
118
+ expect.assertions(3);
119
+
120
+ const id = crypto.randomUUID();
121
+ const callbacks = defaultCallbacks();
122
+ HandleOffscreenResponseService.setResponseCallback(id, callbacks);
123
+
124
+ const consumedCallbacks = HandleOffscreenResponseService._consumeRequestPromiseCallbacksOrFail(id);
125
+
126
+ expect(consumedCallbacks).not.toBeNull();
127
+ expect(consumedCallbacks).toEqual(callbacks);
128
+ expect(Object.keys(HandleOffscreenResponseService._offscreenResponsePromisesCallbacks).length).toEqual(0);
129
+ });
130
+
131
+ it("should throw if no associated callbacks found for the given id", () => {
132
+ expect.assertions(1);
133
+ const id = crypto.randomUUID();
134
+ expect(() => HandleOffscreenResponseService._consumeRequestPromiseCallbacksOrFail(id)).toThrow();
135
+ });
136
+ });
137
+
138
+ describe("::handleOffscreenError", () => {
139
+ it("should reject the given promise with an error containing the cause of the offscreen process failure", () => {
140
+ expect.assertions(2);
141
+
142
+ const callbacks = defaultCallbacks();
143
+ const error = new Error("Something went wrong with the fetch");
144
+ const message = {
145
+ data: {
146
+ error: JSON.stringify(error, Object.getOwnPropertyNames(error))
147
+ },
148
+
149
+ };
150
+ const expectedError = new Error("Something went wrong while processing an offscreen request");
151
+ expectedError.cause = message.data.error;
152
+
153
+ HandleOffscreenResponseService.handleOffscreenError(message, callbacks);
154
+
155
+ expect(callbacks.reject).toHaveBeenCalledTimes(1);
156
+ expect(callbacks.reject).toHaveBeenCalledWith(expectedError);
157
+ });
158
+ });
159
+ });
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 2,
3
3
  "name": "__MSG_appName__",
4
4
  "short_name": "passbolt",
5
- "version": "5.2.0",
5
+ "version": "5.3.2",
6
6
  "description": "__MSG_appDescription__",
7
7
  "default_locale": "en",
8
8
  "browser_specific_settings": {
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "name": "__MSG_appName__",
4
4
  "short_name": "passbolt",
5
- "version": "5.2.0.1",
5
+ "version": "5.3.2",
6
6
  "description": "__MSG_appDescription__",
7
7
  "default_locale": "en",
8
8
  "externally_connectable": {},
@@ -19,6 +19,7 @@ import "./mocks/mockTextEncoder";
19
19
  import "./mocks/mockCryptoKey";
20
20
  import "./matchers/extendExpect";
21
21
  import MockNavigatorLocks from './mocks/mockNavigatorLocks';
22
+ import MockNavigatorClipboard from './mocks/mockNavigatorClipboard';
22
23
  import OrganizationSettingsModel from "../src/all/background_page/model/organizationSettings/organizationSettingsModel";
23
24
  import {Config} from "../src/all/background_page/model/config";
24
25
  import Keyring from "../src/all/background_page/model/keyring";
@@ -49,6 +50,9 @@ if (!global.navigator) {
49
50
  if (!global.navigator.locks) {
50
51
  global.navigator.locks = new MockNavigatorLocks();
51
52
  }
53
+ if (!global.navigator.clipboard) {
54
+ global.navigator.clipboard = new MockNavigatorClipboard();
55
+ }
52
56
 
53
57
  /*
54
58
  * quick polyfill for jest to have stucturedClone function defined
@@ -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.3.2
13
+ */
14
+
15
+ /**
16
+ * Mock class to be used in replacement of navigator.clipboard
17
+ */
18
+ export default class MockNavigatorClipboard {
19
+ /**
20
+ * @type {string}
21
+ * @private
22
+ */
23
+ _clipboardData = "";
24
+
25
+ /**
26
+ * @inheritDoc navigator.clipboard.readText
27
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText
28
+ */
29
+ async readText() {
30
+ return this._clipboardData;
31
+ }
32
+
33
+ /**
34
+ * @inheritDoc navigator.clipboard.writeText
35
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
36
+ */
37
+ async writeText(newClipText) {
38
+ this._clipboardData = newClipText;
39
+ }
40
+ }
@@ -42,7 +42,8 @@ jest.mock("webextension-polyfill", () => {
42
42
  getURL: jest.fn(path => `chrome-extension://didegimhafipceonhjepacocaffmoppf/${path}`),
43
43
  // Force extension version
44
44
  getManifest: jest.fn(() => ({
45
- version: "v3.6.0"
45
+ version: "5.3.0",
46
+ manifest_version: 3,
46
47
  })),
47
48
  // Runtime primitives not mocked by jest-webextension-mock v3.8.9
48
49
  OnInstalledReason: {
@@ -3,7 +3,7 @@ const TerserPlugin = require("terser-webpack-plugin");
3
3
 
4
4
  const config = {
5
5
  entry: {
6
- 'fetch': path.resolve(__dirname, './src/chrome-mv3/offscreens/fetch.js'),
6
+ 'offscreen': path.resolve(__dirname, './src/chrome-mv3/offscreens/offscreen.js'),
7
7
  },
8
8
  mode: 'production',
9
9
  module: {
@@ -13,6 +13,7 @@ const config = {
13
13
  browser: path.resolve(__dirname, './src/all/common/polyfill/browserPolyfill.js'),
14
14
  // Inject custom api client fetch to MV3 extension as workaround of the invalid certificate issue.
15
15
  customApiClientFetch: path.resolve(__dirname, './src/chrome-mv3/polyfill/fetchOffscreenPolyfill.js'),
16
+ customNavigatorClipboard: path.resolve(__dirname, './src/chrome-mv3/polyfill/clipboardOffscreenPolyfill.js'),
16
17
  })
17
18
  ],
18
19
  module: {
@@ -1,68 +0,0 @@
1
- /**
2
- * Passbolt ~ Open source password manager for teams
3
- * Copyright (c) 2023 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) 2023 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 3.9.0
13
- */
14
-
15
- import ClipboardController from './clipboardController';
16
-
17
- describe('ClipboardController', () => {
18
- let controller, workerMock;
19
- const toCopy = "text";
20
-
21
- beforeEach(() => {
22
- workerMock = {
23
- port: {
24
- emit: jest.fn()
25
- }
26
- };
27
- navigator.clipboard = {
28
- writeText: jest.fn()
29
- };
30
- controller = new ClipboardController(workerMock, 'request-id');
31
- });
32
-
33
- describe('constructor', () => {
34
- it('should set the worker and requestId properties', () => {
35
- expect.assertions(2);
36
- expect(controller.worker).toBe(workerMock);
37
- expect(controller.requestId).toBe('request-id');
38
- });
39
- });
40
-
41
- describe('_exec', () => {
42
- it('should call the exec method and emit a success message on the worker port', async() => {
43
- expect.assertions(2);
44
- const execSpy = jest.spyOn(controller, 'exec');
45
- await controller._exec(toCopy);
46
- expect(execSpy).toHaveBeenCalledWith(toCopy);
47
- expect(workerMock.port.emit).toHaveBeenCalledWith('request-id', 'SUCCESS');
48
- });
49
-
50
- it('should emit an error message on the worker port if an error occurs', async() => {
51
- expect.assertions(1);
52
- const error = new Error('Some error');
53
- jest.spyOn(controller, 'exec').mockImplementationOnce(() => {
54
- throw error;
55
- });
56
- await controller._exec(toCopy);
57
- expect(workerMock.port.emit).toHaveBeenCalledWith('request-id', 'ERROR', error);
58
- });
59
- });
60
-
61
- describe('exec', () => {
62
- it('should call navigator.clipboard method of the QuickAccessService', () => {
63
- expect.assertions(1);
64
- controller.exec(toCopy);
65
- expect(navigator.clipboard.writeText).toHaveBeenCalledWith('text');
66
- });
67
- });
68
- });
@@ -1,28 +0,0 @@
1
- /**
2
- * Passbolt ~ Open source password manager for teams
3
- * Copyright (c) 2023 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) 2023 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 3.9.0
13
- */
14
-
15
- import ClipboardController from '../controller/clipboard/clipboardController';
16
-
17
- /**
18
- * Listens the clipboard events
19
- * @param worker
20
- */
21
- const listen = function(worker) {
22
- worker.port.on('passbolt.clipboard.copy', async(requestId, text) => {
23
- const clipboardController = new ClipboardController(worker, requestId, text);
24
- await clipboardController._exec(text);
25
- });
26
- };
27
-
28
- export const ClipboardEvents = {listen};