Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
nodulejs is a lightweight utility based on node/express, whose sole purpose is to discover and initialize web components (standard Javascript objects) called "nodules". Nodules are tied to one or more express routes, and attached to each incoming express request as req.nodule.
For a fully fleshed-out implementation of nodulejs, see the yukon component framework.
$ npm install nodulejs
require('nodulejs')(app, config);
app = express instance
config = any custom properties you want to add or defaults you want to override, see the demoApp
There are 3 global config properties:
A nodule is a self-discovering, self-initializing component that would be analogous to a JSP or PHP page in those worlds. Except it has an advantage in that its route is declared, not tied by default to the file name or file structure. So you are free to re-organize nodules without upsetting urls. But more importantly, because nodules are self-discovering, there are no onerous config files to maintain (IE - Spring). This system allows a much more scalable architecture on large sites--as there are no config or other shared files which grow to enormous sizes as the site grows, and nodules can be re-organized, placed into sub-folders, etc. with zero impact.
Not a whole lot out of the box. See the yukon component framework for a fully-fleshed out implementation. I split nodulejs off from yukon with the idea that it can potentially be a building block for other frameworks.
A nodule can have any properties you want to add, which will be propagated throughout the middleware chain as as req.nodule. But nodulejs only cares about 4 core properties, which are needed to register express middleware at app-init time:
From a feature-development point of view, we wanted to give developers the flexibility of component-based architecture as much as possible, but still keep system-wide control over the middleware chain. On a small site with a small development team the latter might not be an issue. But on a large site with devs scattered all over the globe, some kind of middleware sandbox was a necessity.
Our feature devs spend 80-90% of their effort in jade templates or on the client side. For them, node components are often just a pass-through to the API(s), with some business logic applied to the request on the way in, and API data on the way out. Ideally they should have to learn the as little as possible of the vagaries/plumbing/whatever-your-favorite-metaphor-for-framework-stuff of node. Creating a new node component should be as easy for them as creating a new JSP - but again, without the framework losing control of the middleware chain.
From a framework-development point of view, we knew that as requirements evolved, we would constantly need to add default properties to each component, while hopefully causing as little disruption as possible to existing components. This is easily accomplished by adding a default property to the base config, then specifying the property only in the nodules that need the new property.
We also knew we'd need to add slices of business logic globally or semi-globally at any point in the request chain. By keeping control of the middleware chain we are able to do this with ease.
This diagram, from the fully-fleshed out yukon component framework might make the concept a little more clear:
Download nodulejs - https://github.com/jackspaniel/nodulejs/archive/master.zip
$ npm install
$ make test
(homePage.js from the demoApp)
module.exports = function(app) {
return {
route: ['/', '/home', '/special'],
doNoduleBusinessLogic: function(req, res) {
this.templateName = (req.path.indexOf('special') > -1)
? 'altHomePage.jade'
: 'homePage.jade';
}
};
};
(submitForm.js from the demoApp)
module.exports = function(app) {
return {
route : '/json/submitForm',
routeVerb: 'post',
doPreFormBusinessLogic: function(req, res) {
this.dbParams = {param1: req.body ? req.body.param1 : null}; // in real life don't forget to sanitize query params!
},
doPostFormBusinessLogic: function(req, res) {
if (req.nodule.responseData.dbMsg.indexOf('valid data') === -1)
this.customMsg = 'Form submit failed, please supply valid param1';
}
};
};
(404 error nodule - shows routeIndex and one-off middleware)
module.exports = function(app) {
return {
route: '*',
routeIndex: 1000, // high routes are registered last
middlewares: [
function(req, res, next) {
req.nodule.debug('404 error middleware called!');
res.send('<html><body><h1>404 error!</h1></body></html>');
}
]
};
};
(from demoApp.js - shows defining several nodule-dependent middleware chains at app init time, and adding extra nodule properties)
var config = {
dirs: [
{ path: myDir, exclude: ['demoApp.js', '.test.js'] },
],
debugToConsole: true,
noduleDefaults: {
middlewares: function(nodule) {
var strRoute = nodule.route.toString();
if (nodule.routeVerb === 'post')
return [doPreForm, doPostForm, sendJsonResponse];
else if (strRoute.indexOf('/json') === 0)
return [doBusinessLogic, sendJsonResponse];
else
return [doBusinessLogic, sendHtmlResponse];
},
// custom properties on top of the nodulejs core properties
templateName: 'default.jade',
templateDir: null,
doNoduleBusinessLogic: function(req, res) { },
},
};
(from demoApp.js)
function doBusinessLogic(req, res, next) {
debug('doBusinessLogic middleware executed for: ' + req.nodule.name);
// app-level business logic can go here
req.nodule.doNoduleBusinessLogic(req, res);
// app-level business logic can also go here
next();
}
(from demoApp.js - goes with Form submit example above)
...
middlewares: function(nodule) {
if (nodule.routeVerb === 'post')
return [doPreForm, doPostForm, sendJsonResponse];
...
function doPreForm(req, res, next) {
req.nodule.doPreFormBusinessLogic(req, res);
makeDbCall({
params: req.nodule.dbParams,
callback: function(err, response) {
req.nodule.responseData = response;
next();
}
});
}
function doPostForm(req, res, next) {
req.nodule.doPostFormBusinessLogic(req, res);
next();
}
// DB simulator, see /json/formSubmit.js
function makeDbCall(call) {
var response = (call.params.param1) ? 'valid data, param1='+call.params.param1 : 'missing param1, please resubmit';
call.callback(null, {dbMsg:response});
}
FAQs
Scalable self-discovering web components
The npm package nodulejs receives a total of 0 weekly downloads. As such, nodulejs popularity was classified as not popular.
We found that nodulejs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.