Extra Features Added to Previously Built 2nd Semester Exam App.
The features added to the application after the exam was the Open Authorization feature (OAuth) with auth0 using Google and GitHub as the third-party authorization service apps. The reason for this is to simply enable a more convenient onboarding procedure for users of the application.
Introduction
If you have ever wondered or thought about the inner workings behind any typical blogging application you see, then you need not look any further.
This article is meant to provide a brief exposition of the most essential features of any blogging app with Nodejs/ExpressJs server-side technology.
Prerequisites
It will be assumed that the reader of this article has a basic understanding of the fundamentals of Server-side development & Nodejs fundamentals. Familiarity with MongoDB basic would be an advantage not necessary.
Project Setup
Kickstart the project by creating a folder from your local PC.
mkdir node-blogging-app && cd node-blogging-app
Initialize the dependency manager and install every needful dependency.
npm init --y
npm i express dotenv mongoose jsonwebtoken express-validator passport passport-jwt
Install the needful development package as they would not be required to run production-grade applications.
npm i -D nodemon
Set up the database connection in the javascript file db.js
const mongoose = require('mongoose');
require('dotenv').config();
const DB_URL = process.env.DB_URL;
const connectToDatabase = () => {
mongoose.connect(DB_URL);
mongoose.connection.on('connected', async () => {
console.log('Database now Connected...');
});
mongoose.connection.on('error', (err) => {
console.log('An error occurred while connecting to MongoDB');
console.log(err);
});
};
module.exports = { connectToDatabase };
Next, we define our models.
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const { Schema } = mongoose;
const userSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
first_name: {
type: String,
required: true,
},
last_name: {
type: String,
required: true,
},
username: {
type: String,
trim: true,
},
photo: {
type: String,
trim: true,
},
});
userSchema.pre('save', async function(next) {
let user = this;
const hash = await bcrypt.hash(this.password, 10);
this.password = hash;
next();
});
userSchema.methods.isValidPassword = async function(password) {
const user = this;
return await bcrypt.compare(password, user.password);
};
const User = mongoose.model('User', userSchema);
module.exports = User;
Prepare all your auth controllers as they ought to.
const User = require('../models/user.models');
require('dotenv').config();
const jwt = require('jsonwebtoken');
const passport = require('passport');
const JWT_STRING = process.env.JWT_SECRET;
const registerUser = async (req, res) => {
const userInfo = req.user;
const body = { id: req.user._id, email: req.user.email };
const token = jwt.sign({ user: body }, JWT_STRING, { expiresIn: '1h' });
res.status(200).json({
msg: 'Endeavour successful! You have just registered...',
data: { userInfo, token },
});
};
const loginUser = (req, res, next) => {
passport.authenticate('login', async (err, user, info) => {
try {
if (err) {
return next(err);
}
if (!user) {
const err = new Error('This user does not exist!');
return next(err);
}
req.login(user, { session: false }, async (err) => {
if (err) return next(err);
const body = { id: user._id, email: user.email };
// const token = jwt.sign({ user: body }, JWT_STRING, { expiresIn: '1h' });
return res.json({
status: 'success',
msg: 'Login Successful',
data: user,
});
});
} catch (err) {
return next(err);
}
})(req, res, next);
};
// const seedUsers = async () => {
// try {
// await User.insertMany([
// { name: 'ayomide', password: 'lovely', user_type: 'user' },
// { name: 'ayomikun', password: 'love', user_type: 'user' },
// { name: 'ayobami', password: 'lovingly', user_type: 'admin' },
// { name: 'ayokunumi', password: 'loveful', user_type: 'user' },
// { name: 'ayodimeji', password: 'loving', user_type: 'user' },
// ]);
// } catch (err) {
// throw new Error('Oops! An error occurred...');
// }
// };
module.exports = { registerUser, loginUser };
View both deployed and Github links below