Skip to content
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
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,50 @@ oauthClient
});
```


You can also make the calling using the endpoint path:

```javascript
// Body sample from API explorer examples
const body = {
TrackQtyOnHand: true,
Name: 'Garden Supplies',
QtyOnHand: 10,
InvStartDate: '2015-01-01',
Type: 'Inventory',
IncomeAccountRef: {
name: 'Sales of Product Income',
value: '79',
},
AssetAccountRef: {
name: 'Inventory Asset',
value: '81',
},
ExpenseAccountRef: {
name: 'Cost of Goods Sold',
value: '80',
},
};

oauthClient
.makeApiCall({
url: '/v3/company/1234/item',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
})
.then(function (response) {
console.log('The API response is : ' + response);
})
.catch(function (e) {
console.log('The error is ' + JSON.stringify(e));
});
```



The client validates the ID Token and returns boolean `true` if validates successfully else it would
throw an exception.

Expand Down
31 changes: 30 additions & 1 deletion src/OAuthClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ OAuthClient.environment = {
sandbox: 'https://sandbox-quickbooks.api.intuit.com/',
production: 'https://quickbooks.api.intuit.com/',
};
OAuthClient.qbo_environment = {
sandbox: 'https://sandbox.qbo.intuit.com/app/',
production: 'https://qbo.intuit.com/app/',
};
OAuthClient.jwks_uri = 'https://oauth.platform.intuit.com/op/v1/jwks';
OAuthClient.scopes = {
Accounting: 'com.intuit.quickbooks.accounting',
Expand Down Expand Up @@ -123,6 +127,16 @@ OAuthClient.prototype.setAuthorizeURLs = function setAuthorizeURLs(params) {
return this;
};

OAuthClient.prototype.getEnvironmentURI = function getEnvironmentURI() {
return (this.environment && this.environment === 'production') ? OAuthClient.environment.production : OAuthClient.environment.sandbox;
}


OAuthClient.prototype.getQBOEnvironmentURI = function getQBOEnvironmentURI() {
return (this.environment && this.environment === 'production') ? OAuthClient.qbo_environment.production : OAuthClient.qbo_environment.sandbox;
}


/**
* Redirect User to Authorization Page
* *
Expand Down Expand Up @@ -389,8 +403,23 @@ OAuthClient.prototype.makeApiCall = function makeApiCall(params) {
? Object.assign({}, baseHeaders, params.headers)
: Object.assign({}, baseHeaders);

let baseURL = '';
let endpoint = '';
// backward compatibility:
// checking to see if user has supplied the full url
if (params.url.startsWith(OAuthClient.environment.sandbox) || params.url.startsWith(OAuthClient.environment.production)) {
baseURL = params.url;

} else {
baseURL = (this.environment && this.environment === 'production') ? OAuthClient.environment.production : OAuthClient.environment.sandbox;
// checking to see if user supplied the endpoint only and if it begins with a slash
// if it does, we remove the slash to avoid double slashes in the url
endpoint = params.url.startsWith('/') ? params.url.slice(1) : params.url;

}

const request = {
url: params.url,
url: baseURL + endpoint,
method: params.method || 'GET',
headers,
responseType,
Expand Down
213 changes: 213 additions & 0 deletions test/OAuthClientTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,36 @@ describe('Tests for OAuthClient', () => {
);
});
});
it('Make API Call in Sandbox Environment using relative endpoint - starting slash', () => {
oauthClient.environment = 'sandbox';
oauthClient.getToken().realmId = '12345';
// eslint-disable-next-line no-useless-concat
return oauthClient
.makeApiCall({
url:
'/v3/company/' + '12345' + '/companyinfo/' + '12345',
})
.then((authResponse) => {
expect(JSON.stringify(authResponse.json)).to.be.equal(
JSON.stringify(expectedMakeAPICall),
);
});
});
it('Make API Call in Sandbox Environment using relative endpoint - no starting slash', () => {
oauthClient.environment = 'sandbox';
oauthClient.getToken().realmId = '12345';
// eslint-disable-next-line no-useless-concat
return oauthClient
.makeApiCall({
url:
'v3/company/' + '12345' + '/companyinfo/' + '12345',
})
.then((authResponse) => {
expect(JSON.stringify(authResponse.json)).to.be.equal(
JSON.stringify(expectedMakeAPICall),
);
});
});
it('Make API Call in Sandbox Environment with headers as parameters', () => {
oauthClient.getToken().realmId = '12345';
// eslint-disable-next-line no-useless-concat
Expand All @@ -322,6 +352,38 @@ describe('Tests for OAuthClient', () => {
);
});
});
it('Make API Call in Sandbox Environment with headers as parameters, relative endpoint path - starting slash', () => {
oauthClient.getToken().realmId = '12345';
// eslint-disable-next-line no-useless-concat
return oauthClient
.makeApiCall({
url: `/v3/company/12345/companyinfo/12345`,
headers: {
Accept: 'application/json',
},
})
.then((authResponse) => {
expect(JSON.stringify(authResponse.json)).to.be.equal(
JSON.stringify(expectedMakeAPICall),
);
});
});
it('Make API Call in Sandbox Environment with headers as parameters, relative endpoint path - no starting slash', () => {
oauthClient.getToken().realmId = '12345';
// eslint-disable-next-line no-useless-concat
return oauthClient
.makeApiCall({
url: `v3/company/12345/companyinfo/12345`,
headers: {
Accept: 'application/json',
},
})
.then((authResponse) => {
expect(JSON.stringify(authResponse.json)).to.be.equal(
JSON.stringify(expectedMakeAPICall),
);
});
});
xit('loadResponseFromJWKsURI', () => {
const request = {
url: 'https://sandbox-quickbooks.api.intuit.com/v3/company/12345/companyinfo/12345',
Expand Down Expand Up @@ -362,6 +424,36 @@ describe('Tests for OAuthClient', () => {
);
});
});
it('Make API Call in Production Environment with relative endpoint path - starting slash', () => {
oauthClient.environment = 'production';
oauthClient.getToken().realmId = '12345';
// eslint-disable-next-line no-useless-concat
return oauthClient
.makeApiCall({
url:
'/v3/company/' + '12345' + '/companyinfo/' + '12345',
})
.then((authResponse) => {
expect(JSON.stringify(authResponse.json)).to.be.equal(
JSON.stringify(expectedMakeAPICall),
);
});
});
it('Make API Call in Production Environment with relative endpoing path - no starting slash', () => {
oauthClient.environment = 'production';
oauthClient.getToken().realmId = '12345';
// eslint-disable-next-line no-useless-concat
return oauthClient
.makeApiCall({
url:
'v3/company/' + '12345' + '/companyinfo/' + '12345',
})
.then((authResponse) => {
expect(JSON.stringify(authResponse.json)).to.be.equal(
JSON.stringify(expectedMakeAPICall),
);
});
});
});
});

Expand Down Expand Up @@ -635,3 +727,124 @@ describe('Test Logging', () => {
expect(oauthClient.logger.log.firstCall.args[1]).to.be.equal(message + messageData);
});
});

describe('Tests whether the correct environment urls is returned', () => {
describe('tests sandbox environment', () => {
it('returns the sandbox environment URL when environment is not set', () => {
oauthClient.environment = null;
const environmentURI = oauthClient.getEnvironmentURI();
expect(environmentURI).to.be.equal(OAuthClientTest.environment.sandbox);
});
it('returns the sandbox environment URL when environment is sandbox', () => {
oauthClient.environment = 'sandbox';
const environmentURI = oauthClient.getEnvironmentURI();
expect(environmentURI).to.be.equal(OAuthClientTest.environment.sandbox);
});
it('returns the sandbox environment URL when sandbox environment is misspelt', () => {
oauthClient.environment = 'sandoboxo';
const environmentURI = oauthClient.getEnvironmentURI();
expect(environmentURI).to.be.equal(OAuthClientTest.environment.sandbox);
});

});
describe('tests production environment', () => {
it('returns the production environment URL when environment is production', () => {
oauthClient.environment = 'production';
const environmentURI = oauthClient.getEnvironmentURI();
expect(environmentURI).to.be.equal(OAuthClientTest.environment.production);
});
it('returns the sandbox environment URL when production environment is misspelt', () => {
oauthClient.environment = 'productio';
const environmentURI = oauthClient.getEnvironmentURI();
expect(environmentURI).to.be.equal(OAuthClientTest.environment.sandbox);
});
});
});



describe('Tests whether the correct Quickbooks online (QBO) environment urls is returned', () => {
describe('tests sandbox environment', () => {
it('returns the sandbox QBO environment URL when environment is not set', () => {
oauthClient.environment = null;
const qboEnvironmentURI = oauthClient.getQBOEnvironmentURI();
expect(qboEnvironmentURI).to.be.equal(OAuthClientTest.qbo_environment.sandbox);
});
it('returns the sandbox environment URL when environment is sandbox', () => {
oauthClient.environment = 'sandbox';
const qboEnvironmentURI = oauthClient.getQBOEnvironmentURI();
expect(qboEnvironmentURI).to.be.equal(OAuthClientTest.qbo_environment.sandbox);
});
it('returns the sandbox environment URL when sandbox environment is misspelt', () => {
oauthClient.environment = 'sandoboxo';
const qboEnvironmentURI = oauthClient.getQBOEnvironmentURI();
expect(qboEnvironmentURI).to.be.equal(OAuthClientTest.qbo_environment.sandbox);
});

});
describe('tests production environment', () => {
it('returns the production environment URL when environment is production', () => {
oauthClient.environment = 'production';
const qboEnvironmentURI = oauthClient.getQBOEnvironmentURI();
expect(qboEnvironmentURI).to.be.equal(OAuthClientTest.qbo_environment.production);

});
it('returns the sandbox environment URL when production environment is misspelt', () => {
oauthClient.environment = 'productio';
const qboEnvironmentURI = oauthClient.getQBOEnvironmentURI();
expect(qboEnvironmentURI).to.be.equal(OAuthClientTest.qbo_environment.sandbox);

});
});
});



// must be last test as it changes the endpoints
describe('Tests for OAuthClient to set custom Authorization URIs', () => {
describe('set the authorizationURIs', () => {
it('throws an error when no params provided', () => {
expect(() => { oauthClient.setAuthorizeURLs() }).to.throw("Provide the custom authorize URL's");
});
it('throws an error when no params provided', () => {
expect(() => { oauthClient.setAuthorizeURLs(null) }).to.throw("Provide the custom authorize URL's");
});
it('sets the Authorise urls to custom ones - sandbox', async (done) => {
const customURLs = {
authorizeEndpoint: "https://custom.Authorize.Endpoint",
tokenEndpoint: "https://custom.Token.Endpoint",
revokeEndpoint: "https://custom.Revoke.Endpoint",
userInfoEndpoint: "https://custom.User.Info.Endpoint",
}

oauthClient.environment = 'sandbox';
oauthClient.setAuthorizeURLs(customURLs);
done();
expect(OAuthClientTest.authorizeEndpoint).to.be.equal('https://custom.Authorize.Endpoint');
expect(OAuthClientTest.tokenEndpoint).to.be.equal('https://custom.Token.Endpoint');
expect(OAuthClientTest.revokeEndpoint).to.be.equal('https://custom.Revoke.Endpoint');
expect(OAuthClientTest.userinfo_endpoint_sandbox).to.be.equal('https://custom.User.Info.Endpoint');
expect(OAuthClientTest.userinfo_endpoint_production).to.be.equal('https://accounts.platform.intuit.com/v1/openid_connect/userinfo');

});
it('sets the Authorise urls to custom ones - production', async (done) => {
const customURLs = {
authorizeEndpoint: "https://custom.Authorize.Endpoint",
tokenEndpoint: "https://custom.Token.Endpoint",
revokeEndpoint: "https://custom.Revoke.Endpoint",
userInfoEndpoint: "https://custom.User.Info.Endpoint",
}

oauthClient.environment = 'production';
oauthClient.setAuthorizeURLs(customURLs);
done();
expect(OAuthClientTest.authorizeEndpoint).to.be.equal('https://custom.Authorize.Endpoint');
expect(OAuthClientTest.tokenEndpoint).to.be.equal('https://custom.Token.Endpoint');
expect(OAuthClientTest.revokeEndpoint).to.be.equal('https://custom.Revoke.Endpoint');
expect(OAuthClientTest.userinfo_endpoint_sandbox).to.be.equal('https://sandbox-accounts.platform.intuit.com/v1/openid_connect/userinfo');
expect(OAuthClientTest.userinfo_endpoint_production).to.be.equal('https://custom.User.Info.Endpoint');

});
});

});