diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6c0c1ba --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "attach", + "name": "Attach by Process ID", + "processId": "${command:PickProcess}" + }, + ] +} \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index 729aeb8..8bc5f43 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,6 @@ import express from 'express'; +import {Request, Response, NextFunction} from 'express' import dotenv from 'dotenv'; import mongoose from 'mongoose'; @@ -11,13 +12,13 @@ import path from "path"; import flash from 'connect-flash'; import compression from "compression"; import indexRouter from "./routes/index"; - import cors from 'cors'; const MongoStore = mongo(session); // Create Express server const app = express(); + // view engine setup app.set('views', path.join(__dirname, '../views')); // this is the folder where we keep our pug files app.set('view engine', 'pug'); // we use the engine pug, mustache or EJS work great too @@ -62,6 +63,7 @@ app.use((req, res, next) => { app.use(passport.initialize()); app.use(passport.session()); + // Express Routing URLS app.use('/', indexRouter); diff --git a/src/controllers/authController.ts b/src/controllers/authController.ts index a807bcf..7b6de92 100644 --- a/src/controllers/authController.ts +++ b/src/controllers/authController.ts @@ -1,50 +1,111 @@ import { Request, Response, NextFunction } from "express"; import { validationResult } from "express-validator"; import { User } from "../models/User"; +import passport from 'passport'; +import '../handlers/passport'; export const login = (req: Request, res: Response) => { - res.render('login', { title: 'Login' }) + res.render('login', { title: 'Login' }) } +export const loginForm = async (req: Request, res: Response) => { + try { + const errors = validationResult(req); + + if (!errors.isEmpty()) { + //@ts-ignore + req.flash('error', errors.array().map(err => err.msg)); + res.render('login', { + title: 'Login', + body: req.body, + flashes: req.flash() + }); + } else { + if (!req.body.email || !req.body.password) { + req.flash('error', 'Something is wrong with your input') + } + await passport.authenticate('local', (err:any, user:any) => { + if(err || !user) { + req.flash("error", "Invalid Email address or Password") + res.redirect('/login') + return; + + } + req.login(user, (err) => { + if(err){ + console.log('hello'); + return req.flash('error', 'Authentication failed!'); + } else{ + req.flash("success", "Login Successful!"); + res.redirect('/contact'); + } + + return + + }) + })(req, res) + } + + } catch (e) { + res.redirect('/register'); + throw new Error(e) + } + +} + +exports.isLoggedIn = (req: Request, res: Response, next: NextFunction) => { + // check if the user is authenticated + if (req.isAuthenticated()) { + next(); // carry on to the login + return; + } else { + req.flash('error', 'Oops, you must be logged in to do that!'); + res.redirect('/login'); + } +} export const register = (req: Request, res: Response) => { res.render('register', { title: 'Register' }) - } - -export const registerForm = async (req: Request, res: Response, next: NextFunction ) => { +} + +export const registerForm = async (req: Request, res: Response, next: NextFunction) => { try { - const errors = validationResult(req); - - if (!errors.isEmpty()) { - //@ts-ignore - req.flash('error', errors.array().map(err => err.msg)); - res.render('register', { - title: 'Register', - body: req.body, - flashes: req.flash() - }); - }else { - const user = new User({ email: req.body.email }); - await User.register(user, req.body.password, function(err, user){ - - if(err){ - req.flash(`error`, `${err.message}`); - res.redirect('/register') - }else{ - req.flash(`success`, `${req.body.email} has been registered! Please Login`); - res.redirect('/login') - } - }) - } - + const errors = validationResult(req); + + if (!errors.isEmpty()) { + //@ts-ignore + req.flash('error', errors.array().map(err => err.msg)); + res.render('register', { + title: 'Register', + body: req.body, + flashes: req.flash() + }); + } else { + const user = new User({ email: req.body.email }); + await User.register(user, req.body.password, function (err, user) { + + if (err) { + req.flash(`error`, `${err.message}`); + res.redirect('/register') + } else { + passport.authenticate('local', { + session: true + })(req, res, () => { + req.flash(`success`, `${req.body.email} has been registered! Please Login`); + res.redirect('/login') + }) + + } + }) + } + } catch (e) { - - res.redirect('/register'); - throw new Error(e) + + res.redirect('/register'); + throw new Error(e) } - - } - \ No newline at end of file + +} diff --git a/src/handlers/passport.ts b/src/handlers/passport.ts new file mode 100644 index 0000000..8194c16 --- /dev/null +++ b/src/handlers/passport.ts @@ -0,0 +1,16 @@ +import passport from 'passport'; + + +import { User } from "../models/User"; +import passportLocal from 'passport-local'; +const LocalStrategy = passportLocal.Strategy; + + +passport.use(new LocalStrategy({ + usernameField: 'email', + passwordField: 'password' +}, + User.authenticate())); + +passport.serializeUser(User.serializeUser()); +passport.deserializeUser(User.deserializeUser()); \ No newline at end of file diff --git a/src/routes/index.ts b/src/routes/index.ts index 9bf4b1c..1b79e9b 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -36,6 +36,25 @@ router.post('/contact', router.get('/login', authController.login) ; +router.post('/login', + [ + /**Check the form and validated it before submitting */ + check('email', 'Email is not valid').isEmail(), + check('email').normalizeEmail({ + gmail_remove_subaddress: false, // correct + outlookdotcom_remove_subaddress: false, + gmail_remove_dots: false, + icloud_remove_subaddress: false, + + }), + + body("password", "Password cannot be blank").not().isEmpty(), + check('g-recaptcha-response', "Please validate your Google reCAPTCHA").not().isEmpty() + + ],(req: Request, res: Response) => { + authController.loginForm(req, res); + }); + router.get('/register', authController.register);