Keep getting CANNOT POST /login everytime i login - mysql

I got the codes from a tutorial, seems to work fine until I made routers since I'm trying to create an E-commerce website with a login system.
This is my index.js code
const express = require('express');
const app = express();
const prodRouter = require('./server/routes/prodRouter');
const loginRouter = require('./server/routes/loginRouter');
const regRouter = require('./server/routes/regRouter');
const contRouter = require('./server/routes/contRouter');
const checkRouter = require('./server/routes/checkRouter');
const profRouter = require('./server/routes/profRouter');
const path = require('path'); const port = 3500;
app.use(express.static('public'));
app.set('views', path.join(__dirname, 'server/views'));
app.set('viewengine', 'pug');
app.use('/prod', prodRouter);
app.use('/login',loginRouter);
app.use('/reg', regRouter);
app.use('/cont',contRouter);
app.use('/check', checkRouter);
app.use('/profile',profRouter);
app.get('/', (req, res) =>{res.render('Home.pug', {}); });
app.listen(port, (err) => { // arrow function feature from ES6 if(err){ console.log(err); }
console.log(`Listening to port ${port}!`); });
and loginRouter.js
const express = require('express'); const router = express.Router();
const app = express();
const mysql = require('mysql');
const server = require('http').createServer(app);
bodyParser = require('body-parser');
const connection = mysql.createConnection({
host: 'localhost',
database: 'login',
user: 'root',
password: '',
});
users = []; connections = [];
router.get('/', (req, res) => {
res.render('login', {});
});
app.use(bodyParser.urlencoded({
extended: true
});
app.use(bodyParser.json());
connection.connect();
app.post('/', function(req, res){
var email= req.body.email;
var password = req.body.password;
connection.query('SELECT * FROM user WHERE email = ?',[email],function (error, results, fields) {
if (error) {
// console.log("error ocurred",error);
res.send({
"code":400,
"failed":"error ocurred"
})
}else{
// console.log('The solution is: ', results);
if(results.length >0){
if([0].password == password){
return res.redirect('/profile');
}else{
res.send({
"code":204,
"success":"Email and password does not match"
});
}
}else{
res.send({
"code":204,
"success":"Email does not exits"
});
}
}
});
enter code here
});
module.exports = router;
my pug form:
form#login-form(method='post')
fieldset.input
p#login-form-username
label(for='modlgn_username') Email
input#modlgn_username.inputbox(type='text', name='email', size='18', required)
p#login-form-password
label(for='modlgn_passwd') Password
input#modlgn_passwd.inputbox(type='text', name='password', size='18', required)
.remember
p#login-form-remember
label(for='modlgn_remember')
a(href='#') Forget Your Password ?
input.button(type='submit', value='Sign In')
I'm pretty sure I did something wrong with the router, because every time I login, I keep getting CANNOT POST instead of going to the profile page.
Any help would be greatly appreciated.
EDIT: I added my pug code for form.
EDIT: the problem only occurs if the login page is not the main page.
example:
login page > *logs in > profile - no problem
home page > login page > *logs in > profile - error

This is happening because you don't have an action on your form (see this article for details). When you don't have an action the form is submitted to the URL it lives at, so if you POST on your home page without an action the post will go to /home.
Change the form element to look like this:
form#login-form(method='post' action='/login')

Related

TypeError: req.getConnection is not a function

strong textI'm trying to create my first CRUD with Mysql, Node js and Express.js following a tutorial.
The problem is, in the video this code works, but in my visual give the error aboyt getConnection is not a function.
If anyones can help, I'll apreciate.
Server.js
const express = require("express");
const mysql = require("mysql");
const myconn = require("express-myconnection");
const routes = require("./routes");
const app = express();
const serverPort = process.env.PORT || 9000;
const dbOptions = {
host: "localhost",
user: "3306",
password: "123456",
database: "catalog",
};
//server running
app.listen(serverPort, () => {
console.log(`App listening at ${serverPort}`);
});
//routes
app.get("/", (req, res) => {
res.send("welcome to my API");
});
app.use("/phones", routes);
Routes.js
const express = require("express");
const routes = express.Router();
const myconn = require("express-myconnection");
routes.get("/", (req, res) => {
req.getConnection((err, conn) => {
if (err) return res.send(err);
conn.query("SELECT * FROM phones", (err, rows) => {
if (err) return res.send(err);
res.json(rows);
});
});
});
module.exports = routes;
UPDATE : solved.
IT WAS A POINT after catalog and I didn't write the port correctly!!!!!

Where to place code to show data from MySQL to Handlebars?

Goal:
I am aiming to teach myself how to use Node JS, MySQL and express.
I'm struggling to understand where to place my code for loading MySQL data into HTML.
Let me show you the whole code.
app.js
var express = require('express');
var mysql = require('mysql');
var dotenv = require('dotenv');
var path = require('path');
var cookieParser = require('cookie-parser');
dotenv.config({path: './.env'});
var app = express();
// Connection to MySQL
var db = mysql.createConnection({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE
});
db.connect(function(error) {
if(error) {
console.log(error);
}
else{
console.log("Connected");
}
});
// Parse URL-Encoded bodies
app.use(express.urlencoded({extended: false}));
// Parse JSON bodies
app.use(express.json());
// Initialize a cookie
app.use(cookieParser());
// View engine to control HTML
app.set('view engine', 'hbs');
// Public dir
var publicDir = path.join(__dirname, './public');
app.use(express.static(publicDir));
// Define routes
app.use('/', require('./routes/pages'));
app.use('/auth', require('./routes/auth'));
app.listen(3000, function() {
console.log("Server is running on port 3000");
});
routes/pages.js
var express = require('express');
var authController = require('../controllers/auth');
var router = express.Router();
// Home
router.get("/", authController.isLoggedIn, function(req,res) {
res.render("index", {
user: req.user
});
});
// Register
router.get("/register", function(req, res) {
res.render("register");
});
// Login
router.get("/login", function(req, res) {
res.render("login");
});
// Profile
router.get('/profile', authController.isLoggedIn, function(req, res) {
if(req.user) {
res.render('profile', {
user: req.user
});
}
else {
res.redirect('login');
}
});
// Forum
router.get('/forums', authController.isLoggedIn, function(req, res) {
if(req.user) {
res.render('forums');
} else {
res.redirect('login');
}
});
// English Division //
// Premier League
router.get('/Leagues/EnglishDivision', authController.isLoggedIn, function(req, res) {
if(req.user) {
res.render('PremierLeague');
} else {
res.redirect('../../login');
}
});
module.exports = router;
routes/auth.js
var express = require('express');
var authController = require('../controllers/auth');
var router = express.Router();
// Register
router.post("/register", authController.register);
// Login
router.post("/login", authController.login);
// Logout
router.get('/logout', authController.logout);
module.exports = router;
controllers/auth.js
var mysql = require('mysql');
var jwt = require('jsonwebtoken');
var bcrypt = require('bcryptjs');
var {promisify} = require('util');
// Connection to MySQL
var db = mysql.createConnection({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE
});
// Register function
exports.register = function(req, res) {
console.log(req.body);
var {name, email, password, passwordConfirm} = req.body;
db.query("SELECT email FROM users WHERE email = ?", [email], function(error, result) {
if(error){
console.log(error);
}
if(result.length > 0) {
return res.render('register', {
message: 'That email is already in use'
})
} else if(password !== passwordConfirm) {
return res.render('register', {
message: 'Passwords do not match'
});
}
let hashedPassword = bcrypt.hashSync(password, 8);
console.log(hashedPassword);
// Insert user details into MySQL
db.query('INSERT INTO users set ?', {name: name, email: email, password: hashedPassword, dateJoined: new Date()}, function(error, result) {
if(error) {
console.log(error);
} else {
console.log(result);
return res.render('register', {
message: 'User registered'
});
}
});
});
}
// Login function
exports.login = function(req, res) {
try {
var {email, password} = req.body;
if(!email || !password) {
return res.status(400).render('login', {
message: 'Please provide an email and password'
});
}
db.query('SELECT * FROM users WHERE email = ?', [email], async function(error, result) {
console.log(result);
if(!result.length > 0 || !(await bcrypt.compare(password, result[0].password))) {
res.status(401).render('login', {
message: 'The email or password is incorrect'
});
}
else {
var id = result[0].id;
// Create a token
var token = jwt.sign({id}, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN
});
console.log("The token is " + token);
// Create a cookie
var cookieOptions = {
expires: new Date(
Date.now() + process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true
}
// Set up a cookie
res.cookie('jwt', token, cookieOptions);
res.status(200).redirect("/");
}
});
} catch (error) {
console.log(error);
}
}
// Check if logged in
exports.isLoggedIn = async function(req, res, next) {
console.log(req.cookies);
if(req.cookies.jwt){
try {
// Verify the token
var decoded = await promisify(jwt.verify)(req.cookies.jwt, process.env.JWT_SECRET);
console.log(decoded);
// Check if user exist
db.query("SELECT id, name, email, password, date_format(datejoined, '%d/%m/%Y') as dateJoined FROM users WHERE id = ?", [decoded.id], function(error, result) {
console.log(result);
// If no result
if(!result) {
return next();
}
req.user = result[0];
return next();
});
}
catch (e) {
console.log(e);
return next();
}
} else{
next();
}
}
// Logout function
exports.logout = async function(req, res) {
res.clearCookie('jwt');
res.status(200).redirect('/');
}
Question
In my .hbs file called PremierLeague I'd like to load MySQL data in HTML format. Where in the code below I need to start?
Desired goal:
This is when the user clicks into view premier league
Foreach record in MySQL I'd like to add a new card for each record. I know how to use HandleBars {{some.data}}.
I just don't get where I code the query?
Does it needs to be in a controller or can it be in in the router.get(...?
Also how do I use {{#foreach}} correctly ?
You don't need any other specific controller, the right place to code the query is actually the route itself.
But before entering the core of your question, let's talk a while about your code.
I can see you are performing connection to database more than once, you could add database dedicated controller, something like:
controllers/db.js
var mysql = require('mysql');
var dotenv = require('dotenv');
dotenv.config({path: './.env'});
// Connection to MySQL
var db = mysql.createConnection({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE
});
function connect(done) {
db.connect(done);
}
module.exports = { db: db, connect: connect };
this let you access to the database instance from every file with just one line:
var db = require('./controllers/db').db;
than you could use the connect function in your app:
app.js
var express = require('express');
var db = require(./controllers/db);
var path = require('path');
var cookieParser = require('cookie-parser');
// set up your server
var app = express();
// Parse URL-Encoded bodies
app.use(express.urlencoded({extended: false}));
// Parse JSON bodies
app.use(express.json());
// Initialize a cookie
app.use(cookieParser());
// View engine to control HTML
app.set('view engine', 'hbs');
// Public dir
var publicDir = path.join(__dirname, './public');
app.use(express.static(publicDir));
// Define routes
app.use('/', require('./routes/pages'));
app.use('/auth', require('./routes/auth'));
// finally run your server only if you can connect to the database
db.connect(function(error) {
if(error) return console.log("Error connecting to the database:", error);
app.listen(3000, function() {
console.log("Server is running on port 3000");
});
});
you could also simplify you controllers/auth.js removing database connection stuff and using only the line to require your database controller.
Finally you can code your query:
routes/pages.js
var express = require('express');
var authController = require('../controllers/auth');
var db = require('../controllers/db').db;
var router = express.Router();
// Omissis... other routes
// Premier League
router.get('/Leagues/EnglishDivision', authController.isLoggedIn, function(req, res) {
// a good practice is first to handle possible exit cases to reduce nesting levels
if(! req.user) return res.redirect('../../login');
// this is actually the right place to perform queries
db.query('SELECT ...', [...], function(error, results) {
// once again first possible exit cases
if(error) return res.status(500).end(error.message)
res.render('PremierLeague', { results: results });
});
});
module.exports = router;
Last in your PremierLeague.hbs file you can handle the results in a #foreach directive.
Just pass your data when you render the view
router.get('/Leagues/EnglishDivision', authController.isLoggedIn, function(req, res) {
if(req.user) {
connection.query('SELECT * FROM EnglishDivision',function (err,results) {
if (err) throw err;
res.render('PremierLeague',{data: results});
});
} else {
res.redirect('../../login');
}
});
then in the .hbs file
{{#each data}}
<div class="card">
<h3>{{this.someData}}</h3>
<h2>{{this.someData}}</h2>
</div>
{{/each}}

Express POST Request Appears Undefined in MySQL Database

When I submit form data from HTML form, all values added to MySQL database appear as Undefined. I console.logged req.body and it is shown correctly.
The HTML form in client is a normal form (Important to say that I don't send multipart/form-data, no "enctype" attribute in HTML). I've been looking all over the internet to figure it out what am I doing wrong. I'd like to know what is the problem.
Here's my backend code:
const express = require('express');
const bodyParser = require('body-parser'); // Required for POST requests to work
const mysql = require('mysql');
const path = require('path');
const cors = require('cors');
const app = express();
const port = 1000;
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(cors());
const DB = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '1',
database: 'onlineshop',
});
DB.connect(err => {
if (err) throw err
console.log("Connected to MySQL database")
});
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.post('/register', (req, res) => {
let newCustomer = req.body;
let q = `INSERT INTO customers (firstname, lastname, email, password, city, street, role)
VALUES ("${newCustomer.firstname}",
"${newCustomer.lastname}",
"${newCustomer.email}",
"${newCustomer.password}",
"${newCustomer.city}",
"${newCustomer.address}",
0`
const result = DB.query(q, (err,result)=>{
if (err) throw err
res.json(result)
})
});
app.listen(port, console.log('App listening at port 1000'));
Thank you!
Is your POST from an HTML form?
If so you need the urlencoded body parser, and you only have the json one. The payload for POSTs from HTML forms is in the urlencoded format. (You can see it in the Network tab of devtools if you're curious.)
const bodyParser = require( 'body-parser' )
app.use( bodyParser.json() )
app.use( bodyParser.urlencoded( { extended: true } ) ) /* add this line */

nodejs mysql post method return an old unknow record

i have problem with post method in mysql node js, when i post the request in postman it return an old record i don't know where come from.
in the first i used Get method and it worked very well but when i changed the method to Post i found thid problem.
i use this request for a form in react app i think the problem is not in the form because i tried the request in postman before try it in the app.
const express = require('express');
const cors = require('cors');
const mysql = require('mysql');
const bodyParser = require('body-parser')
const app = express();
// Connection Mysql
const selectQuery = 'SELECT * FROM userstab';
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'nodeusers',
});
connection.connect(err => {
if (err) {
return err;
}
});
console.log(connection);
// Connection Express Body-Parser Cors
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.send('Hello from the products server')
});
app.post('/userss/add', (req, res) => {
const nom = req.body.nom;
const prenom = req.body.prenom;
const adresse = req.body.adresse;
const email = req.body.email;
console.log(nom, prenom);
const insertQuery = `INSERT INTO userstab (nom, prenom, adresse,
email) VALUES
("${nom}","${prenom}","${adresse}",
"${email}")`;
connection.query(insertQuery,[nom,prenom,adresse,email],
(err,results) => {
if(err) {
res.send(err)
}
console.log(nom, prenom);
res.send({ error: false, data: results, message: 'user has
been added successfully.' });
})
});
// First Get request/////////////////////////////////////////
app.get('/userss/add', (req, res) => {
const { nom, prenom, adresse, email } = req.query;
const insertQuery = `INSERT INTO userstab (nom, prenom, adresse, email) VALUES ('${nom}','${prenom}','${adresse}','${email}')`;
connection.query(insertQuery, (err, results) => {
if(err) {
return res.send(err)
}
else {
return res.send('successfully added user')
}
});
});
////////////////////////////////////////////////////////////////////
app.listen(4000, () => {
console.log('Users server worked on port 4000...')
});
Because you are using users table in post request , and another table called userstab in get request.
So please change you query in post request to be the same table in get request.

Trouble modularizing passport.js with node

so I'm sort of having an issue here. I have my login route:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
require('../config/passport')(passport, LocalStrategy);
/* GET /login */
router.get('/', function(req, res) {
//you'll probably write some
res.render('login', { title: 'Please Log In' });
});
router.post('/', function(req, res) {
console.log('posting');
console.log(passport);
passport.initialize();
passport.session();
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login'
});
console.log('after');
});
module.exports = router;
my app.js:
var express = require('express'),
path = require('path'),
favicon = require('serve-favicon'),
logger = require('morgan'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
session = require('express-session'),
RedisStore = require('connect-redis')(session),
passport = require('passport'),
// LocalStrategy = require('passport-local').Strategy,
pool = require('./config/database'),
routes = require('./routes/index'),
api = require('./routes/api'),
login = require('./routes/login'),
app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session(<<redis store info>>);
app.use(passport.initialize());
app.use(passport.session());
app.use('/', routes);
app.use('/api', api);
app.use('/login', login);
...etc
and my ./config/passport.js
var pool = require('./database');
module.exports = function(passport, LocalStrategy) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
mysql.query("select * from users where id = "+id,function(err,rows){
done(err, rows[0]);
});
});
passport.use(new LocalStrategy({
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) { // callback with user and password from our form
console.log('hi');
pool.query("SELECT * FROM `users` WHERE `user` = '" + username + "'",function(err,rows){
if (err)
return done(err);
if (!rows.length) {
return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
if (!( rows[0].password == password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, rows[0]);
});
}));
};
And I can't really understand why the passport config just doesn't seem to be getting processed at all. When I call passport.authenticate it's seemingly doing nothing
So, there were a few things I did to get this to work. The first is I moved the following into passport.js Having anything inside require() passport related in my route was nuts. I started without this mess, but trying to tinker had progressed to that point. Furthermore, my deserialize function incorrectly had a mysql reference instead of my pool.
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
I then just set up passport like normal in the config, and did
module.exports = passport;
Then just did this in app.js:
var passport = require('../config/passport');
then I changed my router, removed essentially the whole thing on the post function, and did:
router.post('/', passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login'
}));
I learned I couldn't just call passport.authenticate. It was meant to be placed in a req handler.
Sorry for the totally insane and ambiguous question guys. Just in case any poor soul looks for this down the line, I figured I at least need to have the courtesy to talk about it.