MongoDB / Express - How to switch database after connecting via connect() - javascript

I am using express to connect to my mongoDB:
mongodb.MongoClient.connect(mongourl, function(err, database) {
// How would one switch to another database here?
});
I have to connect to the admin database in the first place. After the conenction has been established, i would like to switch the database.
Although i have searched through the official documentation, i was unable to find something that fits my needs.
I am aware of the MongoClient::open() method, but i would like to stick to connect().
Any help is appreciated.

You can switch to another database like so:
mongodb.MongoClient.connect(mongourl, function(err, database) {
// switch to another database
database = database.db(DATABASE_NAME);
...
});
(docs)
EDIT: for clarification: this also allows you to open multiple databases over the same connection:
mongodb.MongoClient.connect(mongourl, function(err, database) {
// open another database over the same connection
var database2 = database.db(DATABASE_NAME);
// now you can use both `database` and `database2`
...
});

You just have to call MongoClient.connect once again, because there is one connection per database. That means, you cannot change the database of an existing connection. You have to connect a second time:
mongodb.MongoClient.connect(mongourl, function(err, database) {
mongodb.MongoClient.connect(mongourl_to_other_database, function(err, database2) {
// use database or database2
});
});

Related

Is this a secure enough method to recover data?

I'd love to know if this method I'm using is secure enough to use on a public project, since I can't really find any other way to retrieve my id from my currently logged in user, but it's a fairly straightforward method , I find. If this method is not secure would it be possible to have a way to proceed? Thanks in advance.
I have a button for example when I use the send of the html that there is inside my div userid on the server to then use this information to make SQL queries from my app.js server.
I use socket.io hbs express node js jwt mysql
From my pages.js file generated with the express library where the main roads of my website are located, I send my user ID.
router.get('/accueil', authController.isLoggedIn, (req, res) => {
if(req.user) {
res.render('./accueil', {
data: req.user.id
});
} else {
res.redirect('/');
}
});
With Handlebars I display this data in my index.hbs (display: none;).
<div id="iduser">{{data}}</div>
Then I get my iduser div on my client.js
let userid = document.getElementById('iduser').innerHTML;
// (My method to display this div)
socket.on('uid', (data) => {
pargent.innerHTML = JSON.stringify(data.data[0].argent);
})
//
So I want to use this userid variable to make SQL queries from my app.js.
(let userid = document.getElementById('iduser').innerHTML;)
I am using socket.io for communication between client and server to send my userid data
Example :
db.query('UPDATE users SET money = money + ? WHERE id = ?', [100, theUserId]);
No
Never trust user supplied data.
References:
https://www.oreilly.com/library/view/http-developers-handbook/0672324547/0672324547_ch22lev1sec1.html
https://flylib.com/books/en/1.290.1.90/1/
https://www.garybell.co.uk/never-trust-user-input/
https://medium.com/#berniedurfee/never-trust-a-client-not-even-your-own-2de342723674
https://www.invicti.com/blog/web-security/input-validation-errors-root-of-all-evil/
https://laravel-news.com/never-trust-your-users
https://www.wearenova.co.uk/nova-blog/when-it-comes-to-online-security-why-you-should-never-trust-a-client
It depends on your authController.isLoggedIn logic,
But I would like to suggest an alternative solution simple as that;
iron-session
Read their docs, it's matches your use case and easy to use; here is equivalent of the snippet you provided with iron session:
//initiate session middleware yourself
router.use(session)
// later here
router.get('/accueil', (req, res) => {
if(req.session.user) {
res.render('./accueil', {
data: req.user.id
});
} else {
res.redirect('/');
}
});

How to declare a static array in Node.js?

I am trying to create a static array named "categories" whom I wish it will be initialized ONCE in my Node.js application. I mean, when I close the app and run it again - I want it to KEEP the state of the "categories" array.
What happens is that the array is initialized for each time I run this app. Though I want it to be declared only once in this app's lifetime.
router.post("/add_category", (req, res, next) => {
var category = req.body.category;
categories.push(category);
res.render("index", { categories });
});
The simplest solution is to just write the array to a file as JSON and then load that back in when your server starts.
let categories = require('./categories.json');
router.post("/add_category", (req, res, next) => {
var category = req.body.category;
categories.push(category);
fs.writeFile(`./categories.json`, JSON.stringify(categories), () => {
res.render("index", { categories });
});
});
Node.js, by itself, does not have any automatically persisted variables that get saved to disk by themselves and are automatically available the next time you run the program. You have to code that yourself.
You should need a database for that kind of data persistence. But at times, a full-blown database (MongoDB, SQL) could be considered overkill since you only need to save a simple array.
So, consider using the "node-persist" package, here's a possible solution:
const storage = require('node-persist');
storage.initSync();
storage.setItem('categories', [ . . . ] );
console.log(storage.getItem('categories'));
That is was databases are for. Consider Using some SQL or noSQL database that will store values even if server is reseted.

