-
Notifications
You must be signed in to change notification settings - Fork 219
/
express-init.js
146 lines (116 loc) · 4.88 KB
/
express-init.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { manifestPath as presetThemesManifestPath } from '@growi/preset-themes';
import csrf from 'csurf';
import mongoose from 'mongoose';
import qs from 'qs';
import loggerFactory from '~/utils/logger';
import { resolveFromRoot } from '~/utils/project-dir-utils';
const logger = loggerFactory('growi:crowi:express-init');
module.exports = function(crowi, app) {
const debug = require('debug')('growi:crowi:express-init');
const path = require('path');
const express = require('express');
const compression = require('compression');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const methodOverride = require('method-override');
const passport = require('passport');
const expressSession = require('express-session');
const flash = require('connect-flash');
const mongoSanitize = require('express-mongo-sanitize');
const promster = require('../middlewares/promster')(crowi, app);
const registerSafeRedirect = require('../middlewares/safe-redirect')();
const injectCurrentuserToLocalvars = require('../middlewares/inject-currentuser-to-localvars')();
const autoReconnectToS2sMsgServer = require('../middlewares/auto-reconnect-to-s2s-msg-server')(crowi);
const avoidSessionRoutes = require('../routes/avoid-session-routes');
const env = crowi.node_env;
// see: https://qiita.com/nazomikan/items/9458d591a4831480098d
// Cannot set a custom query parser after app.use() has been called: https://github.com/expressjs/express/issues/3454
app.set('query parser', str => qs.parse(str, { arrayLimit: Infinity }));
app.use(compression());
const { configManager } = crowi;
const trustProxyBool = configManager.getConfig('crowi', 'security:trustProxyBool');
const trustProxyCsv = configManager.getConfig('crowi', 'security:trustProxyCsv');
const trustProxyHops = configManager.getConfig('crowi', 'security:trustProxyHops');
const trustProxy = trustProxyBool ?? trustProxyCsv ?? trustProxyHops;
try {
if (trustProxy != null) {
const isNotSpec = [trustProxyBool, trustProxyCsv, trustProxyHops].filter(trustProxy => trustProxy != null).length !== 1;
if (isNotSpec) {
// eslint-disable-next-line max-len
logger.warn(`If more than one TRUST_PROXY_ ~ environment variable is set, the values are set in the following order of inequality size (BOOL > CSV > HOPS) first. Set value: ${trustProxy}`);
}
app.set('trust proxy', trustProxy);
}
}
catch (err) {
logger.error(err);
}
app.use(helmet({
contentSecurityPolicy: false,
expectCt: false,
referrerPolicy: false,
permittedCrossDomainPolicies: false,
}));
app.use((req, res, next) => {
const now = new Date();
// for datez
app.set('tzoffset', crowi.appService.getTzoffset());
res.locals.req = req;
res.locals.baseUrl = crowi.appService.getSiteUrl();
res.locals.env = env;
res.locals.now = now;
next();
});
app.set('port', crowi.port);
const staticOption = (crowi.node_env === 'production') ? { maxAge: '30d' } : {};
app.use(express.static(crowi.publicDir, staticOption));
app.use('/static/preset-themes', express.static(
resolveFromRoot(`../../node_modules/@growi/preset-themes/${path.dirname(presetThemesManifestPath)}`),
));
app.use('/static/plugins', express.static(path.resolve(__dirname, '../../../tmp/plugins')));
app.use(methodOverride());
// inject rawBody to req
app.use((req, res, next) => {
if (!req.is('multipart/form-data')) {
req.rawBody = '';
req.on('data', (chunk) => {
req.rawBody += chunk;
});
}
next();
});
app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(cookieParser());
// configure express-session
const sessionMiddleware = expressSession(crowi.sessionConfig);
app.use((req, res, next) => {
// test whether the route is listed in avoidSessionRoutes
for (const regex of avoidSessionRoutes) {
if (regex.test(req.path)) {
return next();
}
}
sessionMiddleware(req, res, next);
});
// csurf should be initialized after express-session
// default methods + PUT. See: https://expressjs.com/en/resources/middleware/csurf.html#ignoremethods
app.use(csrf({ ignoreMethods: ['GET', 'HEAD', 'OPTIONS', 'PUT', 'POST', 'DELETE'], cookie: false }));
// passport
debug('initialize Passport');
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(mongoSanitize());
app.use(promster);
app.use(registerSafeRedirect);
app.use(injectCurrentuserToLocalvars);
app.use(autoReconnectToS2sMsgServer);
// TODO: Remove this workaround implementation when i18n works correctly.
// For now, req.t returns string given to req.t(string)
app.use((req, res, next) => {
req.t = str => (typeof str === 'string' ? str : '');
next();
});
};