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 8.7KB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /**
  2. * Express based http & https server
  3. *
  4. * Requires express >= 4
  5. */
  6. var common = require ('./server/common'),
  7. authorize = require ('./server/authorization');
  8. /*
  9. dbs = require ('./server/dbs'),
  10. files = require ('./server/files');
  11. */
  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. //serveFavicon = require ('serve-favicon'),
  19. bodyParser = require ('body-parser'), // post request bodyparser
  20. MongoStore = require ('connect-mongo')(session), // use mongodb as session storage
  21. Message = require('./database/message.model.js');
  22. var app = express();
  23. /*
  24. * Init
  25. */
  26. common .init ();
  27. authorize.init (common);
  28. //dbs .init (common);
  29. //files .init (common);
  30. /*
  31. * Security
  32. *
  33. * TODO: Install helmet
  34. * https://expressjs.com/de/advanced/best-practice-security.html
  35. *
  36. * (Disable Header information: Powerd by Express)
  37. * -> Information disclosure
  38. */
  39. app.disable ('x-powered-by');
  40. // Session Management
  41. app.set('trust proxy', 1) // trust first proxy, neccessary for cookie secure: true flag
  42. app.use (session({
  43. secret: 'ahhgylhuvh', // caesar(3) 2 letter surname
  44. resave: false,
  45. saveUninitialized: false,
  46. cookie: {
  47. maxAge: 30*24*3600*1000, // TODO: ttl for session as well (Store)
  48. secure: true, // true for https only (since our app works only with https)
  49. },
  50. name: 'om.sid',
  51. store: new MongoStore ({mongooseConnection: common.mongoose.connection, ttl: 30*24*3600}), // mongoose + connect-mongo
  52. //store: new MemoryStore ({checkPeriod: 24*3600*1000}), // memorystore
  53. }));
  54. /*
  55. * Route Control
  56. */
  57. // Fastpaths
  58. //app.use (serveFavicon (__dirname + '/public/favicon.ico'));
  59. // Minimal Logging
  60. //app.use (morgan ('dev'));
  61. // Advanced Logging
  62. morgan.token ('user', function (req, res) { return (req.session && req.session.user) || '-'; });
  63. morgan.token ('userColored', function (req, res) {
  64. var color = 0;
  65. if (req.session && req.session.roles)
  66. color = req.session.roles.admin ? 31 // red
  67. : req.session.roles.user ? 34 // blue
  68. : 0; // no color
  69. return '\x1b[' + color + 'm' + ((req.session && req.session.user) || '-') + '\x1b[0m';
  70. });
  71. morgan.token ('statusColored', function (req, res) {
  72. var color = res.statusCode >= 500 ? 31 // red
  73. : res.statusCode >= 400 ? 33 // yellow
  74. : res.statusCode >= 300 ? 36 // cyan
  75. : res.statusCode >= 200 ? 32 // green
  76. : 0; // no color
  77. return '\x1b[' + color + 'm' + (res.headersSent ? res.statusCode : '-') + '\x1b[0m';
  78. });
  79. app.use (morgan (':date[iso] :statusColored :method :url :userColored :response-time ms :res[content-length]'));
  80. // BodyParser
  81. // Returns middleware that only parses json bodies.
  82. // (https://www.npmjs.com/package/body-parser#bodyparserjsonoptions)
  83. app.use (bodyParser.json());
  84. // Returns middleware that only parses urlencoded bodies
  85. // with qs library (https://www.npmjs.com/package/qs#readme)
  86. app.use (bodyParser.urlencoded({extended: true}));
  87. // API
  88. var api_routes = express.Router(); // express app-object routing
  89. app.use ('/api', api_routes);
  90. // Static Files
  91. // Allow server access to 'public' folder
  92. app.use(express.static(__dirname + '/public'));
  93. // Other stuff is NOT authorized unless logged in
  94. //app.use (authorize.genCheckAuthorized ('user'));
  95. // Uploaded files
  96. //app.use ('/uploads', express.static(__dirname + '/uploads'));
  97. // Configuring the database
  98. //var dbConfig = require('./mongodb.config.js');
  99. common.mongoose.Promise = global.Promise;
  100. // Connecting to the database
  101. // Local db: common.config.dbLocalConn
  102. // Efi db: common.config.dbConn
  103. common.mongoose.connect (common.config.dbLocalConn, {useNewUrlParser: true}) .then( () => {
  104. console.log("Successfully connected to MongoDB.");
  105. }).catch( err => {
  106. console.log('Could not connect to MongoDB.');
  107. process.exit();
  108. });
  109. // No error so far? Then it's a 404!
  110. //app.use (function (req, res, next) { next (common.genError (404, req.url)); });
  111. //app.use (routes.errorHandler (true)); /* true: show stack traces */
  112. /*
  113. * API
  114. */
  115. /*
  116. // API allowed for all
  117. api_routes.post ('/login', authorize.login); // /api/login
  118. // Validate all other API calls
  119. api_routes.use (authorize.genCheckAuthorized ('user'));
  120. api_routes.post ('/logout', authorize.logout);
  121. function addRoutes (r) {
  122. for (var e in r.routes) {
  123. var params = r.routes[e].params ? "/" + r.routes[e].params : "";
  124. console.log ("Adding routes for /" + e + params + ":" +
  125. (r.routes[e].get ? " get":" ") + (r.routes[e].post ? " post":" ") +
  126. (r.routes[e].put ? " put":" ") + (r.routes[e].delete ? " delete":" "));
  127. if (r.routes[e].get)
  128. api_routes.get ('/' + e + params, r.routes[e].get);
  129. if (r.routes[e].post)
  130. api_routes.post ('/' + e + params, r.routes[e].post);
  131. if (r.routes[e].put)
  132. api_routes.put ('/' + e + params, r.routes[e].put);
  133. if (r.routes[e].delete)
  134. api_routes.delete ('/' + e + params, r.routes[e].delete);
  135. }
  136. }
  137. */
  138. app.get ('/api/ids', function (req, res) {
  139. Message.find({},{id: true}) .exec () .then(results => {
  140. //selects id from message:
  141. var parsed = [];
  142. for (var i in results) {
  143. parsed.push (results[i].id);
  144. }
  145. //var parsed = results.map (x => x._id);
  146. res.send(parsed);
  147. } )
  148. .catch(err => {
  149. console.log (err);
  150. res .status(500) .json (err);
  151. });
  152. });
  153. app.get ("/api/msg/:id", function (req, res) {
  154. Message.findOne ({_id: req.params.id}) .exec (function (err, results){
  155. if (err) {
  156. console.log (err);
  157. res .status(404) .json (err);
  158. } else {
  159. console.log(JSON.stringify(results));
  160. res.json(results);
  161. }
  162. });
  163. });
  164. /*app.get ("/api/msg/search/:phrase", function (req, res) {
  165. Message.find ({$text: {$search: req.params.phrase}) .then (function (err, results){
  166. if (err) {
  167. console.log (err);
  168. res .status(404) .json (err);
  169. } else {
  170. console.log(JSON.stringify(results));
  171. res.json(results);
  172. }
  173. });
  174. });
  175. */
  176. /*function makeid() {
  177. var text = "";
  178. var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  179. for (var i = 0; i < 5; i++)
  180. text += possible.charAt(Math.floor(Math.random() * possible.length));
  181. return text;
  182. }*/
  183. app.post("/api/createMsg", function(req, res){
  184. //x = mongoose.Types.ObjectId();
  185. //y = x.toString();
  186. //var z = makeid();
  187. console.log("SUbject: "+JSON.stringify(req.body));
  188. var message = new Message( {subject: req.body.sub, message: req.body.mess, user: req.body.use, tag: req.body.ta } );
  189. message.save(function(err,result){
  190. if(err){
  191. return res .status(401) .send(err.message);
  192. }else{
  193. res.json({message: "Message created!!"});
  194. }
  195. });
  196. });
  197. /*
  198. addRoutes (dbs);
  199. addRoutes (admin);
  200. addRoutes (files);
  201. */
  202. /*
  203. * Servers
  204. */
  205. http.createServer (app) .listen (common.config.httpPort, function () {
  206. console.log ("Express http server listening on port " + common.config.httpPort);
  207. });
  208. /*
  209. * SSL certificates
  210. *
  211. * Keys + Certificate in current dir (not servable!)
  212. * to create (self-signed) SSL certs:
  213. *
  214. * openssl genrsa -out privatekey.pem 1024
  215. * openssl req -new -key privatekey.pem -out certrequest.csr
  216. * openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
  217. * rm certrequest.csr
  218. */
  219. if (common.config.httpsPort) {
  220. var options;
  221. try {
  222. try {
  223. // In case it's a real certificate: add CA chain cersts (TODO: use array if required)
  224. var ca = fs.readFileSync ('keys/ca_cert.pem');
  225. } catch (e) {
  226. ca = undefined;
  227. console.log ("Note: Can't read CA bundle: "+e);
  228. }
  229. if (ca != undefined) {
  230. options = {
  231. key: fs.readFileSync ('keys/omkey.pem'),
  232. cert: fs.readFileSync ('keys/certificate.pem'),
  233. ca: ca
  234. };
  235. https.createServer (options, app) .listen (common.config.httpsPort, function () {
  236. console.log ("Express https server listening on port " + common.config.httpsPort);
  237. });
  238. }
  239. } catch (e) {
  240. console.log ("Note: Can't read SSL keys/certs: "+e+"\nDisabling https server");
  241. }
  242. } else {
  243. console.log("Note: https server disabled by config");
  244. }
  245. /*
  246. * Uncaught Exceptions
  247. */
  248. process.on ("uncaughtException", function (err) {
  249. console.error ("*** Uncaught Exception:");
  250. console.error (err.stack);
  251. });