From e84729d5e6dd098513a7d39168878c2dad7b894f Mon Sep 17 00:00:00 2001 From: qyunal Date: Mon, 16 Mar 2020 22:58:57 +0530 Subject: [PATCH 1/6] adds utility functions for v3 signature --- lib/rest/client.js | 9 +++- lib/utils/v3Security.js | 111 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 lib/utils/v3Security.js diff --git a/lib/rest/client.js b/lib/rest/client.js index 6d017e3..7e65fe4 100644 --- a/lib/rest/client.js +++ b/lib/rest/client.js @@ -14,6 +14,7 @@ import { PricingInterface } from "../resources/pricings"; import { RecordingInterface } from "../resources/recordings"; import { Response } from "../utils/plivoxml"; import { validateSignature } from "../utils/security"; +import { validateV3Signature } from "../utils/v3Security"; import { stringify } from "./../utils/jsonStrinfigier"; import { MediaInterface } from "../resources/media.js"; @@ -21,8 +22,12 @@ exports.Response = function() { return new Response(); }; -exports.validateSignature = function(uri, nonce, signature, auth_token) { - return validateSignature(uri, nonce, signature, auth_token); +exports.validateSignature = function(method, uri, nonce, auth_token, v3_signature, params={}) { + return validateSignature(method, uri, nonce, auth_token, v3_signature, params); +}; + +exports.validateV3Signature = function(uri, nonce, signature, auth_token) { + return validateV3Signature(uri, nonce, signature, auth_token); }; /** diff --git a/lib/utils/v3Security.js b/lib/utils/v3Security.js new file mode 100644 index 0000000..8c15448 --- /dev/null +++ b/lib/utils/v3Security.js @@ -0,0 +1,111 @@ +//@flow +const utf8 = require('utf8'); +const buildUrl = require('build-url'); +const base64 = require('base-64'); +const qs = require('querystring'); +import * as parser from 'uri-parser'; +import crypto from 'crypto'; +import _ from 'lodash'; + +function get_map_from_query(params1, params2) { + let params = {}; + Object.keys(params1).forEach(function (key) { + let val = params1[key]; + if (val instanceof Array) { + params[key] = val + } else { + params[key] = [val] + } + }); + Object.keys(params2).forEach(function (key) { + let val = params2[key]; + if (!(val instanceof Array)) { + val = [val]; + } + if (key in params) { + params[key] = params[key].concat(val) + } else { + params[key] = val + } + }); + return params; +} + +function get_sorted_query_string(params) { + let query_string = []; + Object.keys(params).sort().forEach(function (key) { + let val = params[key]; + val.sort().forEach(function (value) { + query_string.push(key.toString() + '=' + value.toString()); + }); + }); + return query_string.join('&'); +} + +function get_sorted_params_string(params) { + let paramsString = []; + Object.keys(params).sort().forEach(function (key) { + let val = params[key]; + if (val instanceof Array) { + val.sort().forEach(function (value) { + paramsString.push(key.toString() + '=' + value.toString()); + }); + } else { + paramsString.push(key.toString() + '=' + val.toString()); + } + }); + return paramsString.join('') +} + +function construct_get_url(uri, params, empty_post_params=true) { + let parsed_uri = parser.parse(uri); + let url_protocol = parsed_uri.protocol === '' ? 'http://' : parsed_uri.protocol+'://'; + let proxy = parsed_uri.port === '' ? parsed_uri.host : parsed_uri.host + ':' + parsed_uri.port; + let base_url = buildUrl(url_protocol + proxy , { path: parsed_uri.path }); + params = get_map_from_query(qs.parse(parsed_uri.query), params); + let query_params = get_sorted_query_string(params); + if (query_params.length > 0 || !empty_post_params) { + base_url = base_url + '?' + query_params; + } + if (query_params.length > 0 && !empty_post_params) { + base_url = base_url + '.'; + } + return base_url; +} + +function construct_post_url(uri, params) { + let base_url = construct_get_url(uri, {}, _.isEmpty(params)); + return base_url + get_sorted_params_string(params); +} + +function get_signature_v3(auth_token, base_url, nonce) { + base_url = base_url + '.' + nonce; + let hmac = crypto.createHmac('sha256', auth_token); + let hmacBytes = base64.decode(hmac.update(base_url).digest('base64')); + return base64.encode(hmacBytes); +} + +export function validateV3Signature(method: string, uri: string, + nonce: string, auth_token: string, + v3_signature: string, params={}) { + auth_token = utf8.encode(auth_token); + nonce = utf8.encode(nonce); + v3_signature = utf8.encode(v3_signature); + uri = utf8.encode(uri); + let base_url = uri; + if (method === 'GET') { + base_url = construct_get_url(uri, params); + } else if (method === 'POST') { + base_url = construct_post_url(uri, params); + } else { + throw new Error("Please provide authToken"); + } + let signature = get_signature_v3(auth_token, base_url, nonce); + let matched = false; + _.split(v3_signature, ',').forEach(function (plivo_sign) { + if (plivo_sign === signature) { + matched = true; + } + }); + return matched; +} From 436b0701dce14d0d2ea1df4b361b54d9466488d4 Mon Sep 17 00:00:00 2001 From: Kunal Sanghvi <40199768+kunal-plivo@users.noreply.github.com> Date: Wed, 1 Apr 2020 10:30:09 +0530 Subject: [PATCH 2/6] remove = sign while appending key and value from post params --- lib/utils/v3Security.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/utils/v3Security.js b/lib/utils/v3Security.js index 8c15448..af9c97b 100644 --- a/lib/utils/v3Security.js +++ b/lib/utils/v3Security.js @@ -48,10 +48,10 @@ function get_sorted_params_string(params) { let val = params[key]; if (val instanceof Array) { val.sort().forEach(function (value) { - paramsString.push(key.toString() + '=' + value.toString()); + paramsString.push(key.toString() + value.toString()); }); } else { - paramsString.push(key.toString() + '=' + val.toString()); + paramsString.push(key.toString() + val.toString()); } }); return paramsString.join('') From 9a90a0eaa85875484a417843f26bb9423132fab5 Mon Sep 17 00:00:00 2001 From: Kunal Sanghvi <40199768+kunal-plivo@users.noreply.github.com> Date: Mon, 6 Apr 2020 17:52:41 +0530 Subject: [PATCH 3/6] fix signature mixup --- lib/rest/client.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/rest/client.js b/lib/rest/client.js index 7e65fe4..5cb9027 100644 --- a/lib/rest/client.js +++ b/lib/rest/client.js @@ -22,12 +22,12 @@ exports.Response = function() { return new Response(); }; -exports.validateSignature = function(method, uri, nonce, auth_token, v3_signature, params={}) { - return validateSignature(method, uri, nonce, auth_token, v3_signature, params); +exports.validateV3Signature = function(method, uri, nonce, auth_token, v3_signature, params={}) { + return validateV3Signature(method, uri, nonce, auth_token, v3_signature, params); }; -exports.validateV3Signature = function(uri, nonce, signature, auth_token) { - return validateV3Signature(uri, nonce, signature, auth_token); +exports.validateSignature = function(uri, nonce, signature, auth_token) { + return validateSignature(uri, nonce, signature, auth_token); }; /** From 182c72eaf83700648f55d92540fb4faef8639251 Mon Sep 17 00:00:00 2001 From: bhuvanvenkat-plivo Date: Mon, 27 Apr 2020 13:03:52 +0530 Subject: [PATCH 4/6] Adding api id to list conferences API --- lib/resources/conferences.js | 2 +- test/conferences.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/resources/conferences.js b/lib/resources/conferences.js index 9730943..1e506f3 100644 --- a/lib/resources/conferences.js +++ b/lib/resources/conferences.js @@ -326,7 +326,7 @@ export class ConferenceInterface extends PlivoResourceInterface { name: conference })); }); - resolve(conferences); + resolve(response.body); }) .catch(error => { reject(error); diff --git a/test/conferences.js b/test/conferences.js index 6541f41..5282930 100644 --- a/test/conferences.js +++ b/test/conferences.js @@ -16,8 +16,8 @@ describe('Conference', function () { it('should get all conferences', function () { return client.conferences.list() - .then(function(conferences) { - assert.equal(conferences[0].name, 'My Conf Room' ) + .then(function(response) { + assert.equal(response.conferences[0], 'My Conf Room' ) }) }); From f7264e7aae85a173845662905abedd0d7a78292d Mon Sep 17 00:00:00 2001 From: nixonsamuel Date: Tue, 28 Apr 2020 12:23:13 +0530 Subject: [PATCH 5/6] bump version to 4.5.2 --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8295bb3..b60c29d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## [4.5.2](https://github.com/plivo/plivo-node/releases/tag/v4.5.2)(2020-04-28) +- Fix List Conferences API response. + ## [4.5.1](https://github.com/plivo/plivo-node/releases/tag/v4.5.1)(2020-04-13) - Fix Cannot read property 'hasOwnProperty' of undefined error. diff --git a/package.json b/package.json index 6e7263f..d4767da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plivo", - "version": "4.5.1", + "version": "4.5.2", "description": "A Node.js SDK to make voice calls and send SMS using Plivo and to generate Plivo XML", "homepage": "https://github.com/plivo/plivo-node", "files": [ From 859fa78bbf5a0ce59fe4060250413991807ee5b3 Mon Sep 17 00:00:00 2001 From: nixonsamuel Date: Wed, 29 Apr 2020 13:24:46 +0530 Subject: [PATCH 6/6] bump version to 4.6.0 --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b60c29d..4828568 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## [4.6.0](https://github.com/plivo/plivo-node/releases/tag/v4.6.0)(2020-04-29) +- Add V3 signature helper functions. + ## [4.5.2](https://github.com/plivo/plivo-node/releases/tag/v4.5.2)(2020-04-28) - Fix List Conferences API response. diff --git a/package.json b/package.json index d4767da..96ae266 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plivo", - "version": "4.5.2", + "version": "4.6.0", "description": "A Node.js SDK to make voice calls and send SMS using Plivo and to generate Plivo XML", "homepage": "https://github.com/plivo/plivo-node", "files": [