express-init.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import mongoose from 'mongoose';
  2. module.exports = function(crowi, app) {
  3. const debug = require('debug')('growi:crowi:express-init');
  4. const path = require('path');
  5. const express = require('express');
  6. const compression = require('compression');
  7. const helmet = require('helmet');
  8. const bodyParser = require('body-parser');
  9. const cookieParser = require('cookie-parser');
  10. const methodOverride = require('method-override');
  11. const passport = require('passport');
  12. const expressSession = require('express-session');
  13. const flash = require('connect-flash');
  14. const mongoSanitize = require('express-mongo-sanitize');
  15. const swig = require('swig-templates');
  16. const webpackAssets = require('express-webpack-assets');
  17. const i18next = require('i18next');
  18. const i18nFsBackend = require('i18next-node-fs-backend');
  19. const i18nSprintf = require('i18next-sprintf-postprocessor');
  20. const i18nMiddleware = require('i18next-express-middleware');
  21. const promster = require('../middlewares/promster')(crowi, app);
  22. const registerSafeRedirect = require('../middlewares/safe-redirect')();
  23. const injectCurrentuserToLocalvars = require('../middlewares/inject-currentuser-to-localvars')();
  24. const autoReconnectToS2sMsgServer = require('../middlewares/auto-reconnect-to-s2s-msg-server')(crowi);
  25. const { listLocaleIds } = require('~/utils/locale-utils');
  26. const avoidSessionRoutes = require('../routes/avoid-session-routes');
  27. const i18nUserSettingDetector = require('../util/i18nUserSettingDetector');
  28. const env = crowi.node_env;
  29. const lngDetector = new i18nMiddleware.LanguageDetector();
  30. lngDetector.addDetector(i18nUserSettingDetector);
  31. i18next
  32. .use(lngDetector)
  33. .use(i18nFsBackend)
  34. .use(i18nSprintf)
  35. .init({
  36. // debug: true,
  37. fallbackLng: ['en_US'],
  38. whitelist: listLocaleIds(),
  39. backend: {
  40. loadPath: `${crowi.localeDir}{{lng}}/translation.json`,
  41. },
  42. detection: {
  43. order: ['userSettingDetector', 'header', 'navigator'],
  44. },
  45. overloadTranslationOptionHandler: i18nSprintf.overloadTranslationOptionHandler,
  46. // change nsSeparator from ':' to '::' because ':' is used in config keys and these are used in i18n keys
  47. nsSeparator: '::',
  48. });
  49. app.use(compression());
  50. const { configManager } = crowi;
  51. const trustedProxies = configManager.getConfig('crowi', 'security:trustedProxies');
  52. if (trustedProxies !== '') {
  53. app.set('trust proxy', trustedProxies);
  54. }
  55. app.use(helmet({
  56. contentSecurityPolicy: false,
  57. expectCt: false,
  58. referrerPolicy: false,
  59. permittedCrossDomainPolicies: false,
  60. }));
  61. app.use((req, res, next) => {
  62. const now = new Date();
  63. // for datez
  64. const Page = crowi.model('Page');
  65. const User = crowi.model('User');
  66. const Config = mongoose.model('Config');
  67. app.set('tzoffset', crowi.appService.getTzoffset());
  68. req.csrfToken = null;
  69. res.locals.req = req;
  70. res.locals.baseUrl = crowi.appService.getSiteUrl();
  71. res.locals.env = env;
  72. res.locals.now = now;
  73. res.locals.consts = {
  74. pageGrants: Page.getGrantLabels(),
  75. userStatus: User.getUserStatusLabels(),
  76. language: listLocaleIds(),
  77. restrictGuestMode: crowi.aclService.getRestrictGuestModeLabels(),
  78. registrationMode: crowi.aclService.getRegistrationModeLabels(),
  79. };
  80. res.locals.local_config = Config.getLocalconfig(crowi); // config for browser context
  81. next();
  82. });
  83. app.set('port', crowi.port);
  84. const staticOption = (crowi.node_env === 'production') ? { maxAge: '30d' } : {};
  85. app.use(express.static(crowi.publicDir, staticOption));
  86. app.engine('html', swig.renderFile);
  87. app.use(webpackAssets(
  88. path.join(crowi.publicDir, 'manifest.json'),
  89. { devMode: (crowi.node_env === 'development') },
  90. ));
  91. // app.set('view cache', false); // Default: true in production, otherwise undefined. -- 2017.07.04 Yuki Takei
  92. app.set('view engine', 'html');
  93. app.set('views', crowi.viewsDir);
  94. app.use(methodOverride());
  95. // inject rawBody to req
  96. app.use((req, res, next) => {
  97. if (!req.is('multipart/form-data')) {
  98. req.rawBody = '';
  99. req.on('data', (chunk) => {
  100. req.rawBody += chunk;
  101. });
  102. }
  103. next();
  104. });
  105. app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
  106. app.use(bodyParser.json({ limit: '50mb' }));
  107. app.use(cookieParser());
  108. // configure express-session
  109. const sessionMiddleware = expressSession(crowi.sessionConfig);
  110. app.use((req, res, next) => {
  111. // test whether the route is listed in avoidSessionRoutes
  112. for (const regex of avoidSessionRoutes) {
  113. if (regex.test(req.path)) {
  114. return next();
  115. }
  116. }
  117. sessionMiddleware(req, res, next);
  118. });
  119. // passport
  120. debug('initialize Passport');
  121. app.use(passport.initialize());
  122. app.use(passport.session());
  123. app.use(flash());
  124. app.use(mongoSanitize());
  125. app.use(promster);
  126. app.use(registerSafeRedirect);
  127. app.use(injectCurrentuserToLocalvars);
  128. app.use(autoReconnectToS2sMsgServer);
  129. const middlewares = require('../util/middlewares')(crowi, app);
  130. app.use(middlewares.swigFilters(swig));
  131. app.use(middlewares.swigFunctions());
  132. app.use(middlewares.csrfKeyGenerator());
  133. app.use(i18nMiddleware.handle(i18next));
  134. };