Receiving a token from a clicked email - html

I'm working on a web application with some team members and I have been tasked with the Password recovery. We are using mysql and node.js for the back-end and API layer. With the following npm packages: nodemailer, mysql, express, body-parser and bcrypt.
The issue at hand is I don't actually know how to create a link with a bcrypt token and then recive the token and interpret it and then send it to the html page/form with the user data.
I haven't tested the code as of yet but some input would be great:
var urlencodedParser = bodyParser.urlencoded({
extended: true
});
app.use(bodyParser.urlencoded({
extended: true
}));
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'youremail#gmail.com',
pass: 'yourpassword'
}
});
var db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
//Change DB name to the one you make.
database: 'projectracetrack'
});
//User clicks on link in email.
app.get('/recover/:token', function(req, res) {
//here
});
app.post('/forget', urlencodedParser, function(req, res) {
let sql = "SELECT * FROM users WHERE email = ? LIMIT 1";
db.connect(function(err) {
if (err) throw err;
db.query(sql, [req.body.email.toString()], function(err, result) {
if (err) throw err;
console.log(result);
//Comparing email to database
if (result.email.toLowerCase() !== req.email.toLowerCase()) {
//send reply that email
return res.send("Your email does not exist in the database, please use the registration page.");
} else {
var token;
//encripting the token
bcrypt.hash(result.username, saltRounds, function(err, hash) {
if (err) throw err;
token = hash;
sql = "INSERT INTO racers (RecoveryToken, RecoverTimeOut) WHERE email = " + result.email + " VALUES ? LIMIT 1";
//inserting the token and data to the database HERE!!
// 1 hour
var data = [
[token,
Date.now() + 3600000 // 1 hour
]
];
db.query(sql, [data], function(err) {
if (err) throw err;
});
var mailOptions = {
from: 'youremail#gmail.com',
to: result.email,
subject: 'Project Racetrack Password Recovery',
text: 'Dear ' + result.username + '\n\n\
This is a confermation that you would like to recover your password please click on the link:' +
'http://' + req.headers.host + '/recover/' + token + '\n\n\
If this has not been requested by you please contact our customer suppport\n\n\
Kind Regards\n\
Team'
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
});
}
});
});
});

Related

make button in html delete a row in MySql

i am currently working on a project where i use nodejs to make a user that adds users to MySql in a table called "users"
i would like to make a button in html which deletes the currently logged in user from the mysql table
how do i make a button in html call a function in nodejs which deletes a Row in MySql
This may be a good start to understand how to trigger API calls from Js
fetch('https://reqres.in/api/deleteUser', {
method: "DELETE",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
id: '1'
})
})
.then(res => {
if (res.ok) { console.log("HTTP request successful") }
else { console.log("HTTP request unsuccessful") }
return res
})
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.log(error))
And then for NodeJs
// Module dependencies
var express = require('express'),
ejs = require('ejs'),
fs = require('fs'),
mysql = require('mysql');
// Application initialization
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '' //<your password
});
var app = module.exports = express.createServer();
// Database setup
connection.query('CREATE DATABASE IF NOT EXISTS test', function (err) {
if (err) throw err;
connection.query('USE test', function (err) {
if (err) throw err;
connection.query('CREATE TABLE IF NOT EXISTS users('
+ 'id INT NOT NULL AUTO_INCREMENT,'
+ 'PRIMARY KEY(id),'
+ 'name VARCHAR(30)'
+ ')', function (err) {
if (err) throw err;
});
});
});
// Configuration
app.use(express.bodyParser());
// Post delete user
app.post('/deleteUser', function(req, res) {
var id=Number(req.query.id);
console.log(id);
connection.query('delete from users where id='+id,
});

requests not going through in nodejs and mysql

I have this code where I am trying to receive data from the user and it should be inserted into the db directly without any module just a controller, can someone tell me how can I do that, I know we can get the user data in the req.body, but I don't know how to send it back to the controller here is the
P.S user will be sending around 10 or more fields that will be inserted
here is the code
controller
sql.query(`INSERT INTO Admin (LoginID,Password,Preference,Name,Last Name) values ? ` , (err, result)=> {
if (err) {
console.error('Something bad happened: ' + err);
return res.status(500);
}
console.log('Response from controller', result);
res.json(result);
});
}
module.exports = {test}
and this is the router page
Router
router.post('/CreateOrganizer',(req,res)=>{
organizer.test
})
This is how you should proceed:
const con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
app.post('',(req, res, next) => {
const user = req.body;
// use the same key in the query that you are getting from body.
const sql = "INSERT INTO Admin (LoginID,Password,Preference,Name,Last Name)
VALUES ('user.LoginID', 'user.Password', 'user.Preference', 'user.Name''user.LastName')";
con.query(sql, function (err, result) {
if (err) {
console.error('Something bad happened: ' + err);
return res.status(500);
}
console.log("1 record inserted");
});
})
There are several tutorials available online that can help you to achieve the same.

