Connections to postgres database failure - node.js

I am trying to implement an auth service using node-express-postgres.
I had the pool configed as such:
const Pool = require('pg').Pool;
const pool = new Pool({
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
port: 5432
});
module.exports = pool;
I am trying to do the following call as a simple test for connection:
const express = require('express');
const router = express.Router();
const pool = require('../db');
const bcrypt = require('bcryptjs');
router.post('/login', async (req, res) => {
try {
let temp = await pool.query("SELECT * FROM records");
console.log(temp)
} catch (error) {
console.log(error.message);
}
});
When I send a post request to this endpoint my app crash with the following error:
Error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string
I have checked all my env vars and they are correct.
Any idea why it is failing to do any operation on the postgres DB?

It seems, that node didn't read .env file.
You can check it with
console.log(process.env.DB_PASSWORD);
It can be fixed with package 'dotenv', for example.
npm i --save dotenv
And then in first line in index.js
require('dotenv').config();

For me configuring 'dotenv' resolved error
require('dotenv').config();

Check your postgres password if it's correct. I had a similar problem while working on a mac, by default the
posgreSQL user is "posgres" and password is "root"
In my case I had something like
...
USER: "postgres",
PASSWORD: "",
...
which generated the error

you probably should indicate your .env file location inside of the config
require('dotenv').config({ path: '../.env' });
dotenv configurations

Fixed it by updating npm script.
cross-env NODE_ENV=development nest start
Installed "cross-env" to set NODE_ENV.
If our code is not able to find .development.env file or unable to find password, then this error will be thrown.

Check out the path in your IDE folder, when i checked, it was by one path below, so i moved it in the correct folder and boom, it all worked.

Related

NodeJS to SQL Server Connection not working: socket hang up issue

Here is my complete code for sql connection, all code I have got from stackoverflow issues.
Everywhere, I found the same code is being suggested, hence I also tried with the same.
I have some other application which uses same connection with NextJs and it works fine, however, If I try only with NodeJS code, it gives some socket hang up error (code:'ESOCKET' name:'ConnectionError').
Please make a note that TCP is already configured on remote server and its working fine with other applications.
Any help is appreciated, thank you.
const express = require('express');
const fs = require('fs');
const path = require('path');
const cheerio = require("cheerio");
const sql = require('mssql');
require('dotenv').config(); //to use the env variables
// config for your database
var config = {
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
server: process.env.DATABASE_HOST,
database: process.env.SOMEDB,
port: 14345, // process.env.DATABASE_PORT,
options: {
encrypt: true, // for azure
trustServerCertificate: false // change to true for local dev / self-signed certs
}
};
// make sure that any items are correctly URL encoded in the connection string
let appPool = new sql.ConnectionPool(config);
//I got error on below connect
sql.connect(config).then(function(pool) {
//It never reaches here, it directly goes to the catch block
app.locals.db = pool;
const server = app.listen(3000, function () {
const host = server.address().address
const port = server.address().port
console.log('Example app listening at http://%s:%s', host, port)
})
}).catch(function(err) {
console.error('Error creating connection pool', err)
});
I have the same issue.
Try to use mssql version 6.0.1, it works on my code, but for sure we need to figure out the problem, since we can't think to mantain forever an old version of a package.
I kept trying to find the solution with different different configuration changes.
Finally, I have made a proper config, which worked and now its connecting properly as well as returning the data from the table.
require('dotenv').config(); //to access the process.env params
const sql = require("mssql"); //mssql object
var dbConfig = {
user: "ajay",
password: "abcd123",
server: "your_remote_sql_server_path",
port: 1433,
database: "your_database_name",
options: {
database: 'your_database_name',
trustServerCertificate: true
}
};
try {
//connection config will be used here to connect to the local/remote db
sql.connect(dbConfig)
.then(async function () {
// Function to retrieve the data from table
const result = await sql.query`select top 1 * from table_name`
console.dir(result)
}).catch(function (error) {
console.dir(error);
});
} catch (error) {
console.dir(error);
}
I am not sure what was the exact issue, but as per the previous config and this one, it seems like adding database name to the options has solved the issue.
Please make sure to save all the sensitive data to the .env file. (which you can access as PROCESS.env.parametername)
For me in driver mssql#9.1.1 making encrypt=false worked
const config = {
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
server: process.env.DATABASE_HOST,
database: process.env.SOMEDB,
port: 14345, // process.env.DATABASE_PORT,
options: {
encrypt: false
}
};

How to connect a Database to an Angular Web Application?

