Socket
Socket
Sign inDemoInstall

@adobe/fetch

Package Overview
Dependencies
Maintainers
46
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@adobe/fetch - npm Package Compare versions

Comparing version 0.1.7 to 0.1.8

34

index.js

@@ -15,4 +15,6 @@ /*

const cache = require('./src/cache');
const uuid = require('uuid/v4');
const auth = require('@adobe/jwt-auth');
const merge = require('deepmerge');
const debug = require('debug')('@adobe/fetch');
const NO_CONFIG = 'Auth configuration missing.';

@@ -44,5 +46,11 @@

let apiKey = authOptions.clientId;
let xrequestid = uuid().replace(/-/g, '');
if (options.headers && options.headers['x-api-key']) {
apiKey = options.headers['x-api-key'];
if (options.headers) {
if (options.headers['x-api-key']) {
apiKey = options.headers['x-api-key'];
}
if (options.headers['x-request-id']) {
xrequestid = options.headers['x-request-id'];
}
}

@@ -54,2 +62,3 @@

'x-api-key': apiKey,
'x-request-id': xrequestid,
'x-gw-ims-org-id': authOptions.orgId

@@ -63,9 +72,22 @@ }

const opts = addAuthHeaders(token, options, configOptions.auth);
debug(
`${opts.method || 'GET'} ${url} - x-request-id: ${
opts.headers['x-request-id']
}`
);
const res = await fetch(url, opts);
if ((res.status === 401 || res.status === 403) && !forceNewToken) {
return await _fetch(url, options, configOptions, tokenCache, true);
} else {
return res;
if (!res.ok) {
debug(
`${opts.method || 'GET'} ${url} - status ${res.statusText} (${
res.status
}). x-request-id: ${opts.headers['x-request-id']}`
);
if ((res.status === 401 || res.status === 403) && !forceNewToken) {
debug(`${opts.method || 'GET'} ${url} - Will get new token.`);
return await _fetch(url, options, configOptions, tokenCache, true);
}
}
return res;
}

@@ -72,0 +94,0 @@

17

package.json
{
"name": "@adobe/fetch",
"version": "0.1.7",
"version": "0.1.8",
"description": "Call Adobe APIs",

@@ -30,14 +30,19 @@ "main": "index.js",

"license": "Apache-2.0",
"publishConfig": {
"registry":"https://registry.npmjs.org"
},
"dependencies": {
"@adobe/jwt-auth": "^0.2.0",
"debug": "^4.1.1",
"deepmerge": "^4.0.0",
"dotenv": "^8.0.0",
"dotenv": "^8.1.0",
"node-fetch": "^2.3.0",
"node-persist": "^3.0.5"
"node-persist": "^3.0.5",
"uuid": "^3.3.3"
},
"devDependencies": {
"eslint": "^6.1.0",
"eslint-config-prettier": "^6.0.0",
"eslint": "^6.2.1",
"eslint-config-prettier": "^6.1.0",
"eslint-plugin-prettier": "^3.1.0",
"jest": "^24.1.0",
"jest": "^24.9.0",
"prettier": "^1.18.2"

@@ -44,0 +49,0 @@ },

@@ -165,2 +165,17 @@ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

## Logging
Every request will include a unique request identifier sent via the **x-request-id**.
The request identifier can be overriden by providing it through the headers:
```javascript
fetch(url, {
headers: { 'x-request-id': myRequestID }
});
```
We use [debug](https://github.com/visionmedia/debug) to log requests. In order to see all the debug output, including the request identifiers, run your app with **DEBUG** environment variable including the **@adobe/fetch** scope as follows:
```
DEBUG=@adobe/fetch
```
### Contributing

@@ -167,0 +182,0 @@

@@ -14,2 +14,3 @@ /*

const auth = require('@adobe/jwt-auth');
const uuid = require('uuid/v4');
const storage = require('node-persist');

@@ -28,2 +29,11 @@ const fetch = require('node-fetch');

function expectHeaders(url, options, access_token, apikey, orgid) {
expect(options.headers).toBeDefined();
expect(options.headers['authorization']).toBe(`bearer ${access_token}`);
expect(options.headers['x-api-key']).toBe(apikey);
expect(options.headers['x-gw-ims-org-id']).toBe(orgid);
expect(options.headers['x-request-id']).toHaveLength(32);
return Promise.resolve(mockData.responseOK);
}
describe('Validate auth behavior', () => {

@@ -40,11 +50,11 @@ beforeEach(() => {

// Default fetch mock - Returns status 200 and expects the auth headers.
fetch.mockImplementation((url, options) => {
expect(options.headers).toBeDefined();
expect(options.headers['authorization']).toBe(
`${mockData.token.token_type} ${mockData.token.access_token}`
);
expect(options.headers['x-api-key']).toBe(mockData.config.clientId);
expect(options.headers['x-gw-ims-org-id']).toBe(mockData.config.orgId);
return Promise.resolve({ status: 200, url: url });
});
fetch.mockImplementation((url, options) =>
expectHeaders(
url,
options,
mockData.token.access_token,
mockData.config.clientId,
mockData.config.orgId
)
);

@@ -56,3 +66,3 @@ // New adobe fetch object.

test('adds authentication headers', () => {
expect.assertions(4);
expect.assertions(5);
return testFetch(mockData.url);

@@ -62,3 +72,3 @@ });

test('caches access token', async () => {
expect.assertions(9);
expect.assertions(11);
await testFetch(mockData.url);

@@ -76,3 +86,3 @@ let authCalled = false;

test('get stored token if valid', async () => {
expect.assertions(4);
expect.assertions(5);
const token = mockData.valid_token[mockData.token_key];

@@ -82,11 +92,11 @@ storage.getItem = jest.fn(() => {

});
fetch.mockImplementation((url, options) => {
expect(options.headers).toBeDefined();
expect(options.headers['authorization']).toBe(
`${token.token_type} ${token.access_token}`
);
expect(options.headers['x-api-key']).toBe(mockData.config.clientId);
expect(options.headers['x-gw-ims-org-id']).toBe(mockData.config.orgId);
return Promise.resolve({ status: 200 });
});
fetch.mockImplementation((url, options) =>
expectHeaders(
url,
options,
token.access_token,
mockData.config.clientId,
mockData.config.orgId
)
);
await testFetch(mockData.url);

@@ -96,3 +106,3 @@ });

test('get new token when cached expires', async () => {
expect.assertions(6);
expect.assertions(7);
storage.getItem = jest.fn(key => {

@@ -106,19 +116,17 @@ expect(key).toBe(TOKENS_KEY);

test('get new token when fetch returns 401', async () => {
expect.assertions(4);
expect.assertions(5);
fetch.mockImplementation(() => {
auth.mockImplementation(() => {
fetch.mockImplementation((url, options) => {
expect(options.headers).toBeDefined();
expect(options.headers['authorization']).toBe(
`${mockData.token2.token_type} ${mockData.token2.access_token}`
);
expect(options.headers['x-api-key']).toBe(mockData.config.clientId);
expect(options.headers['x-gw-ims-org-id']).toBe(
fetch.mockImplementation((url, options) =>
expectHeaders(
url,
options,
mockData.token2.access_token,
mockData.config.clientId,
mockData.config.orgId
);
return Promise.resolve({ status: 200 });
});
)
);
return Promise.resolve(mockData.token2);
});
return Promise.resolve({ status: 401 });
return Promise.resolve(mockData.responseUnauthorized);
});

@@ -129,19 +137,17 @@ await testFetch(mockData.url);

test('get new token when fetch returns 403', async () => {
expect.assertions(4);
fetch.mockImplementation(url => {
expect.assertions(5);
fetch.mockImplementation(() => {
auth.mockImplementation(() => {
fetch.mockImplementation((url, options) => {
expect(options.headers).toBeDefined();
expect(options.headers['authorization']).toBe(
`${mockData.token2.token_type} ${mockData.token2.access_token}`
);
expect(options.headers['x-api-key']).toBe(mockData.config.clientId);
expect(options.headers['x-gw-ims-org-id']).toBe(
fetch.mockImplementation((url, options) =>
expectHeaders(
url,
options,
mockData.token2.access_token,
mockData.config.clientId,
mockData.config.orgId
);
return Promise.resolve({ status: 200, url: url });
});
)
);
return Promise.resolve(mockData.token2);
});
return Promise.resolve({ status: 403, url: url });
return Promise.resolve(mockData.responseForbidden);
});

@@ -152,14 +158,33 @@ await testFetch(mockData.url);

test('allows x-api-key override', async () => {
expect.assertions(4);
expect.assertions(5);
fetch.mockImplementation((url, options) =>
expectHeaders(
url,
options,
mockData.token.access_token,
'test-override',
mockData.config.orgId
)
);
await testFetch(mockData.url, {
headers: { 'x-api-key': 'test-override' }
});
});
test('allows x-request-id override', async () => {
expect.assertions(6);
const xrequestid = uuid().replace(/-/g, '');
fetch.mockImplementation((url, options) => {
expect(options.headers).toBeDefined();
expect(options.headers['authorization']).toBe(
`${mockData.token2.token_type} ${mockData.token.access_token}`
expect(options.headers['x-request-id']).toBe(xrequestid);
return expectHeaders(
url,
options,
mockData.token.access_token,
mockData.config.clientId,
mockData.config.orgId
);
expect(options.headers['x-api-key']).toBe('test-override');
expect(options.headers['x-gw-ims-org-id']).toBe(mockData.config.orgId);
return Promise.resolve({ status: 200, url: url });
});
await testFetch(mockData.url, {
headers: { 'x-api-key': 'test-override' }
headers: { 'x-request-id': xrequestid }
});

@@ -169,3 +194,3 @@ });

test('token stored in default storage', async () => {
expect.assertions(6);
expect.assertions(7);
storage.setItem = jest.fn((key, value) => {

@@ -202,3 +227,3 @@ expect(key).toBe(TOKENS_KEY);

fetch.mockImplementation(() => {
return Promise.resolve({ status: 200 });
return Promise.resolve(mockData.responseOK);
});

@@ -214,7 +239,5 @@ return expect(testFetch(mockData.url)).rejects.toEqual(ERROR);

});
fetch.mockImplementation(() => {
return Promise.resolve({ status: 200 });
});
fetch.mockImplementation(() => Promise.resolve(mockData.responseOK));
return expect(testFetch(mockData.url)).rejects.toEqual(ERROR);
});
});

@@ -21,4 +21,23 @@ /*

const TOKEN_KEY = `${CLIENT_ID}|${SCOPES.join(',')}`;
const MOCK_URL = 'https://mock.com/mock';
module.exports = {
responseOK: {
url: MOCK_URL,
status: 200,
statusText: 'OK',
ok: true
},
responseForbidden: {
url: MOCK_URL,
status: 403,
statusText: 'Forbidden',
ok: false
},
responseUnauthorized: {
url: MOCK_URL,
status: 401,
statusText: 'Unauthorized',
ok: false
},
config: {

@@ -60,3 +79,3 @@ clientId: CLIENT_ID,

},
url: 'https://mock.com/mock'
url: MOCK_URL
};

@@ -79,3 +79,3 @@ /*

);
return Promise.resolve({ status: 200 });
return Promise.resolve(mockData.responseOK);
});

@@ -108,3 +108,3 @@ await adobefetch.config({

);
return Promise.resolve({ status: 200 });
return Promise.resolve(mockData.responseOK);
});

@@ -122,3 +122,3 @@ await adobefetch.config({

fetch.mockImplementation(() => {
return Promise.resolve({ status: 200 });
return Promise.resolve(mockData.responseOK);
});

@@ -153,3 +153,3 @@

fetch.mockImplementation(() => {
return Promise.resolve({ status: 200 });
return Promise.resolve(mockData.responseOK);
});

@@ -156,0 +156,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc