cloudcms-server 0.9.301 → 3.2.280

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.last_command +7 -0
  2. package/LICENSE +1 -1
  3. package/README.md +1 -1
  4. package/broadcast/providers/redis.js +24 -49
  5. package/clients/nrp.js +117 -0
  6. package/clients/redis.js +64 -0
  7. package/framework/controllers.js +4 -4
  8. package/index.js +13 -10
  9. package/insight/insight.js +1 -1
  10. package/launchpad/index.js +174 -11
  11. package/launchpad/launchers/cluster.js +103 -110
  12. package/launchpad/launchers/redis.js +70 -0
  13. package/launchpad/launchers/single.js +36 -22
  14. package/locks/locks.js +53 -7
  15. package/locks/providers/cluster.js +3 -1
  16. package/locks/providers/memory.js +10 -7
  17. package/locks/providers/redis.js +62 -82
  18. package/middleware/admin/admin.js +2 -2
  19. package/middleware/authentication/adapters/session.js +11 -8
  20. package/middleware/authentication/authentication.js +28 -16
  21. package/middleware/authentication/authenticators/default.js +5 -2
  22. package/middleware/authentication/authenticators/session.js +5 -2
  23. package/middleware/authentication/providers/saml.js +1 -1
  24. package/middleware/authorization/authorization.js +11 -8
  25. package/middleware/awareness/awareness.js +51 -29
  26. package/middleware/awareness/plugins/editorial.js +4 -4
  27. package/middleware/awareness/providers/abstract-async.js +107 -84
  28. package/middleware/awareness/providers/abstract.js +1 -1
  29. package/middleware/awareness/providers/memory.js +0 -14
  30. package/middleware/awareness/providers/redis.js +186 -279
  31. package/middleware/cache/providers/redis.js +127 -89
  32. package/middleware/cloudcms/cloudcms.js +22 -16
  33. package/middleware/form/form.js +2 -2
  34. package/middleware/proxy/proxy.js +7 -21
  35. package/middleware/stores/stores.js +2 -2
  36. package/middleware/virtual-config/virtual-config.js +7 -7
  37. package/middleware/wcm/wcm.js +4 -4
  38. package/package.json +54 -52
  39. package/server/index.js +517 -399
  40. package/server/standalone.js +9 -0
  41. package/temp/clusterlock/index.js +3 -3
  42. package/temp/clusterlock/package.json +1 -1
  43. package/temp/passport-saml/LICENSE +23 -0
  44. package/temp/passport-saml/README.md +406 -0
  45. package/temp/passport-saml/lib/node-saml/algorithms.d.ts +5 -0
  46. package/temp/passport-saml/lib/node-saml/algorithms.js +41 -0
  47. package/temp/passport-saml/lib/node-saml/algorithms.js.map +1 -0
  48. package/temp/passport-saml/lib/node-saml/index.d.ts +3 -0
  49. package/temp/passport-saml/lib/node-saml/index.js +6 -0
  50. package/temp/passport-saml/lib/node-saml/index.js.map +1 -0
  51. package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.d.ts +45 -0
  52. package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.js +86 -0
  53. package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.js.map +1 -0
  54. package/temp/passport-saml/lib/node-saml/saml-post-signing.d.ts +3 -0
  55. package/temp/passport-saml/lib/node-saml/saml-post-signing.js +15 -0
  56. package/temp/passport-saml/lib/node-saml/saml-post-signing.js.map +1 -0
  57. package/temp/passport-saml/lib/node-saml/saml.d.ts +77 -0
  58. package/temp/passport-saml/lib/node-saml/saml.js +1170 -0
  59. package/temp/passport-saml/lib/node-saml/saml.js.map +1 -0
  60. package/temp/passport-saml/lib/node-saml/types.d.ts +95 -0
  61. package/temp/passport-saml/lib/node-saml/types.js +8 -0
  62. package/temp/passport-saml/lib/node-saml/types.js.map +1 -0
  63. package/temp/passport-saml/lib/node-saml/utility.d.ts +3 -0
  64. package/temp/passport-saml/lib/node-saml/utility.js +19 -0
  65. package/temp/passport-saml/lib/node-saml/utility.js.map +1 -0
  66. package/temp/passport-saml/lib/node-saml/xml.d.ts +21 -0
  67. package/temp/passport-saml/lib/node-saml/xml.js +140 -0
  68. package/temp/passport-saml/lib/node-saml/xml.js.map +1 -0
  69. package/temp/passport-saml/lib/passport-saml/index.d.ts +6 -0
  70. package/temp/passport-saml/lib/passport-saml/index.js +11 -0
  71. package/temp/passport-saml/lib/passport-saml/index.js.map +1 -0
  72. package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.d.ts +13 -0
  73. package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.js +63 -0
  74. package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.js.map +1 -0
  75. package/temp/passport-saml/lib/passport-saml/strategy.d.ts +20 -0
  76. package/temp/passport-saml/lib/passport-saml/strategy.js +167 -0
  77. package/temp/passport-saml/lib/passport-saml/strategy.js.map +1 -0
  78. package/temp/passport-saml/lib/passport-saml/types.d.ts +51 -0
  79. package/temp/passport-saml/lib/passport-saml/types.js +11 -0
  80. package/temp/passport-saml/lib/passport-saml/types.js.map +1 -0
  81. package/temp/passport-saml/package.json +96 -0
  82. package/util/auth.js +1 -1
  83. package/util/cloudcms.js +72 -93
  84. package/util/proxy-factory.js +230 -260
  85. package/util/redis.js +113 -0
  86. package/util/renditions.js +1 -1
  87. package/util/util.js +15 -2
  88. package/launchpad/launchers/sticky-cluster.js +0 -43
  89. package/web/cms/ice.js +0 -109
  90. package/web/cms/preview.js +0 -106
  91. package/web/socket.io/socket.io.js +0 -2
package/server/index.js CHANGED
@@ -16,19 +16,20 @@ var session = require('express-session');
16
16
  var cookieParser = require('cookie-parser');
17
17
  var flash = require("connect-flash");
18
18
 
