Skip to content

Commit

Permalink
Custom Sign In and Sign Up implemented using iampavangandhi#46
Browse files Browse the repository at this point in the history
  • Loading branch information
fabcodingzest committed Aug 21, 2020
1 parent c9a6635 commit b1c9bc9
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 17 deletions.
8 changes: 8 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ const session = require("express-session");
const mongoose = require("mongoose");
const MongoStore = require("connect-mongo")(session);
const connectDB = require("./config/db");
const flash = require('connect-flash');

// Load config
dotenv.config({ path: "./config/config.env" });

// Passport config
require("./config/passport")(passport);
require("./config/passportLocal")(passport);

// DB Connected
connectDB();
Expand Down Expand Up @@ -75,9 +77,15 @@ app.use(
app.use(passport.initialize());
app.use(passport.session());

// Connect Flash
app.use(flash())

// Set Global variables
app.use(function (req, res, next) {
res.locals.user = req.user || null;
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});

Expand Down
2 changes: 1 addition & 1 deletion middleware/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
if (req.isAuthenticated()) {
return next();
} else {
req.flash('error_msg', 'Please log in to view that resource');
req.flash('error_msg', 'Password or Email does not match');
res.redirect('/');
}
},
Expand Down
8 changes: 8 additions & 0 deletions routes/api/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ router.get(
}
);

router.post('/signin', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/portfolio',
failureRedirect: '/',
failureFlash: true
})(req, res, next)
})

// @desc Logout user
// @route /auth/logout
router.get("/logout", (req, res) => {
Expand Down
69 changes: 64 additions & 5 deletions routes/api/user.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,73 @@
const express = require("express");
const router = express.Router();
const passport = require("passport")
const bcrypt = require("bcryptjs");
const {v4: uuidv4} = require("uuid");
const { ensureGuest } = require("../../middleware/auth");

router.get('/signup', (req, res) => {
// Load User Model
const User = require("../../models/User");

// Sign Up Page
router.get('/signup', ensureGuest, (req, res) => {
res.status(200).render('signup', { layout: 'layouts/login' })
})

// Submit Sign Up Form
router.post('/signup', (req, res) => {

console.log('signup')
const { firstName, lastName, password1, password2, email } = req.body;
let errors = [];

if (!firstName || !lastName || !password1 || !password2 || !email) {
errors.push({ msg: 'Please enter all fields' });
}
if (password1 !== password2) {
errors.push({ msg: 'Passwords do not match' })
}
if (password1.length < 6) {
errors.push({ msg: 'Password must be longer than 6 characters' })
}

if (errors.length > 0) {
res.render('signup', { layout: 'layouts/login', errors, firstName, lastName, password1, password2 })
} else {
User.findOne({ email: email }).then((user) => {
if (user) {
errors.push({ msg: 'Email already exists' })
res.render('signup', { layout: 'layouts/login', errors, firstName, lastName, password1, password2 })
} else {
const newUser = new User({
googleId: uuidv4(),
displayName: `${firstName} ${lastName}`,
firstName,
lastName,
email,
image: 'https://t3.ftcdn.net/jpg/00/64/67/52/240_F_64675209_7ve2XQANuzuHjMZXP3aIYIpsDKEbF5dD.jpg',
password: password1,
balance: 10000,
})

bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser.save().then(user => {
req.flash('success_msg', 'You are now registered and can log in')
res.status(200).redirect('/')
}).catch((err) => console.log(err))
})
})
}
})
}
})
router.post('/signin', (req, res) => {


router.post('/signin', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/portfolio',
failureRedirect: '/',
failureFlash: true,
})(req, res, next)
})

module.exports = router;
5 changes: 3 additions & 2 deletions views/login.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@
src="/images/google.png">Sign in with Google</button>
</a>
</div>
<%- include('./partials/_messages') %>
<hr class="mt-6 border-b-1 border-gray-400">
</div>
<div class="flex-auto px-4 lg:px-10 pb-10 pt-0">
<div class="text-gray-500 text-center mb-3 font-bold"><small>Or sign in with credentials</small></div>
<form action="/user/signin" method="POST">
<div class="relative w-full mb-3">
<label class="block uppercase text-gray-700 text-xs font-bold mb-2" for="grid-password">Email</label>
<input type="email"
<input type="email" name="email"
class="px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
placeholder="Email" style="transition: all 0.15s ease 0s;">
</div>
<div class="relative w-full mb-3">
<label class="block uppercase text-gray-700 text-xs font-bold mb-2" for="grid-password">Password</label>
<input type="password"
<input type="password" name="password"
class="px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
placeholder="Password" style="transition: all 0.15s ease 0s;">
</div>
Expand Down
103 changes: 103 additions & 0 deletions views/partials/_messages.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<% if(typeof errors != "undefined") { %>
<% errors.forEach(function(error) { %>
<div
class="w-full flex items-center justify-between bg-yellow-200 text-yellow-700 border border-yellow-600 p-2 rounded-lg mt-1">
<div class="item flex items-center">
<div slot="avatar">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-alert-octagon w-5 h-5 mx-2">
<polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon>
<line x1="12" y1="8" x2="12" y2="12"></line>
<line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>
</div>
<p class=""><%= error.msg %> </p>
</div>
<div onClick="this.parentNode.remove()">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-x cursor-pointer hover:text-yellow-500 rounded-full w-5 h-5 ml-2">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</div>
</div>
<% }); %>
<% } %>

