Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DXE-4012 Release/v3.5.0 #211

Merged
merged 3 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading