freeCodeCamp/api-server/server/utils/getSetAccessToken.js

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