From ea60931efab8e3257dc92f48e36962d0a3e60010 Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Mon, 6 Nov 2017 10:16:22 -0400 Subject: [PATCH 1/7] Add support for redirecting the protocol and host --- lib/redirect.js | 71 ++++++++++++++++--------------- test/fixtures/site 1/redirects.js | 36 +++++++++++++++- test/solidus.js | 20 +++++++++ 3 files changed, 92 insertions(+), 35 deletions(-) diff --git a/lib/redirect.js b/lib/redirect.js index 16e03f6..315893c 100644 --- a/lib/redirect.js +++ b/lib/redirect.js @@ -7,55 +7,58 @@ var moment = require('moment'); var utils = require('./utils.js'); -var Redirect = function( redirect_data, options ){ - +var Redirect = function(redirect_data, options) { options = options || {}; var redirect = this; - var server = options.server; - var router = server.router; + var router = options.server.router; var status = redirect_data.permanent ? PERMANENT_STATUS : TEMPORARY_STATUS; var start = redirect_data.start; var end = redirect_data.end; - var from = redirect_data.from; - var to = redirect_data.to; - var expired = ( moment() > moment( end ) ); - - // don't create redirect route at all if expired - // don't check prematurity yet since it could become valid later - if( !expired ){ - - if (from instanceof RegExp) { - this.route = from; - } else { - this.route = path.normalize( from ).replace( /\\/g, '/' ); - this.route = utils.formatRouteForExpress(this.route); + var from = _.isObject(redirect_data.from) && !_.isRegExp(redirect_data.from) ? redirect_data.from : {path: redirect_data.from}; + var to = _.isObject(redirect_data.to) && !_.isFunction(redirect_data.to) ? redirect_data.to : {url: redirect_data.to}; + var expired = moment() > moment(end); + + // Don't create redirect route at all if expired + // Don't check prematurity yet since it could become valid later + if (!expired) { + redirect.route = from.path || '*'; + if (_.isString(redirect.route)) { + redirect.route = path.normalize(redirect.route).replace(/\\/g, '/'); + redirect.route = utils.formatRouteForExpress(redirect.route); } - router.get( this.route, function( req, res, next ){ - var expired = ( moment() > moment( end ) ); - var premature = ( moment() < moment( start ) ); - // if redirect is expired or premature skip it - if( !expired && !premature ){ - var url = typeof(to) == 'function' ? to(req.params) : to; - res.redirect( status, utils.expandVariables(url, req.params) ); - } - else { - next(); + router.get(redirect.route, function(req, res, next) { + // If redirect is expired or premature skip it + var expired = moment() > moment(end); + var premature = moment() < moment(start); + if (expired || premature) return next(); + + // If the protocol or host don't match, skip redirect + if (from.protocol && from.protocol !== req.protocol) return next(); + if (from.host && from.host !== req.host) return next(); + + // Compute to + var newTo = to; + if (_.isFunction(newTo.url)) { + newTo = newTo.url(req.params); + if (!_.isObject(newTo)) newTo = Object.assign({}, to, {url: newTo}); } - }); - // removes the redirect route - this.destroy = function(){ + // Compute location + var location = newTo.protocol || newTo.host ? `${newTo.protocol || req.protocol}://${newTo.host || req.host}` : ''; + location += newTo.url ? utils.expandVariables(newTo.url, req.params) : req.url; - router.routes.get = _( router.routes.get ).reject( function( current_route ){ + res.redirect(status, location); + }); + + // Removes the redirect route + this.destroy = function() { + router.routes.get = _(router.routes.get).reject(function(current_route) { return redirect.route === current_route.path; }); - }; - } - }; module.exports = Redirect; \ No newline at end of file diff --git a/test/fixtures/site 1/redirects.js b/test/fixtures/site 1/redirects.js index 9694192..5fc3843 100644 --- a/test/fixtures/site 1/redirects.js +++ b/test/fixtures/site 1/redirects.js @@ -34,4 +34,38 @@ module.exports = [ to: function(params) { return "/new/{1}/{0}/" + (1000 + parseInt(params['2'])); } -}]; \ No newline at end of file +}, { + from: { + protocol: 'http', + host: 'solidusjs.com', + path: '/match-http-root' + }, + to: '/new/match-http-root' +}, { + from: { + protocol: 'https', + host: 'solidusjs.com', + path: '/match-https-root' + }, + to: '/new/match-https-root' +}, { + from: { + host: 'no-path.com' + }, + to: { + host: 'www.no-path.com' + } +}, { + from: '/to-https-www', + to: { + protocol: 'https', + host: 'www.solidusjs.com' + } +}, { + from: '/to-https-www-url/{dynamic}', + to: { + protocol: 'https', + host: 'www.solidusjs.com', + url: '/new/url/{dynamic}' + } +}]; diff --git a/test/solidus.js b/test/solidus.js index a2e687c..24cbc91 100644 --- a/test/solidus.js +++ b/test/solidus.js @@ -583,6 +583,26 @@ describe( 'Solidus', function(){ function( callback ){ s_request.get('/redirect9/12-34-56-78').expect( 'location', '/new/56/12/1078', callback ); }, + function( callback ){ + s_request.get('/match-http-root?with=params').set('Host', 'solidusjs.com').expect( 'location', '/new/match-http-root', callback ); + }, + function( callback ){ + // Bad protocol + s_request.get('/match-https-root?with=params').set('Host', 'solidusjs.com').expect( 404, callback ); + }, + function( callback ){ + // Bad host + s_request.get('/match-http-root?with=params').set('Host', 'www.solidusjs.com').expect( 404, callback ); + }, + function( callback ){ + s_request.get('/some/path?with=params').set('Host', 'no-path.com').expect( 'location', 'http://www.no-path.com/some/path?with=params', callback ); + }, + function( callback ){ + s_request.get('/to-https-www?with=params').set('Host', 'solidusjs.com').expect( 'location', 'https://www.solidusjs.com/to-https-www?with=params', callback ); + }, + function( callback ){ + s_request.get('/to-https-www-url/old-path?with=params').set('Host', 'solidusjs.com').expect( 'location', 'https://www.solidusjs.com/new/url/old-path', callback ); + }, function( callback ){ s_request.get('/past-redirect').expect( 404, callback ); }, From 4786f4d540c8974cedbb4a84e6546cf1aee07142 Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Mon, 6 Nov 2017 10:49:47 -0400 Subject: [PATCH 2/7] =?UTF-8?q?Use=20old=20node=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/redirect.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/redirect.js b/lib/redirect.js index 315893c..b5fc6d1 100644 --- a/lib/redirect.js +++ b/lib/redirect.js @@ -29,6 +29,7 @@ var Redirect = function(redirect_data, options) { } router.get(redirect.route, function(req, res, next) { +console.log(from, to, req.protocol, req.host, req.url); // If redirect is expired or premature skip it var expired = moment() > moment(end); var premature = moment() < moment(start); @@ -46,7 +47,7 @@ var Redirect = function(redirect_data, options) { } // Compute location - var location = newTo.protocol || newTo.host ? `${newTo.protocol || req.protocol}://${newTo.host || req.host}` : ''; + var location = newTo.protocol || newTo.host ? ((newTo.protocol || req.protocol) + '://' + (newTo.host || req.host)) : ''; location += newTo.url ? utils.expandVariables(newTo.url, req.params) : req.url; res.redirect(status, location); From 143d004664ceefcbc1671f674d50efabf9e0b784 Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Mon, 6 Nov 2017 13:11:02 -0400 Subject: [PATCH 3/7] trust proxy --- lib/server.js | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index 47e94c9..d3a6e5b 100644 --- a/lib/server.js +++ b/lib/server.js @@ -116,6 +116,7 @@ var SolidusServer = function( options ){ router.engine( DEFAULT_VIEW_EXTENSION, handlebars.engine ); router.set( 'view engine', DEFAULT_VIEW_EXTENSION ); router.set( 'views', paths.views ); + router.set( 'trust proxy', true ); router.use( express.compress() ); router.use(function(req, res, next) { res.set({'X-Powered-By': 'Solidus/' + VERSION}); diff --git a/package.json b/package.json index 3c6c428..8b6ee40 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "commander": "1.1.x", "continuation-local-storage": "~3.1.1", "express": "3.1.x", - "express-expose": "SparkartGroupInc/express-expose#escape-script-ending-tag", + "express-expose": "sparkartgroupinc/express-expose#escape-script-ending-tag", "express-handlebars": "1.2.2", "glob": "~3.2.6", "handlebars": "^1.3.0", From 1c7a2084eb4eea308d32e3a507b6e4cb7a62f41b Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Mon, 6 Nov 2017 13:55:24 -0400 Subject: [PATCH 4/7] Update CircleCI Node and NPM versions --- circle.yml | 8 +++----- lib/redirect.js | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/circle.yml b/circle.yml index 1961311..fa0613d 100644 --- a/circle.yml +++ b/circle.yml @@ -1,7 +1,5 @@ machine: node: - version: v4.5.0 -dependencies: - # https://discuss.circleci.com/t/testing-multiple-versions-of-node/542 - pre: - - case $CIRCLE_NODE_INDEX in 0) NODE_VERSION=0.12 ;; 1) NODE_VERSION=4 ;; esac; nvm install $NODE_VERSION && nvm alias default $NODE_VERSION + version: v4.8.4 + npm: + version: v2.15.11 diff --git a/lib/redirect.js b/lib/redirect.js index b5fc6d1..58411ea 100644 --- a/lib/redirect.js +++ b/lib/redirect.js @@ -29,7 +29,6 @@ var Redirect = function(redirect_data, options) { } router.get(redirect.route, function(req, res, next) { -console.log(from, to, req.protocol, req.host, req.url); // If redirect is expired or premature skip it var expired = moment() > moment(end); var premature = moment() < moment(start); From dc3616445b121bd5f13c995347e6eae9abbd4251 Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Mon, 6 Nov 2017 14:15:17 -0400 Subject: [PATCH 5/7] Comment --- lib/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index d3a6e5b..24c5830 100644 --- a/lib/server.js +++ b/lib/server.js @@ -116,7 +116,7 @@ var SolidusServer = function( options ){ router.engine( DEFAULT_VIEW_EXTENSION, handlebars.engine ); router.set( 'view engine', DEFAULT_VIEW_EXTENSION ); router.set( 'views', paths.views ); - router.set( 'trust proxy', true ); + router.set( 'trust proxy', true ); // Use the X-Forwarded-* headers: https://expressjs.com/en/guide/behind-proxies.html router.use( express.compress() ); router.use(function(req, res, next) { res.set({'X-Powered-By': 'Solidus/' + VERSION}); From 6ead0d3ce461dcfd8e3700b2da6ebecabe5a6491 Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Mon, 13 Nov 2017 09:39:14 -0400 Subject: [PATCH 6/7] Test without "trust proxy" --- lib/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index 24c5830..937bfb5 100644 --- a/lib/server.js +++ b/lib/server.js @@ -116,7 +116,7 @@ var SolidusServer = function( options ){ router.engine( DEFAULT_VIEW_EXTENSION, handlebars.engine ); router.set( 'view engine', DEFAULT_VIEW_EXTENSION ); router.set( 'views', paths.views ); - router.set( 'trust proxy', true ); // Use the X-Forwarded-* headers: https://expressjs.com/en/guide/behind-proxies.html + // router.set( 'trust proxy', true ); // Use the X-Forwarded-* headers: https://expressjs.com/en/guide/behind-proxies.html router.use( express.compress() ); router.use(function(req, res, next) { res.set({'X-Powered-By': 'Solidus/' + VERSION}); From e37b2ceb5de97cd65406e563ba719593885bb80c Mon Sep 17 00:00:00 2001 From: Joannic Laborde Date: Mon, 13 Nov 2017 09:57:26 -0400 Subject: [PATCH 7/7] "trust proxy" is required --- lib/server.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/server.js b/lib/server.js index 937bfb5..24c5830 100644 --- a/lib/server.js +++ b/lib/server.js @@ -116,7 +116,7 @@ var SolidusServer = function( options ){ router.engine( DEFAULT_VIEW_EXTENSION, handlebars.engine ); router.set( 'view engine', DEFAULT_VIEW_EXTENSION ); router.set( 'views', paths.views ); - // router.set( 'trust proxy', true ); // Use the X-Forwarded-* headers: https://expressjs.com/en/guide/behind-proxies.html + router.set( 'trust proxy', true ); // Use the X-Forwarded-* headers: https://expressjs.com/en/guide/behind-proxies.html router.use( express.compress() ); router.use(function(req, res, next) { res.set({'X-Powered-By': 'Solidus/' + VERSION}); diff --git a/package.json b/package.json index 8b6ee40..6c28dec 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "commander": "1.1.x", "continuation-local-storage": "~3.1.1", "express": "3.1.x", - "express-expose": "sparkartgroupinc/express-expose#escape-script-ending-tag", + "express-expose": "sparkartgroup/express-expose#escape-script-ending-tag", "express-handlebars": "1.2.2", "glob": "~3.2.6", "handlebars": "^1.3.0",