@mountainpass/hooked-cli
Version:
A tool for runnable scripts
105 lines (104 loc) • 3.63 kB
JavaScript
import cookieParser from 'cookie-parser';
import express from 'express';
import jwt from 'jsonwebtoken';
import passport from 'passport';
import { ExtractJwt, Strategy as JwtStrategy } from 'passport-jwt';
import { isDefined, isUndefined } from '../../types.js';
// lazy init
function cookieExtractor(req) {
if (typeof (req === null || req === void 0 ? void 0 : req.cookies) !== 'undefined') {
return req.cookies[jwtOptions.jwtCookieName];
// return req.signedCookies[jwtOptions.jwtCookieName]
}
else {
return null;
}
}
;
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromExtractors([cookieExtractor]),
secretOrKey: 'SECRET_KEY',
issuer: 'www.localhost',
audience: 'api.localhost',
/** max age in seconds */
expiresIn: 86400,
jwtCookieName: 'jwt'
};
/**
* Checks whether the JWT token is valid.
*/
const getJwtStrategy = (authoriser) => {
const { jwtFromRequest, secretOrKey, issuer, audience } = jwtOptions;
return new JwtStrategy({ jwtFromRequest, secretOrKey, issuer, audience }, (jwtPayload, done) => {
try {
const user = authoriser(jwtPayload);
if (isDefined(user)) {
done(null, user);
}
else {
done('Unknown user.', false);
}
}
catch (err) {
console.error('Authoriser error.', err);
done('Server error.', false);
}
});
};
const initialise = (app, authenticator, authoriser) => {
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser(jwtOptions.secretOrKey));
passport.use(getJwtStrategy(authoriser));
app.use(passport.initialize());
// login
app.post('/auth/login', (req, res) => {
try {
const user = authenticator(req.body);
if (isDefined(user)) {
const token = createJwtToken(user);
return res.cookie('jwt', token, {
// domain: '.localhost:3000',
httpOnly: true, // no js access!
secure: process.env.NODE_ENV === 'production',
signed: false, // jwt will do the signing
maxAge: jwtOptions.expiresIn * 1000
})
.status(200)
.json(Object.assign({ message: 'Login successful.' }, user));
}
return res.status(401).json({ message: 'Unauthorised' });
}
catch (err) {
console.error('Authenticator error', err);
return res.status(500).json({ message: 'Server error' });
}
});
// logout
app.get('/auth/logout', (req, res) => {
res
.clearCookie(jwtOptions.jwtCookieName)
.status(200)
.json({ message: 'You have logged out.' });
});
};
const createJwtToken = (jwtPayload) => {
const { issuer, audience, expiresIn } = jwtOptions;
// add any other data you want in here...
const token = jwt.sign(jwtPayload, jwtOptions.secretOrKey, { issuer, audience, expiresIn });
return token;
};
/** Verifies the JWT token issuer, audience, and expiry. */
const requireSigninMiddleware = (req, res, next) => {
passport.authenticate(jwtOptions.jwtCookieName, { session: false }, (err, user, info) => {
if (isDefined(err) || isUndefined(user) || user === false) {
return res.status(401).json({ message: 'Unauthorised' });
}
req.user = user;
next();
})(req, res, next);
};
export default {
initialise,
requireSigninMiddleware
};