Best Practice to Safely Migrate Database in SailsJS App when using Mysql - mysql

I have an application developed with SailsJS and mysql. Only a logged in user is meant to be able to create a fresh user. During development stage, I made creation of the first user easy with a simple request to server. That is however not feasible again as I have written some policy codes to prevent such.
module.exports= async function(req, res, proceed){
const adminId = req.param('adminId');
if(!adminId){
return res.status(401).json({status: 401, message: 'Unauthorized access, invalid user'});
}
//let's check if the user has a role as superadmin
const superAdmin = await Admin.findOne({id: adminId, superAdmin: true});
console.log(superAdmin)
if(superAdmin){
return proceed();
}
else{
return res.status(401).json({status: 401, message: "Unauthorized access. You don't have this privilege"})
}
}
Also, Every saved new user has a compulsory createdBy column in mysql database.
I currently want to host the project on production. What best way should I do this. By default, I am supposed to run
sails lift --prod
On production environment and generate the mysql tables. However, I won't be able to login or create an admin user. So what is the best way for me to create a new user?

The "best" way is obviously subjective. Personally I would write a migration to bootstrap the DB with the first production user (you are using migrations, right?).
Some people eschew including DML in their migrations, although in my experience at some point in the long lifetime of an application under development, some type of "data fixup" needs to happen. Doing it as idempotently as possible in a migration has been the easiest and most reliable approach.

Related

What is the right way to use a database with flutter?

I have an app which interacts with the database directly with mysql1 library like the example below:
Future FetchData() async {
final connection = await MySqlConnection.connect(ConnectionSettings(
host: 'mysql-hostname.example.com',
port: 3306,
user: 'root',
password: 'root',
db: 'testDB',
));
var results = await connection.query('SELECT * FROM `testTable` WHERE 1');
for (var row in results) {
print('${row[0]}');
}
// Finally, close the connection
await connection.close();
}
I wonder if this is a safe and secure method. Because when I build the app I pack all the information (username, password) about connecting my database in the app. Is this risky so should I use a separate back-end for this kind of tasks?
It is generally safer to put a trusted backend environment between your database and app. But even in this case you will have to ensure that only your app has access to this backend resource.
For example if you use Firebase as backend, there is an AppCheck service available. Although this is relatively new, it can attest your app's authenticity.
If you prefer to do it on your own, you can create a bearer token that your app will add the the requests, preferably in the request's Authorization header, and check it in the backend before accessing protected resources. But then the question remains, where do you store this bearer token safely.
If you want to keep it in your code, you should properly obfuscate the code before uploading it to the app stores. Even in this case it is a good idea to check for rooted or jailbroken devices to prevent misuse, for example check out flutter_jailbreak_detection.
There are also secure storage packages, which can store sensitive data in a safer way. Unlike SharedPreferences, these can mitigate the risks of unauthorited access to your secrets. See flutter_secure_storage for example.
It really depends on the level of security that you are looking for. Are you storing user-generated sensitive information in your database? Then the answer is that you should ideally not store that information in your code nor should you ship your application with that information bundled inside it.
I highly suggest that you start using Firebase for your usage. Firebase is an absolutely fantastic and free product provided by the Google, the same company behind Flutter, and within a few minutes you can build a whole experience that relies on authentication with Firebase and you can safely store user-generated content in Firebase.

Long polling using node.js to get database updates

I'm fairly new to Node JS,As I switched from java server pages to node mainly to implement server push technology.
I want to implement a simple application, Which will push the data to users if any new record insertion in Mysql database taken place.
And take database name as wst and table name is registered_people,Table consists of one column named users.
Know if any record is inserted into table it should notify that a new user is added to current users.
How can I achieve that.
Thanks for any help.
This is what libraries like socket.io were designed for. It makes server push operations trivial.
As far as how to actually trigger the server push, that can be more complicated based on how you're getting the data into the database. If all the data into and out of the mysql database goes through the same node application, it's fairly straightforward. Just raise an event when there is an insert into the table, and have your socket.io (or other push code) listen for those events. Then every time a user it added, the message gets sent.
If the database is updated from multiple applications things get a bit more tricky. You can poll the database for updates to the user table, and then fetch the latest users when it changes. You could do something like the following:
setInterval(function() {
getUserCount(function(userCount) {
if(userCount > originalUserCount) {
// We have new users!
// Get the latest user and send it to the connected browsers.
}
});
}, 1000);
This isn't very efficient, but doing a SELECT COUNT(id) FROM Users; shouldn't add much overhead to your database. A cleaner solution would be to use some sort of messaging queue. If you have multiple systems interacting on a single database, a messaging system can ensure that you give all of those systems a chance to subscribe to things that are happening in other parts of the system. In this case you can have your node app subscribe to new user messages in the system and send them to the browsers.
http://socket.io/ is what you are looking for.
As shown in he documentation, its very simple to listen on server using socket.io
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
And connect to it using,
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
You could achieve push by broadcasting the update to all connected clients using io.sockets.emit(object); whenever your database state is changed.
Its also possible to restrict the message to a specific set of clients by using rooms