19
+ //const redis = require('redis');
20
+ const connectRedis = require('connect-redis');
21
+
19
22
  // we don't bind a single passport - instead, we get the constructor here by hand
20
23
  var Passport = require("passport").Passport;
21
24
 
22
25
  var util = require("../util/util");
26
+ var redisHelper = require("../util/redis");
23
27
 
24
28
  var launchPad = require("../launchpad/index");
25
29
  var cluster = require("cluster");
26
30
 
27
31
  var requestParam = require("request-param")();
28
32
 
29
- var app = express();
30
- app.disable('x-powered-by');
31
-
32
33
  // cloudcms app server support
33
34
  var main = require("../index");
34
35
 
@@ -37,17 +38,35 @@ var duster = require("../duster/index");
37
38
 
38
39
  var coreHelpers = require("../duster/helpers/core/index");
39
40
 
41
+ var helmet = require("helmet");
42
+
40
43
  var toobusy = require("toobusy-js");
41
44
  toobusy.maxLag(500); // 500 ms lag in event queue, quite high but usable for now
42
45
  toobusy.interval(250);
43
46
 
44
47
  var responseTime = require("response-time");
45
48
 
49
+ // safely checks for the existence of a path
50
+ var safeExists = function(_path)
51
+ {
52
+ var exists = false;
53
+ try
54
+ {
55
+ exists = fs.existsSync(_path);
56
+ }
57
+ catch (e)
58
+ {
59
+ // swallow
60
+ }
61
+
62
+ return exists;
63
+ }
64
+
46
65
  var requestCounter = 0;
47
66
 
48
67
  // holds configuration settings
