JQuery Custom Validation Rule Mysql function always showing error - javascript

I am trying to add a custom validation rule to check if username exists or not. My code:
jQuery.validator.addMethod("checkexist", function(myvalue, element) {
checkifexist(function(result) {
if (result == true)
{
return true;
}
else
{
return false;
}
});
}, 'Does not exists!');
and
async function checkifexist(callback) {
const secret = keytar.getPassword('Userdata', 'MysqlPassword');
secret.then((result) => {
var mysql = require("mysql");
var connection = mysql.createConnection({
host: store.get('ip'),
port: store.get('port'),
user: store.get('username'),
password: result,
database: "database"
});
var querystring = 'SELECT * FROM `testdb`';
try
{
connection.query(querystring, (err, rows, fields) => {
if(err){
return callback("error with query", err);
}
var found;
for (var i in rows)
{
if (some check...)
{
return callback(true);
}
}
return callback(false);
});
connection.end(() => {
});
}
catch { }
});
However, if I check the valditation it correctly outputs true or false on every keypress. I still get only validation errors, though it should be a valid input.

Related

Add 'time limit' loop in Javascript to use with imap-simple nodejs package

I currently have the code below, which was created from a previous question I posted last year here.
var imaps = require('imap-simple');
var configBauerEmail = {
imap: {
user: '********#hotmail.com',
password: '******',
host: 'imap-mail.outlook.com',
port: 993,
tls: true,
authTimeout: 30000
}
};
module.exports = {
'delete any existing emails...': function () {
imaps.connect(configBauerEmail).then(function (connection) {
connection.openBox('INBOX').then(function () {
var searchCriteria = ['ALL'];
var fetchOptions = { bodies: ['TEXT'], struct: true
};
return connection.search(searchCriteria, fetchOptions);
})
//Loop over each message
.then(function (messages) {
let taskList = messages.map(function (message) {
return new Promise((res, rej) => {
var parts = imaps.getParts(message.attributes.struct);
parts.map(function (part) {
return connection.getPartData(message, part)
.then(function (partData) {
//Display e-mail body
if (part.disposition == null && part.encoding != "base64") {
console.log(partData);
}
//Mark message for deletion
connection.addFlags(message.attributes.uid, "\Deleted", (err) => {
if (err) {
console.log('Problem marking message for deletion');
rej(err);
}
res();
});
});
});
});
});
return Promise.all(taskList).then(() => {
connection.imap.closeBox(true, (err) => {
if (err) {
console.log(err);
}
});
connection.end();
});
});
});
},
'send email to seller and wait for mailbox notification': function (browser) {
browser.url(browser.launch_url + browser.globals.testDealerBfsAdevertEmailTest);
browser.notificationDismissal();
browser.cmpDismissal();
browser.emailFunctionality.emailTheSeller();
browser.browserEnd();
},
'get new email info': function() {
const createPromise = ms => new Promise((resolve, reject) => {
setTimeout(() => resolve(ms), ms);
});
function findUnseenEmails(connection) {
return connection.openBox('INBOX').then(function () {
var searchCriteria = ['UNSEEN'];
var fetchOptions = {
bodies: ['HEADER','TEXT'],
markSeen: false
};
return connection.search(searchCriteria, fetchOptions).then(function (results) {
var subjects = results.map(function (res) {
return res.parts.filter(function (part) {
return part.which === 'HEADER';
})
[0].body.subject[0];
});
console.log(subjects);
if (subjects.length > 0) {
connection.end();
return subjects;
} else {
return createPromise(60000).then(function() {
return findUnseenEmails(connection);
});
}
});
});
}
imaps.connect(configBauerEmail).then(function (connection) {
return findUnseenEmails(connection);
})
.then((subjects) => console.log('finished', subjects));
},
};
This works OK, in that the following loop that was added will loop over every 60 seconds checking that the email has 'arrived' in the mailbox.
if (subjects.length > 0) {
connection.end();
return subjects;
} else {
return createPromise(60000).then(function() {
return findUnseenEmails(connection);
});
}
});
However, at present if the email sending process has failed and the email account does not receive the email, the test will carry on looping continuously until the test is physically stopped.
What I'd now like to do is set some sort of 'time limit' within this loop, so that if the email has not arrived in the mailbox within 30 minutes the test will fail.
I appreciate that this will involve a limit setting in the loop above, but I've tried it in several locations within the loop and I can't get it to work.
Any help would be greatly appreciated. Thanks.

How to fix "Error: Can't set headers after they are sent" in Express

