server.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. Copyright (C) 2017 Cloudbase Solutions SRL
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. import 'babel-polyfill';
  15. import path from 'path';
  16. import express from 'express';
  17. import cookieParser from 'cookie-parser';
  18. import bodyParser from 'body-parser';
  19. import ReactDOM from 'react-dom/server';
  20. import PrettyError from 'pretty-error';
  21. import Router from './routes';
  22. import assets from './assets';
  23. import { port, analytics } from './config';
  24. const server = global.server = express();
  25. //
  26. // Tell any CSS tooling (such as Material UI) to use all vendor prefixes if the
  27. // user agent is not known.
  28. // -----------------------------------------------------------------------------
  29. global.navigator = global.navigator || {};
  30. global.navigator.userAgent = global.navigator.userAgent || 'all';
  31. //
  32. // Register Node.js middleware
  33. // -----------------------------------------------------------------------------
  34. server.use(express.static(path.join(__dirname, 'public')));
  35. server.use(cookieParser());
  36. server.use(bodyParser.urlencoded({ extended: true }));
  37. server.use(bodyParser.json());
  38. server.post('/federation', async (req, res) => {
  39. let token = req.body.token
  40. if (token) {
  41. res.redirect('/federate/' + token);
  42. } else {
  43. res.redirect('/login');
  44. }
  45. });
  46. //
  47. // Register server-side rendering middleware
  48. // -----------------------------------------------------------------------------
  49. server.get('*', async (req, res, next) => {
  50. try {
  51. let statusCode = 200;
  52. const template = require('./views/index.jade');
  53. const data = { title: '', description: '', css: '', body: '', entry: assets.main.js };
  54. if (process.env.NODE_ENV === 'production') {
  55. data.trackingId = analytics.google.trackingId;
  56. }
  57. const css = [];
  58. const context = {
  59. insertCss: styles => css.push(styles._getCss()),
  60. onSetTitle: value => (data.title = value),
  61. onSetMeta: (key, value) => (data[key] = value),
  62. onPageNotFound: () => (statusCode = 404),
  63. };
  64. await Router.dispatch({ path: req.path, query: req.query, context }, (state, component) => {
  65. data.body = ReactDOM.renderToString(component);
  66. data.css = css.join('');
  67. });
  68. res.status(statusCode);
  69. res.send(template(data));
  70. } catch (err) {
  71. next(err);
  72. }
  73. });
  74. //
  75. // Error handling
  76. // -----------------------------------------------------------------------------
  77. const pe = new PrettyError();
  78. pe.skipNodeFiles();
  79. pe.skipPackage('express');
  80. server.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
  81. console.log(pe.render(err)); // eslint-disable-line no-console
  82. const template = require('./views/error.jade');
  83. const statusCode = err.status || 500;
  84. res.status(statusCode);
  85. res.send(template({
  86. message: err.message,
  87. stack: process.env.NODE_ENV === 'production' ? '' : err.stack,
  88. }));
  89. });
  90. //
  91. // Launch the server
  92. // -----------------------------------------------------------------------------
  93. server.listen(port, () => {
  94. /* eslint-disable no-console */
  95. console.log(`The server is running at http://localhost:${port}/`);
  96. });