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 Jan 2, 2019
1 parent 5f96094 commit 239d697
Showing 1 changed file with 89 additions and 25 deletions.
114 changes: 89 additions & 25 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ const AV_HEADER = `application/vnd.thetvdb.${API_VERSION}`;

const DEFAULT_OPTS = {
getAllPages: true,
autoRefreshToken: true,
headers: {
'User-Agent': `node-tvdb/${LIB_VERSION} (+https://github.com/edwellbrook/node-tvdb)`
}
};


//
// API Client
//
Expand All @@ -48,13 +48,20 @@ class Client {
// store and manage auth token
let tokenPromise = null;

this.getToken = function() {
this.getToken = function (autoRefresh) {
if (tokenPromise === null) {
tokenPromise = logIn(this.apiKey);
} else if (autoRefresh) {
tokenPromise.then(token => {
if (shouldTokenRefresh(token)) {
tokenPromise = refreshToken(token);
}
});
}

return tokenPromise;
};

}

/**
Expand Down Expand Up @@ -330,8 +337,10 @@ class Client {
getSeriesImages(seriesId, keyType, opts) {
let query = {};
if (keyType !== null) {
query = { query: {
keyType: keyType }
query = {
query: {
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 All @@ -476,7 +485,7 @@ class Client {
query: query
});

return this.getToken()
return this.getToken(options.autoRefreshToken)
.then(token => {
headers['Authorization'] = `Bearer ${token}`;
return request(requestURL, { headers: headers });
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,6 +631,38 @@ function hasNextPage(response) {
return response && response.links && response.links.next;
}

/**
* Returns the exp key from a JWT
*
* @param token
*/
function getTokenExp(token) {

const tokenParts = token.split('.');
const buffer = Buffer.from(tokenParts[1], 'base64');
const payload = JSON.parse(buffer.toString('ascii'));

if ( payload.exp ) {
return payload.exp;
}

throw new Error(`Couldn't get token expiry`);

}

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

//
// Exports
//
Expand Down

0 comments on commit 239d697

Please sign in to comment.