Skip to content

Commit

Permalink
added refresh and check expiry functions. Also updated the sample app
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan Walsh committed Mar 9, 2017
1 parent 7dd4b15 commit 804e36e
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 131 deletions.
223 changes: 138 additions & 85 deletions lib/application.js
Expand Up @@ -98,55 +98,73 @@ Object.assign(Application.prototype, {
options = options || {};
return new Promise(function(resolve, reject) {
var params = {};
if (options.summarizeErrors === false)
params.summarizeErrors = false;

//Added to support more than 2dp being added.
if (options.unitdp)
params.unitdp = options.unitdp;
self.checkExpiry()
.then(function() {
if (options.summarizeErrors === false)
params.summarizeErrors = false;

var endPointUrl = options.api === 'payroll' ? self.options.payrollAPIEndPointUrl : self.options.coreAPIEndPointUrl;
var url = self.options.baseUrl + endPointUrl + path;
if (!_.isEmpty(params))
url += '?' + querystring.stringify(params);
//Added to support more than 2dp being added.
if (options.unitdp)
params.unitdp = options.unitdp;

self.oa[method](url, self.options.accessToken, self.options.accessSecret, { xml: body }, function(err, data, res) {
var endPointUrl = options.api === 'payroll' ? self.options.payrollAPIEndPointUrl : self.options.coreAPIEndPointUrl;
var url = self.options.baseUrl + endPointUrl + path;
if (!_.isEmpty(params))
url += '?' + querystring.stringify(params);

if (err && data && data.indexOf('oauth_problem') >= 0) {
var errObj = new Error(method.toUpperCase() + ' call failed with: ' + err.statusCode);
errObj.data = qs.parse(data);
reject(errObj);
callback && callback(errObj);
return;
}
self.oa[method](url, self.options.accessToken, self.options.accessSecret, { xml: body }, function(err, data, res) {

self.xml2js(data)
.then(function(obj) {
if (err) {
var exception = "";
if (obj.ApiException)
exception = obj.ApiException;
else if (obj.Response.ErrorNumber)
exception = obj.Response;
var errObj = new Error(method.toUpperCase() + ' call failed with: ' + err.statusCode + ' and exception: ' + JSON.stringify(exception, null, 2));
if (err && data && data.indexOf('oauth_problem') >= 0) {
var errObj = new Error(method.toUpperCase() + ' call failed with: ' + err.statusCode);
errObj.data = qs.parse(data);
reject(errObj);
callback && callback(errObj);
} else {
var ret = { response: obj.Response, res: res };
if (options.entityConstructor) {
ret.entities = self.convertEntities(obj.Response, options);
}
resolve(ret);
callback && callback(null, obj, res, ret.entities);
return;
}

})
.catch(function(err) {
logger.error(err);
throw err;
})
self.xml2js(data)
.then(function(obj) {
if (err) {
var exception = "";
if (obj.ApiException)
exception = obj.ApiException;
else if (obj.Response.ErrorNumber)
exception = obj.Response;
var errObj = new Error(method.toUpperCase() + ' call failed with: ' + err.statusCode + ' and exception: ' + JSON.stringify(exception, null, 2));
reject(errObj);
callback && callback(errObj);
} else {
var ret = { response: obj.Response, res: res };
if (options.entityConstructor) {
ret.entities = self.convertEntities(obj.Response, options);
}
resolve(ret);
callback && callback(null, obj, res, ret.entities);
}

})
.catch(function(err) {
logger.error(err);
throw err;
})

});
})
.catch(function(err) {
logger.debug(err);
if (err && err.data) {
var dataParts = qs.parse(err.data);

var errObj = new Error(method.toUpperCase() + ' call failed with: ' + err.statusCode);
errObj.data = dataParts;
reject(errObj);
callback && callback(errObj);
return;
}
});


});
});
},
delete: function(path, options, callback) {
Expand All @@ -157,42 +175,57 @@ Object.assign(Application.prototype, {
var endPointUrl = options.api === 'payroll' ? self.options.payrollAPIEndPointUrl : self.options.coreAPIEndPointUrl;
var url = self.options.baseUrl + endPointUrl + path;

self.oa.delete(url, self.options.accessToken, self.options.accessSecret, function(err, data, res) {
if (options.stream && !err) {
// Already done
return resolve();
}
if (err && data && data.indexOf('oauth_problem') >= 0) {
var errObj = new Error('DELETE call failed with: ' + err.statusCode);
errObj.data = qs.parse(data);
reject(errObj);
callback && callback(errObj);
return;
}
self.checkExpiry()
.then(function() {
self.oa.delete(url, self.options.accessToken, self.options.accessSecret, function(err, data, res) {
if (options.stream && !err) {
// Already done
return resolve();
}
if (err && data && data.indexOf('oauth_problem') >= 0) {
var errObj = new Error('DELETE call failed with: ' + err.statusCode);
errObj.data = qs.parse(data);
reject(errObj);
callback && callback(errObj);
return;
}

if (err) {
var errObj = new Error('DELETE call failed with: ' + err.statusCode + ' and message: ' + err.data);
reject(errObj);
callback && callback(errObj);
return;
}
if (err) {
var errObj = new Error('DELETE call failed with: ' + err.statusCode + ' and message: ' + err.data);
reject(errObj);
callback && callback(errObj);
return;
}

//Some delete operations don't return any content (e.g. HTTP204) so simply resolve the promise
if (!data || data === "") {
return resolve();
}
//Some delete operations don't return any content (e.g. HTTP204) so simply resolve the promise
if (!data || data === "") {
return resolve();
}

self.xml2js(data)
.then(function(obj) {
var ret = { response: obj.Response, res: res };
resolve(ret);
callback && callback(null, obj, res);
})
.catch(function(err) {
logger.error(err);
throw err;
})
}, { stream: options.stream });
self.xml2js(data)
.then(function(obj) {
var ret = { response: obj.Response, res: res };
resolve(ret);
callback && callback(null, obj, res);
})
.catch(function(err) {
logger.error(err);
throw err;
})
}, { stream: options.stream });
})
.catch(function(err) {
logger.debug(err);
if (err && err.data) {
var dataParts = qs.parse(err.data);

var errObj = new Error('DELETE call failed with: ' + err.statusCode);
errObj.data = dataParts;
reject(errObj);
callback && callback(errObj);
return;
}
});
});
},
get: function(path, options, callback) {
Expand All @@ -213,6 +246,18 @@ Object.assign(Application.prototype, {
getResource(options.pager.start || 1)
else
getResource();
})
.catch(function(err) {
logger.debug(err);
if (err && err.data) {
var dataParts = qs.parse(err.data);

var errObj = new Error('GET call failed with: ' + err.statusCode);
errObj.data = dataParts;
reject(errObj);
callback && callback(errObj);
return;
}
});

function getResource(offset) {
Expand Down Expand Up @@ -418,15 +463,28 @@ Object.assign(Application.prototype, {
return obj;
},
checkExpiry: function() {
var d1 = new Date(this.options.tokenExpiry),
d2 = new Date();

if (d2 > d1) {
/**
* CheckExpiry is a helper function that will compare the current token expiry to the current time.
*
* As there is potential for a time difference, instead of waiting all the way until the current time
* has passed the expiry time, we instead add 3 minutes to the current time, and use that as a comparison.
*
* This ensures that if the token is 'nearing' the expiry, it'll attempt to be refreshed.
*/

var expiry = new Date(this.options.tokenExpiry),
checkTime = addMinutes(new Date(), 3);

if (checkTime >= expiry) {
return this.refreshAccessToken();
} else {
logger.debug("Dates are fine, no need for refresh");
return Promise.resolve();
}

function addMinutes(date, minutes) {
return new Date(date.getTime() + minutes * 60000);
}
}
})

Expand Down Expand Up @@ -490,13 +548,12 @@ var RequireAuthorizationApplication = Application.extend({
reject(err);
else {
var exp = new Date();
exp.setSeconds(exp.getSeconds() + results.oauth_expires_in);

exp.setTime(exp.getTime() + (results.oauth_expires_in * 1000));
self.setOptions({
accessToken: results.oauth_token,
accessSecret: results.oauth_token_secret,
sessionHandle: results.oauth_session_handle,
tokenExpiry: exp.toISOString()
tokenExpiry: exp.toString()
});
resolve({ results: results });
}
Expand All @@ -513,13 +570,12 @@ var RequireAuthorizationApplication = Application.extend({
reject(err);
else {
var exp = new Date();
exp.setSeconds(exp.getSeconds() + results.oauth_expires_in);

exp.setTime(exp.getTime() + (results.oauth_expires_in * 1000));
self.setOptions({
accessToken: results.oauth_token,
accessSecret: results.oauth_token_secret,
sessionHandle: results.oauth_session_handle,
tokenExpiry: exp.toISOString()
tokenExpiry: exp.toString()
});
resolve({ results: results });
}
Expand All @@ -537,9 +593,6 @@ var RequireAuthorizationApplication = Application.extend({
this.options.accessSecret = options.accessSecret;
this.options.sessionHandle = options.sessionHandle;
this.options.tokenExpiry = options.tokenExpiry;

console.log("options set!");
console.log(this.options);
}
});

Expand Down

0 comments on commit 804e36e

Please sign in to comment.