forked from mozilla/network-pulse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
127 lines (108 loc) · 4.73 KB
/
server.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import express from 'express';
import path from 'path';
import helmet from 'helmet';
import { Helmet as ReactHelmet } from "react-helmet";
import React from 'react';
import { renderToString } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import routes from './routes.jsx';
import securityHeaders from './js/security-headers';
const app = express();
// Find the port we're using. If we're deployed on heroku,
// that information will not be in our config because the
// bundle compilation will have taken place on a different
// dyno from where the code actually runs, but is available
// at runtime as a PORT environment variable
import env from "./config/env.generated.json";
const defaultPort = 3000;
const PORT = env.PORT || process.env.PORT || defaultPort;
// disable x-powered-by
app.disable('x-powered-by');
// Some app security settings
app.use(helmet.contentSecurityPolicy(securityHeaders));
app.use(helmet.xssFilter({
setOnOldIE: true
}));
// maxAge for HSTS header must be at least 18 weeks (see https://hstspreload.org/)
app.use(helmet.hsts({
maxAge: 60 * 60 * 24 * 7 * 18, // 18 weeks in seconds
setIf: (req, res) => {
if (req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "https") {
return true;
}
return false;
},
includeSubDomains: true,
preload: true
}));
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.frameguard({
action: 'deny'
}));
// make sure that heroku content is always on https
// (or really, anything that relies on x-forwarded-proto)
app.use((req, res, next) => {
if(req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
return res.redirect("https://" + req.headers.host + req.url);
}
next();
});
app.use(express.static(path.resolve(__dirname, `dist`)));
app.get(`*`, (req, res) => {
match({ routes: routes, location: req.url }, (err, redirect, props) => {
if (err) {
res.status(500).send(err.message);
} else if (redirect) {
res.redirect(302, redirect.pathname + redirect.search);
} else if (props) {
// we've got props!
// let's match a route and render the corresponding page component
const appHtml = renderToString(<RouterContext {...props}/>);
const reactHelmet = ReactHelmet.renderStatic();
if (props.components[props.components.length-1].displayName === `not-found`) {
// if route matches the "Not Found" route, let's render the "Not Found" 404 page
res.status(404).send(renderPage(appHtml,reactHelmet));
} else {
res.status(200).send(renderPage(appHtml,reactHelmet));
}
} else {
// nothing was matched
res.status(404).send(`Not Found`);
}
});
});
function renderPage(appHtml,reactHelmet) {
// this is basically the same as what we have in ./index.html,
// except that we are inserting appHtml as inner DOM of <div id="app"></div>
return `<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<script type="text/javascript" async src="https://platform.twitter.com/widgets.js"></script>
<link rel="icon" type="image/png" sizes="36x36" href="/favicon.png">
<link rel="icon" type="image/png" sizes="128x128" href="/assets/favicons/[email protected]">
<link rel="apple-touch-icon" type="image/png" sizes="152x152" href="/assets/favicons/touch-icon-ipad.png">
<link rel="apple-touch-icon" type="image/png" sizes="167x167" href="/assets/favicons/touch-icon-ipad-retina.png">
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="/assets/favicons/touch-icon-iphone-retina.png">
<link rel="manifest" href="/manifest.json">
<link rel="stylesheet" type="text/css" href="https://code.cdn.mozilla.net/fonts/zilla-slab.css">
<link rel="stylesheet" type="text/css" href="/css/mofo-bootstrap.css">
<link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="/css/main.css">
${reactHelmet.title.toString()}
</head>
<body>
<div id="app">${appHtml}</div>
<script src="/bundle.js"></script>
</body>
</html>`;
}
app.listen(PORT, () => {
console.log(`\n*******************************************`);
console.log(`* *`);
console.log(`* Network Pulse listening on port ${PORT} *`);
console.log(`* *`);
console.log(`*******************************************\n`);
});