/
index.js
80 lines (65 loc) · 2.3 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
var parseUrl = require('url').parse;
var assign = require('lodash.assign');
function isSecure (secure, xfpHeader, trustXFPHeader) {
xfpHeader = xfpHeader ? xfpHeader.toString().toLowerCase() : '';
if (secure) {
return true;
}
return trustXFPHeader && xfpHeader === 'https'
}
function shouldRedirect (redirectsEnabled, method) {
if (!redirectsEnabled) {
return false
}
return method === "GET";
}
function checkForDeprecation (appSettings, optionsHttpsPort) {
var httpsPort = appSettings.get('httpsPort');
if (appSettings.get('env') === 'development') {
if (httpsPort) {
console.warn('express-force-ssl deprecated: app.set("httpsPort", ' + httpsPort + '), use ' +
'app.set("forceSSLOptions", { httpsPort: ' + httpsPort + ' }) instead.');
}
if (httpsPort && optionsHttpsPort) {
console.warn('You have set both app.get("httpsPort") and app.get("forceSSLOptions").httpsPort ' +
'Your app will use the value in forceSSLOptions.');
}
}
}
module.exports = function(req, res, next){
var redirect;
var secure;
var xfpHeader = req.get('X-Forwarded-Proto');
var localHttpsPort;
var appHttpsPort = req.app.get('httpsPort');
var httpsPort;
var fullUrl;
var redirectUrl;
var options = {
trustXFPHeader: false,
enable301Redirects: true,
httpsPort: false,
sslRequiredMessage: 'SSL Required.'
};
var expressOptions = req.app.get('forceSSLOptions') || {};
var localOptions = res.locals.forceSSLOptions || {};
localHttpsPort = localOptions.httpsPort;
assign(options, expressOptions, localOptions);
secure = isSecure(req.secure, xfpHeader, options.trustXFPHeader);
redirect = shouldRedirect(options.enable301Redirects, req.method);
if (!secure) {
if (redirect) {
checkForDeprecation(req.app, options.httpsPort);
httpsPort = localHttpsPort || options.httpsPort || appHttpsPort || 443;
fullUrl = parseUrl(req.protocol + '://' + req.header('Host') + req.originalUrl);
//intentionally allow coercion of https port
redirectUrl = 'https://' + fullUrl.hostname + (httpsPort == 443 ? '' : (':' + httpsPort)) + req.originalUrl;
res.redirect(301, redirectUrl);
} else {
res.status(403).send(options.sslRequiredMessage);
}
} else {
delete res.locals.forceSSLOptions;
next();
}
};