UNPKG

compound-ex4

Version:

Compound-ex4 - MVC framework for NodeJS (ExpressJs 4 version), fork compoundjs(https://github.com/1602/compound)

189 lines (169 loc) 4.92 kB
var crypto = require('crypto'); module.exports = Helpers; function Helpers() { } Helpers.respondToFormats = ['json', 'html', 'xml']; /** * Respond to .:format * @param {Function} block * * Example (respond to json and html): * * action(function index() { * var fruits = this.fruits = ['apple', 'banana', 'kiwi']; * respondTo(function (format) { * format.html(render); * format.json(function () { * send(fruits); * }); * }); * }); * * To extend list of formats use: * * require('kontroller').Helpers.respondToFormats.push('gif', 'png', 'jpg'); */ Helpers.prototype.respondTo = function respondTo(block) { var f = this.params.format || 'html'; var variants = {}; Helpers.respondToFormats.forEach(function (format) { variants[format] = responderFor(format); }); if (!variants[f]) { return this.next(); } block(variants); function responderFor(format) { return function (c) { if (f === format) { c(); } } } }; /** * Enables CSRF Protection * * This filter will check `authenticity_token` param of POST request * and compare with token calculated by session token and app-wide secret * * @param {String} secret * @param {String} paramName * * @example `app/controllers/application_controller.js` * ``` * before('protect from forgery', function () { * protectFromForgery('415858f8c3f63ba98546437f03b5a9a4ddea301f'); * }); * ``` */ Helpers.prototype.protectFromForgery = function protectFromForgery(secret, paramName) { var req = this.req; if (!req.session) { return this.next(); } if (!req.session.csrfToken) { req.session.csrfToken = Math.random(); req.csrfParam = paramName || 'authenticity_token'; req.csrfToken = sign(req.session.csrfToken); return this.next(); } // publish secure credentials req.csrfParam = paramName || 'authenticity_token'; req.csrfToken = sign(req.session.csrfToken); if (['HEAD', 'GET', 'OPTIONS'].indexOf(req.originalMethod) === -1) { var token = req.param(req.csrfParam) || req.header("X-CSRF-Token"); if (!token || token !== sign(req.session.csrfToken)) { console.log('Incorrect authenticity token'); this.send(403); } else { this.next(); } } else { this.next(); } function sign(n) { return crypto.createHash('sha1').update(n.toString()).update(secret.toString()).digest('hex'); } }; Helpers.prototype.protectedFromForgery = function () { return this.req.csrfToken && this.req.csrfParam; }; /** * Add flash error to display in next request * * @param {String} type * @param {String} message */ Helpers.prototype.flash = function flash(type, msg) { var msgs = this.session.flash = this.session.flash || {}; return (msgs[type] = msgs[type] || []).push(msg); }; /** * Send response, as described in ExpressJS guide: * * This method is a high level response utility allowing you * to pass objects to respond with json, strings for html, * Buffer instances, or numbers representing the status code. * The following are all valid uses: * ``` * send(); // 204 * send(new Buffer('wahoo')); * send({ some: 'json' }); * send('<p>some html</p>'); * send('Sorry, cant find that', 404); * send('text', { 'Content-Type': 'text/plain' }, 201); * send(404); * ``` * */ Helpers.prototype.send = function (x) { // log('Send to client: ' + x); this.res.send.apply(this.res, Array.prototype.slice.call(arguments)); if (this.context.inAction) this.next(); }; /** * Set or get response header * * @param {String} key - name of header * @param {String} val - value of header (optional) * * When second argument is omitted method acts as getter. * * Example: * ``` * header('Content-Length'); * // => undefined * * header('Content-Length', 123); * // => 123 * * header('Content-Length'); * // => 123 * ``` */ Helpers.prototype.header = function (key, val) { return this.res.header.call(this.res, key, val); }; /** * Redirect to `path` */ Helpers.prototype.redirect = function (path) { var f = this.params.format || 'html'; if (f === 'json') { this.res.send({code: 304, location: path.toString()}); } else { this.res.redirect(path.toString()); } if (this.context.inAction) this.next(); }; /** * Configure which query params should be filtered from logging * @param {String} param 1 name * @param {String} param 2 name * @param ... * @param {String} param n name */ Helpers.prototype.filterParameterLogging = function filterParameterLogging() { this.constructor.filterParams = (this.constructor.filterParams || []).concat(Array.prototype.slice.call(arguments)); };