login/register logic

This commit is contained in:
James Shiffer 2020-06-09 21:30:32 -07:00
parent 9d1a95aa0a
commit 0b1babf6ce
No known key found for this signature in database
GPG Key ID: C0DB8774A1B3BA45
5 changed files with 83 additions and 11 deletions

View File

@ -1,3 +1,3 @@
SESSION_SECRET= SESSION_SECRET=
MONGODB_CONN= MONGODB_CONN="mongodb://127.0.0.1:27017/howfeed"
SALT_WORK_FACTOR=10 SALT_WORK_FACTOR=10

View File

@ -23,13 +23,13 @@ const ArticleSchema = new Schema({
ArticleSchema.methods.genSlug = () => this.title.toLowerCase().replace(/\W+/g, '-'); ArticleSchema.methods.genSlug = () => this.title.toLowerCase().replace(/\W+/g, '-');
ArticleSchema.pre('findOne', next => { ArticleSchema.pre('findOne', function (next) {
var article = this; var article = this;
article.views++; article.views++;
next(); next();
}); });
ArticleSchema.pre('save', next => { ArticleSchema.pre('save', function (next) {
var article = this; var article = this;
// only gen the slug if title has been modified (or is new) // only gen the slug if title has been modified (or is new)
if (!article.isModified('title')) return next(); if (!article.isModified('title')) return next();

View File

@ -11,19 +11,16 @@ const UserSchema = new Schema({
}); });
UserSchema.pre('save', next => { UserSchema.pre('save', function (next) {
var user = this; var user = this;
// only hash the password if it has been modified (or is new) // only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next(); if (!user.isModified('password')) return next();
// generate a salt // generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) { bcrypt.genSalt(+SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err); if (err) return next(err);
// hash the password along with our new salt // hash the password along with our new salt
bcrypt.hash(user.password, salt, function(err, hash) { bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err); if (err) return next(err);
// override the cleartext password with the hashed one // override the cleartext password with the hashed one
user.password = hash; user.password = hash;
next(); next();
@ -31,7 +28,7 @@ UserSchema.pre('save', next => {
}); });
}); });
UserSchema.methods.comparePassword = (candidatePassword, cb) => { UserSchema.methods.comparePassword = function (candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) { bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err); if (err) return cb(err);
cb(null, isMatch); cb(null, isMatch);

View File

@ -31,6 +31,7 @@ passport.serializeUser((user, cb) => {
passport.deserializeUser((obj, cb) => { passport.deserializeUser((obj, cb) => {
cb(null, obj); cb(null, obj);
}); });
passport.use(new Strategy((username, password, done) => { passport.use(new Strategy((username, password, done) => {
User.findOne({ username }, (err, user) => { User.findOne({ username }, (err, user) => {
if (err) done(err); if (err) done(err);
@ -53,6 +54,7 @@ passport.use(new Strategy((username, password, done) => {
express() express()
.use(passport.initialize()) .use(passport.initialize())
.use(bodyParser.json()) .use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: true }))
.use(session({ .use(session({
secret: SESSION_SECRET, secret: SESSION_SECRET,
resave: false, resave: false,
@ -63,6 +65,79 @@ express()
}) })
})) }))
.post('/cms/register',
(req, res, next) => {
if (!req.user) {
next();
} else {
res.writeHead(401, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `You are already logged in`
}));
}
}, async (req, res) => {
let { username, password, password_confirm } = req.body;
if (!username || !password || !password_confirm) {
res.writeHead(422, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `You need to supply a username, password, and password_confirm.`
}));
return false;
}
if (password.length < 8) {
res.writeHead(422, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `The password must be at least 8 characters long.`
}));
return false;
}
if (password !== password_confirm) {
res.writeHead(422, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `The password does not match the confirmation.`
}));
return false;
}
try {
const user = await User.findOne({ username: req.body.username });
if (user) {
res.writeHead(401, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `This username is taken.`
}));
return false;
}
// password gets automatically hashed
const newUser = await new User({ username, password });
await newUser.save();
req.login(newUser, err => {
if (err) throw err;
return res.redirect('/cms');
});
} catch (err) {
console.error(err);
res.writeHead(500, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `Internal server error`
}));
return false;
}
}
)
.post('/cms/login', .post('/cms/login',
passport.authenticate('local', { passport.authenticate('local', {
successRedirect: '/cms', successRedirect: '/cms',