I have recently been developing a MERN application and I have recently came into the trouble that express is saying that I am setting headers after they are sent.
I am using mongo db and trying to update a user profile.
I have tried to comment out my res.send points to find the issue but I have failed to do so.
Here is my post method for updating the user profile:
app.post("/api/account/update", (req, res) => {
const { body } = req;
// Validating and Checking Email
if (body.email) {
var email = body.email;
email = email.toLowerCase();
email = email.trim();
body.email = email;
User.find(
{
email: body.email
},
(err, previousUsers) => {
if (previousUsers.length > 0) {
return res.send({
success: false,
message:
"Error: There is already another account with that email address"
});
} else {
}
}
);
}
// Validating Names Function
function checkName(name) {
var alphaExp = /^[a-zA-Z]+$/;
if (!name.match(alphaExp)) {
return res.send({
success: false,
message: "Error: Names cannot contain special characters or numbers"
});
}
}
checkName(body.firstName);
checkName(body.lastName);
// Making sure that all fields cannot be empty
if (!body.email && !body.firstName && !body.lastName) {
return res.send({
success: false,
message: "Error: You cannot submit nothing"
});
}
// Getting User ID from the current session
UserSession.findById(body.tokenID, function(err, userData) {
// Finding User ID using the current users session token
if (userData.isDeleted) {
return res.send({
success: false,
message:
"Error: Session token is no longer valid, please login to recieve a new one"
});
}
// Deleting the token ID from the body object as user table entry doesnt store tokens
delete body.tokenID;
// Finding the user profile and updating fields that are present
User.findByIdAndUpdate(userData.userId, body, function(err, userInfo) {
if (!err) {
return res.send({
success: true,
message: "Success: User was updated successfully"
});
}
});
});
});
This is the call that I am doing to the backend of the site:
onUpdateProfile: function(fieldsObj) {
return new Promise(function(resolve, reject) {
// Get Session Token
const obj = getFromStorage("the_main_app");
// Defining what fields are getting updated
fieldsObj.tokenID = obj.token;
// Post request to backend
fetch("/api/account/update", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(fieldsObj)
})
.then(res => {
console.log("Verify Token - Res");
return res.json();
})
.then(json => {
console.log("Verify Token JSON", json);
if (json.success) {
window.location.href = `/manage-account?success=${json.success}`;
} else {
window.location.href = `/manage-account?success=${json.success}`;
}
});
});
}
Here is my error message that I am getting:
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11)
at ServerResponse.setHeader (_http_outgoing.js:498:3)
at ServerResponse.header (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:767:10)
at ServerResponse.send (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:170:12)
at ServerResponse.json (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\express\lib\response.js:158:21)
at C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\routes\api\account.js:270:22
at C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\mongoose\lib\model.js:4641:16
at process.nextTick (C:\Users\kieran.corkin\Desktop\Projects\Mern Template Final\mern-cra-and-server\server\node_modules\mongoose\lib\query.js:2624:28)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
[nodemon] app crashed - waiting for file changes before starting...
Can anyone help me with this?
EDIT
I have changed my code, this seems to now work however I feel like its a little messy when put together. Any refactoring tips?
Code:
app.post("/api/account/update", (req, res) => {
// Preform checks on data that is passed through
const { body } = req;
var messages = {
ExistedUser:
"Error: There is already another account with that email address",
NameFormat: "Error: Names cannot contain special characters or numbers",
BlankInputs: "Error: You cannot submit nothing",
accountLoggedOut:
"Error: Session token is no longer valid, please login to recieve a new one",
successfullyUpdated: "Success: User was updated successfully"
};
var usersFound;
if (body.email) {
var email = body.email;
email = email.toLowerCase();
email = email.trim();
body.email = email;
User.find(
{
email: body.email
},
(err, UserCount) => {
usersFound = UserCount;
}
);
}
function capitalize(text) {
return text.replace(/\b\w/g, function(m) {
return m.toUpperCase();
});
}
if (body.firstName) {
body.firstName = capitalize(body.firstName);
}
if (body.lastName) {
body.lastName = capitalize(body.lastName);
}
//Making sure that all fields cannot be empty
if (!body.email && !body.firstName && !body.lastName) {
return res.send({
success: false,
message: messages.BlankInputs
});
}
// Getting User ID from the current session
UserSession.findById(body.tokenID, function(err, userData) {
// Finding User ID using the current users session token
if (userData.isDeleted) {
return res.end({
success: false,
message: messages.accountLoggedOut
});
}
if (userData) {
// Deleting the token ID from the body object as user table entry doesnt store tokens
delete body.tokenID;
// Finding the user profile and updating fields that are present
User.findByIdAndUpdate(userData.userId, body, function(err, userInfo) {
if (userInfo) {
if (!usersFound.length > 0) {
return res.send({
success: true,
message: messages.successfullyUpdated
});
} else {
return res.send({
success: false,
message: messages.ExistedUser
});
}
}
});
}
});
});
You're calling res.send() twice. res.send() ends the process. You ought to refactor such that you call res.write() and only call res.send() when you're done.
This StackOverflow link describes the difference in more detail. What is the difference between res.send and res.write in express?
I believe this is happening, as you're trying to send a response after the first / initial response has already been sent to the browser. For example:
checkName(body.firstName);
checkName(body.lastName);
Running this function twice is going to try and yield 2 different "response" messages.
The product of a single route, should ultimately be a single response.
Thanks for all your help on this issue.
Here is my final code that allowed it to work.
I have also tried to "refactor" it too. Let me know if you'd do something else.
app.post("/api/account/update", (req, res) => {
const { body } = req;
console.log(body, "Logged body");
// Defining objects to be used at the end of request
var updateUserInfo = {
userInfo: {},
sessionToken: body.tokenID
};
var hasErrors = {
errors: {}
};
// Checking that there is at least one value to update
if (!body.email && !body.firstName && !body.lastName) {
var blankError = {
success: false,
message: "Error: You cannot change your details to nothing"
};
hasErrors.errors = { ...hasErrors.errors, ...blankError };
} else {
console.log("Normal Body", body);
clean(body);
console.log("Cleaned Body", body);
updateUserInfo.userInfo = body;
delete updateUserInfo.userInfo.tokenID;
}
// Function to check if object is empty
function isEmpty(obj) {
if (Object.keys(obj).length === 0) {
return true;
} else {
return false;
}
}
// Function to remove objects from body if blank
function clean(obj) {
for (var propName in obj) {
if (obj[propName] === "" || obj[propName] === null) {
delete obj[propName];
}
}
}
// Checking and Formatting Names Given
function capitalize(text) {
return text.replace(/\b\w/g, function(m) {
return m.toUpperCase();
});
}
if (body.firstName) {
body.firstName = capitalize(body.firstName);
}
if (body.lastName) {
body.lastName = capitalize(body.lastName);
}
// Checking and formatting email
if (body.email) {
body.email = body.email.toLowerCase();
body.email = body.email.trim();
// Checking for email in database
User.find({ email: body.email }, (err, EmailsFound) => {
if (EmailsFound.length > 0) {
var EmailsFoundErr = {
success: false,
message: "There is already an account with that email address"
};
hasErrors.errors = { ...hasErrors.errors, ...EmailsFoundErr };
}
});
}
// Getting User Session Token
UserSession.findById(updateUserInfo.sessionToken, function(err, userData) {
// Finding User ID using the current users session token
if (userData.isDeleted) {
var userDeletedError = {
success: false,
message:
"Your account is currently logged out, you must login to change account details"
};
hasErrors.errors = { ...hasErrors.errors, ...userDeletedError };
} else {
// Finding the user profile and updating fields that are present
User.findByIdAndUpdate(
userData.userId,
updateUserInfo.userInfo,
function(err, userInfo) {
// userInfo varable contains user db entry
if (err) {
var updateUserError = {
success: false,
message: "Error: Server Error"
};
hasErrors.errors = {
...hasErrors.errors,
...updateUserError
};
}
if (isEmpty(hasErrors.errors)) {
res.send({
success: true,
message: "Success: You have updated your profile!"
});
} else {
res.send({
success: false,
message: hasErrors.errors
});
}
}
);
}
});
});

