├── .gitignore ├── .jshintrc ├── examples ├── views │ └── view.jade └── app.js ├── package.json ├── index.js ├── LICENSE ├── README.md └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true 3 | } -------------------------------------------------------------------------------- /examples/views/view.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title req-flash 5 | body 6 | if flash.message 7 | div.flash-message #{flash.message} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "req-flash", 3 | "version": "0.0.3", 4 | "description": "Unopinionated middleware for creating flash messages of all types for Express apps.", 5 | "scripts": { 6 | "test": "mocha" 7 | }, 8 | "keywords": [ 9 | "express", 10 | "middleware", 11 | "flash" 12 | ], 13 | "homepage": "https://github.com/maximilianschmitt/req-flash", 14 | "bugs": "https://github.com/maximilianschmitt/req-flash/issues", 15 | "license": "MIT", 16 | "author": { 17 | "name": "Maximilian Schmitt", 18 | "email": "maximilian.schmitt@googlemail.com", 19 | "url": "http://maximilianschmitt.me" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/maximilianschmitt/req-flash.git" 24 | }, 25 | "devDependencies": { 26 | "chai": "^3.5.0", 27 | "cookie-parser": "^1.0.1", 28 | "express": "^4.1.1", 29 | "express-session": "^1.0.4", 30 | "jade": "^1.3.1", 31 | "mocha": "^2.4.5", 32 | "superagent": "^1.8.3" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var localsKey; 4 | 5 | var _flash = function(container, key, message) { 6 | if (typeof key === 'undefined' && typeof message === 'undefined') { 7 | return container; 8 | } else if (typeof message === 'undefined') { 9 | return container[key]; 10 | } else { 11 | container[key] = message; 12 | } 13 | }; 14 | 15 | var _clear = function(hijack, req, res) { 16 | req.session._flash = {}; 17 | 18 | hijack.apply(res, Array.prototype.slice.call(arguments).slice(3)); 19 | }; 20 | 21 | var flash = function(req, res, next) { 22 | if (!req.session) throw new Error('Sessions are required.'); 23 | 24 | if (typeof req.session._flash === 'undefined') req.session._flash = {}; 25 | 26 | req.flash = _flash.bind(null, req.session._flash); 27 | res.render = _clear.bind(null, res.render, req, res); 28 | res.send = _clear.bind(null, res.send, req, res); 29 | 30 | if (localsKey) res.locals[localsKey] = req.flash(); 31 | 32 | next(); 33 | }; 34 | 35 | module.exports = function(options) { 36 | if (options != null && options.locals) { 37 | localsKey = options.locals; 38 | } 39 | 40 | return flash; 41 | }; 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 maximilianschmitt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /examples/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var cookieParser = require('cookie-parser'); 5 | var session = require('express-session'); 6 | var flash = require('..'); 7 | 8 | var app = express(); 9 | 10 | app.set('view engine', 'jade'); 11 | app.set('views', __dirname + '/views'); 12 | 13 | app.use(cookieParser()); 14 | app.use(session({ secret: '123' })); 15 | app.use(flash({ locals: 'flash' })); 16 | 17 | app.get('/', function(req, res) { 18 | req.flash('message', 'index'); 19 | res.redirect('/flash'); 20 | }); 21 | 22 | app.get('/multiple', function(req, res) { 23 | req.flash('successMessage', 'a message about success'); 24 | req.flash('errorMessage', 'a message about failure'); 25 | res.redirect('/flash'); 26 | }); 27 | 28 | app.get('/stack', function(req, res) { 29 | req.flash('successMessage', 'a message about success'); 30 | req.flash('successMessage', 'a second message'); 31 | res.redirect('/flash'); 32 | }); 33 | 34 | app.get('/flash', function(req, res) { 35 | var messages = req.flash(); 36 | res.send(messages); 37 | }); 38 | 39 | app.get('/view', function(req, res) { 40 | req.flash('message', 'You are viewing a flash message inside a view.'); 41 | res.redirect('/flash-view'); 42 | }); 43 | 44 | app.get('/flash-view', function(req, res) { 45 | res.render('view'); 46 | }); 47 | 48 | module.exports = app; 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | req-flash 2 | ========= 3 | 4 | Unopinionated middleware for creating flash messages of all types for Express apps. 5 | 6 | ## Usage 7 | 8 | ### 1. Install req-flash: 9 | 10 | ``` javascript 11 | npm install req-flash 12 | ``` 13 | 14 | ### 2. Register the req-flash middleware after your session middleware: 15 | 16 | ``` javascript 17 | var express = require('express'); 18 | var cookieParser = require('cookie-parser'); 19 | var session = require('express-session'); 20 | var flash = require('req-flash'); 21 | 22 | var app = express(); 23 | 24 | app.use(cookieParser()); 25 | app.use(session({ secret: '123' })); 26 | app.use(flash()); 27 | ``` 28 | 29 | **Tipp:** Use `flash({ locals: 'flash' })` to magically make all flash messages available to your views by attaching them to `res.locals['flash']` (or whatever you specifiy instead of 'flash'). 30 | 31 | ### 3. Flash any amount of messages: 32 | 33 | ``` javascript 34 | app.get('/test', function() { 35 | req.flash('successMessage', 'You are successfully using req-flash'); 36 | req.flash('errorMessage', 'No errors, you\'re doing fine'); 37 | 38 | res.redirect('/'); 39 | }); 40 | 41 | app.get('/', function() { 42 | res.send(req.flash()); 43 | }); 44 | ``` 45 | 46 | "/test" redirects to "/" and outputs: 47 | 48 | ``` 49 | { 50 | "successMessage": "You are successfully using req-flash", 51 | "errorMessage": "No errors, you're doing fine" 52 | } 53 | ``` -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | /* global describe, it, before, after */ 2 | 'use strict'; 3 | 4 | var superagent = require('superagent'); 5 | var expect = require('chai').expect; 6 | 7 | var app = require('../examples/app'); 8 | var port = 8888; 9 | var url = 'http://localhost:' + port; 10 | 11 | describe('req-flash', function() { 12 | var agent = superagent.agent(); 13 | var server; 14 | 15 | before(function() { 16 | server = app.listen(port); 17 | }); 18 | 19 | after(function(done) { 20 | server.close(done); 21 | }); 22 | 23 | it('should add a single flash message', function(done) { 24 | agent.get(url) 25 | .redirects(1) 26 | .end(function(err, res) { 27 | var data = JSON.parse(res.text); 28 | 29 | expect(res.statusCode).to.equal(200); 30 | expect(data.message).to.equal('index'); 31 | 32 | done(); 33 | }); 34 | }); 35 | 36 | it('should add multiple flash messages', function(done) { 37 | agent.get(url + '/multiple') 38 | .redirects(1) 39 | .end(function(err, res) { 40 | var data = JSON.parse(res.text); 41 | 42 | expect(res.statusCode).to.equal(200); 43 | expect(data.successMessage).to.equal('a message about success'); 44 | expect(data.errorMessage).to.equal('a message about failure'); 45 | 46 | done(); 47 | }); 48 | }); 49 | 50 | it('should not stack multiple messages of the same type into an array', function(done) { 51 | agent.get(url + '/stack') 52 | .redirects(1) 53 | .end(function(err, res) { 54 | var data = JSON.parse(res.text); 55 | 56 | expect(res.statusCode).to.equal(200); 57 | expect(data.successMessage).to.equal('a second message'); 58 | 59 | done(); 60 | }); 61 | }); 62 | 63 | it('should clear flash messages', function(done) { 64 | agent.get(url + '/stack') 65 | .redirects(1) 66 | .end(function() { 67 | agent.get(url + '/flash') 68 | .redirects(0) 69 | .end(function(err, res) { 70 | expect(res.text).to.equal('{}'); 71 | 72 | done(); 73 | }); 74 | }); 75 | }); 76 | 77 | it('should pass flash messages to the view automatically', function(done) { 78 | agent.get(url + '/view') 79 | .redirects(1) 80 | .end(function(err, res) { 81 | expect(res.text).to.contain('You are viewing a flash message inside a view.'); 82 | 83 | done(); 84 | }); 85 | }); 86 | }); --------------------------------------------------------------------------------