forked from openhab/openhab-cloud
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
225 lines (197 loc) · 6.52 KB
/
app.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/**
* Copyright (c) 2010-2019 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
/**
* This is the main application of the openHAB-cloud service
*
* @author Victor Belov - Initial contribution
* @author Dan Cunningham - Extended Features
* @author Mehmet Arziman - Extended Features
*
*/
// Main Logging setup
var logger = require('./logger.js'),
system = require('./system'),
config;
//load and set our configuration, delete any cache first
var loadConfig = function () {
delete require.cache[require.resolve('./config.json')];
config = require('./config.json');
system.setConfiguration(config);
}
loadConfig();
module.exports.config = config;
//require('heapdump');
logger.info('Backend service is starting up...');
process.on('uncaughtException', function (err) {
console.log(JSON.stringify(err))
logger.error(err);
});
process.on('SIGHUP', function () {
logger.info('Reloading config...');
loadConfig();
});
logger.info('Backend logging initialized...');
// If Firebase Cloud Messaging is configured set it up
if (system.isGcmConfigured()) {
require('./fcm-xmpp');
}
// Setup all homepage
var flash = require('connect-flash'),
express = require('express'),
bodyParser = require('body-parser'),
errorHandler = require('errorhandler'),
cookieParser = require('cookie-parser'),
session = require('express-session'),
favicon = require('serve-favicon'),
csurf = require('csurf'),
serveStatic = require('serve-static'),
path = require('path'),
passport = require('passport'),
RedisStore = require('connect-redis')(session),
redis = require('./redis-helper'),
date_util = require('./date_util.js'),
auth = require('./auth.js'),
routes = require('./routes'),
MongoConnect = require('./system/mongoconnect'),
mongoose = require('mongoose'),
cachegoose = require('recachegoose'),
mongooseTypes = require('mongoose-types'),
SocketIO = require('./socket-io');
cachegoose(mongoose, {
engine: 'redis',
port: config.redis.port,
host: config.redis.host,
password: config.redis.password,
});
// Try to setup a mongodb connection, otherwise stopping
var mongoConnect = new MongoConnect(system);
mongoConnect.connect(mongoose);
mongooseTypes.loadTypes(mongoose);
var app = express();
var every5MinStatJob = require('./jobs/every5minstat');
every5MinStatJob.start();
// Configurable support for cross subdomain cookies
var cookie = {};
if (config.system.subDomainCookies) {
cookie.path = '/';
cookie.domain = '.' + system.getHost();
logger.info('Cross sub domain cookie support is configured for domain: ' + cookie.domain);
}
// Configure the openHAB-cloud for development mode, if in development
if (app.get('env') === 'development') {
app.use(errorHandler());
}
if (system.getLoggerMorganOption()){
app.use(system.getLoggerMorganOption());
}
// App configuration for all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(favicon(__dirname + '/public/img/favicon.ico'));
app.use(bodyParser.json({ verify: function (req, res, buf) { req.rawBody = buf } }))
app.use(bodyParser.urlencoded({
verify: function (req, res, buf) { req.rawBody = buf },
extended: true
}));
app.use(cookieParser(config.express.key));
app.use(session({
secret: config.express.key,
store: new RedisStore({
host: 'localhost',
port: 6379,
client: redis,
logErrors: true
}),
cookie: cookie,
resave: false,
saveUninitialized: false
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
//TODO we need to remove this hack, its leftover from long ago.
//we need to know if this is a proxy connection or not (home/remote), other middleware depends on it.
app.use(function (req, res, next) {
var host = req.headers.host;
// console.log(host);
if (!host) {
next(); // No host in header, just go ahead
}
// If host matches names for full /* proxying, go ahead and just proxy it.
if (host.indexOf('remote.') === 0 || host.indexOf('home.') === 0) {
//make sure this was not set by another server
if (req.url.indexOf('/remote') != 0) {
req.url = '/remote' + req.url;
}
}
next();
});
app.use(function (req, res, next) {
var csrf = csurf();
// Check if url needs csrf, remote connections and REST connections are excluded from CSRF
if (!req.path.match('/rest*') && !req.path.match('/oauth2/token') && !req.path.match('/ifttt/*') && !req.path.match('/remote/*'))
csrf(req, res, next);
else
next();
});
app.use(function (req, res, next) {
if (typeof req.csrfToken === 'function') {
res.locals.token = req.csrfToken();
}
next();
});
// Add global usable locals for templates
app.use(function (req, res, next) {
res.locals.baseurl = system.getBaseURL();
res.locals.proxyUrl = system.getProxyURL();
if (req.session.timezone) {
res.locals.timeZone = req.session.timezone;
} else {
res.locals.timeZone = 'undefined';
}
res.locals.date_util = date_util;
res.locals.legal = false;
if (config.legal) {
res.locals.legal = true;
res.locals.terms = config.legal.terms;
res.locals.policy = config.legal.policy;
}
res.locals.registration_enabled = system.isUserRegistrationEnabled();
next();
});
app.use(serveStatic(path.join(__dirname, 'public')));
var server = app.listen(system.getNodeProcessPort(), config.system.listenIp, function () {
logger.info('express server listening on port ' + system.getNodeProcessPort());
});
// setup socket.io connections from openHABs
var socketIO = new SocketIO(server, system);
// setup the routes for the app
var rt = new routes(logger);
rt.setSocketIO(socketIO);
rt.setupRoutes(app);
function shutdown() {
// TODO: save current request id?
logger.info('Stopping every5min statistics job');
every5MinStatJob.stop();
logger.info('Safe shutdown complete');
process.exit();
}
process.on('SIGINT', function () {
logger.info('frontend is shutting down from SIGINT');
shutdown();
});
process.on('SIGTERM', function () {
logger.info('frontend is shutting down from SIGTERM');
shutdown();
});