Best place to define a connection uri using Express - node.js

I have just started learning ExpressJs and I am trying to use it with mongoskin.
What I want to know is where is the best place to define the uri to connect to the database. I don't want to do that in every file that needs to connect to the db.
I tried doing this in my app.js file:
var app = express();
...
app.set('db_uri', process.env.NODE_DB || ""localhost/test"");
...
module.exports = app;
And inside the file that would be accessing the db:
var mongo = require('mongoskin'),
app = require('./../../app'),
db = mongo.db(app.settings.db_uri);
But the problem is that I always receive an empty object for app.
So, I have two questions.
1) Is this the best way to do it?
2) What is wrong that I can't access app?

I think one way of doing it is creating a module that handles the interaction with the database, so you could:
write the url there
or in a configuration file required in it
or you could just use process.env
and require the model when you need database interaction, this way there's no need for express to know about it.
About app not being required: check that you are exporting it via module.exports and that the path is correct (the first ./ could be omitted for example).

Related

What is the best way to handle CAS authentication in NodeJS accross multiple route files?

I am working on an inventory management system RESTful API in NodeJS right now. The API will be accessed by a standalone VueJS application through HTTP requests. I want to use CAS to prevent access to API resources to unauthenticated users. I have settled on using the library found here: https://www.npmjs.com/package/node-cas-authentication
I have got the library working for CAS authentication, but I have to duplicate the initializing code across all of my route files.
The initializing code I have to keep repeating:
const CASAuth = require('node-cas-authentication');
const cas = new CASAuth({
cas_url : 'https://my-cas-host.com/cas',
service_url : 'https://my-service-host.com',
is_dev_mode : true
});
My file structure:
I wanted to know if there is a better way to organize my code so that I do not have to continuously repeat the initializing code in each file. If there is so way to include the CAS Authentication via a separate file and I require, this would be beneficial for organization and for maintenance. I am fairly new to NodeJS, so any suggestions would be helpful!
One option is to create a new module, say cas-middleware.js, which performs the initialization and exports the resulting object:
// cas-middleware.js
const CASAuth = require('node-cas-authentication');
const cas = new CASAuth({
cas_url : 'https://my-cas-host.com/cas',
service_url : 'https://my-service-host.com',
is_dev_mode : true
});
module.exports = cas; // Add this line
You can then reference that same object from all of your other modules using require:
// e.g., routes.js
const cas = require('../cas-middleware')
Each module that imports the object from cas-middleware.js will receive a reference to the same CASAuth object.

How to access app.locals in other modules in NodeJS?

With my main server.js file, I exported my app variable:
//Assume there's other code in this file of course
var app = express();
app.locals.database = //here's my DB connection. This variable works perfectly within the server.js file!
module.exports = app;
I imported it into another module:
var app = require('../server');
But I cannot access the app.locals variables? I set a few of them within my server.js (such as database connection info) but I get this error:
TypeError: Cannot read property 'database' of undefined
when trying to read:
app.locals.database
What am I doing wrong?
NOTE: In my other module app is {}, but when I check it within the originating module it has tons of info.
As per docs Once set, the value of app.locals properties persist throughout the life of the application.
In your case, as you've exported app, it's perfectly fine to access this at file level (not sure the right term), where you've imported as app.locals.database (remember app is an object).
But if you want to access elsewhere where you've not imported, express makes it available to all middleware via req.app.locals. The docs clearly mentions Local variables are available in middleware via req.app.locals
Also checkout this SO question, it give you a nice insight on app.locals and req.locals

Register new route at runtime in NodeJs/ExpressJs

