-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
server.js
128 lines (106 loc) · 3.35 KB
/
server.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
require('dotenv').config({silent: true});
const express = require('express');
const compress = require('compression');
const cookieParser = require('cookie-parser');
const dateFilter = require('nunjucks-date-filter');
const nunjucks = require('nunjucks');
const helmet = require('helmet');
const path = require('path');
const Sentry = require('@sentry/node');
const throng = require('throng');
const { createProxyMiddleware } = require('http-proxy-middleware');
const { handleNotFound } = require('./server/pageNotFound');
const { router } = require('./server/router');
const tools = require('./server/tools');
const {
checkForRedirects,
loadLocalVars
} = require('./server/processRequest');
const {
prismicMiddleware,
announcementBarCronJob
} = require('./server/prismic');
const {
API_URL,
PORT,
PROD,
REDIS_URL,
SENTRY_DSN,
SENTRY_ENVIRONMENT,
WEB_CONCURRENCY
} = require('./server/config');
// start up parallel servers in prod
throng({
workers: WEB_CONCURRENCY,
lifetime: Infinity
}, start)
function start() {
const app = express();
if (SENTRY_DSN) {
Sentry.init({ dsn: SENTRY_DSN, environment: SENTRY_ENVIRONMENT });
}
// rate limit POST requests
if (REDIS_URL) {
var redis = require('redis').createClient(REDIS_URL);
var limiter = require('express-limiter')(app, redis);
// rate limit POST requests
limiter({
path: '*',
method: 'post',
lookup: ['headers.CF-Connecting-IP'],
// 15 requests per 30 seconds
total: 15,
expire: 1000 * 30
})
}
app.set('trust proxy', true);
// The Sentry request handler must be the first middleware on the app
app.use(Sentry.Handlers.requestHandler());
app.use(compress());
app.use(cookieParser());
app.use(helmet());
app.enable('etag');
app.use(checkForRedirects);
// check if this is a valid static file
app.use(express.static('dist', { maxAge: 1000 * 60 * 60 * 24 * 7 }));
// cache images and static assets for 1 week
app.use(express.static('content', { maxAge: 1000 * 60 * 60 * 24 * 7 }));
app.use(prismicMiddleware);
app.use(loadLocalVars);
announcementBarCronJob(app)
if (!PROD) {
// Proxy for oauth when in dev mode
app.use('/oauth', createProxyMiddleware({
target: API_URL || 'https://staging.ionicframework.com',
changeOrigin: true,
secure: false
}));
}
// Proxy for Appflow wizard
const wizardOptions = {
target: API_URL,
changeOrigin: true,
secure: false,
pathRewrite: {
'^/api/v1/wizard': '/apps/wizard/request',
}
};
app.use('/api/v1/wizard', createProxyMiddleware(wizardOptions));
nunjucks.configure('server/pages', {
express: app,
noCache: !PROD,
autoescape: false
}).addFilter('date', dateFilter);
app.set('views', path.resolve(__dirname, '/server/pages'));
app.set('view engine', 'html');
app.use(router(app));
// The Sentry error handler must be before any other error middleware
app.use(Sentry.Handlers.errorHandler());
app.use(handleNotFound);
// bind the app to listen for connections on a specified port
app.listen(PORT, function() {
console.log('Listening on port ' + PORT);
// 5 min delay for heroku rolling start to complete
setTimeout(tools.bustCloudflareCache, 1000 * 60 * 5);
});
} // end start()