UNPKG

react-jwt-store

Version:
113 lines (91 loc) 2.5 kB
'use strict' import extend from 'xtend' import cookie from 'cookie-monster' import decode from 'jwt-decode' import events from 'events' import ls from 'local-storage' const EventEmitter = events.EventEmitter const noop = function () { } module.exports = (options) => { let user let token options = extend({ cookie: 'XSRF-TOKEN' }, options) const logger = options.logger || { info: noop, warn: noop } const decodeToken = token => { if (token) { try { return decode(token) } catch (e) { logger.warn(`[JWT store] Invalid JWT: ${token}`) return void 0 } } } if (options.localStorageKey) { try { token = ls.get(options.localStorageKey) } catch (e) { logger.warn('[JWT store] Unable to get token', e) } } else { token = cookie.get && cookie.get(options.cookie) } logger.info('[JWT store] created store with token', token) const tokenStore = extend({ getToken () { return token }, getUser () { return user }, getUserId () { return user ? user.id : void 0 }, setToken (newToken) { logger.info('[JWT store] setting new token', newToken) token = newToken user = decodeToken(token) this.emit('Token received', token, user) }, refreshToken () { if (options.refresh) { logger.info('[JWT store] refreshing token', token) options.refresh(token) .then(tokenStore.setToken.bind(tokenStore)) } } }, EventEmitter.prototype) const refreshToken = () => { if (!token && options.refresh) { tokenStore.refreshToken() } else { user = decodeToken(token) } let expDate = user ? new Date(user.exp * 1000 - expiryWindow) : null if (expDate && expDate < new Date() && options.refresh) { tokenStore.refreshToken() } } const refreshInterval = options.refreshInterval ? options.refreshInterval : 60 * 1000 // default to checking every minute const expiryWindow = options.expiryWindow ? options.expiryWindow : 2 * refreshInterval // default to refreshing if we're two refreshInterval's away from expiration if (options.listeners) { Object.keys(options.listeners).forEach((key) => { tokenStore.on(key, options.listeners[key]) }) } if (options.refresh) { refreshToken() setInterval(refreshToken, refreshInterval) } if (token) { tokenStore.setToken(token) } return tokenStore }