@webex/plugin-encryption 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.eslintrc.js +6 -0
  2. package/LICENSE +2 -0
  3. package/README.md +88 -0
  4. package/babel.config.js +13 -0
  5. package/browsers.js +97 -0
  6. package/coverage/clover.xml +176 -0
  7. package/coverage/coverage-final.json +3 -0
  8. package/coverage/jest-html-reporters-attach/jest-report/index.js +58 -0
  9. package/coverage/jest-html-reporters-attach/jest-report/result.js +1 -0
  10. package/coverage/jest-report.html +1 -0
  11. package/coverage/junit/coverage-junit.xml +27 -0
  12. package/coverage/lcov-report/base.css +224 -0
  13. package/coverage/lcov-report/block-navigation.js +87 -0
  14. package/coverage/lcov-report/constants.ts.html +100 -0
  15. package/coverage/lcov-report/favicon.png +0 -0
  16. package/coverage/lcov-report/index.html +131 -0
  17. package/coverage/lcov-report/index.ts.html +562 -0
  18. package/coverage/lcov-report/prettify.css +1 -0
  19. package/coverage/lcov-report/prettify.js +2 -0
  20. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  21. package/coverage/lcov-report/sorter.js +196 -0
  22. package/coverage/lcov.info +215 -0
  23. package/developer-quickstart.md +104 -0
  24. package/dist/config.js +10 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/constants.js +6 -0
  27. package/dist/constants.js.map +1 -0
  28. package/dist/cypher/constants.js +12 -0
  29. package/dist/cypher/constants.js.map +1 -0
  30. package/dist/cypher/cypher.types.js +6 -0
  31. package/dist/cypher/cypher.types.js.map +1 -0
  32. package/dist/cypher/index.js +141 -0
  33. package/dist/cypher/index.js.map +1 -0
  34. package/dist/cypher/types.js +6 -0
  35. package/dist/cypher/types.js.map +1 -0
  36. package/dist/encryption/constants.js +12 -0
  37. package/dist/encryption/constants.js.map +1 -0
  38. package/dist/encryption/encryption.types.js +6 -0
  39. package/dist/encryption/encryption.types.js.map +1 -0
  40. package/dist/encryption/index.js +84 -0
  41. package/dist/encryption/index.js.map +1 -0
  42. package/dist/index.js +17 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/types/config.d.ts +4 -0
  45. package/dist/types/constants.d.ts +1 -0
  46. package/dist/types/cypher/constants.d.ts +5 -0
  47. package/dist/types/cypher/cypher.types.d.ts +25 -0
  48. package/dist/types/cypher/index.d.ts +53 -0
  49. package/dist/types/cypher/types.d.ts +25 -0
  50. package/dist/types/encryption/constants.d.ts +5 -0
  51. package/dist/types/encryption/encryption.types.d.ts +25 -0
  52. package/dist/types/encryption/index.d.ts +27 -0
  53. package/dist/types/index.d.ts +4 -0
  54. package/dist/types/types.d.ts +40 -0
  55. package/dist/types.js +6 -0
  56. package/dist/types.js.map +1 -0
  57. package/jest.config.js +44 -0
  58. package/junit.xml +27 -0
  59. package/package.json +57 -0
  60. package/process +1 -0
  61. package/src/config.ts +3 -0
  62. package/src/cypher/constants.ts +5 -0
  63. package/src/cypher/index.ts +159 -0
  64. package/src/cypher/types.ts +28 -0
  65. package/src/index.ts +13 -0
  66. package/src/types.ts +45 -0
  67. package/test/unit/spec/cypher/index.ts +146 -0
  68. package/tsconfig.json +18 -0
