@webex/internal-plugin-encryption 3.0.0-beta.8 → 3.0.0-bnr.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/README.md +1 -3
- package/dist/config.js +0 -9
- package/dist/config.js.map +1 -1
- package/dist/encryption.js +9 -60
- package/dist/encryption.js.map +1 -1
- package/dist/ensure-buffer.browser.js +0 -12
- package/dist/ensure-buffer.browser.js.map +1 -1
- package/dist/ensure-buffer.js +5 -12
- package/dist/ensure-buffer.js.map +1 -1
- package/dist/index.js +7 -33
- package/dist/index.js.map +1 -1
- package/dist/kms-batcher.js +6 -30
- package/dist/kms-batcher.js.map +1 -1
- package/dist/kms-certificate-validation.js +20 -88
- package/dist/kms-certificate-validation.js.map +1 -1
- package/dist/kms-dry-error-interceptor.js +1 -23
- package/dist/kms-dry-error-interceptor.js.map +1 -1
- package/dist/kms-errors.js +3 -50
- package/dist/kms-errors.js.map +1 -1
- package/dist/kms.js +74 -213
- package/dist/kms.js.map +1 -1
- package/dist/types/config.d.ts +16 -0
- package/dist/types/encryption.d.ts +2 -0
- package/dist/types/ensure-buffer.browser.d.ts +10 -0
- package/dist/types/ensure-buffer.d.ts +7 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/kms-batcher.d.ts +6 -0
- package/dist/types/kms-certificate-validation.d.ts +24 -0
- package/dist/types/kms-dry-error-interceptor.d.ts +25 -0
- package/dist/types/kms-errors.d.ts +33 -0
- package/dist/types/kms.d.ts +5 -0
- package/package.json +15 -15
- package/src/config.js +3 -3
- package/src/encryption.js +66 -56
- package/src/ensure-buffer.browser.js +0 -1
- package/src/ensure-buffer.js +5 -5
- package/src/index.js +120 -96
- package/src/kms-batcher.js +50 -44
- package/src/kms-certificate-validation.js +45 -47
- package/src/kms-dry-error-interceptor.js +8 -4
- package/src/kms-errors.js +19 -16
- package/src/kms.js +210 -206
- package/test/integration/spec/encryption.js +311 -230
- package/test/integration/spec/kms.js +532 -404
- package/test/integration/spec/payload-transfom.js +69 -69
- package/test/unit/spec/encryption.js +16 -13
- package/test/unit/spec/kms-certificate-validation.js +41 -32
package/src/encryption.js
CHANGED
|
@@ -15,7 +15,7 @@ import KMS from './kms';
|
|
|
15
15
|
|
|
16
16
|
const Encryption = WebexPlugin.extend({
|
|
17
17
|
children: {
|
|
18
|
-
kms: KMS
|
|
18
|
+
kms: KMS,
|
|
19
19
|
},
|
|
20
20
|
|
|
21
21
|
namespace: 'Encryption',
|
|
@@ -25,15 +25,14 @@ const Encryption = WebexPlugin.extend({
|
|
|
25
25
|
},
|
|
26
26
|
|
|
27
27
|
decryptBinary(scr, buffer) {
|
|
28
|
-
return ensureBuffer(buffer)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
28
|
+
return ensureBuffer(buffer).then((b) => {
|
|
29
|
+
/* istanbul ignore if */
|
|
30
|
+
if (buffer.length === 0 || buffer.byteLength === 0) {
|
|
31
|
+
return Promise.reject(new Error('Attempted to decrypt zero-length buffer'));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return scr.decrypt(b);
|
|
35
|
+
});
|
|
37
36
|
},
|
|
38
37
|
|
|
39
38
|
/**
|
|
@@ -46,8 +45,7 @@ const Encryption = WebexPlugin.extend({
|
|
|
46
45
|
* @returns {Object} Decrypted SCR
|
|
47
46
|
*/
|
|
48
47
|
decryptScr(key, cipherScr, options) {
|
|
49
|
-
return this.getKey(key, options)
|
|
50
|
-
.then((k) => SCR.fromJWE(k.jwk, cipherScr));
|
|
48
|
+
return this.getKey(key, options).then((k) => SCR.fromJWE(k.jwk, cipherScr));
|
|
51
49
|
},
|
|
52
50
|
|
|
53
51
|
/**
|
|
@@ -60,11 +58,11 @@ const Encryption = WebexPlugin.extend({
|
|
|
60
58
|
* @returns {string} Decrypted plaintext
|
|
61
59
|
*/
|
|
62
60
|
decryptText(key, ciphertext, options) {
|
|
63
|
-
return this.getKey(key, options)
|
|
64
|
-
.
|
|
65
|
-
.createDecrypt(k.jwk)
|
|
61
|
+
return this.getKey(key, options).then((k) =>
|
|
62
|
+
jose.JWE.createDecrypt(k.jwk)
|
|
66
63
|
.decrypt(ciphertext)
|
|
67
|
-
.then((result) => result.plaintext.toString())
|
|
64
|
+
.then((result) => result.plaintext.toString())
|
|
65
|
+
);
|
|
68
66
|
},
|
|
69
67
|
|
|
70
68
|
/**
|
|
@@ -83,10 +81,11 @@ const Encryption = WebexPlugin.extend({
|
|
|
83
81
|
const shunt = new EventEmitter();
|
|
84
82
|
const promise = this._fetchDownloadUrl(scr, options)
|
|
85
83
|
.then((uri) => {
|
|
84
|
+
// eslint-disable-next-line no-shadow
|
|
86
85
|
const options = {
|
|
87
86
|
method: 'GET',
|
|
88
87
|
uri,
|
|
89
|
-
responseType: 'buffer'
|
|
88
|
+
responseType: 'buffer',
|
|
90
89
|
};
|
|
91
90
|
|
|
92
91
|
const ret = this.request(options);
|
|
@@ -113,13 +112,15 @@ const Encryption = WebexPlugin.extend({
|
|
|
113
112
|
this.logger.info('encryption: retrieving download url for encrypted file');
|
|
114
113
|
|
|
115
114
|
if (process.env.NODE_ENV !== 'production' && scr.loc.includes('localhost')) {
|
|
116
|
-
this.logger.info(
|
|
115
|
+
this.logger.info(
|
|
116
|
+
'encryption: bypassing webex files because this looks to be a test file on localhost'
|
|
117
|
+
);
|
|
117
118
|
|
|
118
119
|
return Promise.resolve(scr.loc);
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
const inputBody = {
|
|
122
|
-
endpoints: [scr.loc]
|
|
123
|
+
endpoints: [scr.loc],
|
|
123
124
|
};
|
|
124
125
|
const endpointUrl = url.parse(scr.loc);
|
|
125
126
|
|
|
@@ -130,32 +131,39 @@ const Encryption = WebexPlugin.extend({
|
|
|
130
131
|
return this.request({
|
|
131
132
|
method: 'POST',
|
|
132
133
|
uri: url.format(endpointUrl),
|
|
133
|
-
body: options
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return
|
|
149
|
-
}
|
|
134
|
+
body: options
|
|
135
|
+
? {
|
|
136
|
+
...inputBody,
|
|
137
|
+
allow: options.params.allow,
|
|
138
|
+
}
|
|
139
|
+
: inputBody,
|
|
140
|
+
}).then((res) => {
|
|
141
|
+
// eslint-disable-next-line no-shadow
|
|
142
|
+
const url = res.body.endpoints[scr.loc];
|
|
143
|
+
|
|
144
|
+
if (!url) {
|
|
145
|
+
this.logger.warn(
|
|
146
|
+
'encryption: could not determine download url for `scr.loc`; attempting to download `scr.loc` directly'
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
return scr.loc;
|
|
150
|
+
}
|
|
151
|
+
this.logger.info('encryption: retrieved download url for encrypted file');
|
|
152
|
+
|
|
153
|
+
return url;
|
|
154
|
+
});
|
|
150
155
|
},
|
|
151
156
|
|
|
152
157
|
encryptBinary(file) {
|
|
153
|
-
return ensureBuffer(file)
|
|
154
|
-
.then((
|
|
155
|
-
|
|
158
|
+
return ensureBuffer(file).then((buffer) =>
|
|
159
|
+
SCR.create().then((scr) =>
|
|
160
|
+
scr
|
|
161
|
+
.encrypt(buffer)
|
|
156
162
|
.then(ensureBuffer)
|
|
157
163
|
// eslint-disable-next-line max-nested-callbacks
|
|
158
|
-
.then((cdata) => ({scr, cdata}))
|
|
164
|
+
.then((cdata) => ({scr, cdata}))
|
|
165
|
+
)
|
|
166
|
+
);
|
|
159
167
|
},
|
|
160
168
|
|
|
161
169
|
/**
|
|
@@ -173,8 +181,7 @@ const Encryption = WebexPlugin.extend({
|
|
|
173
181
|
return Promise.reject(new Error('Cannot encrypt `scr` without first setting `loc`'));
|
|
174
182
|
}
|
|
175
183
|
|
|
176
|
-
return this.getKey(key, options)
|
|
177
|
-
.then((k) => scr.toJWE(k.jwk));
|
|
184
|
+
return this.getKey(key, options).then((k) => scr.toJWE(k.jwk));
|
|
178
185
|
},
|
|
179
186
|
|
|
180
187
|
/**
|
|
@@ -187,16 +194,15 @@ const Encryption = WebexPlugin.extend({
|
|
|
187
194
|
* @returns {string} Encrypted text
|
|
188
195
|
*/
|
|
189
196
|
encryptText(key, plaintext, options) {
|
|
190
|
-
return this.getKey(key, options)
|
|
191
|
-
.
|
|
192
|
-
.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
.final(plaintext, 'utf8'));
|
|
197
|
+
return this.getKey(key, options).then((k) =>
|
|
198
|
+
jose.JWE.createEncrypt(this.config.joseOptions, {
|
|
199
|
+
key: k.jwk,
|
|
200
|
+
header: {
|
|
201
|
+
alg: 'dir',
|
|
202
|
+
},
|
|
203
|
+
reference: null,
|
|
204
|
+
}).final(plaintext, 'utf8')
|
|
205
|
+
);
|
|
200
206
|
},
|
|
201
207
|
|
|
202
208
|
/**
|
|
@@ -218,12 +224,16 @@ const Encryption = WebexPlugin.extend({
|
|
|
218
224
|
storageKey += `/onBehalfOf/${onBehalfOf}`;
|
|
219
225
|
}
|
|
220
226
|
|
|
221
|
-
return this.unboundedStorage
|
|
227
|
+
return this.unboundedStorage
|
|
228
|
+
.get(storageKey)
|
|
222
229
|
.then((keyString) => JSON.parse(keyString))
|
|
223
230
|
.then((keyObject) => this.kms.asKey(keyObject))
|
|
224
|
-
.catch(() =>
|
|
225
|
-
|
|
226
|
-
|
|
231
|
+
.catch(() =>
|
|
232
|
+
this.kms
|
|
233
|
+
.fetchKey({uri, onBehalfOf})
|
|
234
|
+
.then(tap((key) => this.unboundedStorage.put(storageKey, JSON.stringify(key, replacer))))
|
|
235
|
+
);
|
|
236
|
+
},
|
|
227
237
|
});
|
|
228
238
|
|
|
229
239
|
/**
|
package/src/ensure-buffer.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
import {isBuffer} from '@webex/common';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Ensures the provider Buffer is, indeed, a Buffer; sometimes, they seem to be
|
|
9
|
-
* byte-arrays instead of proper Buffer objects.
|
|
10
|
-
* @param {mixed} buffer
|
|
11
|
-
* @returns {Promise<Buffer>}
|
|
12
|
-
*/
|
|
8
|
+
* Ensures the provider Buffer is, indeed, a Buffer; sometimes, they seem to be
|
|
9
|
+
* byte-arrays instead of proper Buffer objects.
|
|
10
|
+
* @param {mixed} buffer
|
|
11
|
+
* @returns {Promise<Buffer>}
|
|
12
|
+
*/
|
|
13
13
|
export default function ensureBuffer(buffer) {
|
|
14
14
|
/* istanbul ignore if */
|
|
15
15
|
if (!isBuffer(buffer)) {
|
package/src/index.js
CHANGED
|
@@ -8,126 +8,150 @@
|
|
|
8
8
|
// by using Promise.race to resolve replays (as more requests get enqueue for a
|
|
9
9
|
// specific action, accept whichever one completes first).
|
|
10
10
|
|
|
11
|
+
import '@webex/internal-plugin-device';
|
|
12
|
+
|
|
13
|
+
import '@webex/internal-plugin-mercury';
|
|
14
|
+
|
|
11
15
|
import {registerInternalPlugin} from '@webex/webex-core';
|
|
12
16
|
import {has, isObject, isString} from 'lodash';
|
|
13
17
|
|
|
14
18
|
import Encryption from './encryption';
|
|
15
19
|
import config from './config';
|
|
16
20
|
import {DryError} from './kms-errors';
|
|
17
|
-
|
|
18
|
-
import '@webex/internal-plugin-mercury';
|
|
21
|
+
|
|
19
22
|
import KmsDryErrorInterceptor from './kms-dry-error-interceptor';
|
|
20
23
|
|
|
21
24
|
let interceptors;
|
|
22
25
|
|
|
23
26
|
if (process.env.NODE_ENV === 'test') {
|
|
24
27
|
interceptors = {
|
|
25
|
-
KmsDryErrorInterceptor: KmsDryErrorInterceptor.create
|
|
28
|
+
KmsDryErrorInterceptor: KmsDryErrorInterceptor.create,
|
|
26
29
|
};
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
registerInternalPlugin('encryption', Encryption, {
|
|
30
33
|
payloadTransformer: {
|
|
31
|
-
predicates: [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
34
|
+
predicates: [
|
|
35
|
+
{
|
|
36
|
+
name: 'encryptKmsMessage',
|
|
37
|
+
direction: 'outbound',
|
|
38
|
+
// I don't see any practical way to reduce complexity here.
|
|
39
|
+
// eslint-disable-next-line complexity
|
|
40
|
+
test(ctx, options) {
|
|
41
|
+
if (!has(options, 'body.kmsMessage')) {
|
|
42
|
+
return Promise.resolve(false);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!isObject(options.body.kmsMessage)) {
|
|
46
|
+
return Promise.resolve(false);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// If this is a template for a kms message, assume another transform
|
|
50
|
+
// will fill it in later. This is a bit of a leaky abstraction, but the
|
|
51
|
+
// alternative is building a complex rules engine for controlling
|
|
52
|
+
// ordering of transforms
|
|
53
|
+
if (options.body.kmsMessage.keyUris && options.body.kmsMessage.keyUris.length === 0) {
|
|
54
|
+
return Promise.resolve(false);
|
|
55
|
+
}
|
|
56
|
+
if (
|
|
57
|
+
options.body.kmsMessage.resourceUri &&
|
|
58
|
+
(options.body.kmsMessage.resourceUri.includes('<KRO>') ||
|
|
59
|
+
options.body.kmsMessage.resourceUri.includes('<KEYURL>'))
|
|
60
|
+
) {
|
|
61
|
+
return Promise.resolve(false);
|
|
62
|
+
}
|
|
63
|
+
if (
|
|
64
|
+
options.body.kmsMessage.uri &&
|
|
65
|
+
(options.body.kmsMessage.uri.includes('<KRO>') ||
|
|
66
|
+
options.body.kmsMessage.uri.includes('<KEYURL>'))
|
|
67
|
+
) {
|
|
68
|
+
return Promise.resolve(false);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return Promise.resolve(true);
|
|
72
|
+
},
|
|
73
|
+
extract(options) {
|
|
74
|
+
return Promise.resolve(options.body);
|
|
75
|
+
},
|
|
60
76
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
{
|
|
78
|
+
name: 'decryptKmsMessage',
|
|
79
|
+
direction: 'inbound',
|
|
80
|
+
test(ctx, response) {
|
|
81
|
+
return Promise.resolve(
|
|
82
|
+
has(response, 'body.kmsMessage') && isString(response.body.kmsMessage)
|
|
83
|
+
);
|
|
84
|
+
},
|
|
85
|
+
extract(response) {
|
|
86
|
+
return Promise.resolve(response.body);
|
|
87
|
+
},
|
|
69
88
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
{
|
|
90
|
+
name: 'decryptErrorResponse',
|
|
91
|
+
direction: 'inbound',
|
|
92
|
+
test(ctx, reason) {
|
|
93
|
+
return Promise.resolve(Boolean(reason.body && reason.body.errorCode === 1900000));
|
|
94
|
+
},
|
|
95
|
+
extract(reason) {
|
|
96
|
+
return Promise.resolve(reason);
|
|
97
|
+
},
|
|
78
98
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return ctx.webex.internal.encryption.kms.prepareRequest(object.kmsMessage)
|
|
99
|
-
.then((req) => {
|
|
99
|
+
],
|
|
100
|
+
transforms: [
|
|
101
|
+
{
|
|
102
|
+
name: 'encryptKmsMessage',
|
|
103
|
+
fn(ctx, object) {
|
|
104
|
+
if (!object) {
|
|
105
|
+
return Promise.resolve();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!object.kmsMessage) {
|
|
109
|
+
return Promise.resolve();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (isString(object.kmsMessage)) {
|
|
113
|
+
return Promise.resolve();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return ctx.webex.internal.encryption.kms.prepareRequest(object.kmsMessage).then((req) => {
|
|
100
117
|
object.kmsMessage = req.wrapped;
|
|
101
118
|
});
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.
|
|
108
|
-
object.kmsMessage
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'decryptKmsMessage',
|
|
123
|
+
fn(ctx, object) {
|
|
124
|
+
return ctx.webex.internal.encryption.kms
|
|
125
|
+
.decryptKmsMessage(object.kmsMessage)
|
|
126
|
+
.then((kmsMessage) => {
|
|
127
|
+
object.kmsMessage = kmsMessage;
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'decryptErrorResponse',
|
|
133
|
+
fn(ctx, reason) {
|
|
134
|
+
const promises = reason.body.errors.map((error) =>
|
|
135
|
+
ctx.webex.internal.encryption.kms.decryptKmsMessage(error.description).then((desc) => {
|
|
136
|
+
error.description = desc;
|
|
137
|
+
})
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
promises.push(
|
|
141
|
+
ctx.webex.internal.encryption.kms
|
|
142
|
+
.decryptKmsMessage(reason.body.message)
|
|
143
|
+
.then((kmsMessage) => {
|
|
144
|
+
reason.body.message = kmsMessage;
|
|
145
|
+
})
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
return Promise.all(promises).then(() => Promise.reject(new DryError(reason)));
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
],
|
|
128
152
|
},
|
|
129
153
|
interceptors,
|
|
130
|
-
config
|
|
154
|
+
config,
|
|
131
155
|
});
|
|
132
156
|
|
|
133
157
|
export {default} from './encryption';
|
package/src/kms-batcher.js
CHANGED
|
@@ -23,14 +23,19 @@ const KmsBatcher = Batcher.extend({
|
|
|
23
23
|
processKmsMessageEvent(event) {
|
|
24
24
|
this.logger.info('kms-batcher: received kms message');
|
|
25
25
|
|
|
26
|
-
return Promise.all(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
return Promise.all(
|
|
27
|
+
event.encryption.kmsMessages.map(
|
|
28
|
+
(kmsMessage) =>
|
|
29
|
+
new Promise((resolve) => {
|
|
30
|
+
/* istanbul ignore else */
|
|
31
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
32
|
+
this.logger.info('kms-batcher:', kmsMessage.body);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
resolve(this.acceptItem(kmsMessage));
|
|
36
|
+
})
|
|
37
|
+
)
|
|
38
|
+
);
|
|
34
39
|
},
|
|
35
40
|
|
|
36
41
|
/**
|
|
@@ -39,30 +44,34 @@ const KmsBatcher = Batcher.extend({
|
|
|
39
44
|
* @returns {Promise<Object>}
|
|
40
45
|
*/
|
|
41
46
|
prepareItem(item) {
|
|
42
|
-
return this.getDeferredForRequest(item)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
return this.getDeferredForRequest(item).then((defer) => {
|
|
48
|
+
const timeout = item[TIMEOUT_SYMBOL];
|
|
49
|
+
|
|
50
|
+
/* istanbul ignore if */
|
|
51
|
+
if (!timeout) {
|
|
52
|
+
throw new Error('timeout is required');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const timer = safeSetTimeout(() => {
|
|
56
|
+
this.logger.warn(
|
|
57
|
+
`kms: request timed out; request id: ${item.requestId}; timeout: ${timeout}`
|
|
58
|
+
);
|
|
59
|
+
this.handleItemFailure(
|
|
60
|
+
item,
|
|
61
|
+
new KmsTimeoutError({
|
|
54
62
|
timeout,
|
|
55
|
-
request: item
|
|
56
|
-
})
|
|
57
|
-
|
|
63
|
+
request: item,
|
|
64
|
+
})
|
|
65
|
+
);
|
|
66
|
+
}, timeout);
|
|
58
67
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
// Reminder: reassign `promise` is not a viable means of inserting into
|
|
69
|
+
// the Promise chain
|
|
70
|
+
defer.promise.then(() => clearTimeout(timer));
|
|
71
|
+
defer.promise.catch(() => clearTimeout(timer));
|
|
63
72
|
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
return item;
|
|
74
|
+
});
|
|
66
75
|
},
|
|
67
76
|
|
|
68
77
|
/**
|
|
@@ -71,11 +80,10 @@ const KmsBatcher = Batcher.extend({
|
|
|
71
80
|
* @returns {Promise<Array>}
|
|
72
81
|
*/
|
|
73
82
|
prepareRequest(queue) {
|
|
74
|
-
return this.webex.internal.encryption.kms._getKMSCluster()
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}));
|
|
83
|
+
return this.webex.internal.encryption.kms._getKMSCluster().then((cluster) => ({
|
|
84
|
+
destination: cluster,
|
|
85
|
+
kmsMessages: queue.map((req) => req.wrapped),
|
|
86
|
+
}));
|
|
79
87
|
},
|
|
80
88
|
|
|
81
89
|
/**
|
|
@@ -89,7 +97,7 @@ const KmsBatcher = Batcher.extend({
|
|
|
89
97
|
method: 'POST',
|
|
90
98
|
service: 'encryption',
|
|
91
99
|
resource: '/kms/messages',
|
|
92
|
-
body: payload
|
|
100
|
+
body: payload,
|
|
93
101
|
});
|
|
94
102
|
},
|
|
95
103
|
|
|
@@ -114,10 +122,9 @@ const KmsBatcher = Batcher.extend({
|
|
|
114
122
|
* @returns {Promise}
|
|
115
123
|
*/
|
|
116
124
|
handleItemSuccess(item) {
|
|
117
|
-
return this.getDeferredForResponse(item)
|
|
118
|
-
.
|
|
119
|
-
|
|
120
|
-
});
|
|
125
|
+
return this.getDeferredForResponse(item).then((defer) => {
|
|
126
|
+
defer.resolve(item.body);
|
|
127
|
+
});
|
|
121
128
|
},
|
|
122
129
|
|
|
123
130
|
/**
|
|
@@ -126,10 +133,9 @@ const KmsBatcher = Batcher.extend({
|
|
|
126
133
|
* @returns {Promise}
|
|
127
134
|
*/
|
|
128
135
|
handleItemFailure(item, reason) {
|
|
129
|
-
return this.getDeferredForResponse(item)
|
|
130
|
-
.
|
|
131
|
-
|
|
132
|
-
});
|
|
136
|
+
return this.getDeferredForResponse(item).then((defer) => {
|
|
137
|
+
defer.reject(reason || new KmsError(item.body));
|
|
138
|
+
});
|
|
133
139
|
},
|
|
134
140
|
|
|
135
141
|
/**
|
|
@@ -146,7 +152,7 @@ const KmsBatcher = Batcher.extend({
|
|
|
146
152
|
*/
|
|
147
153
|
fingerprintResponse(item) {
|
|
148
154
|
return Promise.resolve(item.requestId);
|
|
149
|
-
}
|
|
155
|
+
},
|
|
150
156
|
});
|
|
151
157
|
|
|
152
158
|
export default KmsBatcher;
|