Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.js 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Original file created by Prof.Dr. Matthias Hopf
  2. /**
  3. * Express based http & https server
  4. *
  5. * Requires express >= 4
  6. */
  7. var common = require('./server/common'),
  8. //admin = require ('./server/admin'),
  9. authorize = require('./server/authorization'),
  10. dbs = require('./server/dbs');
  11. //files = require ('./server/files');
  12. const fs = common.fs, // file sync, read certificates
  13. http = common.http, // http handler
  14. https = require('https'), // https handler
  15. express = require('express'), // node server framework
  16. session = require('express-session'), // session management (security)
  17. morgan = require('morgan'), // logger
  18. mong = common.mongoose, // mongoose
  19. serveFavicon = require('serve-favicon'), // provide favicon
  20. bodyParser = require('body-parser'), // post request bodyparser
  21. MongoStore = require('connect-mongo')(session); // use mongodb as session storage
  22. var app = express();
  23. /*
  24. * Init
  25. */
  26. common .init();
  27. dbs .init (common);
  28. authorize .init(common);
  29. //admin .init (common);
  30. //files .init (common);
  31. mong.Promise = global.Promise;
  32. /*
  33. * Security
  34. *
  35. * TODO: Install helmet
  36. * https://expressjs.com/de/advanced/best-practice-security.html
  37. *
  38. * (Disable Header information: Powerd by Express)
  39. * -> Information disclosure
  40. */
  41. app.disable('x-powered-by');
  42. /*
  43. * Route Control
  44. */
  45. // Session Management
  46. app.set('trust proxy', 1) // trust first proxy, neccessary for cookie secure: true flag
  47. app.use(session({
  48. secret: 'ahhgylhuvh', // caesar(3) 2 letter surname
  49. resave: false,
  50. saveUninitialized: false,
  51. cookie: {
  52. maxAge: 30 * 24 * 3600 * 1000, // TODO: ttl for session as well (Store)
  53. secure: true, // true for https only (since our app works only with https)
  54. },
  55. name: 'om.sid',
  56. store: new MongoStore({
  57. mongooseConnection: mong.connection,
  58. ttl: 30 * 24 * 3600,
  59. }), // mongoose + connect-mongo
  60. //store: new MemoryStore ({checkPeriod: 24*3600*1000}), // memorystore
  61. }));
  62. // Favicon for Desktop
  63. app.use (serveFavicon(__dirname + '/public/img/favicon.ico'));
  64. // Minimal Logging
  65. //app.use (morgan ('dev'));
  66. // Advanced Logging
  67. morgan.token('user', function (req, res) {
  68. return (req.session && req.session.user) || '-';
  69. });
  70. morgan.token('userColored', function (req, res) {
  71. var color = 0;
  72. if (req.session && req.session.roles)
  73. color = req.session.roles.admin ? 31 // red
  74. : req.session.roles.user ? 34 // blue
  75. : 0; // no color
  76. return '\x1b[' + color + 'm' + ((req.session && req.session.user) || '-') + '\x1b[0m';
  77. });
  78. morgan.token('statusColored', function (req, res) {
  79. var color = res.statusCode >= 500 ? 31 // red
  80. : res.statusCode >= 400 ? 33 // yellow
  81. : res.statusCode >= 300 ? 36 // cyan
  82. : res.statusCode >= 200 ? 32 // green
  83. : 0; // no color
  84. return '\x1b[' + color + 'm' + (res.headersSent ? res.statusCode : '-') + '\x1b[0m';
  85. });
  86. app.use(morgan(':date[iso] :statusColored :method :url :userColored :response-time ms :res[content-length]'));
  87. // BodyParser
  88. // Returns middleware that only parses json bodies.
  89. // (https://www.npmjs.com/package/body-parser#bodyparserjsonoptions)
  90. app.use(bodyParser.json());
  91. // Returns middleware that only parses urlencoded bodies
  92. // with qs library (https://www.npmjs.com/package/qs#readme)
  93. app.use(bodyParser.urlencoded({
  94. extended: true
  95. }));
  96. // API
  97. var api_routes = express.Router(); // express app-object routing
  98. app.use('/api', api_routes);
  99. // Static Files - Allow access to 'public' folder
  100. app.use(express.static(__dirname + '/public'));
  101. // Other stuff is NOT authorized unless logged in
  102. app.use (authorize.genCheckAuthorized ('user'));
  103. // No error so far? Then it's a 404!
  104. app.use(function (req, res, next) {
  105. next(common.genError(404, req.url));
  106. });
  107. //app.use (routes.errorHandler (true)); /* true: show stack traces */
  108. /*
  109. * API
  110. */
  111. // API allowed for all
  112. api_routes.post('/login', authorize.login);
  113. api_routes.post('/logout', authorize.logout);
  114. // Validate all other API calls
  115. // TODO - Validate API calls
  116. //api_routes.use(authorize.genCheckAuthorized('user'));
  117. // Add API routes
  118. function addRoutes(r) {
  119. for (var e in r.routes) {
  120. var route = '/' + e + (r.routes[e].params ? "/" + r.routes[e].params : "");
  121. var log = "Adding routes for " + route + ":";
  122. var isAuth = r.routes[e].auth || r.auth;
  123. if (isAuth) {
  124. log += " [auth]";
  125. api_routes.use (route, function (req, res, next) {
  126. if (! auth(req))
  127. return next (common.genError (403, "Unauthorized"));
  128. next ();
  129. });
  130. }
  131. var role = r.routes[e].role || r.role;
  132. if (role) {
  133. log += " [role:"+role+"]";
  134. api_routes.use (route, authorize.genCheckAuthorized (role));
  135. }
  136. const methods = ["get", "post", "put", "delete"];
  137. for (var m in methods) {
  138. if (r.routes[e][methods[m]]) {
  139. log += " " + methods[m];
  140. api_routes[methods[m]](route, r.routes[e][methods[m]]);
  141. }
  142. }
  143. console.log(log);
  144. }
  145. }
  146. addRoutes(dbs);
  147. //addRoutes (admin);
  148. //addRoutes (files);
  149. /*
  150. * Servers
  151. */
  152. http.createServer(app).listen(common.config.httpPort, function () {
  153. console.log("Express http server listening on port " +
  154. common.config.httpPort);
  155. });
  156. /*
  157. * SSL certificates
  158. *
  159. * Keys + Certificate in current dir (not servable!)
  160. * to create (self-signed) SSL certs:
  161. *
  162. * openssl genrsa -out privatekey.pem 1024
  163. * openssl req -new -key privatekey.pem -out certrequest.csr
  164. * openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
  165. * rm certrequest.csr
  166. */
  167. // >>>>>>>>>>>>>>>>>>>>>>>>>>> SSL: DISABLED <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  168. /*
  169. if (common.config.httpsPort) {
  170. var options;
  171. try {
  172. try {
  173. // In case it's a real certificate: add CA chain cersts (TODO: use array if required)
  174. var ca = fs.readFileSync('keys/ca_cert.pem');
  175. } catch (e) {
  176. ca = undefined;
  177. console.log("Note: Can't read CA bundle: " + e);
  178. }
  179. if (ca != undefined) {
  180. options = {
  181. key: fs.readFileSync('keys/omkey.pem'),
  182. cert: fs.readFileSync('keys/certificate.pem'),
  183. ca: ca
  184. };
  185. https.createServer(options, app).listen(common.config.httpsPort, function () {
  186. console.log("Express https server listening on port " + common.config.httpsPort);
  187. });
  188. }
  189. } catch (e) {
  190. console.log("Note: Can't read SSL keys/certs: " + e + "\nDisabling https server");
  191. }
  192. } else {
  193. console.log("Note: https server disabled by config");
  194. }
  195. common.mongoose.set('useCreateIndex', true);*/
  196. /*
  197. * Uncaught Exceptions
  198. */
  199. process.on("uncaughtException", function (err) {
  200. console.error("*** Uncaught Exception:");
  201. console.error(err.stack);
  202. });