Login failed using Express and Sequelize with SQL Server - node.js

I am trying to use Sequelize (v 5.21.13) to connect to my SQL Server database in my Expressjs app.
dbconfig.js
var dbConfig = {
server: process.env.DB_HOST,
authentication: {
type: 'default',
options: {
userName: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD
}
},
options: {
database: process.env.DB_NAME
}
};
module.exports = dbConfig;
index.js:
const dbConfig = require('./dbConfig');
const Sequelize = require('sequelize');
const connection = new Sequelize(
dbConfig.options.database,
dbConfig.authentication.options.userName,
dbConfig.authentication.options.password,
{
host: dbConfig.server,
dialect: 'mssql',
}
);
connection.sync().then(() => {
console.log('Connected!');
}).catch((e) => {
console.log('Error:\n', e);
});
Now the thing is that each time I run the server, I get this error
AccessDeniedError [SequelizeAccessDeniedError]: Login failed for user 'master'.
I have also tried adding additional properties to the new Sequelize() like the following with no luck.
dialectOptions: {
instanceName: 'instance',
options: {
encrypt: true,
trustServerCertificate: true,
requestTimeout: 30000
}
}
I even tried changing the password to a very simple one with no special characters, connection with Datagrip works after changing but not using Sequelize.
Everything on the dbconfig object is correct so I don't see what the issue might be.

Solved it. I was putting the the db instance id as the database name, I realized that the database name was different. Changed it and I'm now connected through Sequelize.

Related

Connection timed out on AWS Lambda

I'm trying to connect to my DB from Lambda as follows:
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'user', 'password', {
host: 'host',
port: '5432',
dialect: 'postgres'
});
const Survey = sequelize.define('survey', {
id: Sequelize.UUID
})
const a = await Survey.findAll({
where:{
share_id: '4bdd12bc-35f3-4c44-8478-741106757bd2',
},
limit:10
})
}
when I try to test this code I'm getting an error saying that it timed out:
"errorMessage": "2022-09-30T10:56:32.069Z c89d7b89-b4b1-4283-8e5e-679ca2de5974 Task timed out after 10.01 seconds"
I tried using different libraries too, like pg, massive, but got the same response from all of them.

typeorm 0.3.6 - db connection per request

I’m migrating from 0.2.* to 0.3.6 version of typeorm. I’m not sure how to handle multi-tenant connections with new DataSource.
My previous implementations was based on connectionManager and it looked something like this:
{
const connectionManager = getConnectionManager();
// Check if tenant connection exists
if (connectionManager.has(tenant.name)) {
const connection = connectionManager.get(tenant.name);
return Promise.resolve(
connection.isConnected ? connection : connection.connect()
);
}
// Create new tenant connection
return createConnection({
type: 'postgres',
name: tenant.name,
host: tenant.host,
port: tenant.port,
username: tenant.username,
password: tenant.password,
database: tenant.database,
entities: [...TenantModule.entities],
});
}
Connection manger is now deprecated. Maintaining my own array of connections doesn’t sound right to me.
Any ideas on how this should be handled the correct way?
with typeorm: 0.3.6 getConnection, createConnection among others are deprecated. You can find migration guide in here
to create a new connection, you will have to use DataSource as follows:
import { DataSource, DataSourceOptions } from 'typeorm';
const dataSourceOptions: DataSourceOptions = {
type: 'mysql',
host,
port,
username,
password,
database,
synchronize: false,
logging: false,
entities: ['src/database/entity/*.ts'],
migrations: ['src/database/migration/*.ts'],
};
export const AppDataSource = new DataSource(dataSourceOptions);
where new DataSource is equivalent to new Connection and dataSource is equal to getConnection.
To check if you are connection to database, you will have utilize AppDataSource:
AppDataSource.initialize()
.then(() => {
// db initialized
})
.catch((err: Error) => {
throw new Error(`'Database connection error: ${err}`);
});

How to use sequelize to connect to Cloud SQL MySQL Instance? Error: sequelizeconnectionerror: connect ENOENT