How to create a awaitable connection with mysql using node.js

I'm new with Node.js and I'm trying to create a async method with Node.js, because I need to check a row inside of my database and then decide what to do with it. So I created a file called sql-service.js
const sql = require('mysql');
var connection = sql.createConnection({
host: '0.0.0.0',
user: 'foo',
password: 'fooo'
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
console.log(connection.state);
module.exports.SignUpUser = (email,password)=>{
connection.query('select * from usuario', function(error, results, fields) {
console.log(results);
});
}
And inside of my Controller :
const sqlService = require('../services/sql-service');
exports.post = async(req,res,next)=>{
const Email = req.body.Email;
const Passw = req.body.Password;
console.log(dateT.getdate());
if (fluentValidation.validateEmail(Email) && fluentValidation.isValidLenght(Passw)) {
try {
await sqlService.SignUpUser(Email,Passw);
//emailService.send(req.body.Email,'Nome','Bem vindo ao hanggu');
} catch (error) {
console.log(error);
}
res.status(201).send({
Email: "Valid " + req.body.Email,
Password: Passw.length,
Send: 's '//Date : dateT.getDateTime()
});
} else {
res.status(500).send({
Error: "Email invalid"
})
}
}
It does connect but the result that I got it's undefined, I tried
console.log('The solution is: ', results[0].usuario);
But still.
what schema you select?
var connection = sql.createConnection ({
host: '0.0.0.0',
user:'foo',
password : 'fooo',
database : 'you_db'
});
test

Node.js with exress handle database connection error outside middleware

I am fairly new to node and I am trying to create a simple login/signup system with passportjs. I have my passport configuration file in which i pass the passport object as a parameter as you can see below.
My passport configuration file:
var LocalStrategy = require('passport-local').Strategy;
var User = require('./../models/user');
var mysql = require('./../database/mysql_setup');
var mysqlPool = mysql.pool;
// expose this function to our app using module.exports
module.exports = function(passport) {
mysqlPool.getConnection(function(error, connection) {
if (error) throw error;
connection.query('USE vidyawxx_build2');
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and deserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.username);
});
// used to deserialize the user
passport.deserializeUser(function(username, done) {
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE username = " + connection.escape(username), function(err,rows){
done(err, rows[0]);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// find a user whose username is the same as the forms username
// we are checking to see if the user trying to login already exists
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = "+connection.escape(username),function(err,rows){
if (err)
return done(err);
if (rows.length) {
return done(null, false, req.flash('error', 'This username is already in use.'));
} else {
// if there is no user with that username
// create the user
var newUserMysql = new User(username, password);
newUserMysql.generateHash(function(error, hash) {
if(error) {
return done(error);
}
var insertQuery = "INSERT INTO `"+mysql.dbSpecs.prefix+"users` ( username, password ) values (" + connection.escape(newUserMysql.username) +",'"+ hash +"')";
connection.query(insertQuery,function(err,rows){
if(err) {
return done(error);
}
return done(null, rows);
});
});
}
});
}
));
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) { // callback with email and password from our form
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = " + connection.escape(username), function(err,rows){
if (err) {
return done(err);
}
if (rows.length === 0) {
return done(null, false, req.flash('error', 'Oops! Wrong username or password.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
var newUser = new User(username, password);
newUser.compareHash(function(error, result) {
if(result) {
return done(null, rows[0]);
} else {
return done(null, false, req.flash('error', 'Oops! Wrong username or password.')); // create the loginMessage and save it to session as flashdata
}
});
});
}
));
connection.release();
});
};
My problem lies in the fact that if my mysql server is down for any reason, the error is thrown in my first line. I want to be able to redirect my users to a simple page that gives him a message like "Something is wrong with the database, please try later". The thing is, when i throw the error, my app just shuts down giving any visitor the ERR_CONNECTION_REFUSED response.( I am currently working this locally.
This is my app.js file:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var passport = require('passport');
var passportConfig = require('./config/passport');
var session = require("express-session");
var flash = require("connect-flash");
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
passportConfig(passport);
app.use(session({
secret: "aPa1fgOed(&fjkKLN34%#$lpv##",
resave: true,
saveUninitialized: true,
cookie: { maxAge: 1000*60*15 } //15 minutes in milliseconds
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
//create local vaariables for all our templates to use
app.use(function(req, res, next) {
res.locals.errors = req.flash("error");
res.locals.infos = req.flash("info");
res.locals.successes = req.flash("success");
next();
});
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
That being said, since the error is thrown in my passport-config file, which doesnt follow the middleware convention of having a req, res and next params, how can i redirect my users to a page like the one mentioned above gracefully ?
Just to be sure, I will say this again, this concerns only mysql connection errors. I know that i can return other errors through my passport-config methods by using done(), but database connection errors occur outside the functions with a done param.
Thanks in advance
Looks like after some digging around the only workaround I could think of is incorporating the queries inside the passport configuration methods so that I could pass back any database connection error through the done() function;
This is my modified passport config file
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
var User = require('./../models/user');
var mysql = require('./../database/mysql_setup');
var mysqlPool = mysql.pool;
// expose this function to our app using module.exports
module.exports = function(passport) {
//connection.query('USE vidyawxx_build2');
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and deserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.username);
});
// used to deserialize the user
passport.deserializeUser(function(username, done) {
mysqlPool.getConnection(function(dbError, connection) {
if(dbError) {
return done(dbError);
}
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE username = " + connection.escape(username), function(err,rows){
if(err) {
done(err);
connection.release();
return;
}
connection.release();
done(err, rows[0]);
});
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// find a user whose username is the same as the forms username
// we are checking to see if the user trying to login already exists
mysqlPool.getConnection(function(dbError, connection) {
if(dbError) {
return done(dbError);
}
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = "+connection.escape(username),function(err,rows){
if (err) {
connection.release();
return done(err);
}
if (rows.length) {
connection.release();
return done(null, false, req.flash('error', 'This username is already in use.'));
} else {
// if there is no user with that username
// create the user
var newUserMysql = new User(username, password);
newUserMysql.generateHash(function(error, hash) {
if(error) {
connection.release();
return done(error);
}
var insertQuery = "INSERT INTO `"+mysql.dbSpecs.prefix+"users` ( username, password ) values (" + connection.escape(newUserMysql.username) +",'"+ hash +"')";
mysqlPool.query(insertQuery,function(err,rows){
if(err) {
connection.release();
return done(error);
}
connection.release();
return done(null, rows);
});
});
}
connection.release();
});
});
}
));
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) { // callback with email and password from our form
mysqlPool.getConnection(function(dbError, connection) {
if(dbError) {
return done(dbError);
}
connection.query("SELECT * FROM `"+mysql.dbSpecs.prefix+"users` WHERE `username` = " + connection.escape(username), function(err,rows){
if (err) {
connection.release();
return done(err);
}
if (rows.length === 0) {
connection.release();
return done(null, false, req.flash('error', 'Oops! Wrong username or password.')); // req.flash is the way to set flashdata using connect-flash
}
// if the user is found but the password is wrong
var newUser = new User(username, password);
newUser.compareHash(function(error, result) {
if(result) {
connection.release();
return done(null, rows[0]);
} else {
connection.release();
return done(null, false, req.flash('error', 'Oops! Wrong username or password.')); // create the loginMessage and save it to session as flashdata
}
});
});
});
}
));
};

