@evervault/sdk
Advanced tools
Comparing version 0.3.4 to 0.3.5
56
index.js
@@ -105,9 +105,6 @@ /** @format */ | ||
const accessToken = await this.getValidAccessToken(); | ||
return fetch(`${this.urls.api}/data/${this.appId}`, { | ||
return this.fetch(`${this.urls.api}/data/${this.appId}`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
@@ -136,9 +133,6 @@ body: JSON.stringify({ | ||
get: async function(toGet = '') { | ||
const accessToken = await this.getValidAccessToken(); | ||
return await fetch(`${this.urls.api}/data/${this.appId}/${toGet}`, { | ||
return this.fetch(`${this.urls.api}/data/${this.appId}/${toGet}`, { | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
@@ -306,9 +300,10 @@ }) | ||
}; | ||
return fetch(`${this.urls.api}/token/refresh`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(requestBody), | ||
}) | ||
return window | ||
.fetch(`${this.urls.api}/token/refresh`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify(requestBody), | ||
}) | ||
.then((res) => { | ||
@@ -320,9 +315,12 @@ if (res.status === 401) { | ||
}) | ||
.then(({ accessToken, refreshToken }) => { | ||
if (!accessToken) { | ||
throw new Error('Unable to retrive access token'); | ||
.then((payload) => { | ||
if (!payload || !payload.accessToken) { | ||
return; | ||
} | ||
const { accessToken, refreshToken } = payload; | ||
localStorage.setItem('evervault-accessToken', accessToken); | ||
this.accessToken = accessToken; | ||
localStorage.setItem('evervault-refreshToken', refreshToken); | ||
return { accessToken, refreshToken }; | ||
this.refreshToken = refreshToken; | ||
return payload; | ||
}) | ||
@@ -385,9 +383,7 @@ .catch((err) => { | ||
}, | ||
auth: (appId) => module.exports.checkAuth(appId), | ||
fetch: function(resource, options) { | ||
const handleRequest = (resource, options, retry) => { | ||
fetch: function(resource, options = {}) { | ||
const handleRequest = (resource, options) => { | ||
const defaultHeaders = { authorization: `Bearer ${this.accessToken}` }; | ||
@@ -398,9 +394,3 @@ const requestHeaders = Object.assign(defaultHeaders, options.headers); | ||
}); | ||
return fetch(resource, requestOptions).then((res) => { | ||
if (!res.ok && res.status === 401 && retry) { | ||
return this.logout(); | ||
} | ||
return res; | ||
}); | ||
return window.fetch(resource, requestOptions); | ||
}; | ||
@@ -413,7 +403,3 @@ | ||
this.refreshToken | ||
).then(({ accessToken, refreshToken }) => { | ||
this.accessToken = accessToken; | ||
this.refreshToken = refreshToken; | ||
return handleRequest(resource, options, true); | ||
}); | ||
).then(() => handleRequest(resource, options)); | ||
} else { | ||
@@ -420,0 +406,0 @@ return res; |
{ | ||
"name": "@evervault/sdk", | ||
"version": "0.3.4", | ||
"version": "0.3.5", | ||
"description": "evervault Browser SDK", | ||
@@ -24,2 +24,3 @@ "repository": { | ||
"mocha": "^7.0.1", | ||
"sinon": "^9.0.1", | ||
"webpack": "^4.41.2", | ||
@@ -26,0 +27,0 @@ "webpack-cli": "^3.3.11" |
283
test/test.js
/** @format */ | ||
const accessToken = 'access'; | ||
const refreshToken = 'refresh'; | ||
const localStorageSpoof = { | ||
'evervault-privateKey': 'aN3AVLGScc/q+DCrzlCvBZp/8kczymmWOKncSe7n0PI=', | ||
'evervault-accessToken': accessToken, | ||
'evervault-refreshToken': refreshToken, | ||
'evervault-haiku': 'spontaneous-seagull-123456', | ||
}; | ||
sinon.stub(localStorage, 'setItem').callsFake((key, value) => { | ||
localStorageSpoof[key] = value; | ||
}); | ||
sinon.stub(localStorage, 'getItem').callsFake((key) => localStorageSpoof[key]); | ||
const appId = '1ffd79c5-0df1-408d-a279-223cee474e2c'; | ||
describe('Test SDK encryption and decryption', function() { | ||
localStorage.setItem( | ||
'evervault-privateKey', | ||
'aN3AVLGScc/q+DCrzlCvBZp/8kczymmWOKncSe7n0PI=' | ||
); | ||
localStorage.setItem('evervault-accessToken', 'access'); | ||
localStorage.setItem('evervault-refreshToken', 'refresh'); | ||
localStorage.setItem('evervault-haiku', 'spontaneous-seagull-123456'); | ||
const appId = '1ffd79c5-0df1-408d-a279-223cee474e2c'; | ||
it('should initialize an evervault app', function(done) { | ||
@@ -267,27 +271,256 @@ try { | ||
}); | ||
}); | ||
const testData = { | ||
foo: 'bar', | ||
bar: 'baz', | ||
describe('Test the SDK functions that make HTTP requests', function() { | ||
const apiUrl = 'https://api.evervault.com'; | ||
const refreshTokenUrl = `${apiUrl}/token/refresh`; | ||
const getMockApiResponse = (status = 200, headers = {}, body = {}) => { | ||
const responseHeaders = new Headers(); | ||
Object.keys(headers).forEach((key) => { | ||
responseHeaders.append(key, headers[key]); | ||
}); | ||
return new window.Response(body, { | ||
status, | ||
headers: responseHeaders, | ||
}); | ||
}; | ||
it('should let a user store data', function(done) { | ||
evervault.set(testData).then((result) => { | ||
chai.assert('foo' in result && 'bar' in result); | ||
done(); | ||
}); | ||
const getMockRefreshRequest = (accessToken, refreshToken) => ({ | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
accessToken, | ||
refreshToken, | ||
}), | ||
}); | ||
it('should let a user get all stored data', function(done) { | ||
evervault.get().then((result) => { | ||
chai.assert(result.foo === testData.foo && result.bar === testData.bar); | ||
done(); | ||
const fakeFetch = sinon.stub(); | ||
const fakeLogout = sinon.stub(); | ||
const fetchStub = sinon.stub(window, 'fetch').callsFake(fakeFetch); | ||
const logoutStub = sinon.stub(evervault, 'logout').callsFake(fakeLogout); | ||
this.afterEach(() => { | ||
fakeFetch.reset(); | ||
fakeLogout.reset(); | ||
}); | ||
describe('Test evervault.fetch', function() { | ||
const requestUrl = 'https://api.acme.com/test'; | ||
it('should receive a response code of 200', function(done) { | ||
//mock request to a third party api | ||
const expectedStatus = 200; | ||
fakeFetch | ||
.withArgs(requestUrl) | ||
.resolves(getMockApiResponse(expectedStatus, {}, {})); | ||
evervault.fetch(requestUrl).then((res) => { | ||
chai.assert(res.status === expectedStatus); | ||
chai.assert.equal( | ||
fakeFetch.calledOnce, | ||
true, | ||
'fetch should only be called once when it receives a valid responses' | ||
); | ||
done(); | ||
}); | ||
}); | ||
it('should retry if it receives a status code of 401', function(done) { | ||
const initialRequestStatus = 401; | ||
const refreshTokenStatus = 200; | ||
const secondRequestStatus = 200; | ||
fakeFetch | ||
.withArgs(requestUrl) | ||
.onFirstCall() | ||
.resolves(getMockApiResponse(initialRequestStatus)) | ||
.onSecondCall() | ||
.resolves(getMockApiResponse(secondRequestStatus)); | ||
fakeFetch | ||
.withArgs( | ||
refreshTokenUrl, | ||
getMockRefreshRequest(accessToken, refreshToken) | ||
) | ||
.resolves( | ||
getMockApiResponse( | ||
refreshTokenStatus, | ||
{ | ||
'Content-Type': 'application/json', | ||
}, | ||
JSON.stringify({ accessToken, refreshToken }) | ||
) | ||
); | ||
evervault.fetch(requestUrl).then((res) => { | ||
chai.assert.equal( | ||
fakeFetch.calledThrice, | ||
true, | ||
'Fetch was not called three times' | ||
); | ||
chai.assert.equal( | ||
res.status, | ||
secondRequestStatus, | ||
'Second request to api did not return the expected status code' | ||
); | ||
done(); | ||
}); | ||
}); | ||
it('should force a logout if the refresh request is rejected', function(done) { | ||
const initialRequestStatus = 401; | ||
const refreshTokenStatus = 401; | ||
fakeFetch | ||
.withArgs(requestUrl) | ||
.onFirstCall() | ||
.resolves(getMockApiResponse(initialRequestStatus)); | ||
fakeFetch | ||
.withArgs( | ||
refreshTokenUrl, | ||
getMockRefreshRequest(accessToken, refreshToken) | ||
) | ||
.resolves(getMockApiResponse(refreshTokenStatus)); | ||
fakeLogout.returns(undefined); | ||
evervault.fetch(requestUrl).then(() => { | ||
chai.assert.equal( | ||
fakeLogout.calledOnce, | ||
true, | ||
'Logout was not attempted' | ||
); | ||
done(); | ||
}); | ||
}); | ||
it('should return all responses including errors after a valid refresh', function(done) { | ||
const initialRequestStatus = 401; | ||
const refreshTokenStatus = 200; | ||
const secondRequestStatus = 500; | ||
fakeFetch | ||
.withArgs(requestUrl) | ||
.onFirstCall() | ||
.resolves(getMockApiResponse(initialRequestStatus)) | ||
.onSecondCall() | ||
.resolves(getMockApiResponse(secondRequestStatus)); | ||
fakeFetch | ||
.withArgs( | ||
refreshTokenUrl, | ||
getMockRefreshRequest(accessToken, refreshToken) | ||
) | ||
.resolves( | ||
getMockApiResponse( | ||
refreshTokenStatus, | ||
{ | ||
'Content-Type': 'application/json', | ||
}, | ||
JSON.stringify({ accessToken, refreshToken }) | ||
) | ||
); | ||
evervault.fetch(requestUrl).then((res) => { | ||
chai.assert.equal( | ||
fakeFetch.calledThrice, | ||
true, | ||
'Fetch was not called three times' | ||
); | ||
chai.assert.equal( | ||
fakeLogout.calledOnce, | ||
false, | ||
'Logout was incorrectly attempted' | ||
); | ||
chai.assert.equal( | ||
res.status, | ||
secondRequestStatus, | ||
'Response was not returned to the developer' | ||
); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should let a user get specfic stored data', function(done) { | ||
evervault.get('foo').then((result) => { | ||
chai.assert(result.foo === testData.foo); | ||
done(); | ||
describe("Test SDK's storage functions", function() { | ||
const testData = { | ||
foo: 'bar', | ||
bar: 'baz', | ||
}; | ||
let mockDB; | ||
this.beforeAll(() => { | ||
fetchStub.reset(); | ||
}); | ||
this.afterEach(() => { | ||
fetchStub.reset(); | ||
}); | ||
it('should let a user store data', function(done) { | ||
fetchStub.callsFake((_, { body }) => { | ||
return Promise.resolve( | ||
getMockApiResponse(201, { 'Content-Type': 'application/json' }, body) | ||
); | ||
}); | ||
evervault.set(testData).then((result) => { | ||
mockDB = result.data; | ||
chai.assert.equal( | ||
fetchStub.calledOnce, | ||
true, | ||
'Fetch was not called once' | ||
); | ||
evervault.decrypt(result.data).then((decrypted) => { | ||
chai.assert.deepEqual( | ||
testData, | ||
decrypted, | ||
'Decrypted data doesnt match the set data' | ||
); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should let a user get all stored data', function(done) { | ||
fetchStub.callsFake(() => { | ||
return Promise.resolve( | ||
getMockApiResponse( | ||
200, | ||
{ 'Content-Type': 'application/json' }, | ||
JSON.stringify(mockDB) | ||
) | ||
); | ||
}); | ||
evervault.get().then((result) => { | ||
chai.assert.equal( | ||
fetchStub.calledOnce, | ||
true, | ||
'Fetch was not called once' | ||
); | ||
chai.assert.deepEqual( | ||
result, | ||
testData, | ||
'Retrieved data does not match original input data' | ||
); | ||
done(); | ||
}); | ||
}); | ||
it('should let a user get specfic stored data', function(done) { | ||
fetchStub.callsFake(() => { | ||
return Promise.resolve( | ||
getMockApiResponse( | ||
200, | ||
{ 'Content-Type': 'application/json' }, | ||
JSON.stringify({ foo: mockDB.foo }) | ||
) | ||
); | ||
}); | ||
evervault.get('foo').then((result) => { | ||
chai.assert(result.foo === testData.foo); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
55601
1005
0
8