I want to extend this open topic: Add Routes at Runtime (ExpressJs) which sadly didn't help me enough.
I'm working on an application that allows the creation of different API's that runs on NodeJs. The UI looks like this:
As you can see, this piece of code contains two endpoints (GET, POST) and as soon as I press "Save", it creates a .js file located in a path where the Nodejs application is looking for its endpoints (e.g: myProject\dynamicRoutes\rule_test.js).
The problem that I have is that being that the Nodejs server is running while I'm developing the code, I'm not able to invoke these new endpoints unless I restart the server once again (and ExpressJs detects the file).
Is there a way to register new routes while the
NodeJs (ExpressJs) is running?
I tried to do the following things with no luck:
app.js
This works if the server is restarted. I tried to include this library (express-dynamic-router, but not working at runtime.)
//this is dynamic routing function
function handleDynamicRoutes(req,res,next) {
var path = req.path; //http://localhost:8080/api/rule_test
//LoadModules(path)
var controllerPath = path.replace("/api/", "./dynamicRoutes/");
var dynamicController = require(controllerPath);
dynamicRouter.index(dynamicController[req.method]).register(app);
dynamicController[req.method] = function(req, res) {
//invocation
}
next();
}
app.all('*', handleDynamicRoutes);
Finally, I readed this article (#NodeJS / #ExpressJS: Adding routes dynamically at runtime), but I couldn't figure out how this can help me.
I believe that this could be possible somehow, but I feel a bit lost. Anyone knows how can I achieve this? I'm getting a CANNOT GET error, after each file creation.
Disclaimer: please know that it is considered as bad design in terms of stability and security to allow the user or even administrator to inject executable code via web forms. Treat this thread as academic discussion and don't use this code in production!
Look at this simple example which adds new route in runtime:
app.get('/subpage', (req, res) => res.send('Hello subpage'))
So basically new route is being registered when app.get is called, no need to walk through routes directory.
All you need to do is simply load your newly created module and pass your app to module.exports function to register new routes. I guess this one-liner should work just fine (not tested):
require('path/to/new/module')(app)
Is req.params enough for you?
app.get('/basebath/:path, (req,res) => {
const content = require('content/' + req.params.path);
res.send(content);
});
So the user can enter whatever after /basepath, for example
http://www.mywebsite.com/basepath/bergur
The router would then try to get the file content/bergur.js
and send it's contents.

Sharing objects across routes

Trying out Keen.io and wondering if it's possible to NOT have to call "configure" in each file that will make a call to the Keen API?
Their docs from here: https://github.com/keenlabs/KeenClient-node show how to configure an instance which I use in one of my routes but I have a number of routes and find that I have to keep configuring.
var Keen = require('keen.io');
// Configure instance. Only projectId and writeKey are required to send data.
var client = Keen.configure({
projectId: "<project_id>",
writeKey: "<write_key>",
readKey: "<read_key>",
masterKey: "<master_key>"
});
Is there a way to "configure" just once or have I got the wrong idea?
Check out this answer to another question on SO. It describes a method to use app.get() and app.set() to access dependencies across the application.
After you configure client, set it in the app:
app.set('keen', client);
Then later get it back out from within any route:
var client = app.get('keen');
I decided to configure the app inserver.js and then pass the client object to each route that requires it. This appears to work well and has tidied my code up considerably.

Node.js Express: require/use one app within another

I'm facing the following situation. In order to further modulize my software development, I've written a few standard modules stand alone. Think for instance of an login module based upon Express and Passport, allowing users to login with all kinds of social services. The module also contains UI for user management, login, registration, profile, etc.
Now, the thing I'm trying to do is to just drop the Auth app folder (containing the express app, all it's routes, views, models, settings and dependecies) into another Express app (for instance, a CMS) and then load it with something like require('./lib/auth/app.js'). I know this is possible, take a look at Kue.
How would I go about doing this? And how do I manage namespacing problems? I could of cours append /auth/ to each route, but I can imagine the settings (app.use()'s) and public folder would conflict with the 'parent' app.js' settings and public folder.
Thanks in advance,
Fabian
Think I found my answer. So, I found this question, and this one. Guess my terminology was off.
I solved my problem by doing a few things. First of all, I changed all routes and url's to be "namespaced" (not really, but this does the job). All routes now have /auth/ in front of them. I did the same to all links, so that's all working.
Next, I removed the server part from my app.js. So, in stead of doing:
require('http').createServer(app).listen(app.get('port'));
I just do:
module.exports = app;
And I add some custom methods to the app object:
app.isLoggedIn = auth.isLoggedIn;
app.notLoggedIn = auth.notLoggedIn;
Then, in my root app, I just do the following to load the auth app in. Routing, public files, and all other stuff happens magically. pretty cool.
var auth = require('./vendor/auth/app');
var app = express();
app.configure(function() {
app.use(auth); // use our auth app
// do a lot of root-app related stuff...
});
Things still to do:
My auth app uses some session stuff. According to the second link, if I understand correctly, the app.use(session...) stuff in my auth app gets overridden by app.use. Also, I want to define an EJS helper to generate my urls (something like site_url('/facebook/callback') which then points to /auth/facebook/callback). Finally, I need to include settings from my root app. I'm thinking of wrapping my entire app.js (in auth) in a function, to which I pass a config object. Like this:
module.exports = function(config) {
var app = express();
app.set('config', config);
// various app settings, routes, etc
// return app so it's available in my root.
return app;
}
I hope this helps, if you need a bit more information I'll see if I can post some code to a gist. just let me know!

Resources