Async pg pool query takes forever to finish - node.js

I am currently working on login/register API for my database search engine. I am using express#4.17.1, pg#7.18.2, PostgreSQL 12. The problem is that on one of the machines (Ubuntu bionic 18.0.4 LTS) the query for /register route resolves fine - the user is saved in postgres db, but on Fedora 32 the await function takes forever to resolve.
Here is the code:
db.js:
const pool = new Pool({
host: "localhost",
user: "postgres",
password: "postgres",
port: 5432,
database: "jimjones"
});
module.exports = pool;
register route in jwtAuth.js:
router.post("/register", validInfo, async (req, res) => {
const { email, name, password } = req.body;
try {
const user = await pool.query("SELECT * FROM users WHERE user_email = $1", [
email
]);
//doesnt get past first query
if (user.rows.length > 0) {
return res.status(401).json("User already exist!");
}
const salt = await bcrypt.genSalt(10);
const bcryptPassword = await bcrypt.hash(password, salt);
let newUser = await pool.query(
"INSERT INTO users (user_name, user_email, user_password) VALUES ($1, $2, $3) RETURNING *",
[name, email, bcryptPassword]
);
const jwtToken = jwtGenerator(newUser.rows[0].user_id);
return res.json({ jwtToken });
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
});
The query:
const user = await pool.query("SELECT * FROM users WHERE user_email = $1", [
email
]);
The req.body on Fedora 32 is parsed, so it's not a firewall problem regarding the POST request.
Using Postman, the program fails on this query (but only on Fedora 32). Both databases have the same tables on both machines. Sql select query in psql returns data on both machines.
Any suggestions on how to fix/debug this? Any help will be greatly appreciated.

Upgrading to pg#8.3.0 solved this issue.
The whole discussion:
https://github.com/brianc/node-postgres/issues/2069

Related

nodejs express rest api post displaying undefined

im currently trying nodejs for the first time and im trying to make a rest api that i can link to my website that uses postgresql to get the data.
categories.js is the file im currently working on, it holds all get and post methods related to the categories table in postgres
Here's the current code in my categories.js:
var express = require('express');
const bodyParser = require("body-parser");
var router = express.Router();
const {Client} = require('pg');
router.use(bodyParser.json());
const client = new Client({
host: 'localhost',
user: 'postgres',
port: 5432,
password: 'admin123',
database: 'postgres'
})
client.connect();
/* GET categories listing. */
router.get('/', function(req, res, next) {
client.query(`select * from categories`, (err, result)=>{
if(!err){
res.send(result.rows);
}
else console.log(err.message);
});
client.end;
});
/* GET category listing by id. */
router.get('/:id', function(req, res, next) {
client.query(`select * from categories where id=${req.params.id}`, (err, result)=>{
if(!err){
res.send(result.rows);
}
else console.log(err.message);
});
client.end;
});
/* POST category listing by postman. */
router.post('/', (req, res)=> {
const category = req.body;
console.log(category)
let insertQuery = `INSERT INTO categories
(name, createdat)
VALUES ('${category.name}','${category.createdat}');`
client.query(insertQuery, (err, result)=>{
if(!err){
res.send('Insertion was successful')
}
else{ console.log(err.message) }
})
client.end;
})
module.exports = router;
the problem is, everytime i try to make a post method through postman using this script:
{
"name": "cat2",
"createdat": "13/05/201"
}
it posts an empty item into the database:
{"id":12,"name":"undefined","available":true,"createdat":"undefined"}
the get methods work normally by the way, but the post method doesn't
here's the categories table in postgres incase that helps
CREATE TABLE IF NOT EXISTS public.categories
(
id integer NOT NULL DEFAULT nextval('categories_id_seq'::regclass),
name text COLLATE pg_catalog."default" NOT NULL,
available boolean NOT NULL DEFAULT true,
createdat text COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT categories_pkey PRIMARY KEY (id)
)
well well well, i found what the problem was lmao, and its actually embarassing.
well basically in the postman program, when i was inputing my data for it to be submitted to the database as json, i had the body selected in text form instead of json, which is why it couldnt recognize my data, cs it was in txt not json..
here's a pic incase someone does a stupid like i did
fix
mistake

Node JS Sequelize: running the same query again is retrieving the previous result

I am building a Web API using Node JS. For database operation, I am using the Sequalize package. In my test when I run the same query that gets a record after updating the record again, it is giving me the old/previous result.
Here is my code:
let testUser = await User.findOne({
where: {
email: {
[Op.eq]: testHelper.testUser.email
}
}
})
let now = new Date();
//genrate the token in the database before making the request.
let verificationToken = await VerificationToken.create({
userId: testUser.id,
verificationToken: "testing",
expiresAt: date.addSeconds(now, 40000)
})
let requestBody = {
email: testUser.email,
password: "Newpassword123",
confirm_password: "Newpassword123",
token: "testing"
}
const res = await request(app).put("/api/auth/reset-password").send(requestBody);
expect(res.statusCode).toBe(200);
expect(res.body.error).toBe(false);
//refresh the user instance by fetching the new record from the database.
let user = await User.findOne({
where: {
email: {
[Op.eq]: testHelper.testUser.email
}
}
})
// here user.password and testUser.password are the same even the record is actually updated
As you can see in the comment, the password of user object is still the same as the password of testUser object even though the password is updated in the database. How can I fix it to get the latest record?

Oracle Database Connection Pool with node.js

I am new to Node.js. I am trying to make connection pools with multiple databases. I have successfully made connection pools (i think) with below mentioned code. I know in order to execute query operations i have to do something at "Connection pool DBX Success", but i can't seem to figure out what to do so that i am able to execute queries on desired pool say crm1.execute or crm2.execute. What can i do here to achieve this. The only way i can think of is to write execute functions for each database separately which i know is wrong and i have to work with 15 databases so it isn't possible to write functions for all 15 databases separately.
const config = require("../config/config");
const oracledb = require("oracledb");
crm1 = config.crm1;
crm2 = config.crm2;
const crm1pool = oracledb.createPool ({
user: crm1.user,
password: crm1.password,
connectString: crm1.connectString,
poolMin: 1,
poolMax: 10,
poolTimeout: 300
}, (error,pool)=>{
if (error){
console.log(error);
}
console.log("Connection Pool DB1 success")
});
const crm2pool = oracledb.createPool ({
user: crm2.user,
password: crm2.password,
connectString: crm2.connectString,
poolMin: 1,
poolMax: 10,
poolTimeout: 300
}, (error,pool)=>{
if (error){
console.log(error);
}
console.log("Connection Pool DB2 success")
});
There is a lot of node-oracledb documentation on pooling and examples. Study those first.
Then you might find that giving each pool a poolAlias will let you easily choose which to use:
await oracledb.createPool({
user: 'hr',
password: myhrpw, // myhrpw contains the hr schema password
connectString: 'localhost/XEPDB1',
poolAlias: 'hrpool'
});
await oracledb.createPool({
user: 'sh',
password: myshpw, // myshpw contains the sh schema password
connectString: 'otherhost/OTHERDB',
poolAlias: 'shpool'
});
const connection = await oracledb.getConnection('hrpool');
const result = await connection.execute(
`SELECT manager_id, department_id, department_name
FROM departments
WHERE manager_id = :id`,
[103], // bind value for :id
);
console.log(result.rows);

Error with async await ( at least in my opinion ) - ExpressJS, MongoDB, NodeJS, multer

This is my code in backend (ExpressJs, multer)
Note: I used cors in server.js file and it working as I expected in previous route, but in this Register Admin route, the other error occurs
const multer = require('multer');
const upload = multer({ dest: './public/uploads/' });
const User = require('../models/user.model'); // User model
router.post('/admin/register', upload.single('avatar'),
async (req, res) => {
const avatar = req.file.path.slice(7);
const user = {
...JSON.parse(req.body.user),
avatar
};
// hapi/joi validate => 1
const { error } = Validation.adminRegisterValidation(user);
if (error) {
return res.json({ error: error.details[0].message });
}
// validate from database => 2
const emailExist = await User.findOne({ email: user.email });
if (emailExist) {
return res.json({ error: 'Email already exist!' });
}
// hash the password => 3
const hashedPassword = await bcrypt.hash(user.password, 10);
const newUser = new User({
...user,
admin: false,
password: hashedPassword,
sub_admin: true
});
try {
await newUser.save();
return res.json("Add user success!");
} catch (err) {
return res.json({ error: err });
}
}
);
If i turn 1,2,3 to comment, the user is added as I expected
This project in my Github Github
- Front-end in file: src -> components -> dashboard -> user-dashboard -> CreateUser.js
- Backend in file: backend -> routes -> user.route.js
THIS IS MY ERROR IMAGE
Well I found two errors that might be causing your issue, not really sure if it will totally fix your issue, but will definitely get you close.
1) Remove Max length property from user schema
Right now you have max length of 30 for password in your user Schema but once you hash the password, hashed password can go beyond 30 characters.
You can click here to see what I'm talking about.
2) You need to remove old password in order to store the new hashed password
In this line of code you are using Spread Syntax to include all the fields in NewUser object from user object, which already includes password that comes from your frontend
const newUser = new User({
...user,
admin: false,
password: hashedPassword,
sub_admin: true
});
This what causes newUser to have 2 password fields, to delete the old password after hashing do this
// hash the password => 3
const hashedPassword = await bcrypt.hash(user.password, 10);
delete user.password
const newUser = new User({
...user,
admin: false,
password: hashedPassword,
sub_admin: true
});
This way you can set password to new Hashed one.
AS your error is very Generic It's almost impossible to DEBUG it, these are the few things I found very odd.
As I said not really sure if it will fix your error but it might get you close

