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'
							 | 
						||
| 
								 | 
							
								};
							 |