Skip to content

Instantly share code, notes, and snippets.

@fabriciofmsilva
Created June 10, 2019 19:30
Show Gist options
  • Save fabriciofmsilva/fe71c13770e3ea950bb0f430ab851b69 to your computer and use it in GitHub Desktop.
Save fabriciofmsilva/fe71c13770e3ea950bb0f430ab851b69 to your computer and use it in GitHub Desktop.
Authentication
// https://github.com/santiq/nodejs-auth/tree/master/src/middlewares
import * as argon2 from 'argon2';
import * as jwt from 'jsonwebtoken';
class AuthService {
public async Login(email, password): Promise<any> {
const userRecord = await UserModel.findOne({ email });
if (!userRecord) {
throw new Error('User not found')
} else {
const correctPassword = await argon2.verify(userRecord.password, password);
if (!correctPassword) {
throw new Error('Incorrect password')
}
}
return {
user: {
email: userRecord.email,
name: userRecord.name,
},
token: this.generateJWT(userRecord),
}
}
public async SignUp(email, password, name): Promise<any> {
const passwordHashed = await argon2.hash(password);
const userRecord = await UserModel.create({
password: passwordHashed,
email,
name,
});
return {
// MAKE SURE TO NEVER SEND BACK THE PASSWORD!!!!
user: {
email: userRecord.email,
name: userRecord.name,
},
}
}
private generateToken(user) {
const data = {
_id: user._id,
name: user.name,
email: user.email
};
const signature = 'MySuP3R_z3kr3t';
const expiration = '6h';
return jwt.sign({ data, }, signature, { expiresIn: expiration });
}
}
// isAuth
import * as jwt from 'express-jwt';
// We are assuming that the JWT will come in the header Authorization but it could come in the req.body or in a query param, you have to decide what works best for you.
const getTokenFromHeader = (req) => {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1];
}
}
export default jwt({
secret: 'MySuP3R_z3kr3t', // Has to be the same that we used to sign the JWT
userProperty: 'token', // this is where the next middleware can find the encoded data generated in services/auth:generateToken -> 'req.token'
getToken: getTokenFromHeader, // A function to get the auth token from the request
})
export default (req, res, next) => {
const decodedTokenData = req.tokenData;
const userRecord = await UserModel.findOne({ _id: decodedTokenData._id })
req.currentUser = userRecord;
if(!userRecord) {
return res.status(401).end('User not found')
} else {
return next();
}
}
// route
import isAuth from '../middlewares/isAuth';
import attachCurrentUser from '../middlewares/attachCurrentUser';
import ItemsModel from '../models/items';
export default (app) => {
app.get('/inventory/personal-items', isAuth, attachCurrentUser, (req, res) => {
const user = req.currentUser;
const userItems = await ItemsModel.find({ owner: user._id });
return res.json(userItems).status(200);
})
}
// userRole
export default (requiredRole) => {
return (req, res, next) => {
if(req.currentUser.role === requiredRole) {
return next();
} else {
return res.status(401).send('Action not allowed');
}
}
}
// route
import isAuth from '../middlewares/isAuth';
import attachCurrentUser from '../middlewares/attachCurrentUser';
import roleRequired from '../middlwares/roleRequired';
import UserModel from '../models/user';
export default (app) => {
app.post('/auth/signin-as-user', isAuth, attachCurrentUser, roleRequired('super-admin'), (req, res) => {
const userEmail = req.body.email;
const userRecord = await UserModel.findOne({ email: userEmail });
if(!userRecord) {
return res.status(404).send('User not found');
}
return res.json({
user: {
email: userRecord.email,
name: userRecord.name
},
jwt: this.generateToken(userRecord)
})
.status(200);
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment