75 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			75 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import jwt from 'jsonwebtoken'; | ||
|  | import { isBefore } from 'date-fns'; | ||
|  | 
 | ||
|  | import { jwtSecret as _jwtSecret } from '../../../config/secrets'; | ||
|  | 
 | ||
|  | export const authHeaderNS = 'X-fcc-access-token'; | ||
|  | export const jwtCookieNS = 'jwt_access_token'; | ||
|  | 
 | ||
|  | export function createCookieConfig(req) { | ||
|  |   return { | ||
|  |     signed: !!req.signedCookies, | ||
|  |     domain: process.env.COOKIE_DOMAIN || 'localhost' | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | export function setAccessTokenToResponse( | ||
|  |   { accessToken }, | ||
|  |   req, | ||
|  |   res, | ||
|  |   jwtSecret = _jwtSecret | ||
|  | ) { | ||
|  |   const cookieConfig = { | ||
|  |     ...createCookieConfig(req), | ||
|  |     maxAge: accessToken.ttl || 77760000000 | ||
|  |   }; | ||
|  |   const jwtAccess = jwt.sign({ accessToken }, jwtSecret); | ||
|  |   res.cookie(jwtCookieNS, jwtAccess, cookieConfig); | ||
|  |   return; | ||
|  | } | ||
|  | 
 | ||
|  | export function getAccessTokenFromRequest(req, jwtSecret = _jwtSecret) { | ||
|  |   const maybeToken = | ||
|  |     (req.headers && req.headers[authHeaderNS]) || | ||
|  |     (req.signedCookies && req.signedCookies[jwtCookieNS]) || | ||
|  |     (req.cookie && req.cookie[jwtCookieNS]); | ||
|  |   if (!maybeToken) { | ||
|  |     return { | ||
|  |       accessToken: null, | ||
|  |       error: errorTypes.noTokenFound | ||
|  |     }; | ||
|  |   } | ||
|  |   let token; | ||
|  |   try { | ||
|  |     token = jwt.verify(maybeToken, jwtSecret); | ||
|  |   } catch (err) { | ||
|  |     return { accessToken: null, error: errorTypes.invalidToken }; | ||
|  |   } | ||
|  | 
 | ||
|  |   const { accessToken } = token; | ||
|  |   const { created, ttl } = accessToken; | ||
|  |   const valid = isBefore(Date.now(), Date.parse(created) + ttl); | ||
|  |   if (!valid) { | ||
|  |     return { | ||
|  |       accessToken: null, | ||
|  |       error: errorTypes.expiredToken | ||
|  |     }; | ||
|  |   } | ||
|  |   return { accessToken, error: '', jwt: maybeToken }; | ||
|  | } | ||
|  | 
 | ||
|  | export function removeCookies(req, res) { | ||
|  |   const config = createCookieConfig(req); | ||
|  |   res.clearCookie(jwtCookieNS, config); | ||
|  |   res.clearCookie('access_token', config); | ||
|  |   res.clearCookie('userId', config); | ||
|  |   res.clearCookie('_csrf', config); | ||
|  |   return; | ||
|  | } | ||
|  | 
 | ||
|  | export const errorTypes = { | ||
|  |   noTokenFound: 'No token found', | ||
|  |   invalidToken: 'Invalid token', | ||
|  |   expiredToken: 'Token timed out' | ||
|  | }; |