@webex/internal-plugin-encryption 3.0.0-beta.169 → 3.0.0-beta.170
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/dist/encryption.js +18 -16
- package/dist/encryption.js.map +1 -1
- package/dist/kms.js +1 -1
- package/package.json +14 -14
- package/src/encryption.js +30 -23
- package/test/unit/spec/encryption.js +10 -10
package/dist/encryption.js
CHANGED
|
@@ -73,19 +73,19 @@ var Encryption = _webexCore.WebexPlugin.extend({
|
|
|
73
73
|
},
|
|
74
74
|
/**
|
|
75
75
|
* Validate and initiate a Download request for requested file
|
|
76
|
-
*
|
|
76
|
+
* @param {Object} fileUrl - Plaintext
|
|
77
77
|
* @param {Object} scr - Plaintext
|
|
78
78
|
* @param {Object} options - optional parameters to download a file
|
|
79
79
|
* @returns {promise}
|
|
80
80
|
*/
|
|
81
|
-
download: function download(scr, options) {
|
|
81
|
+
download: function download(fileUrl, scr, options) {
|
|
82
82
|
var _this = this;
|
|
83
83
|
/* istanbul ignore if */
|
|
84
|
-
if (!scr
|
|
85
|
-
return _promise.default.reject(new Error('`scr
|
|
84
|
+
if (!fileUrl || !scr) {
|
|
85
|
+
return _promise.default.reject(new Error('`scr` and `fileUrl` are required'));
|
|
86
86
|
}
|
|
87
87
|
var shunt = new _events.EventEmitter();
|
|
88
|
-
var promise = this._fetchDownloadUrl(
|
|
88
|
+
var promise = this._fetchDownloadUrl(fileUrl, options).then(function (uri) {
|
|
89
89
|
// eslint-disable-next-line no-shadow
|
|
90
90
|
var options = {
|
|
91
91
|
method: 'GET',
|
|
@@ -103,22 +103,21 @@ var Encryption = _webexCore.WebexPlugin.extend({
|
|
|
103
103
|
},
|
|
104
104
|
/**
|
|
105
105
|
* Fetch Download URL for the requested file
|
|
106
|
-
*
|
|
107
|
-
* @param {Object} scr - Plaintext
|
|
106
|
+
* @param {Object} fileUrl - Plaintext
|
|
108
107
|
* @param {Object} options - optional parameters to download a file
|
|
109
108
|
* @returns {promise} url of the downloadable file
|
|
110
109
|
*/
|
|
111
|
-
_fetchDownloadUrl: function _fetchDownloadUrl(
|
|
110
|
+
_fetchDownloadUrl: function _fetchDownloadUrl(fileUrl, options) {
|
|
112
111
|
var _this2 = this;
|
|
113
112
|
this.logger.info('encryption: retrieving download url for encrypted file');
|
|
114
|
-
if (process.env.NODE_ENV !== 'production' &&
|
|
113
|
+
if (process.env.NODE_ENV !== 'production' && fileUrl.includes('localhost')) {
|
|
115
114
|
this.logger.info('encryption: bypassing webex files because this looks to be a test file on localhost');
|
|
116
|
-
return _promise.default.resolve(
|
|
115
|
+
return _promise.default.resolve(fileUrl);
|
|
117
116
|
}
|
|
118
117
|
var inputBody = {
|
|
119
|
-
endpoints: [
|
|
118
|
+
endpoints: [fileUrl]
|
|
120
119
|
};
|
|
121
|
-
var endpointUrl = _url.default.parse(
|
|
120
|
+
var endpointUrl = _url.default.parse(fileUrl);
|
|
122
121
|
|
|
123
122
|
// hardcode the url to use 'https' and the file service '/v1/download/endpoints' api
|
|
124
123
|
endpointUrl.protocol = 'https';
|
|
@@ -131,13 +130,16 @@ var Encryption = _webexCore.WebexPlugin.extend({
|
|
|
131
130
|
}) : inputBody
|
|
132
131
|
}).then(function (res) {
|
|
133
132
|
// eslint-disable-next-line no-shadow
|
|
134
|
-
var url = res.body.endpoints[
|
|
133
|
+
var url = res.body.endpoints[fileUrl];
|
|
135
134
|
if (!url) {
|
|
136
|
-
_this2.logger.warn('encryption: could not determine download url for `
|
|
137
|
-
return
|
|
135
|
+
_this2.logger.warn('encryption: could not determine download url for `fileUrl`; attempting to download `fileUrl` directly');
|
|
136
|
+
return fileUrl;
|
|
138
137
|
}
|
|
139
138
|
_this2.logger.info('encryption: retrieved download url for encrypted file');
|
|
140
139
|
return url;
|
|
140
|
+
}).catch(function (err) {
|
|
141
|
+
_this2.logger.warn("encryption: ".concat(err, " could not determine download url for ").concat(fileUrl, "; attempting to download ").concat(fileUrl, " directly"));
|
|
142
|
+
return fileUrl;
|
|
141
143
|
});
|
|
142
144
|
},
|
|
143
145
|
encryptBinary: function encryptBinary(file) {
|
|
@@ -225,7 +227,7 @@ var Encryption = _webexCore.WebexPlugin.extend({
|
|
|
225
227
|
}));
|
|
226
228
|
});
|
|
227
229
|
},
|
|
228
|
-
version: "3.0.0-beta.
|
|
230
|
+
version: "3.0.0-beta.170"
|
|
229
231
|
});
|
|
230
232
|
|
|
231
233
|
/**
|
package/dist/encryption.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Encryption","WebexPlugin","extend","children","kms","KMS","namespace","processKmsMessageEvent","event","decryptBinary","scr","buffer","ensureBuffer","then","b","length","byteLength","reject","Error","decrypt","decryptScr","key","cipherScr","options","getKey","k","SCR","fromJWE","jwk","decryptText","ciphertext","jose","JWE","createDecrypt","result","plaintext","toString","download","loc","shunt","EventEmitter","promise","_fetchDownloadUrl","uri","method","responseType","ret","request","transferEvents","res","body","proxyEvents","logger","info","process","env","NODE_ENV","includes","resolve","inputBody","endpoints","endpointUrl","url","parse","protocol","pathname","format","allow","params","warn","encryptBinary","file","create","encrypt","cdata","encryptScr","toJWE","encryptText","createEncrypt","config","joseOptions","header","alg","reference","final","onBehalfOf","asKey","storageKey","unboundedStorage","get","keyString","JSON","keyObject","catch","fetchKey","tap","put","replacer","v","json","toJSON"],"sources":["encryption.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {EventEmitter} from 'events';\nimport url from 'url';\n\nimport {WebexPlugin} from '@webex/webex-core';\nimport {proxyEvents, tap, transferEvents} from '@webex/common';\nimport jose from 'node-jose';\nimport SCR from 'node-scr';\n\nimport ensureBuffer from './ensure-buffer';\nimport KMS from './kms';\n\nconst Encryption = WebexPlugin.extend({\n children: {\n kms: KMS,\n },\n\n namespace: 'Encryption',\n\n processKmsMessageEvent(event) {\n return this.kms.processKmsMessageEvent(event);\n },\n\n decryptBinary(scr, buffer) {\n return ensureBuffer(buffer).then((b) => {\n /* istanbul ignore if */\n if (buffer.length === 0 || buffer.byteLength === 0) {\n return Promise.reject(new Error('Attempted to decrypt zero-length buffer'));\n }\n\n return scr.decrypt(b);\n });\n },\n\n /**\n * Decrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} cipherScr - An encrypted SCR\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {Object} Decrypted SCR\n */\n decryptScr(key, cipherScr, options) {\n return this.getKey(key, options).then((k) => SCR.fromJWE(k.jwk, cipherScr));\n },\n\n /**\n * Decrypt text using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} ciphertext - Encrypted text\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Decrypted plaintext\n */\n decryptText(key, ciphertext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createDecrypt(k.jwk)\n .decrypt(ciphertext)\n .then((result) => result.plaintext.toString())\n );\n },\n\n /**\n * Validate and initiate a Download request for requested file\n *\n * @param {Object} scr - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise}\n */\n download(scr, options) {\n /* istanbul ignore if */\n if (!scr.loc) {\n return Promise.reject(new Error('`scr.loc` is required'));\n }\n\n const shunt = new EventEmitter();\n const promise = this._fetchDownloadUrl(scr, options)\n .then((uri) => {\n // eslint-disable-next-line no-shadow\n const options = {\n method: 'GET',\n uri,\n responseType: 'buffer',\n };\n\n const ret = this.request(options);\n\n transferEvents('progress', options.download, shunt);\n\n return ret;\n })\n .then((res) => this.decryptBinary(scr, res.body));\n\n proxyEvents(shunt, promise);\n\n return promise;\n },\n\n /**\n * Fetch Download URL for the requested file\n *\n * @param {Object} scr - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise} url of the downloadable file\n */\n _fetchDownloadUrl(scr, options) {\n this.logger.info('encryption: retrieving download url for encrypted file');\n\n if (process.env.NODE_ENV !== 'production' && scr.loc.includes('localhost')) {\n this.logger.info(\n 'encryption: bypassing webex files because this looks to be a test file on localhost'\n );\n\n return Promise.resolve(scr.loc);\n }\n\n const inputBody = {\n endpoints: [scr.loc],\n };\n const endpointUrl = url.parse(scr.loc);\n\n // hardcode the url to use 'https' and the file service '/v1/download/endpoints' api\n endpointUrl.protocol = 'https';\n endpointUrl.pathname = '/v1/download/endpoints';\n\n return this.request({\n method: 'POST',\n uri: url.format(endpointUrl),\n body: options\n ? {\n ...inputBody,\n allow: options.params.allow,\n }\n : inputBody,\n }).then((res) => {\n // eslint-disable-next-line no-shadow\n const url = res.body.endpoints[scr.loc];\n\n if (!url) {\n this.logger.warn(\n 'encryption: could not determine download url for `scr.loc`; attempting to download `scr.loc` directly'\n );\n\n return scr.loc;\n }\n this.logger.info('encryption: retrieved download url for encrypted file');\n\n return url;\n });\n },\n\n encryptBinary(file) {\n return ensureBuffer(file).then((buffer) =>\n SCR.create().then((scr) =>\n scr\n .encrypt(buffer)\n .then(ensureBuffer)\n // eslint-disable-next-line max-nested-callbacks\n .then((cdata) => ({scr, cdata}))\n )\n );\n },\n\n /**\n * Encrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} scr - Plaintext\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted SCR\n */\n encryptScr(key, scr, options) {\n /* istanbul ignore if */\n if (!scr.loc) {\n return Promise.reject(new Error('Cannot encrypt `scr` without first setting `loc`'));\n }\n\n return this.getKey(key, options).then((k) => scr.toJWE(k.jwk));\n },\n\n /**\n * Encrypt plaintext using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} plaintext\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted text\n */\n encryptText(key, plaintext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createEncrypt(this.config.joseOptions, {\n key: k.jwk,\n header: {\n alg: 'dir',\n },\n reference: null,\n }).final(plaintext, 'utf8')\n );\n },\n\n /**\n * Fetch the key associated with the supplied KMS uri.\n *\n * @param {string} uri - The uri of a key stored in KMS\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Key\n */\n getKey(uri, {onBehalfOf} = {}) {\n if (uri.jwk) {\n return this.kms.asKey(uri);\n }\n\n let storageKey = uri;\n\n if (onBehalfOf) {\n storageKey += `/onBehalfOf/${onBehalfOf}`;\n }\n\n return this.unboundedStorage\n .get(storageKey)\n .then((keyString) => JSON.parse(keyString))\n .then((keyObject) => this.kms.asKey(keyObject))\n .catch(() =>\n this.kms\n .fetchKey({uri, onBehalfOf})\n .then(tap((key) => this.unboundedStorage.put(storageKey, JSON.stringify(key, replacer))))\n );\n },\n});\n\n/**\n * JSON.stringify replacer that ensures private key data is serialized.\n * @param {string} k\n * @param {mixed} v\n * @returns {mixed}\n */\nfunction replacer(k, v) {\n if (k === 'jwk') {\n // note: this[k] and v may be different representations of the same value\n // eslint-disable-next-line no-invalid-this\n const json = this[k].toJSON(true);\n\n return json;\n }\n\n return v;\n}\n\nexport default Encryption;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["Encryption","WebexPlugin","extend","children","kms","KMS","namespace","processKmsMessageEvent","event","decryptBinary","scr","buffer","ensureBuffer","then","b","length","byteLength","reject","Error","decrypt","decryptScr","key","cipherScr","options","getKey","k","SCR","fromJWE","jwk","decryptText","ciphertext","jose","JWE","createDecrypt","result","plaintext","toString","download","fileUrl","shunt","EventEmitter","promise","_fetchDownloadUrl","uri","method","responseType","ret","request","transferEvents","res","body","proxyEvents","logger","info","process","env","NODE_ENV","includes","resolve","inputBody","endpoints","endpointUrl","url","parse","protocol","pathname","format","allow","params","warn","catch","err","encryptBinary","file","create","encrypt","cdata","encryptScr","loc","toJWE","encryptText","createEncrypt","config","joseOptions","header","alg","reference","final","onBehalfOf","asKey","storageKey","unboundedStorage","get","keyString","JSON","keyObject","fetchKey","tap","put","replacer","v","json","toJSON"],"sources":["encryption.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {EventEmitter} from 'events';\nimport url from 'url';\n\nimport {WebexPlugin} from '@webex/webex-core';\nimport {proxyEvents, tap, transferEvents} from '@webex/common';\nimport jose from 'node-jose';\nimport SCR from 'node-scr';\n\nimport ensureBuffer from './ensure-buffer';\nimport KMS from './kms';\n\nconst Encryption = WebexPlugin.extend({\n children: {\n kms: KMS,\n },\n\n namespace: 'Encryption',\n\n processKmsMessageEvent(event) {\n return this.kms.processKmsMessageEvent(event);\n },\n\n decryptBinary(scr, buffer) {\n return ensureBuffer(buffer).then((b) => {\n /* istanbul ignore if */\n if (buffer.length === 0 || buffer.byteLength === 0) {\n return Promise.reject(new Error('Attempted to decrypt zero-length buffer'));\n }\n\n return scr.decrypt(b);\n });\n },\n\n /**\n * Decrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} cipherScr - An encrypted SCR\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {Object} Decrypted SCR\n */\n decryptScr(key, cipherScr, options) {\n return this.getKey(key, options).then((k) => SCR.fromJWE(k.jwk, cipherScr));\n },\n\n /**\n * Decrypt text using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} ciphertext - Encrypted text\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Decrypted plaintext\n */\n decryptText(key, ciphertext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createDecrypt(k.jwk)\n .decrypt(ciphertext)\n .then((result) => result.plaintext.toString())\n );\n },\n\n /**\n * Validate and initiate a Download request for requested file\n * @param {Object} fileUrl - Plaintext\n * @param {Object} scr - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise}\n */\n download(fileUrl, scr, options) {\n /* istanbul ignore if */\n if (!fileUrl || !scr) {\n return Promise.reject(new Error('`scr` and `fileUrl` are required'));\n }\n\n const shunt = new EventEmitter();\n const promise = this._fetchDownloadUrl(fileUrl, options)\n .then((uri) => {\n // eslint-disable-next-line no-shadow\n const options = {\n method: 'GET',\n uri,\n responseType: 'buffer',\n };\n\n const ret = this.request(options);\n\n transferEvents('progress', options.download, shunt);\n\n return ret;\n })\n .then((res) => this.decryptBinary(scr, res.body));\n\n proxyEvents(shunt, promise);\n\n return promise;\n },\n\n /**\n * Fetch Download URL for the requested file\n * @param {Object} fileUrl - Plaintext\n * @param {Object} options - optional parameters to download a file\n * @returns {promise} url of the downloadable file\n */\n _fetchDownloadUrl(fileUrl, options) {\n this.logger.info('encryption: retrieving download url for encrypted file');\n\n if (process.env.NODE_ENV !== 'production' && fileUrl.includes('localhost')) {\n this.logger.info(\n 'encryption: bypassing webex files because this looks to be a test file on localhost'\n );\n\n return Promise.resolve(fileUrl);\n }\n\n const inputBody = {\n endpoints: [fileUrl],\n };\n const endpointUrl = url.parse(fileUrl);\n\n // hardcode the url to use 'https' and the file service '/v1/download/endpoints' api\n endpointUrl.protocol = 'https';\n endpointUrl.pathname = '/v1/download/endpoints';\n\n return this.request({\n method: 'POST',\n uri: url.format(endpointUrl),\n body: options\n ? {\n ...inputBody,\n allow: options.params.allow,\n }\n : inputBody,\n })\n .then((res) => {\n // eslint-disable-next-line no-shadow\n const url = res.body.endpoints[fileUrl];\n\n if (!url) {\n this.logger.warn(\n 'encryption: could not determine download url for `fileUrl`; attempting to download `fileUrl` directly'\n );\n\n return fileUrl;\n }\n this.logger.info('encryption: retrieved download url for encrypted file');\n\n return url;\n })\n .catch((err) => {\n this.logger.warn(\n `encryption: ${err} could not determine download url for ${fileUrl}; attempting to download ${fileUrl} directly`\n );\n\n return fileUrl;\n });\n },\n\n encryptBinary(file) {\n return ensureBuffer(file).then((buffer) =>\n SCR.create().then((scr) =>\n scr\n .encrypt(buffer)\n .then(ensureBuffer)\n // eslint-disable-next-line max-nested-callbacks\n .then((cdata) => ({scr, cdata}))\n )\n );\n },\n\n /**\n * Encrypt a SCR (Secure Content Resource) using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {Object} scr - Plaintext\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted SCR\n */\n encryptScr(key, scr, options) {\n /* istanbul ignore if */\n if (!scr.loc) {\n return Promise.reject(new Error('Cannot encrypt `scr` without first setting `loc`'));\n }\n\n return this.getKey(key, options).then((k) => scr.toJWE(k.jwk));\n },\n\n /**\n * Encrypt plaintext using the supplied key uri.\n *\n * @param {string} key - The uri of a key stored in KMS\n * @param {string} plaintext\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Encrypted text\n */\n encryptText(key, plaintext, options) {\n return this.getKey(key, options).then((k) =>\n jose.JWE.createEncrypt(this.config.joseOptions, {\n key: k.jwk,\n header: {\n alg: 'dir',\n },\n reference: null,\n }).final(plaintext, 'utf8')\n );\n },\n\n /**\n * Fetch the key associated with the supplied KMS uri.\n *\n * @param {string} uri - The uri of a key stored in KMS\n * @param {Object} options\n * @param {string} options.onBehalfOf - Fetch the KMS key on behalf of another user (using the user's UUID), active user requires the 'spark.kms_orgagent' role\n * @returns {string} Key\n */\n getKey(uri, {onBehalfOf} = {}) {\n if (uri.jwk) {\n return this.kms.asKey(uri);\n }\n\n let storageKey = uri;\n\n if (onBehalfOf) {\n storageKey += `/onBehalfOf/${onBehalfOf}`;\n }\n\n return this.unboundedStorage\n .get(storageKey)\n .then((keyString) => JSON.parse(keyString))\n .then((keyObject) => this.kms.asKey(keyObject))\n .catch(() =>\n this.kms\n .fetchKey({uri, onBehalfOf})\n .then(tap((key) => this.unboundedStorage.put(storageKey, JSON.stringify(key, replacer))))\n );\n },\n});\n\n/**\n * JSON.stringify replacer that ensures private key data is serialized.\n * @param {string} k\n * @param {mixed} v\n * @returns {mixed}\n */\nfunction replacer(k, v) {\n if (k === 'jwk') {\n // note: this[k] and v may be different representations of the same value\n // eslint-disable-next-line no-invalid-this\n const json = this[k].toJSON(true);\n\n return json;\n }\n\n return v;\n}\n\nexport default Encryption;\n"],"mappings":"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"}
|
package/dist/kms.js
CHANGED
|
@@ -802,7 +802,7 @@ var KMS = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
802
802
|
context.ephemeralKey = originalContext.ephemeralKey;
|
|
803
803
|
return context;
|
|
804
804
|
},
|
|
805
|
-
version: "3.0.0-beta.
|
|
805
|
+
version: "3.0.0-beta.170"
|
|
806
806
|
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "fetchKey", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "fetchKey"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "_getContext", [_common.oneFlight], (0, _getOwnPropertyDescriptor.default)(_obj, "_getContext"), _obj)), _obj)));
|
|
807
807
|
var _default = KMS;
|
|
808
808
|
exports.default = _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-encryption",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.170",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,22 +24,22 @@
|
|
|
24
24
|
]
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
28
|
-
"@webex/test-helper-make-local-url": "3.0.0-beta.
|
|
29
|
-
"@webex/test-helper-mocha": "3.0.0-beta.
|
|
30
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
31
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
27
|
+
"@webex/test-helper-chai": "3.0.0-beta.170",
|
|
28
|
+
"@webex/test-helper-make-local-url": "3.0.0-beta.170",
|
|
29
|
+
"@webex/test-helper-mocha": "3.0.0-beta.170",
|
|
30
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.170",
|
|
31
|
+
"@webex/test-helper-test-users": "3.0.0-beta.170",
|
|
32
32
|
"sinon": "^9.2.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@webex/common": "3.0.0-beta.
|
|
36
|
-
"@webex/common-timers": "3.0.0-beta.
|
|
37
|
-
"@webex/http-core": "3.0.0-beta.
|
|
38
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
39
|
-
"@webex/internal-plugin-encryption": "3.0.0-beta.
|
|
40
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
41
|
-
"@webex/test-helper-file": "3.0.0-beta.
|
|
42
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
35
|
+
"@webex/common": "3.0.0-beta.170",
|
|
36
|
+
"@webex/common-timers": "3.0.0-beta.170",
|
|
37
|
+
"@webex/http-core": "3.0.0-beta.170",
|
|
38
|
+
"@webex/internal-plugin-device": "3.0.0-beta.170",
|
|
39
|
+
"@webex/internal-plugin-encryption": "3.0.0-beta.170",
|
|
40
|
+
"@webex/internal-plugin-mercury": "3.0.0-beta.170",
|
|
41
|
+
"@webex/test-helper-file": "3.0.0-beta.170",
|
|
42
|
+
"@webex/webex-core": "3.0.0-beta.170",
|
|
43
43
|
"asn1js": "^2.0.26",
|
|
44
44
|
"debug": "^4.3.4",
|
|
45
45
|
"isomorphic-webcrypto": "^2.3.8",
|
package/src/encryption.js
CHANGED
|
@@ -67,19 +67,19 @@ const Encryption = WebexPlugin.extend({
|
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
69
|
* Validate and initiate a Download request for requested file
|
|
70
|
-
*
|
|
70
|
+
* @param {Object} fileUrl - Plaintext
|
|
71
71
|
* @param {Object} scr - Plaintext
|
|
72
72
|
* @param {Object} options - optional parameters to download a file
|
|
73
73
|
* @returns {promise}
|
|
74
74
|
*/
|
|
75
|
-
download(scr, options) {
|
|
75
|
+
download(fileUrl, scr, options) {
|
|
76
76
|
/* istanbul ignore if */
|
|
77
|
-
if (!scr
|
|
78
|
-
return Promise.reject(new Error('`scr
|
|
77
|
+
if (!fileUrl || !scr) {
|
|
78
|
+
return Promise.reject(new Error('`scr` and `fileUrl` are required'));
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const shunt = new EventEmitter();
|
|
82
|
-
const promise = this._fetchDownloadUrl(
|
|
82
|
+
const promise = this._fetchDownloadUrl(fileUrl, options)
|
|
83
83
|
.then((uri) => {
|
|
84
84
|
// eslint-disable-next-line no-shadow
|
|
85
85
|
const options = {
|
|
@@ -103,26 +103,25 @@ const Encryption = WebexPlugin.extend({
|
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
105
|
* Fetch Download URL for the requested file
|
|
106
|
-
*
|
|
107
|
-
* @param {Object} scr - Plaintext
|
|
106
|
+
* @param {Object} fileUrl - Plaintext
|
|
108
107
|
* @param {Object} options - optional parameters to download a file
|
|
109
108
|
* @returns {promise} url of the downloadable file
|
|
110
109
|
*/
|
|
111
|
-
_fetchDownloadUrl(
|
|
110
|
+
_fetchDownloadUrl(fileUrl, options) {
|
|
112
111
|
this.logger.info('encryption: retrieving download url for encrypted file');
|
|
113
112
|
|
|
114
|
-
if (process.env.NODE_ENV !== 'production' &&
|
|
113
|
+
if (process.env.NODE_ENV !== 'production' && fileUrl.includes('localhost')) {
|
|
115
114
|
this.logger.info(
|
|
116
115
|
'encryption: bypassing webex files because this looks to be a test file on localhost'
|
|
117
116
|
);
|
|
118
117
|
|
|
119
|
-
return Promise.resolve(
|
|
118
|
+
return Promise.resolve(fileUrl);
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
const inputBody = {
|
|
123
|
-
endpoints: [
|
|
122
|
+
endpoints: [fileUrl],
|
|
124
123
|
};
|
|
125
|
-
const endpointUrl = url.parse(
|
|
124
|
+
const endpointUrl = url.parse(fileUrl);
|
|
126
125
|
|
|
127
126
|
// hardcode the url to use 'https' and the file service '/v1/download/endpoints' api
|
|
128
127
|
endpointUrl.protocol = 'https';
|
|
@@ -137,21 +136,29 @@ const Encryption = WebexPlugin.extend({
|
|
|
137
136
|
allow: options.params.allow,
|
|
138
137
|
}
|
|
139
138
|
: inputBody,
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
})
|
|
140
|
+
.then((res) => {
|
|
141
|
+
// eslint-disable-next-line no-shadow
|
|
142
|
+
const url = res.body.endpoints[fileUrl];
|
|
143
|
+
|
|
144
|
+
if (!url) {
|
|
145
|
+
this.logger.warn(
|
|
146
|
+
'encryption: could not determine download url for `fileUrl`; attempting to download `fileUrl` directly'
|
|
147
|
+
);
|
|
143
148
|
|
|
144
|
-
|
|
149
|
+
return fileUrl;
|
|
150
|
+
}
|
|
151
|
+
this.logger.info('encryption: retrieved download url for encrypted file');
|
|
152
|
+
|
|
153
|
+
return url;
|
|
154
|
+
})
|
|
155
|
+
.catch((err) => {
|
|
145
156
|
this.logger.warn(
|
|
146
|
-
|
|
157
|
+
`encryption: ${err} could not determine download url for ${fileUrl}; attempting to download ${fileUrl} directly`
|
|
147
158
|
);
|
|
148
159
|
|
|
149
|
-
return
|
|
150
|
-
}
|
|
151
|
-
this.logger.info('encryption: retrieved download url for encrypted file');
|
|
152
|
-
|
|
153
|
-
return url;
|
|
154
|
-
});
|
|
160
|
+
return fileUrl;
|
|
161
|
+
});
|
|
155
162
|
},
|
|
156
163
|
|
|
157
164
|
encryptBinary(file) {
|
|
@@ -22,18 +22,18 @@ describe('internal-plugin-encryption', () => {
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
describe('check _fetchDownloadUrl()', () => {
|
|
25
|
-
const
|
|
25
|
+
const fileArray = [
|
|
26
26
|
{
|
|
27
|
-
|
|
27
|
+
url: 'https://files-api-intb1.ciscospark.com/v1/spaces/a0cba376-fc05-4b88-af4b-cfffa7465f9a/contents/1d3931e7-9e31-46bc-8084-d766a8f72c99/versions/5fa9caf87a98410aae49e0173856a974/bytes',
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
|
-
|
|
30
|
+
url: 'https://files-api-intb2.ciscospark.com/v1/spaces/a0cba376-fc05-4b88-af4b-cfffa7465f9a/contents/1d3931e7-9e31-46bc-8084-d766a8f72c99/versions/5fa9caf87a98410aae49e0173856a974/bytes',
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
|
-
|
|
33
|
+
url: 'https://www.test-api.com/v1/spaces/test-path-name-space/contents/test-path-name-contents/versions/test-version/bytes',
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
|
|
36
|
+
url: 'http://www.test-api.com/v1/spaces/test-path-name-space/contents/test-path-name-contents/versions/test-version/bytes',
|
|
37
37
|
},
|
|
38
38
|
];
|
|
39
39
|
const options = undefined;
|
|
@@ -44,7 +44,7 @@ describe('internal-plugin-encryption', () => {
|
|
|
44
44
|
|
|
45
45
|
spyStub = sinon.stub(webex.internal.encryption, 'request').callsFake(returnStub);
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
fileArray.forEach((file) => webex.internal.encryption._fetchDownloadUrl(file.url, options));
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
it('verifying file service uris', () => {
|
|
@@ -68,10 +68,10 @@ describe('internal-plugin-encryption', () => {
|
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
it('verifying endpoints', () => {
|
|
71
|
-
assert.equal(spyStub.args[0][0].body.endpoints[0],
|
|
72
|
-
assert.equal(spyStub.args[1][0].body.endpoints[0],
|
|
73
|
-
assert.equal(spyStub.args[2][0].body.endpoints[0],
|
|
74
|
-
assert.equal(spyStub.args[3][0].body.endpoints[0],
|
|
71
|
+
assert.equal(spyStub.args[0][0].body.endpoints[0], fileArray[0].url);
|
|
72
|
+
assert.equal(spyStub.args[1][0].body.endpoints[0], fileArray[1].url);
|
|
73
|
+
assert.equal(spyStub.args[2][0].body.endpoints[0], fileArray[2].url);
|
|
74
|
+
assert.equal(spyStub.args[3][0].body.endpoints[0], fileArray[3].url);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
afterEach(() => {
|