Skip to content

Commit

Permalink
DXE-4012 Merge pull request #211 from akamai/release/v3.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dawiddzhafarov authored Jul 2, 2024
2 parents f577c2a + 91e75d8 commit 202dafb
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 85 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# RELEASE NOTES

## 3.5.0 (Jul 02, 2024)

#### IMPROVEMENTS:

* Updated various dependencies

#### BUG FIXES:

* `max_body` is deprecated, ignored and replaced with constant value of 131072 bytes

## 3.4.5 (Apr 3, 2024)

#### BUG FIXES
Expand Down
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "akamai-edgegrid",
"version": "3.4.5",
"version": "3.5.0",
"description": "Authentication handler for the Akamai OPEN EdgeGrid Authentication scheme in Node.js",
"main": "index.js",
"scripts": {
Expand Down
27 changes: 19 additions & 8 deletions src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,24 @@ const axios = require('axios'),
helpers = require('./helpers'),
logger = require('./logger');

/**
*
* @param {String} client_token The client token value from the .edgerc file.
* @param {String} client_secret The client secret value from the .edgerc file.
* @param {String} access_token The access token value from the .edgerc file.
* @param {String} host The host a unique string followed by luna.akamaiapis.net from the .edgerc file.
* @param {Boolean} debug The debug value allows to enable debugging.
* @param {Number} max_body This value is deprecated.
* @constructor
* @deprecated max_body
*/
const EdgeGrid = function (client_token, client_secret, access_token, host, debug, max_body) {
// accepting an object containing a path to .edgerc and a config section
if (typeof arguments[0] === 'object') {
let edgercPath = arguments[0];
this._setConfigFromObj(edgercPath);
} else {
this._setConfigFromStrings(client_token, client_secret, access_token, host, max_body);
this._setConfigFromStrings(client_token, client_secret, access_token, host);
}
if (process.env.EG_VERBOSE || debug || (typeof arguments[0] === 'object' && arguments[0].debug)) {
axios.interceptors.request.use(request => {
Expand Down Expand Up @@ -76,7 +87,7 @@ EdgeGrid.prototype.auth = function (req) {
this.config.client_secret,
this.config.access_token,
this.config.host,
this.config.max_body
helpers.MAX_BODY
);
if (req.headers['Accept'] === 'application/gzip' || req.headers['Accept'] === 'application/tar+gzip') {
this.request["responseType"] = 'arraybuffer';
Expand Down Expand Up @@ -119,12 +130,12 @@ EdgeGrid.prototype._handleRedirect = function (resp, callback) {
/**
* Creates a config object from a set of parameters.
*
* @param {String} client_token The client token
* @param {String} client_secret The client secret
* @param {String} access_token The access token
* @param {String} host The host
* @param {String} client_token The client token value from the .edgerc file.
* @param {String} client_secret The client secret value from the .edgerc file.
* @param {String} access_token The access token value from the .edgerc file.
* @param {String} host The host a unique string followed by luna.akamaiapis.net from the .edgerc file.
*/
EdgeGrid.prototype._setConfigFromStrings = function (client_token, client_secret, access_token, host, max_body) {
EdgeGrid.prototype._setConfigFromStrings = function (client_token, client_secret, access_token, host) {
if (!validatedArgs([client_token, client_secret, access_token, host])) {
throw new Error('Insufficient Akamai credentials');
}
Expand All @@ -134,7 +145,7 @@ EdgeGrid.prototype._setConfigFromStrings = function (client_token, client_secret
client_secret: client_secret,
access_token: access_token,
host: host.indexOf('https://') > -1 ? host : 'https://' + host,
max_body: helpers.getDefaultOrMaxBody(max_body)
max_body: helpers.MAX_BODY
};
};

Expand Down
31 changes: 31 additions & 0 deletions src/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ const uuid = require('uuid'),
logger = require('./logger'),
url = require('url');

/**
*
* @param {Object} request The request Object. Can optionally contain a
* 'headersToSign' property: An ordered list header names
* that will be included in the signature. This will be
* provided by specific APIs.
* @param {String} clientToken The client token value from the .edgerc file.
* @param {String} accessToken The access token value from the .edgerc file.
* @param {String} clientSecret The client secret value from the .edgerc file.
* @param {Date} timestamp The timestamp with format "yyyyMMddTHH:mm:ss+0000".
* @param {String} nonce A random string used to detect replayed request messages.
* @param {Number} maxBody This parameter is deprecated.
* @returns {string}
* @deprecated maxBody
*/
function makeAuthHeader(request, clientToken, accessToken, clientSecret, timestamp, nonce, maxBody) {
const keyValuePairs = {
client_token: clientToken,
Expand Down Expand Up @@ -58,6 +73,22 @@ function makeURL(host, path, queryStringObj) {
}

module.exports = {
/**
*
* @param {Object} request The request Object. Can optionally contain a
* 'headersToSign' property: An ordered list header names
* that will be included in the signature. This will be
* provided by specific APIs.
* @param {String} clientToken The client token value from the .edgerc file.
* @param {String} clientSecret The client secret value from the .edgerc file.
* @param {String} accessToken The access token value from the .edgerc file.
* @param {String} host The host a unique string followed by luna.akamaiapis.net from the .edgerc file.
* @param {Number} maxBody This value is deprecated.
* @param {String} guid A random string used to detect replayed request messages.
* @param {Date} timestamp The timestamp with format "yyyyMMddTHH:mm:ss+0000".
* @returns {{headers}|*} The request Object.
* @deprecated maxBody
*/
generateAuth: function (request, clientToken, clientSecret, accessToken, host, maxBody, guid, timestamp) {
guid = guid || uuid.v4();
timestamp = timestamp || helpers.createTimestamp();
Expand Down
5 changes: 4 additions & 1 deletion src/edgerc.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ function getSection(lines, sectionName) {
}

function validatedConfig(config) {
config.max_body = helpers.getDefaultOrMaxBody(config.max_body);
/**
* @deprecated max_body - This value is deprecated.
*/
config.max_body = helpers.MAX_BODY

if (!(config.host && config.access_token &&
config.client_secret && config.client_token)) {
Expand Down
46 changes: 31 additions & 15 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const crypto = require('crypto'),
logger = require('./logger'),
path = require('path'),
os = require('os');
const MAX_BODY = 131072

function twoDigitNumberPad(number) {
return String(number).padStart(2, '0');
Expand All @@ -27,6 +28,7 @@ module.exports = {
*
* @see https://developer.akamai.com/legacy/introduction/Client_Auth.html#authorizationheaderfields
*/
MAX_BODY,
createTimestamp: function () {
const date = new Date(Date.now());

Expand All @@ -40,8 +42,8 @@ module.exports = {
twoDigitNumberPad(date.getUTCSeconds()) +
'+0000';
},
contentHash: function (request) {

contentHash: function (request, maxBody) {
let contentHash = '',
preparedBody = request.body || '',
isTarball = preparedBody instanceof Uint8Array && request.headers['Content-Type'] === 'application/gzip';
Expand Down Expand Up @@ -70,13 +72,13 @@ module.exports = {

logger.info('Signing content: \"' + preparedBody + '\"');

// If body data is too large, cut down to max-body size
if (preparedBody.length > maxBody) {
logger.warn('Data length (' + preparedBody.length + ') is larger than maximum ' + maxBody);
// If body data is too large, cut down to max-body size which is const value
if (preparedBody.length > MAX_BODY) {
logger.warn('Data length (' + preparedBody.length + ') is larger than maximum ' + MAX_BODY);
if (isTarball)
preparedBody = preparedBody.slice(0, maxBody);
preparedBody = preparedBody.slice(0, MAX_BODY);
else
preparedBody = preparedBody.substring(0, maxBody);
preparedBody = preparedBody.substring(0, MAX_BODY);
logger.info('Body truncated. New value \"' + preparedBody + '\"');
}

Expand All @@ -88,7 +90,16 @@ module.exports = {

return contentHash;
},

/**
*
* @param {Object} request The request Object. Can optionally contain a
* 'headersToSign' property: An ordered list header names
* that will be included in the signature. This will be
* provided by specific APIs.
* @param {String} authHeader The authorization header.
* @param {Number} maxBody This value is deprecated.
* @deprecated maxBody
*/
dataToSign: function (request, authHeader, maxBody) {
const parsedUrl = new URL(request.url),
dataToSign = [
Expand Down Expand Up @@ -187,7 +198,19 @@ module.exports = {

return key;
},

/**
*
* @param {Object} request The request Object. Can optionally contain a
* 'headersToSign' property: An ordered list header names
* that will be included in the signature. This will be
* provided by specific APIs.
* @param {Date} timestamp The timestamp with format "yyyyMMddTHH:mm:ss+0000".
* @param {String} clientSecret The client secret value from the .edgerc file.
* @param {String} authHeader The authorization header.
* @param maxBody This value is deprecated.
* @returns {string}
* @deprecated maxBody
*/
signRequest: function (request, timestamp, clientSecret, authHeader, maxBody) {
return this.base64HmacSha256(this.dataToSign(request, authHeader, maxBody), this.signingKey(timestamp, clientSecret));
},
Expand All @@ -198,11 +221,4 @@ module.exports = {
}
return filePath;
},

getDefaultOrMaxBody:function(max_body){
if (max_body !== undefined && isNaN(Number(max_body))) {
throw new Error('max_body is not a valid number.');
}
return Number(max_body) || 131072;
}
};
56 changes: 18 additions & 38 deletions test/src/api_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,35 +96,6 @@ describe('Api', function () {
assert.equal(this.api.config.max_body, 131072);
});

describe('when it is instantiated with an object with custom `max-body` value', function () {
beforeEach(function () {
this.api = new Api({
path: path.resolve(__dirname, '../test_edgerc'),
section: 'custom:max-body'
});
});

it('reports the client token from the edgerc associated with the specified section with custom `max-body`', function () {
assert.strictEqual(this.api.config.client_token, 'sectionClientToken');
});

it('reports the client secret from the edgerc associated with the specified section with custom `max-body`', function () {
assert.strictEqual(this.api.config.client_secret, 'sectionClientSecret');
});

it('reports the access token from the edgerc associated with the specified section with custom `max-body`', function () {
assert.strictEqual(this.api.config.access_token, 'sectionAccessToken');
});

it('reports the API host from the edgerc associated with the specified section with custom `max-body`', function () {
assert.strictEqual(this.api.config.host, 'https://sectionexample.luna.akamaiapis.net');
});

it('reports the max-body from the edgerc associated with the specified section with custom `max-body`', function () {
assert.equal(this.api.config.max_body, 4096);
});
});

describe('when it is instantiated with an object with custom `max_body` value', function () {
beforeEach(function () {
this.api = new Api({
Expand All @@ -150,7 +121,7 @@ describe('Api', function () {
});

it('reports the max-body from the edgerc associated with the specified section with custom `max_body`', function () {
assert.equal(this.api.config.max_body, 8192);
assert.equal(this.api.config.max_body, 131072);
});
});

Expand Down Expand Up @@ -590,20 +561,29 @@ describe('Api', function () {
// Call auth method
const response = edgeGrid.auth(req);
// Assertions
assert.strictEqual(response.config.max_body, 8192);
assert.strictEqual(response.config.max_body, 131072);
});

it('when max_body is provided in the config - NAN', () => {
const req = {
path: '/api/resource',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: {key: 'value'}
};

const edgercObject = {
path: path.resolve(__dirname, '../test_edgerc'),
section: 'custom:max_body_NAN'
};
assert.throws(
function () {
return new EdgeGrid(edgercObject);
},
/max_body is not a valid number./
);
const edgeGrid = new EdgeGrid(edgercObject);
// Call auth method
const response = edgeGrid.auth(req);
// Assertions
assert.strictEqual(response.config.max_body, 131072);
});

it('when max_body is not provided in the configuration, the default value is used', () => {
Expand Down Expand Up @@ -646,7 +626,7 @@ describe('Api', function () {
// Call auth method
const response = edgeGrid.auth(req);
// Assertions
assert.strictEqual(response.config.max_body, 8192);
assert.strictEqual(response.config.max_body, 131072);
});


Expand Down
2 changes: 1 addition & 1 deletion test/src/edgerc_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ describe('edgerc', function () {
});

it('reports the max_body associated with the section with with custom `max_body`', function () {
assert.equal(this.config.max_body, 8192);
assert.equal(this.config.max_body, 131072);
});
});

Expand Down
Loading

0 comments on commit 202dafb

Please sign in to comment.