Skip to content

Instantly share code, notes, and snippets.

@peter
Created February 20, 2014 19:24

Revisions

  1. peter revised this gist Feb 20, 2014. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions gistfile1.js
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,17 @@
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // Hooking up the middleware with the express app
    // In app.js
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    var forceSSL = require('../middleware/ssl').force(config.hostname);
    if ('production' == app.get('env')) {
    app.use(forceSSL);
    }

    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // Middleware
    // In middleware/ssl.js
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    var redirectUrl = exports.redirectUrl = function(protocol, hostname, url) {
    return protocol === 'https' ? null : ('https://' + hostname + url);
    @@ -24,8 +28,10 @@ exports.force = function(hostname) {
    };
    };

    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // Mocha test
    // In test/middleware/ssl_test.js
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    var _ = require('lodash'),
    assert = require('assert'),
  2. peter created this gist Feb 20, 2014.
    67 changes: 67 additions & 0 deletions gistfile1.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    // Hooking up the middleware with the express app
    // In app.js

    var forceSSL = require('../middleware/ssl').force(config.hostname);
    if ('production' == app.get('env')) {
    app.use(forceSSL);
    }

    // Middleware
    // In middleware/ssl.js

    var redirectUrl = exports.redirectUrl = function(protocol, hostname, url) {
    return protocol === 'https' ? null : ('https://' + hostname + url);
    };

    exports.force = function(hostname) {
    return function(req, res, next) {
    var redirectTo = redirectUrl(req.header('X-Forwarded-Proto'), hostname, req.url);
    if (redirectTo) {
    res.redirect(301, redirectTo);
    } else {
    next();
    }
    };
    };

    // Mocha test
    // In test/middleware/ssl_test.js

    var _ = require('lodash'),
    assert = require('assert'),
    sinon = require('sinon'),
    ssl = require('../../lib/middleware/ssl');

    describe('middleware/ssl', function() {
    describe('redirectUrl', function() {
    it('returns an https url if protocol is http', function() {
    assert.equal('https://api.naturkartan.se/some/url', ssl.redirectUrl('http', 'api.naturkartan.se', '/some/url'));
    });

    it('returns null if protocol is https', function() {
    assert.equal(null, ssl.redirectUrl('https', 'api.naturkartan.se', '/some/url'));
    });
    });

    describe('force', function() {
    it('calls next if request is secure', function() {
    var req = {header: sinon.stub().withArgs('X-Forwarded-Proto').returns('https')},
    res = {},
    next = sinon.mock().once();

    ssl.force('api.naturkartan.se')(req, res, next);

    next.verify();
    });

    it('redirects to https if request is not secure', function() {
    var req = {url: '/foobar', header: sinon.stub().withArgs('X-Forwarded-Proto').returns('http')},
    res = {redirect: sinon.mock().withArgs(301, 'https://api.naturkartan.se/foobar').once()},
    next = {};

    ssl.force('api.naturkartan.se')(req, res, next);

    res.redirect.verify();
    });
    });
    });