Dealing with models and model methods using Node + Knex + Postgres

I was hoping to get some help. I just started using Postgres with my Node applications and am curious to find out how to go about dealing with models and model methods. What is the best practice when working with Node and Postgres in regards to models and methods? I was looking around and all I could find is something called Objection, but is it absolutely necessary I take that route?
Ideally I would like to have a model.js file for each component but I have not seen them used when dealing with Postgres + Node.
Any help is greatly appreciated. Thanks guys, hope you all had a great Thanksgiving!
Assuming that viewer can understand basic javascript modules and that the codes are mostly self explanatory
This is my model.js file
module.exports = ({
knex = require('./connection'),
name = '',
tableName = '',
selectableProps = [],
timeout = 1000
}) => {
const query = knex.from(tableName)
const create = props => {
delete props.id
return knex.insert(props)
.returning(selectableProps)
.into(tableName)
.timeout(timeout)
}
const findAll = () => {
return knex.select(selectableProps)
.from(tableName)
.timeout(timeout)
}
const find = filters => {
return knex.select(selectableProps)
.from(tableName)
.where(filters)
.timeout(timeout)
}
const update = (id, props) => {
delete props.id
return knex.update(props)
.from(tableName)
.where({
id
})
.returning(selectableProps)
.timeout(timeout)
}
const destroy = id => {
return knex.del()
.from(tableName)
.where({
id
})
.timeout(timeout)
}
return {
query,
name,
tableName,
selectableProps,
timeout,
create,
findAll,
find,
update,
destroy
}
}
This is my controller.js file
const model = require('./model');
const user = model({
name: "users",
tableName: "tbl_users",
});
const getAllUsers = async (req, res, next)=>{
let result = await user.findAll();
res.send(result);
}
module.exports = { getAllUsers }
And Lastly a the connection.js file
const knex = require('knex')({
client: 'pg',
connection: {
host: 'YOUR_HOST_ADDR',
user: 'YOUR_USERNAME',
password: 'YOUR_PASS',
database: 'YOUR_DB_NAME'
},
pool: {
min: 0,
max: 7
}
});
module.exports = knex;

Resources