I want to display and edit data from a existing PostgreSQL database in an Angular Web Application.
I am completely new to angular and stuff.
I downloaded pg and express already.
After a look on this page: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose
I figured I will need jugglingdb to connect the database to angular: https://npm.taobao.org/package/jugglingdb or https://www.npmjs.com/package/connect-jugglingdb
-> more specific: Juggling-db with postgres: https://npm.taobao.org/package/jugglingdb-postgres
So I created a new file called postgres.js:
var Schema = require('jugglingdb').Schema;
var schema = new Schema('postgres', {
database: 'mydatabase',
username: 'myusername',
host: 'myhostname', //I don't use the local user
port: XXXX,
password: s.password,
ssl: false
});
var Model = schema.define('Model', {
realNumber: {type: Number, dataType: 'float'}
});
Then I tried it with the help of this answer: Restful Api express postgres database
so I created a File called "dbconnector.js
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const port = 1234
const db = require('./dbconnector')
// 'db' is exported from a file such as
// dbconnector.js.
app.get('/things', db.getThings)
//In dbconnector.js:
const Pool = require('pg').Pool
const pool = new Pool({
user: 'myuser',
host: 'myhost',
database: 'mydb',
password: 'mypassword',
port: 5432,
})
const getThings = (request, response) => {
pool.query('SELECT * FROM public.regulation',
(error, results) =>
{
if (error) {
throw error
}
response.status(200).json(results.rows)
})
}
module.exports = {
getThings
}
I have searched, read and tried a lot of tutorials.
But whatever I try - I just can't display the data from the database in the web applikation.
Any ideas how I shall proceed?
Do you know a complete guide (connecting the database and displaying the data?)
or do you have any links or tips?
Edit
Found this very useful Link to a download example: https://grokonez.com/frontend/angular/angular-6/angular-6-httpclient-postgresql-node-js-express-sequelize-crud-apis-post-get-put-delete
An Angular application typically runs in the browser, while your database lives on a server. In simple terms, you usually connect them up by building a backend to your application that exposes any required data to consumers via an API.
It looks like you are using NodeJS for your backend from the links that you posted, so you could look into creating a RESTful API using express.

Sequelize migration in Heroku Postgres: Chain of errors

My express.js app is on a heroku dyno. I created some rest api endpoints for crud operations (connected to heroku-postgres db) and checked they worked with Postman.
My problems have started after I tried incorporating migrations. I am just a jr. dev so please let me know if I am investigating dead leads, and what other information to provide to properly diagnose these error messages.
Starting migrations with sequelize model:create --name tableName --attributes ... was fine.
When running sequelize db:migrate, the error I get is:
ERROR: Dialect needs to be explicitly supplied as of v4.0.0
My current config.json is
{
"production": {
"use_env_variable": "DATABASE_URL",
"dialect": "postgres",
"dialectOptions": {
"ssl": {
"require": true
}
},
"ssl": true
}
}
and I have also specified the dialect in models/index.js (this was generated along with config.json in the sequelize model:create... command)
require('dotenv').config();
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = 'production' || process.env.NODE_ENV;
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
const sequelize = new Sequelize(process.env.DATABASE_URL, {
logging: false,
dialect: "postgres",
dialectOptions: {
ssl: true,
}
});
// let sequelize;
// if (config.use_env_variable) {
// sequelize = new Sequelize(process.env[config.use_env_variable], config);
// } else {
// sequelize = new Sequelize(config.database, config.username, config.password, config);
// }
If const sequelize = ... is commented out, and let sequelize; ... is used instead, the same dialect error occurs.
Interestingly, when I set the shell variable export NODE_ENV=production, a new error occurs - ERROR: Error parsing url: undefined.
This is more baffling to me as I thought it was already defined in the const env = ... line in index.js.
So then I tried specifying url in the migration command - sequelize db:migrate --url 'postgres://username:password#localhost/test1'.
This url that I have provided worked for the CRUD testing via Postman, as well as via the front-end collecting the form data.
Now the error is ERROR: connect ECONNREFUSED 127.0.0.1:5432. I am unsure how to proceed from this point, and not sure that the steps I have taken since the dialect error are the correct ways to fix these problems.
My questions really are the cause of these errors.
1) Where else do I need to specify dialect?
2) Why does the dialect error go away when I export NODE_ENV, even though the environment is already specified in index.js?
3) Similarly for the url, why won't url from my .env brought in with require('dotenv').config() be accepted?
It was all well and good to generate migration and model files using the sequelize-cli. I had pushed these changes to heroku but was running the migration commands locally. (I do not have a local dev database, my only environment is production).
Another problem was, the heroku bash ran in what I can only describe as a snapshot of the application's state when heroku run bash is run. This meant that even though I was creating, editing, and pushing just fine, the migration commands would be 'stuck' on the old version until the bash was restarted.

