Update user information - javascript

Tried this for updating user information , only phone number but it's not getting update.
router.post('/edit', checkAuth, function (req, res, next) {
console.log(req.userData.userId)
User.update({_id: req.userData.userId}, {$set:req.userData.phoneNo}, function (err){
if (err) {
console.log(err);
}
res.status(200).send(req.userData);
});
});
My user controller const mongoose = require ('mongoose');
const User = mongoose.model('User');
module.exports.register = (req, res, next) =>{
var user = new User();
user.fullName = req.body.fullName;
user.email = req.body.email;
user.password = req.body.password;
user.phoneNumber = req.body.phoneNumber;
user.save((err, doc) =>{
if(!err)
res.send(doc);
else{
if (err.code == 11000)
res.status(422).send(["Entered duplicate email address. Please check"]);
else
return next(err);
}
});
}
And then I am authenticating by passing jwt on this field
phoneNo: user[0].phoneNumber
The auth-token verifies and decode the fields
const token = req.headers.authorization.split(" ")[1];
const decoded = jwt.verify(token, process.env.JWT_KEY)
req.userData = decoded;
Update is not working and getting error message Invalid atomic update value for $set. Expected an object, received string .

first of all, you should use PATCH-method - because you are updating only one item in existed object, in body you should send id of user and new value of certain value. If you use mongoose you can try it
User.findOneAndUpdate({ _id: id }, updatedItem, { new: true }, (err, doc) => {
if (err) return res.send(err.message)
if (doc) return res.send(doc);
})
const id = req.body._id;, if you dont use mongoose you should try findAndModify method