Error with get request for users

When using a get request for all the users in my database (see code below) i only get the "first" user in the database. If i instead try to use the "findOne"-method i get the same user as before no matter what i put in (the username doesn't even have to be in the db it still gives me the same user). I've been trying to understand why this isn't working but can't find any problems with the code. Could it be a problem with db settings or something similar? All help is appreciated!
In AuthController:
// Get all users
AuthController.allusers = function(req, res) {
User.find({}, function(err, users) {
}).then(function(users) {
res.json({users: users});
});
}
In routes:
// GET Routes.
router.get('/users', AuthController.allusers);
Since you are using Sequelizejs, you might want to do findAll.
AuthController.allusers = function(req, res) {
User.findAll().then(function (users) {
res.send({users: users});
}
}
According to the docs:
find - Search for one specific element in the database
findAll - Search for multiple elements in the database

Is it safe to use a single Mongoose database from two files/processes?

I've been working on a server and a push notification daemon that will both run simultaneously and interact with the same database. The idea behind this is that if one goes down, the other will still function.
I normally use Swift but for this project I'm writing it in Node, using Mongoose as my database. I've created a helper class that I import in both my server.js file and my notifier.js file.
const Mongoose = require('mongoose');
const Device = require('./device'); // This is a Schema
var uri = 'mongodb://localhost/devices';
function Database() {
Mongoose.connect(uri, { useMongoClient: true }, function(err) {
console.log('connected: ' + err);
});
}
Database.prototype.findDevice = function(params, callback) {
Device.findOne(params, function(err, device) {
// etc...
});
};
module.exports = Database;
Then separately from both server.js and notifier.js I create objects and query the database:
const Database = require('./db');
const db = new Database();
db.findDevice(params, function(err, device) {
// Simplified, but I edit and save things back to the database via db
device.token = 'blah';
device.save();
});
Is this safe to do? When working with Swift (and Objective-C) I'm always concerned about making things thread safe. Is this a concern? Should I be worried about race conditions and modifying the same files at the same time?
Also, bonus question: How does Mongoose share a connection between files (or processes?). For example Mongoose.connection.readyState returns the same thing from different files.
The short answer is "safe enough."
The long answer has to do with understanding what sort of consistency guarantees your system needs, how you've configured MongoDB, and whether there's any sharding or replication going on.
For the latter, you'll want to read about atomicity and consistency and perhaps also peek at write concern.
A good way to answer these questions, even when you think you've figured it out, is to test scenarios: Hammer a duplicate of your system with fake data and events and see if what happen is OK or not.

sequelizejs saving an object when row was removed

I have the following code. The idea is that I update a database row in an interval, however if I remove the row manually from the database while this script runs, the save() still goes into success(), but the row is not actually put back into the database. (Because sequelize does an update query with a where clause and no rows match.) I expected a new row to be created or error() to be called. Any ideas to what I can do to make this behave like I want to?
var Sequelize = require("sequelize")
, sequelize = new Sequelize('test', 'test', 'test', {logging: false, host: 'localhost'})
, Server = sequelize.import(__dirname + "/models/Servers")
sequelize.sync({force: true}).on('success', function() {
Server
.create({ hostname: 'Sequelize Server 1', ip: '127.0.0.1', port: 0})
.on('success', function(server) {
console.log('Server added to db, going to interval');
setInterval(function() { console.log('timeout reached'); server.port = server.port + 1; server.save().success(function() { console.log('saved ' + server.port) }).error(function(error) { console.log(error); }); }, 1000);
})
})
I'm afraid what you are trying to do is not currently supported by sequelize.
Error callbacks are only ment for actual error situations, i.e. SQL syntax errors, stuff like that. Trying to update a non-existing row is not an error in SQL.
The import distinction here is, that you are modifying your database outside of your program. Sequelize has no way of knowing that! I have two possible solutions, only one of which is viable right now:
1 (works right now)
Use sequelize.query to include error handling in your query
IF EXISTS (SELELCT * FROM table WHERE id = 42)
UPDATE table SET port = newport WHERE id = 42
ELSE
INSERT INTO table ... port = newport
Alternatively you could create a feature request on the sequelize github for INSERT ... ON DUPLICATE KEY UPDATE syntax to be implemented see and here
2 (will work when transactions are implemented
Use transactions to first check if the row exists, and insert it if it does not. Transactions are on the roadmap for sequelize, but not currently supported. If you are NOT using connection pooling, you might be able to acomplish transactions manually by calling sequelize.query('BEGIN / COMMIT TRANSACTION').

Categories