Can't connect to database with process.env variables but process.env vars print in log

I'm connecting to a redshift database with Node/express. I put the variables to connect to the database in a .env file, and on my local machine, I'm able to connect to the website on localhost.
However, when I upload the files to the server and change the clientConfiguration, it no longer works, even after I've changed my require('dotenv').config({path: }) to the correct path. I'm pretty sure the path is correct because process.env.HOST will print in the logs.
This error will show up: password authentication failed for user "root"
This is the hardcoded part that works.
var clientConfiguration = {
user: "user",
database: "database",
password: "password",
port: 1234,
host: "hosturl.com",
};
When I swap this part in, it no longer works.
var clientConfiguration = {
user: process.env.USER,
database: process.env.DATABASE,
password: process.env.PASSWORD,
port: process.env.PORT,
host: process.env.HOST,
};
I thought it was because process.env variables get read in as strings, but that didn't help even after I used parseInt(process.env.PORT) -- I also didn't need the parseInt on my local machine, so I dont understand the
Are you calling dotenv.config() as early as possible? I call it right after creating a new Express instance and it usually works.
Also, not sure if this is the 'accepted way', but I have had a similar issue before and found making an async dotenv.config() call inside the IIFE where I start my server solved the issue:
//AWAIT DB CONNECTION BEFORE STARTING SERVER
(async function () {
try {
await dotenv.config();
await connectDB();
app.listen(PORT, ()=> {
console.log(`Server listening in ${MODE} mode on ${PORT}`);
});
} catch (err) {
console.log(`Failure to start server: ${err}`);
}
})();
connectDB() is my attempt to connect to a MongoDB database via mongoose.connect(). Obviously not the ideal solution as you want to call it earlier, but it did work.

heroku db connection refused

I am pretty new to heroku and node. While I was trying to connect to heroku db, the following error shows up.
Error: connect ECONNREFUSED 127.0.0.1:5432
I am using connection pooling:
var pg = require('pg');
var heroconfig =process.env.DATABASE_URL || "postgres://jykyslkwkdsvhz:3ba43ff7db0c8dv9a914bac02f55ce944d8ccec31b67f858df3a858faa386c8e#ec2-54-243-214-198.compute-1.amazonaws.com:5432/dfiijlh3fbe3g9";
//var pool1 = new Pool(heroconfig);
var pool1 = new Pool(heroconfig);
app.get('/db', function(req, res){
pool1.query('SELECT * FROM test_table;',function(err, result){
if(err){
res.status(500).send(err.toString());
} else{
res.send(JSON.stringify(result.rows));
}
});
});
I tried to look at similar questions form other users but could not find solution involving pooling.
Please help.
I figured it out partially,
Storing the configuration data as object as below makes it works
var heroconfig = {
user: 'username',
database: 'database name',
password: 'some pass word',
host: 'host name',
port: 5432,
max: 10,
idleTimeoutMillis: 30000,
};
However while using the line of code mentioned in my original question, where database url is stored into the variable, it is not working:
var heroconfig =process.env.DATABASE_URL || "postgres://jykyslkwkdsvhz:3ba43ff7db0c8dv9a914bac02f55ce944d8ccec31b67f858df3a858faa386c8e#ec2-54-243-214-198.compute-1.amazonaws.com:5432/dfiijlh3fbe3g9";
I am planning to store my credentials in a different file and require it in my server file which seems to be a better approach.
I know this is late, but according to the docs in order to use a connection string, you must do this:
const { Pool, Client } = require('pg')
const connectionString = 'postgresql://dbuser:secretpassword#database.server.com:3211/mydb'
const pool = new Pool({
connectionString: connectionString,
})
See here: https://node-postgres.com/features/connecting#connection-uri
I have had such an error. After a lot of hours of research, I found out that my server deployed to Heroku was trying to access my PC PostgreSQL database. But it should have connected to the added-on PostgreSQL database in Heroku. I mean my server wasn't connecting to the database link in production mode, it was connecting to the database in development mode. I fixed it in my code like this.
db.js contents:
// focus on const environment
const environment = process.env.NODE_ENV || "development";
const knex = require("knex");
const knexfile = require("./knexfile");
const db = knex(knexfile[environment]);
module.exports = db;

Resources