NodeJS and Mysql connection configuration ignored - javascript

I have a weird behavior while I'm trying to query my MySQL database from a nodeJS API.
I define a connection pool to mysql on node using the following code
const mysql = require('mysql2')
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: 'mydb.user',
database: process.env.DB_DB,
password: process.env.DB_PWD,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
multipleStatements: true
}).promise()
Before that, I was using another user named mydb.owner defined in a .env file.
When I execute a query, I have the following error
Access denied for user 'mydb.owner'#'localhost' to database 'mydb'
That's not the user I've configured, that's the old one.
If I have a look on the Mysql connections, I can see that the user of the pool is correct:
show processlist;
Returns
Id User Host db
6 root localhost:37752 mydb
9 mydb.user localhost:38102 mydb
It seems I haven't any environment variable defined from elsewhere:
echo $DB_USER
Returns nothing.
The user seems to have the necessary rights :
SHOW GRANTS FOR 'mydb.user'#'localhost';
GRANT USAGE ON *.* TO 'mydb.user'#'localhost'
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `mydb`.* TO 'mydb.user'#'localhost' WITH GRANT OPTION
I don't understand why mysql2 returns me an error about my old user mydb.owner.

The query was a stored procedure and was created by default with the tag
CREATE definer = 'mydb.owner'#'localhost' PROCEDURE ...
No matter which user execute the stored procedure, it was impersonated with the mydb.owner account.
To specify that the procedure must be executed under the current account, I added the following instructions:
CREATE definer = 'mydb.owner'#'localhost' PROCEDURE ...()
SQL SECURITY INVOKER
BEGIN ...

Related

Is there a way to create a database with mongoose that has a username and password?

I'm currently working on a app (dev with electron). I'm using mongoDB and mongoose for my persistant storage but I can't find a way to do something that seem really basic : when creating a database I'd like to add an user and a password to it (I realy search for it, but no way to find anything usable).
I have this need because it's going to be a multi-user app and I definitly don't want an user to know the contents of another user account.
The idea is that once you create an account, the app create a database that has the same username and password of the account. For login, the app try to connect you to the database with your account & password.
I'm working with :
electron
HTML / CSS / javascript
mongoDB
mongoose
Here is the code that I tested :
var mongoose = require('mongoose');
var connStr = "mongodb://localhost:27017/test";
mongoose.connect(connStr, {user: 'newUser', password: 'pwd', useNewUrlParser: true }, function(err) {
if (err) {throw err};
console.log("Successfully connected to MongoDB");
});
I get the error
Uncaught (in promise) MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoError: password must be a string]
However with those, the database is correctly created (but anyone can access it) :
user: '', password: ''
What I expect is to create a new database with the user name set as "newUser" and the password as "pwd", in that way only with the correct id & password would it be possible to connect to it.
Thanks for your help !
I don't know if this will work or not but I ran a mongo service using docker and then connected mongoose to it with the following code
mongoose.connect('mongodb://user:pass#localhost:port/MyDB?authSource=admin', {
useNewUrlParser: true
})
.then(() => console.log('MongoDB connection successful'))
.catch(err => console.error('Could not connect to MongoDB:‌', err));
this is equivalent to
mongo --username user --password pass --authenticationDatabase admin --port 27017

How to create dynamic database connection with NodeJS, Express, and Sequelize?

how are you doing? Does anyone know how to create database connection dynamically using NodeJS, Express, and Sequelize?
My development team is developing an API for our mobile application, and on the login page, we'll have 3 fields:
Enterprise Code
Username
Password
When the user inputs the "Enterprise Code", I need to go to my default database, which stores all our customers and search the client data based on what was inputted in the field. Let's suppose that the enterprise code is 147, then the API goes to the customer's table into the default database and search for the data where customer_id = 147. That will return the customer data, which also contains its database name, for example, 147_enterprisename, which is a database named "147_enterprisename" referring to this customer.
What I need is: Create a Sequelize connection based on which "Enterprise Code" was typed, like this:
const Sequelize = require('sequelize')
const sequelize = new Sequelize(dynamic_database_name, 'root', 'root', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000
}
})
I also need that the API returns the connection to all routes, where is the functions that fetch data from the database and so on.

Knex.js / SQL : Knex / SQL Connection Pools