Your code
User.update({_id: req.userData.userId}, {$set:req.userData.phoneNo}
Correct code:
User.update({_id: req.userData.userId}, {$set:{phoneNumber:req.userData.phoneNo}}
Try this method:
User.findByIdAndUpdate(req.userData.userId, { $set:{phoneNumber:req.userData.phoneNo}}, { new: true }, function (err, user) {
if (err) console.log(err);
res.send(user);
});

Related

Condition if/else don't work like expected in nodejs

I'm creating a simple api witch verify if the username and/or password are in the DB and if they are correct.
When I post correct data, it works. When I post a wrong password, it also works. But when I post a wrong username, my condition don't jump to the else. If the username is wrong, it means it is not in the DB. But here, it is like if it was in the DB, but he is not, so I get an error : " TypeError: Cannot read properties of undefined (reading 'Username') "
Here the code
app.post('/login', function(req, res) {
(async () => {
const bcrypt = require('bcrypt')
try {
username = req.query.username
password = req.query.password
let salt = await bcrypt.genSalt(10)
let hash = await bcrypt.hash(password, salt)
db_conn.getConnection( (err, conn) => {
if(err) throw err;
conn.query("SELECT * FROM mod803_appusers WHERE Username=? ", [username], (err, rows) => {
//Problem here : when I put a wrong password, it's ok, this condition works because there is a password, and if bcrypt.compare is true, it sends response, but if it's false, it sends 'Wrong password'.
//But if the Username is Wrong, it means there is no username in the DB. So here, I want this condition jump to the else : 'Incorrect username' but it doesn't.
if(rows[0]['Username'] && rows[0]['Password']) {
bcrypt.compare(password, rows[0]['Password'], function(err, result) {
if(result){
res.send({"table": rows});
} else {
res.send("Wrong password");
}});
} else {
res.send('Incorrect username');
}
})
})
} catch (error) {
console.log(error.message)
}
})()
})
Thanks

Is there a way to convert this pg.Pool query to Knex?

I am trying to convert my pg pool queries to Knex and am having an issue with this query:
router.post('/register', validInfo, async (req, res, next) => {
const { email, name, password } = req.body;
try {
const user = await pool.query('SELECT * FROM users WHERE user_email = $1', [email]);
res.json(user);
} catch (err) {
console.error(err);
}
});
Here is what I have so far:
router.post('/register', validInfo, async (req, res, next) => {
const { email, name, password } = req.body;
try {
//Check if user exists
const user = await knex('users')
.select('*')
.where('user_email', $1, [email]);
res.json(user);
} catch (err) {
console.error(err);
}
});
When I create a new user in Postman I should receive an empty array but it's not working. What needs to change in order to match the first query?

Node.js - PostgreSQL (pg) : Client has already been connected. You cannot reuse a client

I am just trying to write simple register/login system.
I am trying to find if username exists. Here is the steps :
Go localhost:3000/users/register page
Fill in all fields and click register button
Checking my command line if username exists it should print it with console.log
Everything works fine until now.
When I go back to the register page, I fill in all fields again and click register button. Then it throws it in command line :
Error: Client has already been connected. You cannot reuse a client.
at Client._connect (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:91:17)
at C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:310:10
at new Promise (<anonymous>)
at Client.connect (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:309:10)
at Object.module.exports.findUserById (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\database\register_sql.js:8:22)
at C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\routes\users.js:37:29
at Layer.handle [as handle_request] (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:137:13)
at next (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:131:14)
at Route.dispatch (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:112:3)
I dont understand because I already end my client after I call my method.
register_sql.js :
module.exports.findUserById =(async (username) =>{
try {
await client.connect();
console.log('Connected successfuly');
const result = await client.query("select * from users where username = ($1)", [username]);
console.log(result.rows[0]['username']);
await client.end();
console.log('Client disconnected...');
} catch (err) {
console.log(err);
}
});
I call register_sql.js in users.js. Here is users.js :
const router = express.Router();
const registerSQL = require('../database/register_sql');
router.route('/register')
.get((req, res, next) => {
res.render('register');
})
.post((req, res, next) => {
const {
username,
password,
password2
} = req.body;
let errors = [];
if (!username || !password || !password2) {
errors.push("Please fill in all fields!");
}
if (password != password2) {
errors.push("Passwords do not match!");
}
if (password.length < 6) {
errors.push("Password has to be at least 6 characters!");
}
if (errors.length > 0) {
res.render('register', {
errors
});
} else {
registerSQL.findUserById(username);
res.redirect('/');
}
});
module.exports = router;
Thank you for helping!
With node-postgres (which is the one you're using) I've only made it work using the pool do manage the connections.
const pg = require('pg')
const pool = new pg.Pool();
pool.connect(function(err, client, done) {
if(err) {
return console.error('connexion error', err);
}
client.query("select * from users where username = ($1)", [username], function(err, result) {
// call `done()` to release the client back to the pool
done();
if(err) {
return console.error('error running query', err);
}
console.log(result.rows[0]['username'])
});
});
I had the same problem, dont create the new Client outside the function.
- const client = new pg.Client(connection);
-
function test() {
+ const client = new pg.Client(connection);
+
client.connect(err => {
if (err) {
console.log(err);
return;
}
client.query('select 123', [], (err, data) => {
if (err) {
console.log(err);
} else {
console.log('DATA:', data.rows[0]);
}
client.end();
});
});
}
I managed to fix this problem without using pool. Maybe that's not the most correct solution, but it works.
First create a separate js file, where you connect the client and export it:
const pg = require('pg')
const client = new pg.Client('your connection string')
client.connect()
module.exports = client
Then you just use the exported client, which has already been connected, so it won't reconnect again on each request. Be sure to import the client from the js file where you connect it.
const client = require('../db')
const register = async (req, res) => {
const {email, password, username} = req.body
const hashedPassword = await bcrypt.hash(password, 10)
const command = `insert into users(email, username, password, created) VALUES ('${email}', '${username}', '${hashedPassword}', current_timestamp)`
await client.query(command, (err, result) => {
err ? res.json({error: err.detail}) : res.json({message: 'User created!'})
})
}
well the problem occur because you haven't closed the connection to database.
Remember you have to close the connection before you sent something to client like that:
try {
await client.connect();
const result = await client.query(query, values);
await client.end();
res.status(201).send({
result,
});
} catch (err) {
return res.send({
error: err.detail,
message: "Can't create a new user, please check your info again!",
});
}
Pool approach is better practice but if someone want to connect with Client approach then this solution will work.
Code which will work with Client approach :
client.connect();
client.query(`select * from users where username = ($1)`, (err, result)=>{
try{
console.log("Test", result)
res.send(result)
} catch{
console.log("err", err)
res.status(500).json(err);
}
client.end();
})

Cannot set headers after they are sent to the client error

I have a login form that authenticates using postgresql I'm trying to check if users exists then redirect the client to the other page. The code is:
app.post('/login', (req, res) => {
var Enteredusername = req.body.username;
var Enteredpassword = req.body.password;
pool.query("SELECT * FROM tbl_users WHERE username = $1 AND password = $2", [Enteredusername, Enteredpassword], (err, result) => {
if (err) return console.log('error in query', err);
// need to check if user exists
let user = (result.rows.length > 0) ? result.rows[0] : null;
if (!user) {
req.flash('notify', 'This is a test notification.')
res.render('login', {
messages: req.flash('Username or Password is incorrect !')
});
return res.redirect('/login')
}
res.redirect('/posts')
});
});
And I got the error:
_http_outgoing.js:470
throw new ERR_HTTP_HEADERS_SENT('set');
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.
How Can I fix it?
It's the async behavior of javascript res.redirect('/posts') is executed before req.flash and res.render you can hack it like this :
req.session.userId = Enteredusername;
if (!user) {
req.flash('notify', 'This is a test notification.')
res.render('login', {
messages: req.flash('Username or Password is incorrect !')
});
return res.redirect('/login')
}else{
return res.redirect('/posts')
}

NodeJS and Mongodb findOneAndUpdate

I need help to figure this out. The update function is called to reset a password on database. I got this error.
TypeError: Cannot read property 'password' of undefined
module.exports.update = function (token, req, res) {
User.findOneAndUpdate({resetPasswordToken: token, password: req.body.password, resetPasswordExpires: {$gt: Date.now()}}, function(err) {
if (err) throw err;
return res.sendStatus(200);
console.log(User);
});
}
router.post('/forgot', function (req, res) {
var password = req.body.passwordnew;
var password2 = req.body.passwordnew2;
var update = User.update(password, password2, function (err, user) {
//userToken = token;
if (!update) {
console.log("token2 = " + req.params.resetPasswordToken);
req.flash('error', 'Password reset token is invalid or has expired.');
return res.redirect('forgot');
}
else {
user.save(function (err) {
user.password = password;
user.password2 = password2;
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
});
console.log("save new password");
}
});
//}
})
when you use update method of mongoose 1st parameter will be query( by which you can find that doccument in collection) and 2nd will be what you want to update ..
So what query you make is not make sense , it will be like :
var userId=user; //mongoId
var newPassWord=req.body.passwordnew;
User.update({_id:userId}, {password:newPassWord}, callbackFunction);
this will update password of that perticular user.
Thanks

Categories