Skip to content

Commit

Permalink
Add token refreshing
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-barker-reflow committed Dec 21, 2018
1 parent 5f96094 commit 54ed562
Showing 1 changed file with 66 additions and 22 deletions.
88 changes: 66 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const DEFAULT_OPTS = {
}
};

// API docs state that the JWT token expires after 24h so to be safe refresh
// every 12 hours
const TOKEN_TTL = 43200000;


//
// API Client
Expand All @@ -47,10 +51,15 @@ class Client {

// store and manage auth token
let tokenPromise = null;
let tokenLastRefresh = null;

this.getToken = function() {
if (tokenPromise === null) {
tokenPromise = logIn(this.apiKey);
tokenLastRefresh = new Date().getTime();
} else if (shouldTokenRefresh(tokenLastRefresh)) {
tokenPromise = refreshToken(tokenPromise);
tokenLastRefresh = new Date().getTime();
}

return tokenPromise;
Expand Down Expand Up @@ -331,7 +340,7 @@ class Client {
let query = {};
if (keyType !== null) {
query = { query: {
keyType: keyType }
keyType: keyType }
};
}
const reqOpts = Object.assign({}, opts, query);
Expand Down Expand Up @@ -439,29 +448,29 @@ class Client {
this.getSeriesById(seriesId, opts),
this.getEpisodesBySeriesId(seriesId, opts)
])
.then(results => {
let series = results[0];
series.episodes = results[1];
return series;
});
.then(results => {
let series = results[0];
series.episodes = results[1];
return series;
});
}

/**
* Runs a get request with the given options, useful for running custom
* requests.
*
* ``` javascript
* tvdb.sendRequest('custom/endpoint', { custom: 'options' })
* .then(response => { handle response })
* .catch(error => { handle error });
* ```
*
* @param {String} path - path for http resource
* @param {Object} [opts] - additional options for request
* @returns {Promise}
*
* @public
*/
* Runs a get request with the given options, useful for running custom
* requests.
*
* ``` javascript
* tvdb.sendRequest('custom/endpoint', { custom: 'options' })
* .then(response => { handle response })
* .catch(error => { handle error });
* ```
*
* @param {String} path - path for http resource
* @param {Object} [opts] - additional options for request
* @returns {Promise}
*
* @public
*/

sendRequest(path, opts) {
const options = Object.assign({}, DEFAULT_OPTS, opts);
Expand Down Expand Up @@ -587,6 +596,29 @@ function logIn(apiKey) {
.then(json => json.token);
}

/**
* Perform a token refresh
*
* @param currentToken
* @returns {Promise}
* @private
*/
function refreshToken(currentToken) {
const opts = {
method: 'GET',
headers: {
'Accept': AV_HEADER,
'Content-Type': 'application/json',
'Authorization': `Bearer ${currentToken}`,
}
};

return request(`${BASE_URL}/refresh_token`, opts)
.then(res => checkHttpError(res))
.then(res => checkJsonError(res))
.then(json => json.token);
}

/**
* Returns true if the response has additional pages, otherwise returns false.
*
Expand All @@ -599,8 +631,20 @@ function hasNextPage(response) {
return response && response.links && response.links.next;
}

/**
* Returns true if the last token refresh was long enough ago
*
* @param lastTokenRefresh
* @returns {boolean}
* @private
*/
function shouldTokenRefresh(lastTokenRefresh) {
const now = new Date().getTime();
return ( now - lastTokenRefresh ) > TOKEN_TTL;
}

//
// Exports
//

module.exports = Client;
module.exports = Client;

0 comments on commit 54ed562

Please sign in to comment.