I am trying to connect to my database from my Nodejs server like this:
const db = new Sequelize(sql.database, sql.username, sql.password, sql.config);
const connectDB = async () => {
try {
await db.authenticate();
logger.info(`MySQL DB Connected: ${sql.config.host}`)
} catch (error) {
logger.error(`Error: ${error}`);
process.exit(1)
}
}
My configuration looks like:
const sql = {
database: process.env.SQL_DATABASE as string,
username: process.env.SQL_USER as string,
password: process.env.SQL_PASSWORD,
config: {
dialect: "mysql" as Dialect,
host: "/cloudsql/{instance}" as string,
dialectOptions: {
socketPath: "/cloudsql/{instance}",
},
},
};
However I am getting a sequelizeconnectionerror: connect ENOENT
Is there anything I'm missing to connect to my Cloud SQL instance in GCP?
Your sql.config object is missing a "port" key to access the database at. The default port in MySql is 3306.
Depending on your database setup you should also add ssl configuration options.
If you have SSL setup you'd do that by adding a key "ssl" to your dialectOptions with an object containing "key", "ca" and "cert" passing the appropriate certificate to each of them.
Your code would then look like this:
const sql = {
database: process.env.SQL_DATABASE as string,
username: process.env.SQL_USER as string,
password: process.env.SQL_PASSWORD,
config: {
dialect: "mysql" as Dialect,
host: "/cloudsql/{instance}" as string,
port: process.env.SQL_PORT,
dialectOptions: {
socketPath: "/cloudsql/{instance}",
ssl: {
key: process.env.SQL_KEY,
ca: process.env.SQL_CA,
cert: process.env.SQL_CERT
}
},
},
};

SQL Server database access issue from AWS Lambda

I'm getting this error while accessing SQL Server database from aws-lambda. Everything works fine from local machine.Only having access issue when executing the code from lambda.
ConnectionError: Failed to connect to 10.2.3.44\SQLSRVR code: ETIMEOUT
This is my code snippet, any help would be appreciated!
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('DBname', null, null, {
dialect: 'mssql',
host: '10.2.3.44', //MSSQL Server IP sample
dialectOptions: {
authentication: {
type: 'ntlm',
options: {
domain: 'addidas',
userName: "uname",
password: "pwd"
}
},
options: {
instanceName: 'SQLSRVR'
}
}
})
async function connect() {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (error) {
console.error('Unable to connect to the database:', error);
}
}
connect();
It was because of the network restrictions only, as assumed. So had to assign lambdas in the same network which SQL server is hosted.
Thanks for all the suggestions.

How to add an SSL certificate (ca-cert) to node.js environment variables in order to connect to Digital Ocean Postgres Managed Database?

I am currently using node-postgres to create my pool. This is my current code:
const { Pool } = require('pg')
const pgPool = new Pool({
user: process.env.PGUSER,
password: process.env.PGPASSWORD,
host: process.env.PGHOST,
database: process.env.PGDATABASE,
port: process.env.PGPORT,
ssl: {
rejectUnauthorized: true,
// Would like to add line below
// ca: process.env.CACERT,
},
})
I found another post where they read in the cert using 'fs' which can be seen below.
const config = {
database: 'database-name',
host: 'host-or-ip',
user: 'username',
password: 'password',
port: 1234,
// this object will be passed to the TLSSocket constructor
ssl: {
ca: fs.readFileSync('/path/to/digitalOcean/certificate.crt').toString()
}
}
I am unable to do that as I am using git to deploy my application. Specifically Digital Oceans new App Platform. I have attempted reaching out to them with no success. I would prefer not to commit my certificate in my source control. I see a lot of posts of people suggesting to set
ssl : { rejectUnauthorized: false}
That is not the approach I want to take. My code does work with that but I want it to be secure.
Any help is appreciated thanks.
Alright I finally was able to figure it out. I think the issue was multiline and just unfamiliarity with dotenv for my local developing environment.
I was able to get it all working with my code like this. It also worked with the fs.readFileSync() but I didn't want to commit that to my source control.
const { Pool } = require('pg')
const fs = require('fs')
const pgPool = new Pool({
user: process.env.PGUSER,
password: process.env.PGPASSWORD,
host: process.env.PGHOST,
database: process.env.PGDATABASE,
port: process.env.PGPORT,
ssl: {
rejectUnauthorized: true,
// ca: fs.readFileSync(
// `${process.cwd()}/cert/ca-certificate.crt`.toString()
// ),
ca: process.env.CA_CERT,
},
})
.on('connect', () => {
console.log('connected to the database!')
})
.on('error', (err) => {
console.log('error connecting to database ', err)
})
Now in my config.env I had to make it look like this:
CA_CERT="-----BEGIN CERTIFICATE-----\nVALUES HERE WITH NO SPACES AND A \n
AFTER EACH LINE\n-----END CERTIFICATE-----"
I had to keep it as a single line string to have it work. But I was finally to connect with
{rejectUnauthorized:true}
For the digital ocean app platform environment variable, I copied everything including the double quotes and pasted it in there. Seems to work great. I do not think you will be able to have this setting set to true with their $7 development database though. I had to upgrade to the managed one in order to find any CA cert to download.

Resources