<% if(success_msg != "") { %>
<div
class="w-full flex items-center justify-between bg-green-200 text-green-700 border border-green-600 p-2 rounded-lg mt-1">
<div class="item flex items-center">
<div slot="avatar">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-alert-octagon w-5 h-5 mx-2">
<polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon>
<line x1="12" y1="8" x2="12" y2="12"></line>
<line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>
</div>
<p class=""><%= success_msg %> </p>
</div>
<div onClick="this.parentNode.remove()">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-x cursor-pointer hover:text-green-500 rounded-full w-5 h-5 ml-2">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</div>
</div>
<% } %>

<% if(error_msg != "") { %>
<div class="w-full flex items-center justify-between bg-red-200 text-red-700 border border-red-600 p-2 rounded-lg mt-1">
<div class="item flex items-center">
<div slot="avatar">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-alert-octagon w-5 h-5 mx-2">
<polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon>
<line x1="12" y1="8" x2="12" y2="12"></line>
<line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>
</div>
<p class=""><%= error_msg %> </p>
</div>
<div onClick="this.parentNode.remove()">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-x cursor-pointer hover:text-red-500 rounded-full w-5 h-5 ml-2">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</div>
</div>
<% } %>

<% if(error != "") { %>
<div class="w-full flex items-center justify-between bg-red-200 text-red-700 border border-red-600 p-2 rounded-lg mt-1">
<div class="item flex items-center">
<div slot="avatar">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-alert-octagon w-5 h-5 mx-2">
<polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon>
<line x1="12" y1="8" x2="12" y2="12"></line>
<line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>
</div>
<p class=""><%= error %> </p>
</div>
<div onClick="this.parentNode.remove()">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" fill="none" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-x cursor-pointer hover:text-red-500 rounded-full w-5 h-5 ml-2">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</div>
</div>
<% } %>
26 changes: 17 additions & 9 deletions views/signup.ejs
Original file line number Diff line number Diff line change
@@ -1,41 +1,49 @@
<section class="p-4" style="min-width: 300px;">
<h2 class="text-blue-200 text-center text-4xl lg:text-5xl font-semibold">TradeByte</h2>
<div class="flex flex-col my-6 shadow-lg rounded-lg bg-gray-300">
<div class="rounded-t mb-0 px-6 py-6 text-lg font-bold w-full flex justify-center items-center">
Sign Up for&nbsp; <a href="/" class="text-blue-700">TradeByte</a>
<div class="rounded-t mb-0 px-6 py-6 text-lg font-bold w-full flex justify-center items-center flex-col">
<p>Sign Up for&nbsp; <a href="/" class="text-blue-700">TradeByte</a></p>
<%- include('./partials/_messages') %>
</div>
<div class="flex-auto px-4 lg:px-10 py-8 pt-0">
<form method="POST" action="/user/signup">
<div class="relative flex items-center justify-center w-full mb-3">
<div class="relative w-1/2 mr-1">
<label class="block uppercase text-gray-700 text-xs font-bold mb-2" for="grid-password">First Name</label>
<input type="text" required
<input type="text" required value="<%= typeof firstName != 'undefined' ? firstName : '' %>"
class="px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
placeholder="First Name" style="transition: all 0.15s ease 0s;">
name="firstName" placeholder="First Name" style="transition: all 0.15s ease 0s;">
</div>
<div class="relative w-1/2 ml-1">
<label class="block uppercase text-gray-700 text-xs font-bold mb-2" for="grid-password">Last Name</label>
<input type="text" required
<input type="text" required name="lastName" value="<%= typeof lastName != 'undefined' ? lastName : '' %>"
class="px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
placeholder="Last Name" style="transition: all 0.15s ease 0s;">
</div>
</div>
<div class="relative w-full mb-3">
<label class="block uppercase text-gray-700 text-xs font-bold mb-2" for="grid-password">Email</label>
<input type="email"
<input type="email" name="email" value="<%= typeof email != 'undefined' ? email : '' %>"
class="px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
placeholder="Email" style="transition: all 0.15s ease 0s;" required>
</div>
<div class="relative w-full mb-3">
<label class="block uppercase text-gray-700 text-xs font-bold mb-2" for="grid-password">Password</label>
<input type="password"
<input type="password" name="password1" value="<%= typeof password1 != 'undefined' ? password1 : '' %>"
class="px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
placeholder="Password" style="transition: all 0.15s ease 0s;" required>
</div>
<div class="relative w-full mb-3">
<label class="block uppercase text-gray-700 text-xs font-bold mb-2" for="grid-password">Enter your Password
again</label>
<input type="password" name="password2" value="<%= typeof password2 != 'undefined' ? password2 : '' %>"
class="px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
placeholder="Password" style="transition: all 0.15s ease 0s;" required>
</div>
<div class="text-center mt-4">
<button
class="bg-gray-900 text-white active:bg-gray-700 text-sm font-bold uppercase px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 w-full"
type="submit" style="transition: all 0.15s ease 0s;">Sign Up</button>
class="bg-gray-900 text-white active:bg-gray-700 text-sm font-bold uppercase px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 w-full"
type="submit" style="transition: all 0.15s ease 0s;">Sign Up</button>
<p class="mt-2">Go back to <a href="/" class="text-red-600">Login</a></p>
</div>
</form>
Expand Down

0 comments on commit b1c9bc9

Please sign in to comment.