Keeping a user logged in with nodeJS

I have a login system with my NodeJS using mysql-node.
The problem i have how ever is how to keep the user logged in, if they refresh the page they have to login again, because i do not know how to store the session.
My login system is like this:
socket.on('login', function(data,callBack){
var username = sanitize(data['login']).escape(),
pass = sanitize(data['password']).escape();
var query = connection.query('SELECT uid FROM users WHERE name = ? AND pass = ?', [username,pass],
function(err,results){
if(err){
console.log('Oh No! '+err);
} else if(results.length == 1){
//some how set a session here
} else if(!results.length) {
console.log('No rows found!');
}
});
});
I'm having difficulty understanding how i set up a session for each client that connects. Is this possible with NodeJS ?
Reading that they assign express to var app but if i already have this : var app = http.createServer( ... how can i also assign express to it :S bit confusing
You need to understand the difference between a express' server and a native NodeJS' server, here my link comparaison nodejs server vs express server
So you can do:
var app = express();
var server = http.createServer(app);
This enable you to have still the low level functionnaly with NodeJS.
So, if you don't want to use existing modules or framework, you can build your own session manager:
using cookie
using IP/UA
using socket
The best way would be first to implement it with socket, for example:
server.on('connection', function (socket) {
socket.id = id;
});
or
server.on('request', function (req, res) {
req.connection.id = id; // The socket can also be accessed at request.connection.
});
So, you just need to implement a middleware who check the id.
If you want to prevent from session prediction, session sidejacking, etc. you need to combine cookies, ip, socket, and your ideas to make it more secure for your app.
Once you've done your session manager, you can choose where to store the sessions, in a simple object, in redis, in mongodb, in mysql ... (express use MemoryStore by default, but maybe not now)
I don't have an idea if nodejs has core feature of saving sessions. you need to use a database along with it. using Express will help you to utilized a database to persist user sessions. You better study and use it
http://expressjs.com/
http://blog.modulus.io/nodejs-and-express-sessions
I don't think there is any session mechanism within Nodejs' core. However, they are plenty of libraries that would allow you to do it. The first that comes to mind is Connect's session, which is a middleware for Nodejs. Have a look at this question for more details on how to use it.
Have a look at this tutorial from dailyjs which tries to include Express's session into a notepad webapp. The source code is available here. (Note that Express' session is based on Connect's, and is practically the same).
EDIT: Here is a more complete example for Node authentication, using mongoose. They do however show their schemas, so I assume you can easily do the transition to MySQL.

How do I connect to a Google Cloud SQL database using CodeIgniter?

My CodeIgniter app on Google App Engine is not able to connect to my database on Google Cloud SQL. I tried so many things.
My site loads when I leave database username, password & database name empty but, pages that have database calls show an error. It says that no database was selected.
I noticed that my database was not created and created a new database and a user with all privileges. I entered this details in my app and now, it doesn't even connect to the database server. No pages serve.
When I remove only the username & password fields in database.php, it connects to the database server but, doesn't connect to the database.
I checked the mysql database for users and my user has all privileges. I checked all spellings and it is correct. The app is working locally. HOW I CAN FIX THIS? i just can't get it to connect.
Out of the box CodeIgniter will not connect to a Google Cloud SQL instance, modifications to the CI database driver files are required, this is because CI expects that it’s choices are either to connect to localhost or to a remote tcpip host, the developers never anticipated that anybody would want to connect directly to a socket.
I chose to use the Mysqli driver instead of Mysql for performance reasons and here is how I did it:
Step 1) Edit the codeigniter/system/database/drivers/mysqli/mysqli_driver.php file and replace the db_connect function with the following code:
function db_connect()
{
if(isset($this->socket)){
return mysqli_connect(null, $this->username, null, $this->database, null, $this->socket);
}
elseif ($this->port != ”)
{
return mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);
}
else
{
return mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
}
}
Step 2) Alter your application’s config/database.php (or wherver you want to declare your database settings) - Depending on your application you may choose to add “database” to the autoload array in the yourapp/config/autoload.php or you may choose to manually call the load->database() function. This assumes your application name is “myappname”. Replace APPENGINE-ID and DATABASE-INSTANCE-ID and YOUR_DATABASE_NAME appropriately.
$db[‘myappname’][‘hostname’] = ‘localhost’;
$db[‘myappname’][‘username’] = ‘root’;
$db[‘myappname’][‘password’] = null;
$db[‘myappname’][‘database’] = ‘YOUR_DATABASE_NAME’;
$db[‘myappname’][‘dbdriver’] = ‘mysqli’;
$db[‘myappname’][‘pconnect’] = FALSE;
$db[‘myappname’][‘dbprefix’] = ‘’;
$db[‘myappname’][‘swap_pre’] = ‘’;
$db[‘myappname’][‘db_debug’] = FALSE;
$db[‘myappname’][‘cache_on’] = FALSE;
$db[‘myappname’][‘autoinit’] = FALSE;
$db[‘myappname’][‘char_set’] = ‘utf8’;
$db[‘myappname’][‘dbcollat’] = ‘utf8_general_ci’;
$db[‘myappname’][‘cachedir’] = ”;
$db[‘myappname’][‘socket’] = ‘/cloudsql/APPENGINE-ID:DATABASE-INSTANCE-ID’;
Viola, your CodeIgniter application should now be able to connect and talk to your Google Cloud MySQL database!
Now if you want to get really fancy and enable the database caching, either make alterations to the CI code to use memcache (fastest) or Google Cloud Storage (more guaranteed persistance) but I won’t cover that in this blog…
Answer courtesy of http://arlogilbert.com/post/67855755252/how-to-connect-a-codeigniter-project-to-google-cloud
Have you authorized your appengine app for access to the Cloud SQL instance? Go to the access control panel on the console for the instance (at https://cloud.google.com/console#/project/{project name}/sql/instances/{instance name}/access-control). Look for authorized app engine applications.
Otherwise, if you're connecting to the instance successfully, you'll have to choose the database from your code or configuration (depending on the app). For example, from the "running wordpress" guide (https://developers.google.com/appengine/articles/wordpress) you have to define DB_NAME. If you're handling the connections in your own code you'll need to use mysql_select_db.
From skimming the codeigniter docs, it looks like you need something like:
$config['database'] = "mydatabase";
I'm not familiar with this framework though, so check the docs yourself (http://ellislab.com/codeigniter/user-guide/database/configuration.html).

How to do authentication in node.js that I can use from my website?

I want a Node.js service to authenticate the user of my website. How can I do this?
I want to implement Everyauth authentication using the simple password method, not OpenID.
I tried https://github.com/jimpick/everyauth-example-password and it works.
I want to use the database to store. This script does not use a database. I have used MySQL in past so I prefer that but I am ok with anything else as well such as MongoDB.
I just want to add database to my script. Please help.
You only need to modify .authenticate method. Since connecting to database is (or should be) an asynchronous operation, then you need to add promise object (see everyauth documentation).
Assuming you have some ORM with user data corresponding to user object with username and password attributes (in my example I'll use mongoose engine), this is how it may look:
.authenticate( function (login, password) {
var promise = this.Promise(); /* setup promise object */
/* asynchrnously connect to DB and retrieve the data for authentication */
db.find({ username:login }, function(err, user) {
if (err)
return promise.fulfill([err]);
if ((!user) || (user.password != password))
return promise.fulfill(['Incorrect username or password!']);
promise.fulfill(user);
});
return promise; /* return promise object */
})
I didn't test it, but according to the documentation it should work. Remember that errors are supposed to be held in array.
By the way: if you are using only the password method, then there is no need to, you know, use a cannon against a fly. :) Writing your own (not necessarly perfect, but working) authentication mechanism is really simple and if you don't know how to do this you should learn it. It will benefit in the future, because authentication and security in general are very important in every web app.