/
express.js
140 lines (119 loc) · 4.21 KB
/
express.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
import bodyParser from 'body-parser';
import config from 'config';
import connectRedis from 'connect-redis';
import cookieParser from 'cookie-parser';
import cors from 'cors';
import debug from 'debug';
import errorHandler from 'errorhandler';
import helmet from 'helmet';
import morgan from 'morgan';
import passport from 'passport';
import redis from 'redis';
import session from 'express-session';
import cloudflareIps from 'cloudflare-ip/ips.json';
import { Strategy as GitHubStrategy } from 'passport-github';
import { Strategy as TwitterStrategy } from 'passport-twitter';
import { Strategy as MeetupStrategy } from 'passport-meetup-oauth2';
import { has, get } from 'lodash';
import forest from './forest';
import cacheMiddleware from '../middleware/cache';
import { loadersMiddleware } from '../graphql/loaders';
import { sanitizeForLogs } from '../lib/utils';
export default function(app) {
app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal'].concat(cloudflareIps));
app.use(helmet());
// Loaders are attached to the request to batch DB queries per request
// It also creates in-memory caching (based on request auth);
app.use(loadersMiddleware);
if (process.env.DEBUG && process.env.DEBUG.match(/response/)) {
app.use((req, res, next) => {
const temp = res.end;
res.end = function(str) {
try {
const obj = JSON.parse(str);
debug('response')(JSON.stringify(obj, null, ' '));
} catch (e) {
debug('response', str);
}
temp.apply(this, arguments);
};
next();
});
}
// Log requests if enabled (default false)
if (get(config, 'log.accessLogs')) {
app.use(morgan('combined'));
}
// Body parser.
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
// Slow requests if enabled (default false)
if (get(config, 'log.slowRequest')) {
app.use((req, res, next) => {
req.startAt = new Date();
const temp = res.end;
res.end = function() {
const timeElapsed = new Date() - req.startAt;
if (timeElapsed > get(config, 'log.slowRequestThreshold', 1000)) {
if (req.body && req.body.query) {
console.log(
`>>> slow request ${timeElapsed}ms`,
req.body.operationName,
'query:',
req.body.query.substr(0, req.body.query.indexOf(')') + 1),
);
if (req.body.variables) {
console.log('>>> variables: ', sanitizeForLogs(req.body.variables));
}
}
}
temp.apply(this, arguments);
};
next();
});
}
// Cache Middleware
if (get(config, 'cache.middleware')) {
app.use(cacheMiddleware());
}
// Error handling.
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'staging') {
app.use(errorHandler());
}
// Forest
forest(app);
// Cors.
app.use(cors());
const verify = (accessToken, tokenSecret, profile, done) => done(null, accessToken, { tokenSecret, profile });
if (has(config, 'github.clientID') && has(config, 'github.clientSecret')) {
passport.use(new GitHubStrategy(get(config, 'github'), verify));
} else {
console.warn('Configuration missing for passport GitHubStrategy, skipping.');
}
if (has(config, 'meetup.clientID') && has(config, 'meetup.clientSecret')) {
passport.use(new MeetupStrategy(get(config, 'meetup'), verify));
} else {
console.warn('Configuration missing for passport MeetupStrategy, skipping.');
}
if (has(config, 'twitter.consumerKey') && has(config, 'twitter.consumerSecret')) {
passport.use(new TwitterStrategy(get(config, 'twitter'), verify));
} else {
console.warn('Configuration missing for passport TwitterStrategy, skipping.');
}
app.use(cookieParser());
// Setup session (required by passport)
let store;
if (get(config, 'redis.serverUrl')) {
const RedisStore = connectRedis(session);
store = new RedisStore({ client: redis.createClient(get(config, 'redis.serverUrl')) });
}
app.use(
session({
store,
secret: config.keys.opencollective.sessionSecret,
resave: false,
saveUninitialized: false,
}),
);
app.use(passport.initialize());
}