@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.
- package/.eslintrc.js +6 -0
- package/LICENSE +2 -0
- package/README.md +88 -0
- package/babel.config.js +13 -0
- package/browsers.js +97 -0
- package/coverage/clover.xml +176 -0
- package/coverage/coverage-final.json +3 -0
- package/coverage/jest-html-reporters-attach/jest-report/index.js +58 -0
- package/coverage/jest-html-reporters-attach/jest-report/result.js +1 -0
- package/coverage/jest-report.html +1 -0
- package/coverage/junit/coverage-junit.xml +27 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/constants.ts.html +100 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +131 -0
- package/coverage/lcov-report/index.ts.html +562 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +215 -0
- package/developer-quickstart.md +104 -0
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +6 -0
- package/dist/constants.js.map +1 -0
- package/dist/cypher/constants.js +12 -0
- package/dist/cypher/constants.js.map +1 -0
- package/dist/cypher/cypher.types.js +6 -0
- package/dist/cypher/cypher.types.js.map +1 -0
- package/dist/cypher/index.js +141 -0
- package/dist/cypher/index.js.map +1 -0
- package/dist/cypher/types.js +6 -0
- package/dist/cypher/types.js.map +1 -0
- package/dist/encryption/constants.js +12 -0
- package/dist/encryption/constants.js.map +1 -0
- package/dist/encryption/encryption.types.js +6 -0
- package/dist/encryption/encryption.types.js.map +1 -0
- package/dist/encryption/index.js +84 -0
- package/dist/encryption/index.js.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/types/config.d.ts +4 -0
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/cypher/constants.d.ts +5 -0
- package/dist/types/cypher/cypher.types.d.ts +25 -0
- package/dist/types/cypher/index.d.ts +53 -0
- package/dist/types/cypher/types.d.ts +25 -0
- package/dist/types/encryption/constants.d.ts +5 -0
- package/dist/types/encryption/encryption.types.d.ts +25 -0
- package/dist/types/encryption/index.d.ts +27 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/types.d.ts +40 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/jest.config.js +44 -0
- package/junit.xml +27 -0
- package/package.json +57 -0
- package/process +1 -0
- package/src/config.ts +3 -0
- package/src/cypher/constants.ts +5 -0
- package/src/cypher/index.ts +159 -0
- package/src/cypher/types.ts +28 -0
- package/src/index.ts +13 -0
- package/src/types.ts +45 -0
- package/test/unit/spec/cypher/index.ts +146 -0
- 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 @@
|
|
|
1
|
+
null
|
|
@@ -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 @@
|
|
|
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
|