@@ -0,0 +1,196 @@
1
+ /* eslint-disable */
2
+ var addSorting = (function() {
3
+ 'use strict';
4
+ var cols,
5
+ currentSort = {
6
+ index: 0,
7
+ desc: false
8
+ };
9
+
10
+ // returns the summary table element
11
+ function getTable() {
12
+ return document.querySelector('.coverage-summary');
13
+ }
14
+ // returns the thead element of the summary table
15
+ function getTableHeader() {
16
+ return getTable().querySelector('thead tr');
17
+ }
18
+ // returns the tbody element of the summary table
19
+ function getTableBody() {
20
+ return getTable().querySelector('tbody');
21
+ }
22
+ // returns the th element for nth column
23
+ function getNthColumn(n) {
24
+ return getTableHeader().querySelectorAll('th')[n];
25
+ }
26
+
27
+ function onFilterInput() {
28
+ const searchValue = document.getElementById('fileSearch').value;
29
+ const rows = document.getElementsByTagName('tbody')[0].children;
30
+ for (let i = 0; i < rows.length; i++) {
31
+ const row = rows[i];
32
+ if (
33
+ row.textContent
34
+ .toLowerCase()
35
+ .includes(searchValue.toLowerCase())
36
+ ) {
37
+ row.style.display = '';
38
+ } else {
39
+ row.style.display = 'none';
40
+ }
41
+ }
42
+ }
43
+
44
+ // loads the search box
45
+ function addSearchBox() {
46
+ var template = document.getElementById('filterTemplate');
47
+ var templateClone = template.content.cloneNode(true);
48
+ templateClone.getElementById('fileSearch').oninput = onFilterInput;
49
+ template.parentElement.appendChild(templateClone);
50
+ }
51
+
52
+ // loads all columns
53
+ function loadColumns() {
54
+ var colNodes = getTableHeader().querySelectorAll('th'),
55
+ colNode,
56
+ cols = [],
57
+ col,
58
+ i;
59
+
60
+ for (i = 0; i < colNodes.length; i += 1) {
61
+ colNode = colNodes[i];
62
+ col = {
63
+ key: colNode.getAttribute('data-col'),
64
+ sortable: !colNode.getAttribute('data-nosort'),
65
+ type: colNode.getAttribute('data-type') || 'string'
66
+ };
67
+ cols.push(col);
68
+ if (col.sortable) {
69
+ col.defaultDescSort = col.type === 'number';
70
+ colNode.innerHTML =
71
+ colNode.innerHTML + '<span class="sorter"></span>';
72
+ }
73
+ }
74
+ return cols;
75
+ }
76
+ // attaches a data attribute to every tr element with an object
77
+ // of data values keyed by column name
78
+ function loadRowData(tableRow) {
79
+ var tableCols = tableRow.querySelectorAll('td'),
80
+ colNode,
81
+ col,
82
+ data = {},
83
+ i,
84
+ val;
85
+ for (i = 0; i < tableCols.length; i += 1) {
86
+ colNode = tableCols[i];
87
+ col = cols[i];
88
+ val = colNode.getAttribute('data-value');
89
+ if (col.type === 'number') {
90
+ val = Number(val);
91
+ }
92
+ data[col.key] = val;
93
+ }
94
+ return data;
95
+ }
96
+ // loads all row data
97
+ function loadData() {
98
+ var rows = getTableBody().querySelectorAll('tr'),
99
+ i;
100
+
101
+ for (i = 0; i < rows.length; i += 1) {
102
+ rows[i].data = loadRowData(rows[i]);
103
+ }
104
+ }
105
+ // sorts the table using the data for the ith column
106
+ function sortByIndex(index, desc) {
107
+ var key = cols[index].key,
108
+ sorter = function(a, b) {
109
+ a = a.data[key];
110
+ b = b.data[key];
111
+ return a < b ? -1 : a > b ? 1 : 0;
112
+ },
113
+ finalSorter = sorter,
114
+ tableBody = document.querySelector('.coverage-summary tbody'),
115
+ rowNodes = tableBody.querySelectorAll('tr'),
116
+ rows = [],
117
+ i;
118
+
119
+ if (desc) {
120
+ finalSorter = function(a, b) {
121
+ return -1 * sorter(a, b);
122
+ };
123
+ }
124
+
125
+ for (i = 0; i < rowNodes.length; i += 1) {
126
+ rows.push(rowNodes[i]);
127
+ tableBody.removeChild(rowNodes[i]);
128
+ }
129
+
130
+ rows.sort(finalSorter);
131
+
132
+ for (i = 0; i < rows.length; i += 1) {
133
+ tableBody.appendChild(rows[i]);
134
+ }
135
+ }
136
+ // removes sort indicators for current column being sorted
137
+ function removeSortIndicators() {
138
+ var col = getNthColumn(currentSort.index),
139
+ cls = col.className;
140
+
141
+ cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
142
+ col.className = cls;
143
+ }
144
+ // adds sort indicators for current column being sorted
145
+ function addSortIndicators() {
146
+ getNthColumn(currentSort.index).className += currentSort.desc
147
+ ? ' sorted-desc'
148
+ : ' sorted';
149
+ }
150
+ // adds event listeners for all sorter widgets
151
+ function enableUI() {
152
+ var i,
153
+ el,
154
+ ithSorter = function ithSorter(i) {
155
+ var col = cols[i];
156
+
157
+ return function() {
158
+ var desc = col.defaultDescSort;
159
+
160
+ if (currentSort.index === i) {
161
+ desc = !currentSort.desc;
162
+ }
163
+ sortByIndex(i, desc);
164
+ removeSortIndicators();
165
+ currentSort.index = i;
166
+ currentSort.desc = desc;
167
+ addSortIndicators();
168
+ };
169
+ };
170
+ for (i = 0; i < cols.length; i += 1) {
171
+ if (cols[i].sortable) {
172
+ // add the click event handler on the th so users
173
+ // dont have to click on those tiny arrows
174
+ el = getNthColumn(i).querySelector('.sorter').parentElement;
175
+ if (el.addEventListener) {
176
+ el.addEventListener('click', ithSorter(i));
177
+ } else {
178
+ el.attachEvent('onclick', ithSorter(i));
179
+ }
180
+ }
181
+ }
182
+ }
183
+ // adds sorting functionality to the UI
184
+ return function() {
185
+ if (!getTable()) {
186
+ return;
187
+ }
188
+ cols = loadColumns();
189
+ loadData();
190
+ addSearchBox();
191
+ addSortIndicators();
192
+ enableUI();
193
+ };
194
+ })();
195
+
196
+ window.addEventListener('load', addSorting);
@@ -0,0 +1,215 @@
1
+ TN:
2
+ SF:src/cypher/constants.ts
3
+ FNF:0
4
+ FNH:0
5
+ DA:1,1
6
+ DA:2,1
7
+ DA:3,1
8
+ DA:4,1
9
+ DA:5,1
10
+ LF:5
11
+ LH:5
12
+ BRF:0
13
+ BRH:0
14
+ end_of_record
15
+ TN:
16
+ SF:src/cypher/index.ts
17
+ FN:12,<instance_members_initializer>
18
+ FN:25,Cypher
19
+ FN:34,register
20
+ FN:58,deregister
21
+ FN:98,downloadAndDecryptFile
22
+ FNF:5
23
+ FNH:5
24
+ FNDA:22,<instance_members_initializer>
25
+ FNDA:22,Cypher
26
+ FNDA:3,register
27
+ FNDA:3,deregister
28
+ FNDA:5,downloadAndDecryptFile
29
+ DA:1,1
30
+ DA:2,1
31
+ DA:3,1
32
+ DA:4,1
33
+ DA:5,1
34
+ DA:6,1
35
+ DA:7,1
36
+ DA:8,1
37
+ DA:9,1
38
+ DA:10,1
39
+ DA:11,1
40
+ DA:12,1
41
+ DA:13,22
42
+ DA:14,1
43
+ DA:15,1
44
+ DA:16,1
45
+ DA:17,1
46
+ DA:18,1
47
+ DA:19,1
48
+ DA:20,1
49
+ DA:21,1
50
+ DA:22,1
51
+ DA:23,1
52
+ DA:24,1
53
+ DA:25,1
54
+ DA:26,22
55
+ DA:27,22
56
+ DA:28,22
57
+ DA:29,1
58
+ DA:30,1
59
+ DA:31,1
60
+ DA:32,1
61
+ DA:33,1
62
+ DA:34,1
63
+ DA:35,3
64
+ DA:36,1
65
+ DA:37,1
66
+ DA:38,1
67
+ DA:39,1
68
+ DA:40,2
69
+ DA:41,2
70
+ DA:42,2
71
+ DA:43,2
72
+ DA:44,1
73
+ DA:45,1
74
+ DA:46,2
75
+ DA:47,2
76
+ DA:48,1
77
+ DA:49,1
78
+ DA:50,1
79
+ DA:51,2
80
+ DA:52,2
81
+ DA:53,1
82
+ DA:54,1
83
+ DA:55,1
84
+ DA:56,1
85
+ DA:57,1
86
+ DA:58,1
87
+ DA:59,3
88
+ DA:60,1
89
+ DA:61,1
90
+ DA:62,1
91
+ DA:63,1
92
+ DA:64,2
93
+ DA:65,2
94
+ DA:66,2
95
+ DA:67,2
96
+ DA:68,1
97
+ DA:69,1
98
+ DA:70,2
99
+ DA:71,2
100
+ DA:72,1
101
+ DA:73,1
102
+ DA:74,1
103
+ DA:75,2
104
+ DA:76,2
105
+ DA:77,1
106
+ DA:78,1
107
+ DA:79,1
108
+ DA:80,1
109
+ DA:81,1
110
+ DA:82,1
111
+ DA:83,1
112
+ DA:84,1
113
+ DA:85,1
114
+ DA:86,1
115
+ DA:87,1
116
+ DA:88,1
117
+ DA:89,1
118
+ DA:90,1
119
+ DA:91,1
120
+ DA:92,1
121
+ DA:93,1
122
+ DA:94,1
123
+ DA:95,1
124
+ DA:96,1
125
+ DA:97,1
126
+ DA:98,1
127
+ DA:99,5
128
+ DA:100,5
129
+ DA:101,5
130
+ DA:102,5
131
+ DA:103,5
132
+ DA:104,5
133
+ DA:105,5
134
+ DA:106,5
135
+ DA:107,5
136
+ DA:108,5
137
+ DA:109,5
138
+ DA:110,5
139
+ DA:111,5
140
+ DA:112,5
141
+ DA:113,5
142
+ DA:114,5
143
+ DA:115,5
144
+ DA:116,5
145
+ DA:117,5
146
+ DA:118,5
147
+ DA:119,5
148
+ DA:120,5
149
+ DA:121,5
150
+ DA:122,0
151
+ DA:123,0
152
+ DA:124,0
153
+ DA:125,0
154
+ DA:126,0
155
+ DA:127,5
156
+ DA:128,5
157
+ DA:129,5
158
+ DA:130,2
159
+ DA:131,2
160
+ DA:132,2
161
+ DA:133,5
162
+ DA:134,5
163
+ DA:135,5
164
+ DA:136,1
165
+ DA:137,1
166
+ DA:138,1
167
+ DA:139,1
168
+ DA:140,4
169
+ DA:141,4
170
+ DA:142,4
171
+ DA:143,4
172
+ DA:144,3
173
+ DA:145,3
174
+ DA:146,3
175
+ DA:147,5
176
+ DA:148,1
177
+ DA:149,1
178
+ DA:150,1
179
+ DA:151,1
180
+ DA:152,1
181
+ DA:153,1
182
+ DA:154,1
183
+ DA:155,1
184
+ DA:156,5
185
+ DA:157,1
186
+ DA:158,1
187
+ DA:159,1
188
+ LF:159
189
+ LH:154
190
+ BRDA:12,0,0,22
191
+ BRDA:25,1,0,22
192
+ BRDA:34,2,0,3
193
+ BRDA:35,3,0,1
194
+ BRDA:39,4,0,2
195
+ BRDA:43,5,0,1
196
+ BRDA:47,6,0,1
197
+ BRDA:58,7,0,3
198
+ BRDA:59,8,0,1
199
+ BRDA:63,9,0,2
200
+ BRDA:67,10,0,1
201
+ BRDA:71,11,0,1
202
+ BRDA:98,12,0,5
203
+ BRDA:119,13,0,2
204
+ BRDA:120,14,0,2
205
+ BRDA:121,15,0,0
206
+ BRDA:129,16,0,3
207
+ BRDA:129,17,0,2
208
+ BRDA:135,18,0,4
209
+ BRDA:135,19,0,1
210
+ BRDA:139,20,0,4
211
+ BRDA:143,21,0,3
212
+ BRDA:147,22,0,1
213
+ BRF:23
214
+ BRH:22
215
+ end_of_record
@@ -0,0 +1,104 @@
1
+ # Webex Encryption Kitchen Sink
2
+
3
+ This project demonstrates how to interact with the Webex encryption service using the Webex JS SDK. It includes examples of how to authenticate, initialize the SDK, and decrypt files.
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - An access token from the Webex developer portal with the spark:kms
10
+ - This token can also be obtained from the agent desktop by using developer tools and inspecting the local storage for access token
11
+
12
+ ### Installation
13
+
14
+ 1. Clone the repository.
15
+ 2. yarn build:local
16
+ 3. yarn samples:build && yarn samples:serve
17
+
18
+ ### Usage
19
+
20
+ #### Authentication
21
+
22
+ 1. Navigate to [https://localhost:8000/samples/plugin-encryption](https://localhost:8000/samples/plugin-encryption)
23
+ 2. Get an access token from either the developer portal or from the agent desktop
24
+ 3. Make sure to select the environment to be integration or production
25
+ 4. Enter your access token in the "Access Token" field.
26
+ 5. Click the "Initialize Webex" button to initialize the Webex SDK.
27
+
28
+ #### Initialize Webex SDK
29
+
30
+ The Webex SDK is initialized using the access token provided by the user. The initialization process registers the Webex JS SDK as a device.
31
+
32
+ ```typescript
33
+ function initializeWebex(accessToken) {
34
+ const webex = Webex.init({
35
+ credentials: {
36
+ access_token: accessToken,
37
+ },
38
+ });
39
+
40
+ return new Promise((resolve) => {
41
+ webex.once('ready', () => {
42
+ localStorage.setItem('access-token', accessToken);
43
+ localStorage.setItem('date', new Date().getTime() + 60 * 60 * 1000); // 1 hour expiration
44
+ webex.cypher.register().then(() => {
45
+ resolve(webex);
46
+ });
47
+ });
48
+ });
49
+ }
50
+ ```
51
+
52
+ ### Decrypt Files
53
+
54
+ To decrypt a file, provide the encrypted file URL, the desired file name, and the MIME type.
55
+
56
+ ```typescript
57
+ async function decryptFile(webex, encryptedFileUrl, options, decryptedFileName, mimeType) {
58
+ try {
59
+ const decryptedFileBuf = await webex.cypher.downloadAndDecryptFile(encryptedFileUrl, options);
60
+ const file = new File([decryptedFileBuf], decryptedFileName, { type: mimeType });
61
+ const url = window.URL.createObjectURL(file);
62
+ const a = document.createElement('a');
63
+ a.style.display = 'none';
64
+ a.href = url;
65
+ a.download = decryptedFileName;
66
+ document.body.appendChild(a);
67
+ a.click();
68
+ window.URL.revokeObjectURL(url);
69
+ console.log('File decrypted and downloaded successfully');
70
+ } catch (error) {
71
+ console.error('Error decrypting file:', error);
72
+ }
73
+ }
74
+
75
+ const attachmentURL = 'https:/myfileurl.xyz/zzz/fileid?keyUri=somekeyuri&JWE=somejwe';
76
+ const options = {
77
+ useFileService: false,
78
+ jwe: somejwe, // Provide the JWE here if not already present in the attachmentURL
79
+ keyUri: someKeyUri // Provide the keyURI here if not already present in the attachmentURL
80
+ };
81
+
82
+ await decryptFile(webex, attachmentURL, options, 'MyFile.png', 'image/png');
83
+ ```
84
+
85
+ ### Example Usage
86
+
87
+ ```typescript
88
+ const accessToken = 'YOUR_ACCESS_TOKEN';
89
+ const encryptedFileUrl = 'https://example.com/encrypted-file';
90
+ const decryptedFileName = 'my-decrypted-file.jpeg';
91
+ const mimeType = 'image/jpeg';
92
+
93
+ initializeWebex(accessToken).then((webex) => {
94
+ decryptFile(webex, encryptedFileUrl, decryptedFileName, mimeType);
95
+ });
96
+ ```
97
+
98
+ ### Additional Information
99
+
100
+ For more information on the Webex JS SDK, please visit the [developer portal](https://developer.webex.com/).
101
+
102
+ ### License
103
+
104
+ This project is licensed under the Cisco General Terms - see the [LICENSE](https://github.com/webex/webex-js-sdk/blob/next/LICENSE.md) for details.
package/dist/config.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _default = exports.default = {
8
+ cypher: {}
9
+ };
10
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ null
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ null
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DECRYPTION_SUCCESS = exports.DECRYPTION_IN_PROGRESS = exports.DECRYPTION_FAILED = exports.DECRYPTION = exports.CYPHER = void 0;
7
+ const CYPHER = exports.CYPHER = 'cypher';
8
+ const DECRYPTION = exports.DECRYPTION = 'decryption';
9
+ const DECRYPTION_FAILED = exports.DECRYPTION_FAILED = 'decryptionFailed';
10
+ const DECRYPTION_IN_PROGRESS = exports.DECRYPTION_IN_PROGRESS = 'decryptionInProgress';
11
+ const DECRYPTION_SUCCESS = exports.DECRYPTION_SUCCESS = 'decryptionSuccess';
12
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ null
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=cypher.types.js.map
@@ -0,0 +1 @@
1
+ null
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _webexCore = require("@webex/webex-core");
8
+ var _constants = require("./constants");
9
+ /**
10
+ * @description Encryption APIs for KMS
11
+ * @class
12
+ */
13
+ class Cypher extends _webexCore.WebexPlugin {
14
+ namespace = _constants.CYPHER;
15
+ registered = false;
16
+
17
+ /**
18
+ * Constructs an instance of the class.
19
+ *
20
+ * @param {...any[]} args - The arguments to pass to the superclass constructor.
21
+ *
22
+ * @remarks
23
+ * This constructor calls the superclass constructor with the provided arguments.
24
+ * It also assigns the `webex` property to the `$webex` property, ignoring TypeScript errors.
25
+ */
26
+ constructor(...args) {
27
+ super(...args);
28
+ this.$webex = this.webex;
29
+ }
30
+
31
+ /**
32
+ * Registers the device to WDM. This is required for metrics and other services.
33
+ * @returns {Promise<void>}
34
+ */
35
+ async register() {
36
+ if (this.registered) {
37
+ this.$webex.logger.info('Cypher: webex.internal.device.register already done');
38
+ return Promise.resolve();
39
+ }
40
+ return this.$webex.internal.device.register().then(() => {
41
+ this.$webex.logger.info('Cypher: webex.internal.device.register successful');
42
+ this.registered = true;
43
+ }).catch(error => {
44
+ this.$webex.logger.error(`Error occurred during device.register() ${error}`);
45
+ throw error;
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Deregisters the device.
51
+ * @returns {Promise<void>}
52
+ */
53
+ async deregister() {
54
+ if (!this.registered) {
55
+ this.$webex.logger.info('Cypher: webex.internal.device.deregister already done');
56
+ return Promise.resolve();
57
+ }
58
+ return this.$webex.internal.device.unregister().then(() => {
59
+ this.$webex.logger.info('Cypher: webex.internal.device.deregister successful');
60
+ this.registered = false;
61
+ }).catch(error => {
62
+ this.$webex.logger.error(`Error occurred during device.deregister() ${error}`);
63
+ throw error;
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Downloads and decrypts a file from the given URI.
69
+ *
70
+ * @param {string} fileUri - The URI of the file to be decrypted.
71
+ * @param {FileDownloadOptions} options - The options for file download.
72
+ * @returns {Promise<ArrayBuffer>} A promise that resolves to the decrypted ArrayBuffer.
73
+ * @throws {Error} If the file download or decryption fails.
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const attachmentURL = 'https:/myfileurl.xyz/zzz/fileid?keyUri=somekeyuri&JWE=somejwe';
78
+ * const options: FileDownloadOptions = {
79
+ * useFileService: false,
80
+ * jwe: somejwe, // Provide the JWE here if not already present in the attachmentURL
81
+ * keyUri: someKeyUri, // Provide the keyURI here if not already present in the attachmentURL
82
+ * };
83
+ * const decryptedBuf = await webex.cypher.downloadAndDecryptFile(attachmentURL, options);
84
+ * const file = new File([decryptedBuf], "myFileName.jpeg", {type: 'image/jpeg'});
85
+ * ```
86
+ */
87
+ async downloadAndDecryptFile(fileUri, {
88
+ useFileService = false,
89
+ ...options
90
+ } = {}) {
91
+ // Sample fileUri: https://someserver.com/3cc29537-7f39-4cce-b204-a529960997fcab9375d8-4fd4-4788-bb12-18426674e95b.jpg?keyUri=kms://kms.wbx2.com/keys/79be16-a4dd-4195-93ef-a72604509aca&JWE=eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiZGlyIn0..EHYI5SmnFisaOJgv.6Ie3Zui7LFtAr4eWMSnxXAzfi8Cgixcy2b9jy9cImDWvBjjvJQfwik7qvZewCaq-u8lhtTbjEzsJLeVtOKhW_9RoZt3U0RQ-cKaSh2RaK3N_mvuH7_BsoXCMf5zxaqP1HD-3jXUtVSnqFYvEGdGRWxTCWK-PK9BoIUjX6v5t22CUNYbBQBuHizLWvrGAM0UkSvFNRX5n07Xd3WVJ7OnIhYi0JvOb50lbZIrBn27AQL-_CIKoOQxQLkW9zmVACsVpHxLZx9wIo9XYsBYADRTZaw_l_uTiosAd2P1QAGHgLr_Q_qf1wGUn3eGhmptpPx-YCSJikvs2DttwWOg_-vg4jI3EiIXlc0gGsDnleeNRguCLtrks0PMz5hOp5_w9Z5EW05Cx2UAztnp1hE9_nCvPP9wTzdHsG3flkK82HMbPpeVStWvWmAlzp24vTw2KzYrCemdS2AkrShWsNt6_G7_G8nB4RhUnZ11MKaduE5jYpCXNcTx84RBYwA.vqYHCx8uIn-IMQAsPvrw
92
+ // KeyUri: An attachment level unique ID generated by Webex KMS post encryption of an attachment. In order to
93
+ // decrypt an attachment, KeyUri is a required parameter.
94
+ // JWE: JWE can be decrypted using KMS key to obtain the SCR key.
95
+ // Decrypting an attachment requires the SCR key parameter.
96
+ // We need to download the encrypted file from the given URI and then decrypt it using the SCR key.
97
+ // The decrypted file is then returned.
98
+
99
+ // step 1: parse the fileUri to get the keyUri and JWE
100
+ // step 2: if keyUri and JWE are not present in the fileUri, use the options
101
+ // step 3: use the keyUri to decrypt the JWE to get the SCR
102
+ // step 4: download the file from the fileUri and decrypt it using the SCR
103
+
104
+ let keyUri;
105
+ let JWE;
106
+ try {
107
+ const url = new URL(fileUri);
108
+ keyUri = url.searchParams.get('keyUri') ?? undefined;
109
+ JWE = url.searchParams.get('JWE') ?? undefined;
110
+ } catch (error) {
111
+ this.$webex.logger.error(`Cypher: Invalid fileUri: ${error.message}`);
112
+ throw new Error(`Failed to decrypt the JWE: ${error.message}\nStack: ${error.stack}`);
113
+ }
114
+
115
+ // Check if the keyUri and JWE are present, else take it from options
116
+ if (!keyUri || !JWE) {
117
+ keyUri = options.keyUri;
118
+ JWE = options.jwe;
119
+ }
120
+
121
+ // Check if the keyUri and JWE are present, else throw an error
122
+ if (!keyUri || !JWE) {
123
+ throw new Error('KeyUri and JWE are required to decrypt the file. Either provide them in the fileUri or in the options.');
124
+ }
125
+ try {
126
+ // Decrypt the JWE to get the SCR
127
+ const scr = await this.$webex.internal.encryption.decryptScr(keyUri, JWE);
128
+
129
+ // Start the download and decryption process, returning a promise
130
+ return this.$webex.internal.encryption.download(fileUri, scr, {
131
+ useFileService
132
+ });
133
+ } catch (error) {
134
+ const enhancedError = new Error(`Failed to decrypt or download the file: ${error.message}\nStack: ${error.stack}`);
135
+ enhancedError.cause = error;
136
+ throw enhancedError;
137
+ }
138
+ }
139
+ }
140
+ var _default = exports.default = Cypher;
141
+ //# sourceMappingURL=index.js.map