Reputation: 59
After creating validators in a separate file to check if an email exists in mongodb users.findOne
no longer works. How do I fix this issue? it was originally in auth.js
and working correctly now it's in validators.js
. The project is so big I'm having trouble figuring out why it's not working. I noticed that I am still able to save users info to DB on sign-up because the save function is still in auth.js
but not able to find users.
index.js
filerequire('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const authRouter = require('./routes/admin/auth')
const app = express();
//route handler request, response
// req receives info
// res sends info back
app.use(bodyParser.urlencoded({ extended: true }));
mongoose.connect('mongodb://localhost:27017/userDB', { useNewUrlParser: true });
app.use(authRouter);
app.listen(3000, () => {
console.log('Listening');
});
auth.js
fileconst express = require('express');
const { check, validationResult } = require('express-validator');
const bcrypt = require('bcrypt');
const saltRounds = 10;
const mongoose = require('mongoose');
const signupTemplate = require('../../views/admin/auth/signup');
const signinTemplate = require('../../views/admin/auth/signin');
const {
requireEmail,
requirePassword,
requirePasswordConfirmation,
} = require('./validators');
const router = express.Router();
const userSchema = new mongoose.Schema({
email: String,
password: String,
passwordConfirmation: String,
});
const User = new mongoose.model('User', userSchema);
router.get('/signup', (req, res) => {
res.send(signupTemplate({ req }));
});
router.post(
'/signup',
[requireEmail, requirePassword, requirePasswordConfirmation],
async (req, res) => {
bcrypt.hash(req.body.password, saltRounds, async (err, hash) => {
const newUser = new User({
email: req.body.email,
password: hash,
});
const errors = validationResult(req);
console.log(errors);
const { email, password, passwordConfirmation } = req.body;
//saves users to db
newUser.save((err) => {
if (err) {
console.log(err);
} else {
console.log('success');
res.send('Account created!!!');
}
});
});
}
);
module.exports = router;
validators.js
(The file from which the code that's having errors was moved from file auth.js
to validators.js
.)
const { check } = require('express-validator');
const User = require('./auth');
module.exports = {
requireEmail: check('email')
.trim()
.normalizeEmail()
.isEmail()
.withMessage('Must be a valid email')
//code below is what is having the issue
.custom(async (email) => {
const existingUser = User.findOne({ email: email });
if (existingUser) {
throw new Error('Email in use');
}
}),
requirePassword: check('password')
.trim()
.isLength({ min: 4, max: 20 })
.withMessage('Must be between 4 and 20 characters'),
requirePasswordConfirmation: check('passwordConfirmation')
.trim()
.isLength({ min: 4, max: 20 })
.withMessage('Must be between 4 and 20 characters')
.custom(async (passwordConfirmation, { req }) => {
if (passwordConfirmation !== req.body.password) {
throw new Error('Passwords must match');
}
}),
};
signup.js
Used to render HTML on screen.
const layout = require('../layout');
const { getError } = require('../../utils')
module.exports = ({ errors }) => {
return layout({
content: `
<div>
<form method="POST">
<input name="email" placeholder="email" />
${getError(errors, 'email')}
<input name="password" placeholder="password" />
${getError(errors, 'password')}
<input name="passwordConfirmation" placeholder="confirm password" />
${getError(errors, 'passwordConfirmation')}
<button>Sign Up</button>
</form>
</div>
`
});
};
Upvotes: 1
Views: 123
Reputation: 135742
You are not exporting User
in auth.js
. You could just do it like:
router.User = User; // added this line
module.exports = router;
Which you would use like: const { User } = require('./auth');
But the likely cleanest approach is just to move the User
declaration to get rid of the cycle you now have between the auth.js
and validation.js
files. E.g.,
// user.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
email: String,
password: String,
passwordConfirmation: String,
});
const User = new mongoose.model('User', userSchema);
module.exports = User;
And use it like in both auth.js
and validators.js
:
const User = require('./user');
Upvotes: 1