Account CRUD - pmvdbijl7/matching-app GitHub Wiki
On the login page there is an option to Sign up if the user hasn't already made an account. From there they can first fill a form just to create an account, after that the user is asked to login with the credentials they gave while creating an account.
The function in the authController used for the client's GET request to send Create Account the page:
// Get Register Page
const registerGet = (req, res) => {
res.render('pages/auth/register', { title: 'Create an Account' });
};
The function in the authController used for the client's POST request to save the Create Account form data in the database:
// Register New User
const registerPost = async (req, res) => {
// Validate Register Data
const { error } = registerValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
// Hash Password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt);
// Create New User
const user = new User({
name: req.body.name,
email: req.body.email,
password: hashedPassword,
});
user.save()
.then((user) => {
// Redirect to Home
res.redirect('/signin');
})
.catch((err) => {
res.send(err.message);
});
};
When the user is logged in for the first time and the profile data hasn't been added to the database they will be directed to the page were you can enter profile data, like their birthdate or residence.
The function in the authController used for the client's GET request to send the Create Profile page:
// Get Preferences Page
const preferencesGet = (req, res) => {
Genre.find((err, genres) => {
res.render('pages/auth/preferences', {
title: 'Preferences',
genders: ['Male', 'Female', 'Non-binary'],
interests: ['Men', 'Women', 'Everyone'],
genres: genres
});
});
};
The function in the authController used for the client's POST request to save the Create Profile form data in the database:
// Update Preferences
const preferencesPost = (req, res) => {
// Validate Preferences Data
const { error } = preferencesValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
// Get Authenticated User
const authUser = req.user._id;
// Update User
User.findByIdAndUpdate(authUser, {
gender: req.body.gender,
birthdate: req.body.birthdate,
residence: req.body.residence,
interested_in: req.body.interested_in,
biography: req.body.biography,
genres: req.body.genres
})
.then((user) => {
res.redirect('/');
})
.catch((err) => {
res.send(err.message);
});
};
On the home page of the application other users their profile data is read from the database and sent to the client.
The function in the homeController used for the client's GET request to send the Home page with data from other accounts:
// Get Home page with data from other users
const homeGet = (req, res) => {
const authUser = req.user._id;
User.find((err, docs) => {
if (!err) {
res.render('pages/home', {
title: 'Home',
users: docs,
authUser: authUser,
headerLeft: { path: '/logout', text: 'Log out' },
headerRight: { path: '/matches', text: 'Matches' },
});
} else {
console.log('Error in retrieving profile data: ' + err);
}
});
};
On this page users can edit and update their account and profile data with a form.
The function in the accountController used for the client's GET request to send the Edit Account page with the user's current set data:
// Get account edit page
const editGet = (req, res) => {
const authUser = req.user._id;
Genre.find((err, genres) => {
User.findById(authUser).then((user) => {
res.render('pages/account/edit', {
title: 'Edit your profile',
user: user.toJSON(),
headerLeft: { path: '/account/profile', text: 'Back' },
optionsRight: [{ path: '/account/edit-password', text: 'Edit password' },{ path: '/account/delete', text: 'Delete' }],
interests: ['Men', 'Women', 'Everyone'],
genders: ['Male', 'Female', 'Non-binary'],
genres: genres
});
});
});
};
Part of the EJS code that inserts the currently saved gender data in the form where the corresponding radio button is checked
:
<%for(i=0; i < genders.length; i++){ %>
<div class="radio-group">
<input type="radio" id="<%= genders[i] %>" name="gender" value="<%= genders[i] %>" <% if (user.gender == genders[i]){ %> checked <% } %> required>
<label for="<%= genders[i] %>">
<%= genders[i] %>
</label>
</div>
<% } %>
The function in the accountController used for the client's POST request to update the current data in the database with the new Edit Profile form data:
// Update account profile data
const editPost = (req, res) => {
const authUser = req.user._id;
// Validate Edit data
const { error } = editValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
User.findById(authUser).then((result) => {
User.findByIdAndUpdate(authUser, {
profile_image: req.file ? req.file.filename : result.profile_image,
name: req.body.name,
email: req.body.email,
gender: req.body.gender,
birthdate: req.body.birthdate,
residence: req.body.residence,
interested_in: req.body.interested_in,
biography: req.body.biography,
genres: req.body.genres,
}).then((updatedUser) => {
res.redirect('/account/profile');
});
});
};
For the user to delete their account they can enter a form with their password twice and confirm for deletion.
The function in the accountController used for the client's GET request to send the Delete Account page:
// Get delete account page
const deleteGet = (req, res) => {
const authUser = req.user._id;
User.findById(authUser).then((user) => {
res.render('pages/account/delete', {
title: 'Advanced account settings',
user: user.toJSON(),
headerLeft: { path: '/account/profile', text: 'Back' },
});
});
};
The function in the accountController used for the client's POST request to send the password and the repeated password data to the server and check if their both the same, if this is true the account will be deleted:
// Delete account data
const deletePost = async (req, res) => {
const authUser = req.user._id;
const { error } = deleteValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
// Check if Password is Correct
const user = await User.findById(authUser).exec();
console.log(req.body.password, user.password);
const validPass = await bcrypt.compare(req.body.password, user.password);
if (!validPass) return res.status(400).send("Your password isn't valid.");
User.findByIdAndRemove(authUser, (error, doc) => {
if (!error) {
res.redirect('/logout');
} else {
console.log(
'Error: No or invalid profile id given. Profile id: ' +
req.body._id
);
}
});
};