I have a question regarding SQL connection pools. My team is using the knex.js library in one of our node applications to make database query's.
The application from time to time needs to switch databases. So my team created an initialization function that returns a knex object configured to the correct database. Then that object is used to do said query. To me this seems redundant and can cause bad performance, because we initiate a knex object every time need to do a query instead of reusing a single knex object. Which i could ignore if knex already does this when you which databases (and if anyone could shed light on this question as well that would be FANTASTIC !) . Moreover, (and this leads me to my question titled above) the connection pool properties are redefined. So does that mean we are creating new pools every time, or does the SQL ( SQL Sever in this case) reuse the connection pool you already defined ? The question might not be Knex specific, like if i used a library like knex for C#, and call that library a similar way, would SQL Server know not to make more connection pools?
Example code:
/** db.js
* #param {any} database
* #returns db: Knex
*/
module.exports = ( database ) => {
var knex = require('knex')({
client: 'mssql',
connection: {
database: database,
server: '127.0.0.1',
user: 'your_database_user',
password: 'your_database_password'
},
pool: {
min: 0,
max: 10,
idleTimeoutMillis: 5000,
softIdleTimeoutMillis: 2000,
evictionRunIntervalMillis: 500
}
});
return knex;
};
Index.js
var db = require('./db.js');
/**
* #returns users:Array
*/
const getUsers = async() => {
const users = await db('master')
.select()
.from('users_table')
.orderBy('user_id');
return users;
}
Short answer: The 'singleton' nature of the node require() statement prevents reinitialization of multiple occurrences of knex. So the initially created pool continues to be used for the duration of your process, not recreated, as long as you don't discard the db. variable reference.
More discussion...
... my team created an initialization function that returns a knex
object configured to the correct database. Then that object is used to
do said query. To me this seems redundant and can cause bad
performance, because we initiate a knex object every time need to do a
query instead of reusing a single knex object. Which i could ignore if
knex already does this when you switch databases...
var db = require('./db.js');
The node.js require statement creates a singleton object. (You probably already know) this means that the first time the module is called by your program using the require statement, the module and it's data will be initialized, but successive identical require calls will just reuse the same module reference and will not reinitialize the module.
... the connection pool properties are redefined. So does that mean
we are creating new pools every time, or does the SQL ( SQL Sever
in this case) reuse the connection pool you already defined ?
So since the require()-ed module is not reinitialized, then the originally created pool will not be re-created. Unless you discard the db variable reference (discussed more below).
The question might not be Knex specific, like if i used a library like
knex for C#, and call that library a similar way, would SQL Server
know not to make more connection pools?
Generally speaking, you need to build or acquire connection some code to properly manage a pool of connections throughout the life of your process. Knex and most other database wrappers do this for us. (Under the covers Knex uses this library before v0.18.3 and this one on/after.)
Properly initializing and then using the singly initialized pooling code throughout the life of your application process accomplishes this. Discarding the pool and recreating it within your process defeats the purpose of having pooling. Often pooling is setup as part of process initialization.
Also, this was probably just a misstatement within your question, but your Node.js module is making the connection pools, not the SQL Server.
... The application from time to time needs to switch databases. my
team created an initialization function that returns a knex object
configured to the correct database.
From that statement, I would expect to see code like the following:
var db = require('./db.js');
var dbOther = require('./dbOther.js');
... which each establishes a different database connection. If you are instead using:
var db = require('./db.js');
// ... do other stuff here in the same module ...
var db = require('./dbOther.js');
... then you are likely throwing away the original reference to your first database, and in that case, YES, you are discarding your DB connection and connection pool as you switch connections.
Or, you could do something like the following:
// initialize the 2 connection pools
const dbFirst = require('./db.js');
const dbOther = require('./dbOther.js');
// set the active connection
var db = dbFirst;
// change the active connection
db = dbOther;

Trying to connect to SQL Server 2014 on NodeJS

I am trying to connect to SQL Server 2014 with NodeJS, i am using the "mssql" package, i dont have answer here is my code
var sql = require('mssql');
var opciones = {
user: 'myuser',
password: 'mypass',
server: 'myserver',
database: 'mydatabase',
options: {
encrypt: true
}
};
sql.connect(opciones,function(err){
if(err){
console.log(err);
}else{
console.log("CONEXIÓN EXITOSA");
}
});
the name of that js is "cnSQL.js", when i execute on cmd "node cnSQL" I dont have answer.
Tested the code as above with my local DB instance.
The code is actually correct.
var sql = require('mssql');
var opciones = {
user: 'sa',
password: 'mypass',
server: '127.0.0.1',
database: 'mydb',
options: {
encrypt: true
}
};
sql.connect(opciones,function(err){
if(err){
console.log(err);
}else{
console.log("CONEXIÓN EXITOSA");
}
});
I have managed to get the 'Connexion Exitosa' message.
In order to further debug your issue, attempt the following:
With the username you are trying to login with (In my case 'sa')
Open SQL Server Management Studio and attempt to put in the connection information as above. Click login, does that work?
If not:
Open SQL Server Management Studio
Connect to the SQL Server Instance you are trying to connect to from NodeJS
Right click on the instance of your SQL server and click properties
Click security and ensure that the "SQL Server and Windows Authentication mode" radio button is selected.
When done click OK
On the left hand navigation expand the Node "Security"
Expand Logins
Find your user and ensure it is enabled and that the password you selected reflects the password within your NodeJS app.
If so:
Amend all the information within the code to reflect exactly the credentials used to login
Special Note: '.' will not represent localhost here. Use 127.0.0.1 or localhost
Furthermore, if the SQL server instance you are trying to connect to is not hosted locally. Ensure that the machine it is hosted on accepts connections on port 1433 (by default for SQL Server).
Hope it helps!

Mysql pooling in node.js, should I use only one pool?

Here's the issue: When I use my local environment MYSQL I get no issues when not using MYSQL pools, however, when I connect to the remote DB that I want to use for production, I get an error about too many connections (it says the current amount of connections is 10).
So here's what I did to solve the issue:
if (typeof GLOBAL.connection === 'undefined') {
GLOBAL.connection = mysql.createPool({
connectionLimit : 10,
host : this.host,
user : this.user,
password : this.password,
database : this.database
});
}
this.connection = GLOBAL.connection;
This solves the issue by creating one global pool, that all queries must run through. The only "problem" as I can see it is that now I have this pool sitting in my global variable.
Each time my queries run it instantiates a new Query(); object, which contains the above code in it. I'm basically just trying to find out if this has repercussions that I can't currently see, that may bite me in the butt later?
Thanks for your help!

Categories

Resources