Show User the error message when problem when logging in - node.js

I have just started working on an already existing Web application project. Right now when the user tries logging in with incorrect credentials , the page is getting redirected to 'relogin' page. Where the Message "Please enter valid credentials" is hardcoded in the HTML to show a "error message". I have been asked to add another functionality to the Application. I want to show the user the message which server returns.
For Example :-
If server response is
{ result : "false" , message : " Invalid email " }
i want to show "Please enter Valid email" to the user.
If server response is
{ result : "false" ,message : " Invalid password " }
i want to show "Please enter Correct Password" to the user.
,but because of the present code i am not able to do that.
Please help me with this task.
Thanks in advance.
I am attaching my app.js , passport.js , authenticate.js code. please inform if you need any more details.
--app.js--
var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var initPassport = require('./passport');
initPassport(passport);
var routes = require('./routes/routes');
var authenticate = require('./routes/authenticate')(passport);
app.use('/',routes);
app.use('/auth',authenticate);
'''
--authenticate.js--
var express = require('express');
var router = express.Router();
var path = require('path');
module.exports = function(passport) {
router.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
router.post('/login',passport.authenticate('login',{
successRedirect: '/',
failureRedirect: '/relogin',
}));
return router;
};
'''
--passport.js--
var LocalStrategy = require('passport-local').Strategy;
var pg = require('pg');
var path = require('path');
var fs = require('fs');
var Client = require('node-rest-client').Client;
var client = new Client();
module.exports = function(passport){
passport.use('login', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
var client = new Client();
client.get(serverHost+serverRoot+"/validateuser?username="+username+"& password="+password, function (data, response) {
// parsed response body as js object
// raw response
console.log("response from server ", data);
if(data.result == "true")
return done(null, username);
else
return done(null ,false );
});
}));
}
'''
EDIT 1 :-
There is no angular code for logging in.
All the procedure happens in html only.
I am attaching the HTML code. Thanks
HTML code :-
<body>
<div class="col-md-6 offset-3">
<form action="/auth/login" method="post" >
<div class="form-group mb-4 mt-4"><input id="email" class="form-control
form-control-rounded" type="text" name = "username"
placeholder="Username" ></div>
<div class="form-group mb-4 mt-4"><input id="password" class="form-control
form-control-rounded" type="password" name="password"
placeholder="Password"></div>
<button type = "submit" value = "Login" class="btn btn-rounded btn-primary btn-block mt-2">Sign In</button>
</form>
</div>
</body>

You can use res.render function to send data to your view. Documentation for the same is available at:
https://expressjs.com/en/api.html#res.render
Regarding the specific issue related to validation via passport.js have a look at:
Send data back with the Passport js failureRedirect method

Related

Cant get the data from form post to nodeJS server

I am trying to write a login page . i got the html page with the login box
im enter email and password than submit to server , on server i got route who get the data check on db if doc exists , if its exists should redirect to main page
the problem is the data i send from form to server always undefined i check here on other ppl questions and i didnt find any good result for this
html login page :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/css/style.css" />
<title>{{PageTitle}}</title>
</head>
<body>
{{> header}}
<div class="login-box">
<div class="form">
<form action="/get_user" method="post" class="login-form">
<input type="email" name="Email" placeholder="Email"/>
<input type="password" name="Password" placeholder="Password"/>
<button type="submit">login</button>
</form>
</div>
</div>
{{> footer}}
</body>
server code :
const _ = require('lodash');
const express = require('express');
const bodyParser = require('body-parser');
const {mongoose} = require('./db/mongoose');
const hbs = require('hbs');
var {User} = require('./models/user');
var app = express();
app.set('view engine', 'hbs');
const port = process.env.PORT;
hbs.registerPartials(__dirname + '/../views/partials');
app.user(bodyParser.json());
app.use(express.static(__dirname + '/../public'));
app.use(express.static(__dirname + '/../public/images'));
app.use(express.static(__dirname + '/../public/fonts'));
app.listen(port, () => {
console.log(`Started on port ${port}`);
});
app.get('/', (req, res) => {
res.render('login.hbs', {
PageTitle: 'Log In',
ConnectUser: 'Guest'
});
});
app.post('/get_user', (req, res) => {
var body = _.pick(req.body, ['Email , 'Password']);
User.findOne({
Email: body.Email,
Password: body.Password
}).then((user) => {
console.log(body.Email + ' ' + body.Password);
if(!user) {
return res.status(404).send();
}
var fullName = user.First_Name + ' ' + user.Last_Name;
res.redirect('/mainPage', {ConnectUser: fullName});
}).catch((e) => {
res.status(400).send();
});
});
i did few checks and when i call /get_user req.body->var body -> user r empty
the data arnt pass from form to server im also check this route on postman and its work find when i write the body by myself the only problem i can think is the data i send from form arnt send as json and the body parser send only in json format so maybe i need to change the line
app.use(bodyParser.json());
if any 1 can put in the right direction ill appraise that ty.
When using an html form with method post, the data is posted to the server withContent-Type: application/x-www-form-urlencoded instead of JSON.
Json bodyparser will not do anything with that, as its not using JSON format to send the data. See MDN guide under post method.
In your server code, below app.use(bodyParser.json()) add the following:
app.use(bodyParser.urlencoded({extended: true}));
This will add the data onto the request body the way you expect.
Try playing with the form enc-type attribute and see how to configure the bodyparser to get the values you need based on the enc-type.
application/x-www-form-urlencoded
multipart/form-data
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/enctype

Formidable always returns empty fields and files when I upload a file in Node.js

Basically I want to upload a csv file from local computer and parse it in the backend to do required operations. I'm attaching the csv file in the front end. Checked that its not empty. But I'm unable to fetch the same in the server.
Is there something I'm missing or doing in the wrong way?
Here is what I have tried till now.
Front end code:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="file" id="file" />
<input type="submit" value="Submit">
</form>
Backend Code:
var express = require('express');
var methodOverride = require('method-override');
var http = require('follow-redirects').http;
var formidable = require('formidable');
var app = express();
const fs = require('fs');
app.use(methodOverride('_method'));
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.post('/testcsv', requireLogin, function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
console.log(err);
console.log(fields);
console.log(files);
});
});
Log Output:
null
{}
{}
This problem is caused by Frontend code, it has nothing to do with Backend code (formidable).
For the following console.log statement:
console.log(err);
console.log(fields);
console.log(files);
err is null because there is no error.
fields is {} because in the form, all input fields are file selector. fields in formidable only indicate plain input field, such as <input type="text">.
files is {} because the name of file selector in the form is missing.
To get expected value, here is an example form:
<form id="myForm" method="POST" enctype="multipart/form-data" action='/testcsv' >
<input type="text" name="testtext" />
<input type="file" id="file" name="testfile" />
<input type="submit" value="Submit">
</form>
The console.log result for above form would be:
null
{ testtext: '....' }
{ testfile: File....}

res.render an ember route with express

I currently have a webapp using Express, Node, Ember, and Mongo. Ember app resides in a project folder (./public/index.html) in the root of the node/express install. I have express set to serve static files from the public directory and render index.html to any get requests so the ember app is accessible.
I have a route/view in my Ember app that has a form that accepts a file upload, this form's action is a post request to an express route that performs calculations and queries a local mysql database with updates. The function works fine but at the end of the .post express function when I res.json or res.send the response appears in the browser window and clears out my ember view.
I assume the correct way to handle this is to res.render('view',{data:'Finished processing file'});
then display the data value on the ember template. Question is how can I render an ember view with express. I added express-handlebars to my project and setup the view engine correctly but I don't know how to associate ember views with express so it knows how to render the correct view with response data.
hbs file for the ember view
<div class="col-md-8 col-md-offset-2 text-center">
<h2 class="toolTitle">Reactivate SKUs</h2>
<p class="lead">CSV Should Contain 1 Column (SKU) Only</p>
<form action="/tools/sku/reactivate" method="POST" enctype="multipart/form-data">
<input class="center-block" type="file" name="csvdata">
<button type="submit" class="btn btn-md btn-danger">Submit</button>
</form>
</div>
router.js(express router)
var quotes = require('../api/quote');
var cors = require('cors');
var sku = require('../api/tools/sku');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var util = require("util");
var fs = require("fs");
var corsOptions = {
origin: 'http://localhost:4200'
}
module.exports = function(router){
router.route('/quotes').post(cors(corsOptions),function(req,res){
console.log(req.body);
quotes.addQuote(req,res);
}).get(cors(corsOptions),function(req,res){
quotes.getAllQuotes(req,res);
});
router.route('*').get(cors(corsOptions), function(req,res){
res.sendFile('public/index.html',{root:'./'});
});
router.route('/tools/sku/reactivate').post(upload.single('csvdata'),function(req,res){
console.log('handing request over to sku.reactivate');
sku.reactivate(req,res);
});
};
sku.js express function
var mysql = require('mysql');
var csv = require('csv-parse');
var multer = require('multer');
var fs = require('fs');
//mysql setup
const connection = mysql.createConnection(
{
host : 'localhost',
user : 'rugs_remote2',
password : 'ofbiz',
database : 'rugs_prd2',
multipleStatements: true
}
);
connection.connect();
module.exports.reactivate = function(req,res){
//define mysql query function for once readStream emits end event
function reactivationQuery(arr){
console.log(arr);
const queryString = "UPDATE PRODUCT SET SALES_DISCONTINUATION_DATE = NULL WHERE PRODUCT_ID IN (?)";
connection.query(queryString,arr,function(err,rows,fields){
console.log(rows,fields);
if(err){
console.log('Error running sku.reactivate module error is: '+err);
}
res.send('DONE');
});
}
//define array for holding csv data in this case skus
const skuArray = [];
//define filesystem readstream from uploaded file
let readStream = fs.createReadStream(req.file.path).pipe(csv());
//push csv data to array ignoring headers to skuArray
readStream.on('data', function(chunk){
if(chunk[0] !== 'SKU'){
skuArray.push(chunk[0]);
}
});
//error handling
readStream.on('error',function(err){
console.log('Error while reading file stream [ERROR] '+ err);
res.send('Error while processing file');
});
//once read is finished map skuArray to usable string for IN Clause
readStream.on('end',function(){
let stringifyArray = skuArray;
stringifyArray = [stringifyArray];
reactivationQuery(stringifyArray);
});
}
Figured this out thanks to Max's help in the comments.
I was doing a full post request on form submit instead of using ajax to make the request this is why I was being routed out of my ember app and express would just render the response to the upload in the browser.
I installed ember-uploader again which was originally giving me issues because I didn't set the paramName option to match my file input name. Updated code below incase anyone else is running into a similar issue.
Ember HBS Template:
<div class="col-md-8 col-md-offset-2 text-center">
<h2 class="toolTitle">Reactivate SKUs</h2>
<p class="lead">CSV Should Contain 1 Column (SKU) Only</p>
<p class="lead flash-msg"></p>
{{file-upload id="upload" url="/tools/sku/reactivate" class="center-block" name="csvdata"}}
</div>
file-upload.js (ember-uploader component)
import Ember from 'ember';
import EmberUploader from 'ember-uploader';
export default EmberUploader.FileField.extend({
filesDidChange: function(files) {
const uploader = EmberUploader.Uploader.create({
url: this.get('url'),
paramName: 'csvdata'
});
if (!Ember.isEmpty(files)) {
alert(JSON.stringify(files));
// this second argument is optional and can to be sent as extra data with the upload
uploader.upload(files[0]).then(data => {
$('#upload').fadeOut('slow', function(){
$('.flash-msg').text(data);
$('.flash-msg').fadeIn('slow');
});
}, error => {
$('.flash-msg').text('Error uploading file please contact Jay: ' + error);
$('.flash-msg').fadeIn('slow');
});
}
}
});
express router
var quotes = require('../api/quote');
var cors = require('cors');
var sku = require('../api/tools/sku');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var util = require("util");
var fs = require("fs");
var corsOptions = {
origin: 'http://localhost:4200'
}
module.exports = function(router){
router.route('/quotes').post(cors(corsOptions),function(req,res){
console.log(req.body);
quotes.addQuote(req,res);
}).get(cors(corsOptions),function(req,res){
quotes.getAllQuotes(req,res);
});
router.route('*').get(cors(corsOptions), function(req,res){
res.sendFile('public/index.html',{root:'./'});
});
router.route('/tools/sku/reactivate').post(upload.single('csvdata'),function(req,res){
console.log('handing request over to sku.reactivate');
sku.reactivate(req,res);
});
};
express api function module:
var mysql = require('mysql');
var csv = require('csv-parse');
var multer = require('multer');
var fs = require('fs');
//mysql setup
const connection = mysql.createConnection(
{
host : 'localhost',
user : 'rugs_remote2',
password : 'ofbiz',
database : 'rugs_prd2',
multipleStatements: true
}
);
connection.connect();
module.exports.reactivate = function(req,res){
//define mysql query function for once readStream emits end event
function reactivationQuery(arr){
const queryString = "UPDATE PRODUCT SET SALES_DISCONTINUATION_DATE = NULL WHERE PRODUCT_ID IN (?)";
connection.query(queryString,arr,function(err,rows,fields){
if(err){
console.log('Error running sku.reactivate module error is: '+err);
res.json(err);
}
res.json('Successfully reactivated '+rows.changedRows+' SKUs');
});
}
//define array for holding csv data in this case skus
const skuArray = [];
//define filesystem readstream from uploaded file
let readStream = fs.createReadStream(req.file.path).pipe(csv());
//push csv data to array ignoring headers to skuArray
readStream.on('data', function(chunk){
if(chunk[0] !== 'SKU'){
skuArray.push(chunk[0]);
}
});
//error handling
readStream.on('error',function(err){
console.log('Error while reading file stream [ERROR] '+ err);
res.json('Error while processing file');
});
//once read is finished map skuArray to usable string for IN Clause
readStream.on('end',function(){
let stringifyArray = skuArray;
stringifyArray = [stringifyArray];
reactivationQuery(stringifyArray);
});
}

router.get not posting multiple params

Hi so I am learning basics of node.js and express, and I was trying to submit a form with two parameters and trying to get that in the same screen.
But for some reason I guess I am not sure how to use router.get to get the both input fields parameters.
Here is my js file
var express = require('express');
var router = express.Router();
router.get('/:awesomeTitle?/:awesomeAuthor?', function(req, res, next) {
res.render('node',
{title: req.params.awesomeTitle ? req.params.awesomeTitle : '' , author: req.params.awesomeAuthor ? req.params.awesomeAuthor : '' });
});
router.post('/', function(req, res, next) {
var awesomeTitle = req.body.title;
var awesomeAuthor = req.body.author;
res.redirect('/' + awesomeTitle + awesomeAuthor);
});
module.exports = router;
And here is my hbs file.
<h1> Result </h1>
<h2>{{author}}</h2>
<h1>{{title}}</h1>
<form action="/" method="post">
<input type="text"/ name="title">
<input type="text"/ name="author">
<button type="submit">Submit</submit>
</form>
So just wanted to know how to get the awesome title and author from submit to the page again in the h1 and h2 tags.
P.S I am not sure how to debug this application so.. and it doesn't show any errors, all I get is both the input fields answer combined.
It looks like you're missing a / in your redirect. Try changing the last line in your post handler to this:
res.redirect('/' + awesomeTitle + '/' + awesomeAuthor);

nodejs throws cannot post error

I am trying to post the data from html form but it is showing an error "cannot POST".
This is my code:
controller/InquiryDetails.js:
var mongoose = require('mongoose'),
InquiryDetails = mongoose.model('InquiryDetails');
exports.add = function(req, res) {
InquiryDetails.create(req.body, function (error, details) {
if (error) return console.log(error);
return res.send(details);
});
}
routes/Inquiry.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended:true}));
app.post('/InquiryDetails', function(req,res,err){
if(err) console.log(err);
res.json(req.body);
console.log(req.body);
});
module.exports = router;
model/InquiryDetails.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var myskyll = new Schema({
name: String,
email: String,
state: String,
country: String,
school: String,
profession: String,
phone: Number
});
mongoose.model('InquiryDetails', myskyll);
app.js:
var express = require('express');
var mongoose = require('mongoose');
var request = require('request');
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname+"/index.html")).listen(8080);
var mongoUri = 'mongodb://localhost/myskyll';
mongoose.connect(mongoUri);
var db = mongoose.connection;
db.on('error', function () {
throw new Error('unable to connect to database at ' + mongoUri);
});
var app = express();
console.log("connection successfull");
app.configure(function(req,res){
app.use(express.bodyParser());
});
app.use(express.static(__dirname + "/" ));
require('./models/InquiryDetails');
require('./routes/Inquiry');
app.listen(3000);
console.log('Listening on port 3000...');
index.html:
<form method="post" id="form1" action="InquiryDetails">
Your Name:<span class="imp">*</span><br/><input type="text"
name="name" placeholder="Firstname Lastname" class="textbox"
autofocus required pattern="[A-Za-z-0-9]+\s[A-Za-z-'0-9]+"
title="'Firstname' <space> 'Lastname'"/> <br/><br/>
Email:<span class="imp">*</span><br/><input
type="email" name="email" placeholder="Email" class="textbox"
required/><br/><br/>
city:<span class="imp">*</span><br/><input type="text" name="city"
placeholder="city" class="textbox" required/><br/><br/>
State/Country:<span class="imp">*</span><br/>
<input type="text" name="country"
placeholder="State/Country" class="textbox" required /><br/>
<br/>
School/Institution:<span class="imp">*</span><br/><input
type="text" name="school" placeholder="Your School or
Institution" c lass="textbox" required /><br/><br/>
Your Profession:<br/><input type="text" name="profession"
placeholder="Profession" class="textbox"><br/><br/>
Phone:<br/><input type="text" name="phone" placeholder="Phn. no.
with country code" class="textbox" pattern="\+[0-9]+" title="Only
digits" /><br/><br/>
<input type="submit" value="Submit"
class="btn3"/>
<input type="reset" value="Clear" class="btn3" />
</form>
I have tried in postman API client to post the data but it shows 404 status while posting the data.
Do I have any problem in my code?
Any suggestion will be appreciated!
You are creating multiple app objects. One in app.js and a different one in routes/Inquiry.js.
For this type of application, you will want to be using only one app object that you share with anyone who needs it because only one of them is actually registered with your web server and is being used.
That is likely why your app.post() handler is not working because it's registered on the wrong app object - the one that is not connected to a live server.
There are several other things that look incorrect in the code:
The third argument to an app.post() callback is a next() function reference, not the err that you have declared and are testing.
You are doing require('./models/InquiryDetails'); and that module exports some things, but you are not assigning the result of the require to anything so those exports are unusable.
You are initializing the connect module, but if you are using a recent version of Express that module is no longer needed as the functionality it used to provide for Express is now built into Express.

Resources