Skip to content

Commit

Permalink
Merge pull request #50 from fabcodingzest/fix/#46
Browse files Browse the repository at this point in the history
Custom Sign In and Sign Up Implemented using passport.js package. Fixes #46 (Task 1)
  • Loading branch information
iampavangandhi authored Aug 22, 2020
2 parents e87ac41 + 1de1b1f commit 13c8fe1
Show file tree
Hide file tree
Showing 15 changed files with 377 additions and 20 deletions.
9 changes: 9 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 All @@ -87,6 +95,7 @@ app.use(express.static(path.join(__dirname, "/public")));
// Routes
app.use("/", require("./routes/api/index"));
app.use("/auth", require("./routes/api/auth"));
app.use("/user", require("./routes/api/user"));
app.use("/portfolio", require("./routes/api/portfolio"));
app.use("/market", require("./routes/api/market"));
app.use("/view", require("./routes/api/view"));
Expand Down
40 changes: 40 additions & 0 deletions config/passportLocal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');

// Load User model
const User = require('../models/User');

module.exports = function (passport) {
passport.use(
new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
// Match User
User.findOne({
email: email
}).then(user => {
if (!user) {
return done(null, false, { message: 'That email is not registered' })
}

// Match user Password
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
done(null, user);
} else {
return done(null, false, { message: 'That password is incorrect' })
}
})
})
})
)

passport.serializeUser((user, done) => {
done(null, user.id);
});

passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
}
3 changes: 2 additions & 1 deletion middleware/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module.exports = {
if (req.isAuthenticated()) {
return next();
} else {
res.redirect("/");
req.flash('error_msg', 'Password or Email does not match');
res.redirect('/');
}
},
ensureGuest: function (req, res, next) {
Expand Down
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"alphavantage": "^2.1.0",
"autoprefixer": "^9.8.6",
"axios": "^0.19.2",
"bcryptjs": "^2.4.3",
"concurrently": "^5.3.0",
"connect-flash": "^0.1.1",
"connect-mongo": "^3.2.0",
"cross-env": "^7.0.2",
"date-fns": "^2.15.0",
Expand All @@ -48,6 +50,7 @@
"npm": "^6.14.7",
"passport": "^0.4.1",
"passport-google-oauth20": "^2.0.0",
"passport-local": "^1.0.0",
"postcss-cli": "^7.1.1",
"tailwindcss": "^1.6.2",
"uuid": "^8.3.0"
Expand Down
2 changes: 1 addition & 1 deletion public/css/style.css

Large diffs are not rendered by default.

19 changes: 15 additions & 4 deletions public/css/tailwind.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Custom CSS */
/* Main CSS */

Expand All @@ -23,10 +20,24 @@ body {
width: 75vw;
}

@tailwind components;

.symbolicon {
font-size: 72px;
background: -webkit-linear-gradient(#eee, #333);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}

.min-w{
min-width: 400px;
}

@media (max-width:400px){
.min-w{
min-width: 300px;
}
}

@tailwind utilities;
Binary file added public/images/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
78 changes: 78 additions & 0 deletions routes/api/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
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");

// Load User Model
const User = require("../../models/User");

// @desc Sign Up Page
// @route GET /user/signup
// @access Public
router.get('/signup', ensureGuest, (req, res) => {
res.status(200).render('signup', { layout: 'layouts/login' })
})

// @desc Submit Sign Up Form
// @route GET /user/signup
router.post('/signup', (req, res) => {
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))
})
})
}
})
}
})

// @desc Submit Sign In Form
// @route GET /user/signin
router.post('/signin', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/portfolio',
failureRedirect: '/',
failureFlash: true,
})(req, res, next)
})

module.exports = router;
4 changes: 0 additions & 4 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ module.exports = {
100: '#E2E2D5',
200: '#888883',
},


// colors according to design 400->blue 200->red 500->green


tempc: {
100: '#365088',
200: '#E93434',
Expand Down
8 changes: 5 additions & 3 deletions views/layouts/login.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css" integrity="sha256-46r060N2LrChLLb5zowXQ72/iKKNiw/lAmygmHExk/o=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css"
integrity="sha256-46r060N2LrChLLb5zowXQ72/iKKNiw/lAmygmHExk/o=" crossorigin="anonymous" />
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="../css/style.css" />
<title>TradeByte</title>
</head>

<body>
<body class="flex justify-center items-center bg-gray-900 w-full">
<%- body %>

<script src="javascript/script.js"></script>
<script src="javascript/script.js"></script>
</body>

</html>
50 changes: 43 additions & 7 deletions views/login.ejs
Original file line number Diff line number Diff line change
@@ -1,7 +1,43 @@
<h3>**Login/Landing Page**</h3>

<br />

<a href="/auth/google" class="" style="margin-top: 5px;">
<i class="fab fa-google"></i> Login With Google
</a>
<section class="p-1 min-w">
<h2 class="text-blue-200 text-center text-4xl lg:text-6xl font-semibold">TradeByte</h2>
<div class="flex flex-col mb-6 shadow-lg rounded-lg bg-gray-300">
<div class="rounded-t mb-0 px-6 pt-6 pb-2">
<div class="btn-wrapper text-center">
<a href="/auth/google" class="w-full">
<button
class="bg-white active:bg-gray-100 text-gray-800 font-normal px-4 py-2 rounded outline-none focus:outline-none mr-1 mb-1 uppercase shadow hover:shadow-md inline-flex items-center font-bold text-xs justify-center w-full"
type="button" style="transition: all 0.15s ease 0s;"><img alt="..." class="w-5 mr-1"
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" 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" 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>
<div class="text-center mt-6">
<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 In</button>
</div>
</form>
<a href="/user/signup"><button
class="bg-red-900 text-white active:bg-red-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="button" style="transition: all 0.15s ease 0s;">Sign Up</button>
</a>
</div>
</div>
</section>
Loading

0 comments on commit 13c8fe1

Please sign in to comment.