network-pulse/server.js

128 строки
4.7 KiB
JavaScript

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/favicon-128x128@2x.png">
<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`);
});