Exporting Mysql Connection in nodeJS

In my database.js I have
var Mysql = require('Mysql');
var Jwt = require('jsonwebtoken');
var bcrypt = require('bcrypt');
var supersecretkey = 'JMDub_Super_Secret_key';
var config = require('./config');
var signupErrors = require('./Signuperrors.js');
var sucessMsg = require('./SucessMessages.js');
var App_errors = require('./error.js');
var query = require('./queryDB.js');
var connection = Mysql.createConnection({
"host": "******",
"user": "****",
"password": "***",
"database": "***"
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
//Sign Up Methods
var createUser = function createwithCredentails(post,callback) {
bcrypt.hash(post.password, 10, function(err, hash){
//console.log('Cache Hash : +',hash);
var createUserQuery = connection.query('INSERT INTO users SET ?',{"email":post.email,"password":hash,"username":post.username},function(err,result){
if (err) {
if (err.code == 'ER_DUP_ENTRY') {
//console.log(err.code);
callback(signupErrors.error_5000);
}
else callback(App_errors.error_1003);
}
if (result) {
callback(sucessMsg.success_signup);
}
});
});
}
//connection.query('SELECT * FROM Users Where Username = '' AND Password = ''');
var validateUser = function ValidateUserWithUserNameAndPassword(post,callback) {
var UserCheckQuery = connection.query('SELECT * FROM users WHERE email="'+post.email+'"',function(err, results, fields) {
if (err){
console.log(err);
callback(App_errors.error_1000);
}
if (results.length == 1) {
//console.log(results[0].password,post.password);
var givenPassword = post.password;
var DBhash = results[0].password;
bcrypt.compare(givenPassword, DBhash,function(err, res) {
if (res) {
console.log('Password matched');
var token = Jwt.sign({"email":post.email,"username":post.username},supersecretkey, {
expiresIn: 60*60*5 // expires in 5 hours
});
callback({
message:{
"success":1,
"description":"sucessfully logged in - please cache the token for any queries in future",
"environment":"test",
"errorCode":null
},
"token":token
});
}
if (!res) {
console.log('password doesnt match');
callback(signupErrors.error_6000);
}
if (err) {
console.log('Error Comparing Passwords');
callback(App_errors.error_1004);
}
});
}
else{
callback(signupErrors.error_6000);
}
});
};
var isauthenticate = function isauthenticated(post,route,callback) {
if (post.headers.token) {
Jwt.verify(post.headers.token, supersecretkey, function(err, decoded) {
if (decoded) {
//console.log(decoded);
//From this part the user is Sucessully Authenticated and autherization params can be extracted from token if required
//Write Business Logic in future as per the requirement
//Operation 1 - Update Profile
//Profile Details consists of {1.first name 2.last name 3. profile pictur(base 64 encoded) 4.further settings in future that can be added to DB if required}
if (route == '/update-profile') {
query.updateProfile(connection,decoded.email,post.body,function(response) {
callback(response);
});
}
//callback({"message":"is a valid token"});
}
if (decoded == null) {
console.log('is not a valid token');
//callback(App_errors.error_1000);
}
if (err) {
console.log('error verifying token');
callback(App_errors.error_1000);
}
});
}
else{
callback(App_errors.error_1001);
}
};
module.exports = {
validateUser:validateUser,
createUser:createUser,
isauthenticate:isauthenticate,
connection:connection
}
I am exporting connection object to queryDB.js file. But when I try to log the exported connection object I get undefined object. Why is this happening?
When I pass connection object as function argument, everything works fine. Not sure why?
below is queryDB.js file
var errors = require('./error.js')
var Dbconnection = require('./Database.js').connection;
var updateProfile = function profiledata(connection,email,data,callback) {
console.log(Dbconnection);
if ((!data)|| (Object.keys(data).length < 1)) {
//console.log(data);
callback(errors.error_1001);
}
else{
callback({"message":"update Sucesss"});
//console.log(connection);
//var updateData = mapProfileDataTomodel(data);
//console.log(updateData);
connection.query('SELECT * FROM users WHERE email = "'+email+'"',function(err, result,feilds) {
if (err) throw err;
if (result) {
console.log(result);
}
});
}
}
var mapProfileDataTomodel = function mapProfileDataTomodel(data) {
var profileDataModel = {};
for (var key in data) {
//console.log('looping and mapping data');
if (data.firstname) {
profileDataModel.firstname = data.firstname;
}
if (data.lastname) {
profileDataModel.lastname = data.lastname;
}
if (data.profilepic) {
profileDataModel.profilepic = data.profilepic;
}
}
return profileDataModel;
}
module.exports = {
updateProfile:updateProfile
}
I have commented out connection object log via function arguments.
So, Why I am unable to get the connection object that is exported? But I used the same exported connection object in my app.js file. It did work fine there.

How to wait for results inside an if statement in js?

I'm bulding a node.js backend for a webapp and when i submit a form, i do various validations. One of them is to check if an invitation already exists with the same email address.(isUserAlreadyInvited function)
I created a function for this, however when i call this, i guess the response is not that fast and it just moves to the next statement even if the check returns true. How
//Loop through emails one by one
var emails_to_invite = ["test#test.com","invalid.com"];
var response_items = [];
async.each(emails_to_invite,
function(email, callback){
//Response item
var response_item = {}
response_item.email = email;
//Validate
if(Joi.validate({ email: email }, apiSchema).error) {
response_item.error = "not valid email";
response_items.push(response_item);
callback();
} else if(email == user.email) {
response_item.error = "Sending an invitation to your own email is kinda dumb";
response_items.push(response_item);
callback();
} else if(isUserAlreadyInvited(email,user_id)) {
response_item.error = "already invited";
response_items.push(response_item);
callback();
} else {
sendInvitationEmail(email,user_id,null,null,function(invitation_code){
if(invitation_code) {
response_item.invitationCode = invitation_code;
} else {
response_item.error = "server error";
}
response_items.push(response_item);
callback();
});
};
},
function(err){
//Return response
res.status(200).send(response_items);
}
);
function isUserAlreadyInvited(email,invited_by) {
User.findOne({
email: email,
invited_by: invited_by
}, function(err, user) {
if(err) {
return false;
} else {
return true;
}
});
}
Two returns here:
function isUserAlreadyInvited(email,invited_by) {
User.findOne({
email: email,
invited_by: invited_by
}, function(err, user) {
if(err) {
return false;
} else {
return true;
}
});
}
are defined inside this function
function(err, user) {
if(err) {
return false;
} else {
return true;
}
}
and have nothing with return value of isUserAlreadyInvited().
Apparently your isUserAlreadyInvited() is an asynchronous function that needs to be treated asynchronously - it shall get callback function as a parameter. That callback shall be invoked in place of that function(err, user) {}

AngularJS javascript function gets stuck inside an else statement

I have this code whereby i want to check if code input data is the same in the local db. This code works fine until it gets to where i have marked as code hangs or stops here. Once the code gets to the condition it runs perfectly and assigns notifier to be true but it doesnt come out of that function and is stuck there hence the remaining part of the code is not executed. Can anyone explain to me why ? I am building an Ionic, AngularJS app.
function checklocalDB(localdb, result) {
var d= $q.defer();
var identifier = false;
var notifier = false;
// var f = function(localdb, result){
if(localdb === false) {
console.log("inside localdb false")
var insert_into_table = "INSERT INTO preferences(description, value) VALUES ('username','" + result[0].username + "'), ('token','" + result[0].token.toString() + "')";
$cordovaSQLite.execute(db, insert_into_table).then(function (res) {
console.log("executedd")
var updateDB = "UPDATE preferences SET value='true' WHERE description='registered'";
$cordovaSQLite.execute(db, updateDB).then(function (res) {
console.log("executed")
identifier = true;
notifier = true;
//d.resolve(identifier)
var query = "SELECT id, description, value FROM preferences";
$cordovaSQLite.execute(db, query).then(function (res) {
}, function (err) {
console.error(err);
});
}, function (err) {
console.error(err);
});
});
}
else {
console.log("inside localdb true")
var dbNew = null;
var query = "SELECT id, description, value FROM preferences";
console.log(localdb)
$cordovaSQLite.execute(db, query).then(function (res) {
console.log("hhhhhhhhhhhhhh")
console.log(res.rows.item(2).value)
console.log(result[0].username)
if(res.rows.item(2).value != result[0].username) {
console.log("username different")
$cordovaSQLite.deleteDB("loanstreet_partners.db");
dbNew = $cordovaSQLite.openDB("loanstreet_partners.db");
$cordovaSQLite.execute(dbNew, "CREATE TABLE IF NOT EXISTS preferences (id integer primary key, description string, value string)").then(function (res) {
console.log("done")
var insert_into_table = "INSERT INTO preferences (description, value) SELECT 'registered' as registered, 'false' as value UNION SELECT 'logged_in', 'false'";
$cordovaSQLite.execute(db, insert_into_table).then(function (res) {
console.log("1st")
var insert_into_table = "INSERT INTO preferences(description, value) VALUES ('username','" + result[0].username + "'), ('token','" + result[0].token.toString() + "')";
$cordovaSQLite.execute(db, insert_into_table).then(function (res) {
console.log("2nd")
identifier = true;
notifier = true;
var updateDB = "UPDATE preferences SET value='true' WHERE description='registered'";
$cordovaSQLite.execute(db, updateDB).then(function (res) {
}, function (err) {
console.error(err);
});
});
}, function (err) {
console.error(err);
});
}, function (err) {
console.error(err);
});
}
else {
notifier = true;
console.log("im here")
return notifier;
// ***code hangs or stops here***
}
}, function (err) {
console.error(err);
});
}
// ***this is never executed because it still remains false***
if(notifier === true) {
console.log(identifier)
console.log(notifier)
d.resolve(identifier)
}
return d.promise;
// watch identifier when value change then only resolve
//d.resolve(identifier)
//return d.promise;
}
Any help appreciated

Categories

Resources