Passport.JS doesn't work (AngularJS + NodeJS + MySQL + Redis Store for session datas)

I'm trying to use PassportJS to authenticate requests on my site, but it's not working. When I trying to login nothing happening. I'm using MYSQL database to store the user datas and I didn't find a tutorial for this.
APP.JS:
var session = require('express-session');
var routes = require('./routes');
var sha1 = require('sha1');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var RedisStore = require('connect-redis')(session);
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(session({
store: new RedisStore({
host: '127.0.0.1',
port: 6379,
prefix: 'sess'
}),
resave: true,
saveUninitialized: true,
secret: 'xxxxxxx'
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
passport.use('local-login', new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(username, password, done){
var connection = mysql.createConnection(
{
host : sql.host,
user : sql.user,
password : sql.password,
database : sql.db_users
}
);
console.log(username);
console.log(password);
connection.connect();
var queryUserCheck = 'SELECT userID, email, password, users WHERE email = "' + username + '"';
connection.query(queryUserCheck, function(err, rows, field) {
if(err){
res.status(500).end(err);
console.log(err);
connection.end();
}else{
user = rows[0];
userID = rows[0].userID;
console.log('Checkpoint 1');
if(!user) { return done(null, false, {message: 'The user is not exist'});}
else if(sha1(password) != user.password) { return done(null, false, {message: "Wrong password"});}
else{
console.log('Checkpoint 2');
return done(null, user);}
connection.end();
}
});
}
));
passport.serializeUser(function(user, done) {
console.log('serializeUser');
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
routes.init(app, passport);
I'm actually not really understand the above 2 function. I know it's need to attach and deattach the user from the session, but do I need to change anything on these functions to make it customized or just leave as is?
Router:
exports.init = function(app, passport){
app.post('/login', login);
app.get('/logout', logout);
app.get('/userinfo', checkAuth, require('./users/users/userDetails'));
function login(req, res, next){
passport.authenticate('local-login', function(err, user, info){
if(err){
return next(err);
}
console.log('Authentication is successfull');
});
}
function logout(req, res){
if(req.isAuthenticated()){
req.logout();
req.session.messages = "Log out successfully";
}
res.writeHead(200, { 'Content-Type': 'application/json'});
res.end(true);
}
function checkAuth(req, res, next){
if(req.isAuthenticated) return next();
else{
res.status(401).end("Not Authorized!");
}
}
};
Could somebody help me what I missed? Thank you so much.