cloudcms-server 3.3.1-beta.9 → 4.0.0-beta.1

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