49
68
  var SETTINGS = {
50
- "setup": "single", // single, cluster, sticky-cluster
69
+ "setup": "single", // single, cluster, redis
51
70
  "name": "Cloud CMS Application Server",
52
71
  "socketFunctions": [],
53
72
  "routeFunctions": [],
@@ -292,9 +311,7 @@ var SETTINGS = {
292
311
  //"reapInterval": -1
293
312
  },
294
313
  "awareness": {
295
- "enabled": false,
296
- "type": "memory",
297
- "config": {}
314
+ "enabled": false
298
315
  },
299
316
  "graphql": {
300
317
  "enabled": true,
@@ -304,17 +321,67 @@ var SETTINGS = {
304
321
  }
305
322
  };
306
323
 
324
+ // always push core tag helpers to the front
325
+ SETTINGS.dustFunctions.unshift(coreHelpers);
326
+
327
+ // if SETTINGS.errorFunctions is empty, plug in a default error handler
328
+ if (SETTINGS.errorFunctions.length === 0)
329
+ {
330
+ SETTINGS.errorFunctions.push(main.defaultErrorHandler);
331
+ }
332
+ else
333
+ {
334
+ // otherwise, if they plugged in a custom error handler, make sure we at least have a console logger ahead of it
335
+ // so that things are sure to get logged out to console
336
+ SETTINGS.errorFunctions.unshift(main.consoleErrorLogger);
337
+ }
338
+
339
+ // insert an error handler to handle refresh token failures
340
+ SETTINGS.errorFunctions.unshift(main.refreshTokenErrorHandler);
341
+
342
+ // CLOUDCMS_HOSTS_PATH environment variable
343
+ // assume /hosts with optional fallback to /System/Volumes/Data/hosts for MacOS support
344
+ if (!process.env.CLOUDCMS_HOSTS_PATH)
345
+ {
346
+ process.env.CLOUDCMS_HOSTS_PATH = "/hosts";
347
+
348
+ if (!safeExists(process.env.CLOUDCMS_HOSTS_PATH))
349
+ {
350
+ if (safeExists("/System/Volumes/Data/hosts"))
351
+ {
352
+ process.env.CLOUDCMS_HOSTS_PATH = "/System/Volumes/Data/hosts";
353
+ }
354
+ else
355
+ {
356
+ const homedir = require('os').homedir();
357
+
358
+ if (safeExists(homedir + "/hosts"))
359
+ {
360
+ process.env.CLOUDCMS_HOSTS_PATH = homedir + "/hosts";
361
+ }
362
+ }
363
+ }
364
+ }
365
+
366
+
367
+
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
307
382
  // runs on 2999 by default
308
383
  process.env.PORT = process.env.PORT || 2999;
309
384
 
310
- // allows for specification of alternative transports
311
- SETTINGS.socketTransports = [
312
- 'websocket',
313
- 'xhr-polling',
314
- 'jsonp-polling',
315
- 'polling'
316
- ];
317
-
318
385
  var exports = module.exports;
319
386
 
320
387
  /**
@@ -498,62 +565,19 @@ var _start = function(overrides, callback) {
498
565
  callback = function() {};
499
566
  }
500
567
 
501
- // always push core tag helpers to the front
502
- SETTINGS.dustFunctions.unshift(coreHelpers);
503
-
504
- // if SETTINGS.errorFunctions is empty, plug in a default error handler
505
- if (SETTINGS.errorFunctions.length === 0)
506
- {
507
- SETTINGS.errorFunctions.push(main.defaultErrorHandler);
508
- }
509
- else
510
- {
511
- // otherwise, if they plugged in a custom error handler, make sure we at least have a console logger ahead of it
512
- // so that things are sure to get logged out to console
513
- SETTINGS.errorFunctions.unshift(main.consoleErrorLogger);
514
- }
515
-
516
- // insert an error handler to handle refresh token failures
517
- SETTINGS.errorFunctions.unshift(main.refreshTokenErrorHandler);
518
-
519
568
  // create our master config
520
569
  var config = clone(SETTINGS);
521
570
  if (overrides) {
522
571
  util.merge(overrides, config);
523
572
  }
524
-
525
- // assume for launchpad
526
- if (!config.setup) {
527
- config.setup = "single";
528
- }
529
-
530
- launchPad({
531
- "setup": config.setup,
532
- "factory": function(done) {
533
- startSlave(config, function(app, server) {
534
- done(server);
535
- });
536
- },
537
- "report": function() {
538
- runFunctions(config.reportFunctions, [], function(err) {
539
- // todo
540
- });
541
- },
542
- "complete": function() {
543
- callback();
544
- }
545
- });
546
- };
547
-
548
- var startSlave = function(config, afterStartFn)
549
- {
573
+
550
574
  // set up modes
551
575
  process.env.CLOUDCMS_APPSERVER_MODE = "development";
552
-
553
- if (process.env.NODE_ENV == "production") {
576
+
577
+ if (process.env.NODE_ENV === "production") {
554
578
  process.env.CLOUDCMS_APPSERVER_MODE = "production";
555
579
  }
556
-
580
+
557
581
  /*
558
582
  // set up domain hosting
559
583
  // if not otherwise specified, we assume hosting at *.cloudcms.net
@@ -564,10 +588,10 @@ var startSlave = function(config, afterStartFn)
564
588
  }
565
589
  }
566
590
  */
567
-
591
+
568
592
  // store config on process instance
569
593
  process.configuration = config;
570
-
594
+
571
595
  // some config overrides can come in through process.configuration
572
596
  if (process.configuration) {
573
597
  if (process.configuration.virtualHost && process.configuration.virtualHost.domain) {
@@ -581,111 +605,181 @@ var startSlave = function(config, afterStartFn)
581
605
  if (process.env.CLOUDCMS_VIRTUAL_HOST_DOMAIN) {
582
606
  process.env.CLOUDCMS_VIRTUAL_HOST_DOMAIN = process.env.CLOUDCMS_VIRTUAL_HOST_DOMAIN.toLowerCase();
583
607
  }
584
-
608
+
585
609
  if (!process.env.CLOUDCMS_STANDALONE_HOST) {
586
610
  process.env.CLOUDCMS_STANDALONE_HOST = "local";
587
611
  }
588
-
589
- // session store
590
- var initializedSession = null;
591
- if (process.configuration.session)
592
- {
593
- if (process.configuration.session.enabled)
594
- {
595
- var sessionSecret = process.configuration.session.secret;
596
- if (!sessionSecret) {
597
- sessionSecret = "secret";
598
- }
599
-
600
- var sessionConfig = {
601
- secret: sessionSecret,
602
- resave: false,
603
- saveUninitialized: false
604
- };
605
-
606
- if (process.configuration.session.type === "file")
607
- {
608
- var options = {};
609
- if (process.configuration.session.ttl)
610
- {
611
- options.ttl = process.configuration.session.ttl;
612
- }
613
- if (process.configuration.session.reapInterval)
614
- {
615
- options.reapInterval = process.configuration.session.reapInterval;
616
- }
617
- // session file store
618
- var SessionFileStore = require('session-file-store')(session);
619
- sessionConfig.store = new SessionFileStore(options);
620
- }
621
- else if (process.configuration.session.type === "memory" || !process.configuration.session.type)
622
- {
623
- var options = {};
624
- options.checkPeriod = 86400000; // prune expired entries every 24h
625
-
626
- // session memory store
627
- var MemoryStore = require('memorystore')(session);
628
- sessionConfig.store = new MemoryStore(options);
612
+
613
+
614
+ // auto-configuration for HTTPS
615
+ if (!process.configuration.https) {
616
+ process.configuration.https = {};
617
+ }
618
+ if (process.env.CLOUDCMS_HTTPS) {
619
+ process.configuration.https = JSON.parse(process.env.CLOUDCMS_HTTPS);
620
+ }
621
+ if (process.env.CLOUDCMS_HTTPS_KEY_FILEPATH) {
622
+ process.configuration.https.key = fs.readFileSync(process.env.CLOUDCMS_HTTPS_KEY_FILEPATH);
623
+ }
624
+ if (process.env.CLOUDCMS_HTTPS_CERT_FILEPATH) {
625
+ process.configuration.https.cert = fs.readFileSync(process.env.CLOUDCMS_HTTPS_CERT_FILEPATH);
626
+ }
627
+ if (process.env.CLOUDCMS_HTTPS_PFX_FILEPATH) {
628
+ process.configuration.https.pfx = fs.readFileSync(process.env.CLOUDCMS_HTTPS_PFX_FILEPATH);
629
+ }
630
+ if (process.env.CLOUDCMS_HTTPS_PASSPHRASE) {
631
+ process.configuration.https.passphrase = process.env.CLOUDCMS_HTTPS_PASSPHRASE;
632
+ }
633
+ if (process.env.CLOUDCMS_HTTPS_REQUEST_CERT === "true") {
634
+ process.configuration.https.requestCert = true;
635
+ }
636
+ if (process.env.CLOUDCMS_HTTPS_CA_FILEPATH) {
637
+ process.configuration.https.ca = [ fs.readFileSync(process.env.CLOUDCMS_HTTPS_CA_FILEPATH) ];
638
+ }
639
+
640
+ // if https config is empty, remove it
641
+ if (Object.keys(process.configuration.https).length === 0) {
642
+ delete process.configuration.https;
643
+ }
644
+
645
+
646
+ // auto configuration of session store
647
+ if (!process.configuration.session) {
648
+ process.configuration.session = {};
649
+ }
650
+ // auto-configuration for redis?
651
+ if (process.env.CLOUDCMS_REDIS_URL || (process.env.CLOUDCMS_REDIS_ENDPOINT && process.env.CLOUDCMS_REDIS_PORT)) {
652
+ process.env.CLOUDCMS_SESSION_TYPE = "redis";
653
+ }
654
+
655
+ if (process.env.CLOUDCMS_SESSION_TYPE) {
656
+ process.configuration.session.enabled = true;
657
+ process.configuration.session.type = process.env.CLOUDCMS_SESSION_TYPE;
658
+ }
659
+ if (process.env.CLOUDCMS_SESSION_SECRET) {
660
+ process.configuration.session.secret = process.env.CLOUDCMS_SESSION_SECRET;
661
+ }
662
+
663
+
664
+ // determine the max files
665
+ util.maxFiles(function(err, maxFiles) {
666
+ process.env.CLOUDCMS_MAX_FILES = maxFiles;
667
+
668
+ // assume for launchpad
669
+ if (!config.setup) {
670
+ config.setup = "single";
671
+ }
672
+
673
+ launchPad(config.setup, config, {
674
+ "createHttpServer": function(app, done) {
675
+ createHttpServer(app, function(err, httpServer) {
676
+ done(err, httpServer);
677
+ });
678
+ },
679
+ "startServer": function(config, done) {
680
+ startServer(config, function(err, app, httpServer, httpServerPort) {
681
+ done(err, app, httpServer, httpServerPort);
682
+ });
683
+ },
684
+ "configureServer": function(config, app, httpServer, done) {
685
+ configureServer(config, app, httpServer, function(err) {
686
+ done(err);
687
+ });
688
+ },
689
+ "report": function(config) {
690
+ runFunctions(config.reportFunctions, [], function(err) {
691
+ // todo
692
+ });
693
+ },
694
+ "complete": function(config, err) {
695
+ callback(err);
629
696
  }
697
+ });
698
+ });
699
+ };
630
700
 
631
- initializedSession = session(sessionConfig);
632
- }
701
+ var initSession = function(initDone)
702
+ {
703
+ if (!process.configuration.session) {
704
+ return initDone();
633
705
  }
634
-
635
- // safely checks for the existence of a path
636
- var safeExists = function(_path)
706
+ if (!process.configuration.session.enabled) {
707
+ return initDone();
708
+ }
709
+
710
+ var sessionSecret = process.configuration.session.secret;
711
+ if (!sessionSecret) {
712
+ sessionSecret = "secret";
713
+ }
714
+
715
+ var sessionConfig = {
716
+ secret: sessionSecret,
717
+ resave: false,
718
+ saveUninitialized: false
719
+ };
720
+
721
+ if (process.configuration.session.type) {
722
+ process.configuration.session.type = process.configuration.session.type.toLowerCase();
723
+ }
724
+
725
+ if (process.configuration.session.type === "file")
637
726
  {
638
- var exists = false;
639
- try
727
+ var options = {};
728
+ if (process.configuration.session.ttl)
640
729
  {
641
- exists = fs.existsSync(_path);
730
+ options.ttl = process.configuration.session.ttl;
642
731
  }
643
- catch (e)
732
+ if (process.configuration.session.reapInterval)
644
733
  {
645
- // swallow
734
+ options.reapInterval = process.configuration.session.reapInterval;
646
735
  }
647
-
648
- return exists;
736
+ // session file store
737
+ var SessionFileStore = require('session-file-store')(session);
738
+ sessionConfig.store = new SessionFileStore(options);
739
+ return initDone(null, session(sessionConfig));
649
740
  }
650
-
651
- // CLOUDCMS_HOSTS_PATH environment variable
652
- // assume /hosts with optional fallback to /System/Volumes/Data/hosts for MacOS support
653
- if (!process.env.CLOUDCMS_HOSTS_PATH)
741
+ else if (process.configuration.session.type === "redis")
654
742
  {
655
- process.env.CLOUDCMS_HOSTS_PATH = "/hosts";
656
-
657
- if (!safeExists(process.env.CLOUDCMS_HOSTS_PATH))
658
- {
659
- if (safeExists("/System/Volumes/Data/hosts"))
660
- {
661
- process.env.CLOUDCMS_HOSTS_PATH = "/System/Volumes/Data/hosts";
662
- }
663
- else
664
- {
665
- const homedir = require('os').homedir();
666
-
667
- if (safeExists(homedir + "/hosts"))
668
- {
669
- process.env.CLOUDCMS_HOSTS_PATH = homedir + "/hosts";
670
- }
671
- }
672
- }
743
+ var IORedis = require("ioredis");
744
+ var redisOptions = redisHelper.redisOptions();
745
+ var redisClient = new IORedis(redisOptions.url);
746
+
747
+ var RedisStore = connectRedis(session);
748
+ sessionConfig.store = new RedisStore({ client: redisClient });
749
+ initDone(null, session(sessionConfig));
673
750
  }
751
+ else if (process.configuration.session.type === "memory" || !process.configuration.session.type)
752
+ {
753
+ var options = {};
754
+ options.checkPeriod = 86400000; // prune expired entries every 24h
755
+
756
+ // session memory store
757
+ var MemoryStore = require('memorystore')(session);
758
+ sessionConfig.store = new MemoryStore(options);
759
+ return initDone(null, session(sessionConfig));
760
+ }
761
+ };
674
762
 
675
- // global temp directory
676
- util.createTempDirectory(function(err, tempDirectory) {
677
- process.env.CLOUDCMS_TEMPDIR_PATH = tempDirectory;
678
-
679
- // determine the max files
680
- util.maxFiles(function(err, maxFiles) {
681
-
682
- process.env.CLOUDCMS_MAX_FILES = maxFiles;
763
+ var startServer = function(config, startServerFinishedFn)
764
+ {
765
+ var app = express();
766
+ app.disable('x-powered-by');
767
+
768
+ initSession(function(err, initializedSession) {
683
769
 
770
+ if (err) {
771
+ throw err;
772
+ }
773
+
774
+ // global temp directory
775
+ util.createTempDirectory(function(err, tempDirectory) {
776
+ process.env.CLOUDCMS_TEMPDIR_PATH = tempDirectory;
777
+
684
778
  // global service starts
685
779
  main.init(app, function (err) {
686
-
780
+
687
781
  app.enable('strict routing');
688
-
782
+
689
783
  ////////////////////////////////////////////////////////////////////////////
690
784
  //
691
785
  // BASE CONFIGURATION
@@ -694,15 +788,15 @@ var startSlave = function(config, afterStartFn)
694
788
  // Runs on port 3000 by default
695
789
  //
696
790
  ////////////////////////////////////////////////////////////////////////////
697
-
791
+
698
792
  // all environments
699
793
  app.set('port', process.env.PORT);
700
794
  app.set('views', process.env.CLOUDCMS_APPSERVER_BASE_PATH + "/views");
701
-
795
+
702
796
  if (config.viewEngine === "dust")
703
797
  {
704
798
  var cons = require('consolidate');
705
-
799
+
706
800
  app.set('view engine', 'html');
707
801
  app.set('view engine', 'dust');
708
802
  app.engine('html', cons.dust);
@@ -711,13 +805,13 @@ var startSlave = function(config, afterStartFn)
711
805
  else if (config.viewEngine === "handlebars" || config.viewEngine === "hbs")
712
806
  {
713
807
  var hbs = require('hbs');
714
-
808
+
715
809
  app.set('view engine', 'html');
716
810
  app.set('view engine', 'hbs');
717
811
  app.engine('html', hbs.__express);
718
812
  app.engine('hbs', hbs.__express);
719
813
  }
720
-
814
+
721
815
  ////////////////////////////////////////////////////////////////////////////
722
816
  //
723
817
  // VIRTUAL SUPPORT
@@ -726,26 +820,26 @@ var startSlave = function(config, afterStartFn)
726
820
  // ahead of anything else running.
727
821
  //
728
822
  ////////////////////////////////////////////////////////////////////////////
729
-
823
+
730
824
  // custom morgan logger
731
825
  morgan(function (tokens, req, res) {
732
-
826
+
733
827
  var status = res.statusCode;
734
828
  var len = parseInt(res.getHeader('Content-Length'), 10);
735
829
  var host = req.domainHost;
736
830
  if (req.virtualHost) {
737
831
  host = req.virtualHost;
738
832
  }
739
-
833
+
740
834
  len = isNaN(len) ? '0b' : len = bytes(len);
741
-
835
+
742
836
  var d = new Date();
743
837
  var dateString = d.toDateString();
744
838
  var timeString = d.toTimeString();
745
-
839
+
746
840
  // gray color
747
841
  var grayColor = "\x1b[90m";
748
-
842
+
749
843
  // status color
750
844
  var color = 32;
751
845
  if (status >= 500) {
@@ -758,17 +852,17 @@ var startSlave = function(config, afterStartFn)
758
852
  color = 36;
759
853
  }
760
854
  var statusColor = "\x1b[" + color + "m";
761
-
855
+
762
856
  // final color
763
857
  var finalColor = "\x1b[0m";
764
-
765
- if (process.env.CLOUDCMS_APPSERVER_MODE == "production")
858
+
859
+ if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
766
860
  {
767
861
  grayColor = "";
768
862
  statusColor = "";
769
863
  finalColor = "";
770
864
  }
771
-
865
+
772
866
  var message = '';
773
867
  message += grayColor + '<' + req.id + '> ';
774
868
  message += grayColor + '[' + dateString + ' ' + timeString + '] ';
@@ -780,10 +874,10 @@ var startSlave = function(config, afterStartFn)
780
874
  message += grayColor + req.originalUrl + '" ';
781
875
  message += grayColor + len + ' ';
782
876
  message += finalColor;
783
-
877
+
784
878
  return message;
785
879
  });
786
-
880
+
787
881
  /*
788
882
  // debug headers being set
789
883
  app.use(function(req, res, next) {
@@ -795,7 +889,7 @@ var startSlave = function(config, afterStartFn)
795
889
  next();
796
890
  });
797
891
  */
798
-
892
+
799
893
  // middleware which blocks requests when we're too busy
800
894
  app.use(function(req, res, next) {
801
895
  if (toobusy()) {
@@ -804,49 +898,49 @@ var startSlave = function(config, afterStartFn)
804
898
  next();
805
899
  }
806
900
  });
807
-
901
+
808
902
  // add req.id re
809
903
  app.use(function (req, res, next) {
810
904
  requestCounter++;
811
905
  req.id = requestCounter;
812
906
  next();
813
907
  });
814
-
908
+
815
909
  // APPLY CUSTOM INIT FUNCTIONS
816
910
  runFunctions(config.initFunctions, [app], function (err) {
817
-
911
+
818
912
  // retain originalUrl and originalPath since these can get modified along the way
819
913
  app.use(function (req, res, next) {
820
914
  req.originalUrl = req.url;
821
915
  req.originalPath = req.path;
822
916
  next();
823
917
  });
824
-
918
+
825
919
  // req.param method
826
920
  app.use(requestParam);
827
-
921
+
828
922
  // add req.log function
829
923
  app.use(function (req, res, next) {
830
-
924
+
831
925
  req._log = req.log = function (text/*, warn*/) {
832
-
926
+
833
927
  var host = req.domainHost;
834
928
  if (req.virtualHost)
835
929
  {
836
930
  host = req.virtualHost;
837
931
  }
838
-
932
+
839
933
  var timestamp = moment(new Date()).format("MM/DD/YYYY HH:mm:ss Z");
840
934
  var grayColor = "\x1b[90m";
841
935
  var finalColor = "\x1b[0m";
842
-
936
+
843
937
  // in production, don't use colors
844
938
  if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
845
939
  {
846
940
  grayColor = "";
847
941
  finalColor = "";
848
942
  }
849
-
943
+
850
944
  var message = '';
851
945
  message += grayColor + '<' + req.id + '> ';
852
946
  if (cluster.worker && cluster.worker.id)
@@ -857,33 +951,33 @@ var startSlave = function(config, afterStartFn)
857
951
  message += grayColor + host + ' ';
858
952
  message += grayColor + text + '';
859
953
  message += finalColor;
860
-
954
+
861
955
  /*
862
956
  if (warn)
863
957
  {
864
958
  message = "\r\n**** SLOW RESPONSE ****\r\n" + message + "\r\n";
865
959
  }
866
960
  */
867
-
961
+
868
962
  console.log(message);
869
963
  };
870
-
964
+
871
965
  next();
872
966
  });
873
-
967
+
874
968
  // common interceptors and config
875
969
  main.common1(app);
876
-
970
+
877
971
  // general logging of requests
878
972
  // gather statistics on response time
879
973
  app.use(responseTime(function (req, res, time) {
880
-
974
+
881
975
  var warn = false;
882
976
  if (time > 1000)
883
977
  {
884
978
  warn = true;
885
979
  }
886
-
980
+
887
981
  var requestPath = req.originalPath;
888
982
  if (requestPath)
889
983
  {
@@ -901,51 +995,51 @@ var startSlave = function(config, afterStartFn)
901
995
  requestPath = util.stripQueryStringFromUrl(requestPath);
902
996
  }
903
997
  }
904
-
998
+
905
999
  req.log(req.method + " " + requestPath + " [" + res.statusCode + "] (" + time.toFixed(2) + " ms)", warn);
906
1000
  }));
907
-
1001
+
908
1002
  // set up CORS allowances
909
1003
  // this lets CORS requests float through the proxy
910
1004
  app.use(main.ensureCORS());
911
-
1005
+
912
1006
  // set up default security headers
913
1007
  app.use(main.ensureHeaders());
914
-
1008
+
915
1009
  // common interceptors and config
916
1010
  main.common2(app);
917
-
1011
+
918
1012
  // APPLY CUSTOM DRIVER FUNCTIONS
919
1013
  runFunctions(config.driverFunctions, [app], function(err) {
920
-
1014
+
921
1015
  // binds gitana driver into place
922
1016
  main.common3(app);
923
-
1017
+
924
1018
  // parse cookies
925
1019
  app.use(cookieParser());
926
-
1020
+
927
1021
  // cloudcms things need to run here
928
1022
  main.common4(app, true);
929
-
1023
+
930
1024
  // APPLY CUSTOM FILTER FUNCTIONS
931
1025
  runFunctions(config.filterFunctions, [app], function (err) {
932
-
1026
+
933
1027
  // PATH BASED PERFORMANCE CACHING
934
1028
  main.perf1(app);
935
-
1029
+
936
1030
  // proxy - anything that goes to /proxy is handled here early and nothing processes afterwards
937
1031
  main.proxy(app);
938
-
1032
+
939
1033
  // MIMETYPE BASED PERFORMANCE CACHING
940
1034
  main.perf2(app);
941
-
1035
+
942
1036
  // DEVELOPMENT BASED PERFORMANCE CACHING
943
1037
  main.perf3(app);
944
-
1038
+
945
1039
  // standard body parsing + a special cloud cms body parser that makes a last ditch effort for anything
946
1040
  // that might be JSON (regardless of content type)
947
1041
  app.use(function (req, res, next) {
948
-
1042
+
949
1043
  multipart(process.configuration.bodyParsers.multipart || {})(req, res, function (err) {
950
1044
  bodyParser.json(process.configuration.bodyParsers.json || {})(req, res, function (err) {
951
1045
  bodyParser.urlencoded(process.configuration.bodyParsers.urlencoded || {})(req, res, function (err) {
@@ -955,35 +1049,35 @@ var startSlave = function(config, afterStartFn)
955
1049
  });
956
1050
  });
957
1051
  });
958
-
1052
+
959
1053
  });
960
-
1054
+
961
1055
  if (initializedSession)
962
1056
  {
963
1057
  app.use(initializedSession);
964
1058
  app.use(flash());
965
1059
  }
966
-
1060
+
967
1061
  // this is the same as calling
968
1062
  // app.use(passport.initialize());
969
1063
  // except we create a new passport each time and store on request to support multitenancy
970
1064
  app.use(function(req, res, next) {
971
-
1065
+
972
1066
  var passport = new Passport();
973
1067
  passport._key = "passport-" + req.virtualHost;
974
-
1068
+
975
1069
  req._passport = {};
976
1070
  req._passport.instance = passport;
977
-
1071
+
978
1072
  if (req.session && req.session[passport._key])
979
1073
  {
980
1074
  // load data from existing session
981
1075
  req._passport.session = req.session[passport._key];
982
1076
  }
983
-
1077
+
984
1078
  // add this in
985
1079
  req.passport = req._passport.instance;
986
-
1080
+
987
1081
  // passport - serialize and deserialize
988
1082
  req.passport.serializeUser(function(user, done) {
989
1083
  done(null, user);
@@ -991,10 +1085,10 @@ var startSlave = function(config, afterStartFn)
991
1085
  req.passport.deserializeUser(function(user, done) {
992
1086
  done(null, user);
993
1087
  });
994
-
1088
+
995
1089
  next();
996
1090
  });
997
-
1091
+
998
1092
  // passport session
999
1093
  if (initializedSession)
1000
1094
  {
@@ -1002,27 +1096,27 @@ var startSlave = function(config, afterStartFn)
1002
1096
  req.passport.session()(req, res, next);
1003
1097
  });
1004
1098
  }
1005
-
1099
+
1006
1100
  // welcome files
1007
1101
  main.welcome(app);
1008
-
1102
+
1009
1103
  // configure cloudcms app server command handing
1010
1104
  main.interceptors(app, true);
1011
-
1105
+
1012
1106
  //app.use(app.router);
1013
-
1107
+
1014
1108
  // healthcheck middleware
1015
1109
  main.healthcheck(app);
1016
-
1110
+
1017
1111
  // APPLY CUSTOM ROUTES
1018
1112
  runFunctions(config.routeFunctions, [app], function (err) {
1019
-
1113
+
1020
1114
  // configure cloudcms app server handlers
1021
1115
  main.handlers(app, true);
1022
-
1116
+
1023
1117
  // register error functions
1024
1118
  runFunctions(config.errorFunctions, [app], function (err) {
1025
-
1119
+
1026
1120
  // APPLY CUSTOM CONFIGURE FUNCTIONS
1027
1121
  var allConfigureFunctions = [];
1028
1122
  for (var env in config.configureFunctions)
@@ -1037,187 +1131,15 @@ var startSlave = function(config, afterStartFn)
1037
1131
  }
1038
1132
  }
1039
1133
  runFunctions(allConfigureFunctions, [app], function (err) {
1040
-
1041
- ////////////////////////////////////////////////////////////////////////////
1042
- //
1043
- // INITIALIZE THE SERVER
1044
- //
1045
- ////////////////////////////////////////////////////////////////////////////
1046
-
1047
-
1048
- // CORE OBJECTS
1049
- var server = http.Server(app);
1050
-
1051
- // request timeout
1052
- var requestTimeout = 30000; // 30 seconds
1053
- if (process.configuration && process.configuration.timeout)
1054
- {
1055
- requestTimeout = process.configuration.timeout;
1056
- }
1057
- server.setTimeout(requestTimeout);
1058
-
1059
- // socket
1060
- server.on("connection", function (socket) {
1061
- socket.setNoDelay(true);
1062
- });
1063
- var io = process.IO = require("socket.io")(server);
1064
- io.set('transports', config.socketTransports);
1065
- io.use(function (socket, next) {
1066
-
1067
- // console.log("New socket being initialized");
1068
-
1069
- // attach _log function
1070
- socket._log = function (text) {
1071
-
1072
- var host = socket.handshake.headers.host;
1073
- if (socket.handshake.headers["x-forwarded-host"])
1074
- {
1075
- host = socket.handshake.headers["x-forwarded-host"];
1076
- }
1077
-
1078
- var d = new Date();
1079
- var dateString = d.toDateString();
1080
- var timeString = d.toTimeString();
1081
-
1082
- // gray color
1083
- var grayColor = "\x1b[90m";
1084
-
1085
- // final color
1086
- var finalColor = "\x1b[0m";
1087
-
1088
- if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
1089
- {
1090
- grayColor = "";
1091
- finalColor = "";
1092
- }
1093
-
1094
- var message = '';
1095
- message += grayColor + '<socket> ';
1096
- message += grayColor + '[' + dateString + ' ' + timeString + '] ';
1097
- message += grayColor + host + ' ';
1098
- message += grayColor + text + '';
1099
- message += finalColor;
1100
-
1101
- console.log(message);
1102
- };
1103
- /*
1104
- socket.on("connect", function () {
1105
- console.log("Socket connect()");
1106
- });
1107
- */
1108
- /*
1109
- socket.on("disconnect", function () {
1110
- var message = "Socket disconnected";
1111
- if (socket && socket.host)
1112
- {
1113
- message += ", host=" + socket.host;
1114
- }
1115
- if (socket && socket.gitana && socket.gitana.application && socket.gitana.application())
1116
- {
1117
- message += ", application=" + socket.gitana.application().title;
1118
- }
1119
- console.log(message);
1120
- });
1121
- */
1122
-
1123
- // APPLY CUSTOM SOCKET.IO CONFIG
1124
- runFunctions(config.socketFunctions, [socket], function (err) {
1125
-
1126
- require("../middleware/awareness/awareness").initSocketIO(function() {
1127
- next();
1128
- });
1129
-
1130
- // INSIGHT SERVER
1131
- // if (config.insight && config.insight.enabled)
1132
- // {
1133
- // console.log("Init Insight to Socket");
1134
-
1135
- // require("../insight/insight").init(socket, function () {
1136
- // next();
1137
- // });
1138
- // }
1139
- // else
1140
- // {
1141
- // next();
1142
- // }
1143
- });
1144
-
1145
- });
1146
-
1147
- // SET INITIAL VALUE FOR SERVER TIMESTAMP
1148
- process.env.CLOUDCMS_APPSERVER_TIMESTAMP = new Date().getTime();
1149
-
1150
- // DUST
1151
- runFunctions(config.dustFunctions, [app, duster.getDust()], function (err) {
1152
-
1153
- // APPLY SERVER BEFORE START FUNCTIONS
1154
- runFunctions(config.beforeFunctions, [app], function (err) {
1155
-
1156
- server._listenPort = app.get("port");
1157
-
1158
- // AFTER SERVER START
1159
- runFunctions(config.afterFunctions, [app], function (err) {
1160
-
1161
- function cleanup() {
1162
-
1163
- if (cluster.isMaster)
1164
- {
1165
- console.log("");
1166
- console.log("");
1167
-
1168
- console.log("Cloud CMS Module shutting down");
1169
-
1170
- // close server connections as cleanly as we can
1171
- console.log(" -> Closing server connections");
1172
- }
1173
-
1174
- try
1175
- {
1176
- server.close();
1177
- }
1178
- catch (e)
1179
- {
1180
- console.log("Server.close produced error: " + JSON.stringify(e));
1181
- }
1182
-
1183
- // ask toobusy to shut down as cleanly as we can
1184
- if (cluster.isMaster)
1185
- {
1186
- console.log(" -> Closing toobusy monitor");
1187
- }
1188
-
1189
- try
1190
- {
1191
- toobusy.shutdown();
1192
- }
1193
- catch (e)
1194
- {
1195
- console.log("toobusy.shutdown produced error: " + JSON.stringify(e));
1196
- }
1197
-
1198
- if (cluster.isMaster)
1199
- {
1200
- console.log("");
1201
- }
1202
-
1203
- // tell the process to exit
1204
- process.exit();
1205
- }
1206
-
1207
- // listen for kill or interrupt so that we can shut down cleanly
1208
- process.on('SIGINT', cleanup);
1209
- process.on('SIGTERM', cleanup);
1210
-
1211
- // if we are on a worker process, then inform the master that we completed
1212
- if (process.send)
1213
- {
1214
- process.send("server-startup");
1215
- }
1216
-
1217
- afterStartFn(app, server);
1218
-
1219
- });
1220
- });
1134
+
1135
+ // create the server (either HTTP or HTTPS)
1136
+ createHttpServer(app, function(err, httpServer) {
1137
+
1138
+ if (err) {
1139
+ return startServerFinishedFn(err);
1140
+ }
1141
+
1142
+ startServerFinishedFn(null, app, httpServer);
1221
1143
  });
1222
1144
  });
1223
1145
  });
@@ -1230,6 +1152,202 @@ var startSlave = function(config, afterStartFn)
1230
1152
  });
1231
1153
  };
1232
1154
 
1155
+ var createHttpServer = function(app, done)
1156
+ {
1157
+ // create the server (either HTTP or HTTPS)
1158
+ var httpServer = null;
1159
+
1160
+ if (process.configuration.https)
1161
+ {
1162
+ if (app)
1163
+ {
1164
+ // configure helmet to support auto-upgrade of http->https
1165
+ app.use(helmet());
1166
+ }
1167
+
1168
+ // create https server
1169
+ httpServer = https.createServer(process.configuration.https, app);
1170
+ }
1171
+ else
1172
+ {
1173
+ // legacy
1174
+ httpServer = http.Server(app);
1175
+ }
1176
+
1177
+ // request timeout
1178
+ var requestTimeout = 30000; // 30 seconds
1179
+ if (process.configuration && process.configuration.timeout)
1180
+ {
1181
+ requestTimeout = process.configuration.timeout;
1182
+ }
1183
+ httpServer.setTimeout(requestTimeout);
1184
+
1185
+ // socket
1186
+ httpServer.on("connection", function (socket) {
1187
+ socket.setNoDelay(true);
1188
+ });
1189
+
1190
+ done(null, httpServer);
1191
+ }
1192
+
1193
+ var configureServer = function(config, app, httpServer, configureServerFinishedFn)
1194
+ {
1195
+ var io = httpServer.io;
1196
+ if (io)
1197
+ {
1198
+ //io.set('transports', config.socketTransports);
1199
+ io.use(function (socket, next) {
1200
+
1201
+ // console.log("New socket being initialized");
1202
+
1203
+ // attach _log function
1204
+ socket._log = function (text) {
1205
+
1206
+ var host = socket.handshake.headers.host;
1207
+ if (socket.handshake.headers["x-forwarded-host"])
1208
+ {
1209
+ host = socket.handshake.headers["x-forwarded-host"];
1210
+ }
1211
+
1212
+ var d = new Date();
1213
+ var dateString = d.toDateString();
1214
+ var timeString = d.toTimeString();
1215
+
1216
+ // gray color
1217
+ var grayColor = "\x1b[90m";
1218
+
1219
+ // final color
1220
+ var finalColor = "\x1b[0m";
1221
+
1222
+ if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
1223
+ {
1224
+ grayColor = "";
1225
+ finalColor = "";
1226
+ }
1227
+
1228
+ var message = '';
1229
+ message += grayColor + '<socket> ';
1230
+ message += grayColor + '[' + dateString + ' ' + timeString + '] ';
1231
+ message += grayColor + host + ' ';
1232
+ message += grayColor + text + '';
1233
+ message += finalColor;
1234
+
1235
+ console.log(message);
1236
+ };
1237
+ /*
1238
+ socket.on("connect", function () {
1239
+ console.log("Socket connect()");
1240
+ });
1241
+ */
1242
+ /*
1243
+ socket.on("disconnect", function () {
1244
+ var message = "Socket disconnected";
1245
+ if (socket && socket.host)
1246
+ {
1247
+ message += ", host=" + socket.host;
1248
+ }
1249
+ if (socket && socket.gitana && socket.gitana.application && socket.gitana.application())
1250
+ {
1251
+ message += ", application=" + socket.gitana.application().title;
1252
+ }
1253
+ console.log(message);
1254
+ });
1255
+ */
1256
+
1257
+ // APPLY CUSTOM SOCKET.IO CONFIG
1258
+ runFunctions(config.socketFunctions, [socket], function (err) {
1259
+
1260
+ require("../middleware/awareness/awareness").initSocketIO(io, function() {
1261
+ next();
1262
+ });
1263
+
1264
+ // INSIGHT SERVER
1265
+ // if (config.insight && config.insight.enabled)
1266
+ // {
1267
+ // console.log("Init Insight to Socket");
1268
+
1269
+ // require("../insight/insight").init(socket, function () {
1270
+ // next();
1271
+ // });
1272
+ // }
1273
+ // else
1274
+ // {
1275
+ // next();
1276
+ // }
1277
+ });
1278
+
1279
+ });
1280
+ }
1281
+
1282
+ // SET INITIAL VALUE FOR SERVER TIMESTAMP
1283
+ process.env.CLOUDCMS_APPSERVER_TIMESTAMP = new Date().getTime();
1284
+
1285
+ // DUST
1286
+ runFunctions(config.dustFunctions, [app, duster.getDust()], function (err) {
1287
+
1288
+ // APPLY SERVER BEFORE START FUNCTIONS
1289
+ runFunctions(config.beforeFunctions, [app], function (err) {
1290
+
1291
+ // AFTER SERVER START
1292
+ runFunctions(config.afterFunctions, [app], function (err) {
1293
+
1294
+ function cleanup() {
1295
+
1296
+ if (cluster.isMaster)
1297
+ {
1298
+ console.log("");
1299
+ console.log("");
1300
+
1301
+ console.log("Cloud CMS Module shutting down");
1302
+
1303
+ // close server connections as cleanly as we can
1304
+ console.log(" -> Closing server connections");
1305
+ }
1306
+
1307
+ try
1308
+ {
1309
+ httpServer.close();
1310
+ }
1311
+ catch (e)
1312
+ {
1313
+ console.log("Server.close produced error: " + JSON.stringify(e));
1314
+ }
1315
+
1316
+ // ask toobusy to shut down as cleanly as we can
1317
+ if (cluster.isMaster)
1318
+ {
1319
+ console.log(" -> Closing toobusy monitor");
1320
+ }
1321
+
1322
+ try
1323
+ {
1324
+ toobusy.shutdown();
1325
+ }
1326
+ catch (e)
1327
+ {
1328
+ console.log("toobusy.shutdown produced error: " + JSON.stringify(e));
1329
+ }
1330
+
1331
+ if (cluster.isMaster)
1332
+ {
1333
+ console.log("");
1334
+ }
1335
+
1336
+ // tell the process to exit
1337
+ process.exit();
1338
+ }
1339
+
1340
+ // listen for kill or interrupt so that we can shut down cleanly
1341
+ process.on('SIGINT', cleanup);
1342
+ process.on('SIGTERM', cleanup);
1343
+
1344
+ configureServerFinishedFn();
1345
+ });
1346
+ });
1347
+ });
1348
+ };
1349
+
1350
+
1233
1351
 
1234
1352
  ////////////////////////////////////////////////////////////////////////////
1235
1353
  //