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
@@ -9,15 +9,18 @@ class SessionAdapter extends AbstractAdapter
9
9
 
10
10
  identify(req, callback)
11
11
  {
12
- if (req.session && req.session._auth_profile)
12
+ if (req.session)
13
13
  {
14
- var properties = {
15
- "token": req.session._auth_profile.unique_name,
16
- "trusted": true,
17
- "profile": req.session._auth_profile
18
- };
19
-
20
- return callback(null, properties);
14
+ if (req.session._auth_profile)
15
+ {
16
+ var properties = {
17
+ "token": req.session._auth_profile.unique_name,
18
+ "trusted": true,
19
+ "profile": req.session._auth_profile
20
+ };
21
+
22
+ return callback(null, properties);
23
+ }
21
24
  }
22
25
 
23
26
  return super.identify(req, callback);
@@ -436,15 +436,21 @@ exports = module.exports = function()
436
436
  }
437
437
  else
438
438
  {
439
- req.session.registration_strategy_id = strategyId;
440
- req.session.registration_user_object = userObject;
441
- req.session.registration_user_identifier = userIdentifier;
442
- req.session.registration_groups_array = groupsArray;
443
- req.session.registration_mandatory_groups_array = mandatoryGroupsArray;
444
- req.session.registration_token = info.token;
445
- req.session.registration_refresh_token = info.refresh_token;
446
-
447
- return res.redirect(registrationRedirectUrl);
439
+ return req.session.reload(function() {
440
+
441
+ req.session.registration_strategy_id = strategyId;
442
+ req.session.registration_user_object = userObject;
443
+ req.session.registration_user_identifier = userIdentifier;
444
+ req.session.registration_groups_array = groupsArray;
445
+ req.session.registration_mandatory_groups_array = mandatoryGroupsArray;
446
+ req.session.registration_token = info.token;
447
+ req.session.registration_refresh_token = info.refresh_token;
448
+
449
+ req.session.save(function() {
450
+ res.redirect(registrationRedirectUrl);
451
+ });
452
+
453
+ });
448
454
  }
449
455
  });
450
456
  }
@@ -765,13 +771,19 @@ exports = module.exports = function()
765
771
  }
766
772
  else
767
773
  {
768
- req.session.registration_strategy_id = strategyId;
769
- req.session.registration_user_object = properties.user_object;
770
- req.session.registration_user_identifier = properties.user_identifier;
771
- req.session.registration_token = properties.token;
772
- req.session.registration_refresh_token = properties.refresh_token;
773
-
774
- return res.redirect(registrationRedirect);
774
+ return req.session.reload(function() {
775
+
776
+ req.session.registration_strategy_id = strategyId;
777
+ req.session.registration_user_object = properties.user_object;
778
+ req.session.registration_user_identifier = properties.user_identifier;
779
+ req.session.registration_token = properties.token;
780
+ req.session.registration_refresh_token = properties.refresh_token;
781
+
782
+ req.session.save(function() {
783
+ res.redirect(registrationRedirect);
784
+ });
785
+
786
+ });
775
787
  }
776
788
  }
777
789
 
@@ -15,8 +15,11 @@ class DefaultAuthenticator extends AbstractAuthenticator
15
15
  {
16
16
  return req.logIn(gitanaUser, function() {
17
17
 
18
- if (req.session && req.session.save) {
19
- req.session.save();
18
+ if (req.session)
19
+ {
20
+ return req.session.save(function() {
21
+ callback();
22
+ });
20
23
  }
21
24
 
22
25
  callback();
@@ -25,8 +25,11 @@ class SessionAuthenticator extends DefaultAuthenticator
25
25
 
26
26
  req.user = gitanaUser;
27
27
 
28
- if (req.session && req.session.save) {
29
- req.session.save();
28
+ if (req.session)
29
+ {
30
+ return req.session.save(function() {
31
+ callback();
32
+ });
30
33
  }
31
34
 
32
35
  callback();
@@ -1,4 +1,4 @@
1
- var auth = require("../../../util/auth");
1
+ //var auth = require("../../../util/auth");
2
2
 
3
3
  var SamlStrategy = require('passport-saml').Strategy;
4
4
  var AbstractProvider = require("./abstract");
@@ -41,17 +41,20 @@ exports = module.exports = function()
41
41
  }
42
42
  */
43
43
 
44
- if (pathRequiresAuthorization) {
45
- if (req.session && req.session.requestContext) {
46
- next();
47
- }
48
- else {
49
- res.redirect("/login");
50
- }
44
+ if (!pathRequiresAuthorization)
45
+ {
46
+ return next();
51
47
  }
52
- else {
48
+
49
+ if (req.session && req.session.requestContext)
50
+ {
53
51
  next();
54
52
  }
53
+ else
54
+ {
55
+ res.redirect("/login");
56
+ }
57
+
55
58
  });
56
59
  };
57
60
 
@@ -60,10 +60,15 @@ exports = module.exports = function()
60
60
  if (!process.configuration.awareness.config) {
61
61
  process.configuration.awareness.config = {};
62
62
  }
63
-
63
+
64
+ // init any plugins?
65
+ if (!process.configuration.awareness.plugins) {
66
+ process.configuration.awareness.plugins = [];
67
+ }
68
+
64
69
  var type = process.configuration.awareness.type;
65
70
  var config = process.configuration.awareness.config;
66
-
71
+
67
72
  var providerFactory = require("./providers/" + type);
68
73
  provider = new providerFactory(config);
69
74
 
@@ -74,12 +79,6 @@ exports = module.exports = function()
74
79
  return callback(err);
75
80
  }
76
81
 
77
- // init any plugins?
78
- if (!process.configuration.awareness.plugins) {
79
- process.configuration.awareness.plugins = [];
80
- }
81
-
82
-
83
82
  var fns = [];
84
83
  for (var i = 0; i < pluginPaths.length; i++)
85
84
  {
@@ -115,15 +114,18 @@ exports = module.exports = function()
115
114
  /**
116
115
  * This gets called whenever a new socket is connected to the Cloud CMS server.
117
116
  *
117
+ * @param io
118
+ * @param callback
119
+ *
118
120
  * @type {Function}
119
121
  */
120
- var initSocketIO = r.initSocketIO = function(callback) {
121
-
122
+ var initSocketIO = r.initSocketIO = function(io, callback) {
123
+
122
124
  // initialize socket IO event handlers so that awareness binds to any new, incoming sockets
123
- socketInit(process.IO);
125
+ socketInit(io);
124
126
 
125
127
  // ensure the reaper is initialized
126
- reaperInit(process.IO, REAP_FREQUENCY_MS, REAP_MAX_AGE_MS, function(err) {
128
+ reaperInit(io, REAP_FREQUENCY_MS, REAP_MAX_AGE_MS, function(err) {
127
129
  callback(err);
128
130
  });
129
131
  };
@@ -172,7 +174,7 @@ exports = module.exports = function()
172
174
  // when a socket.io connection is established, we set up some default listeners for events that the client
173
175
  // may emit to us
174
176
  io.on("connection", function(socket) {
175
-
177
+
176
178
  // "register" -> indicates that a user is in a channel
177
179
  socket.on("register", function(channelId, user, dirty, callback) {
178
180
 
@@ -193,24 +195,32 @@ exports = module.exports = function()
193
195
  return callback(err);
194
196
  }
195
197
 
196
- // if we were already registered, just callback
197
- // however, if "dirty" is set, then we always hand back membership
198
- if (!dirty && alreadyRegistered)
199
- {
200
- return callback();
201
- }
202
-
203
- if (!alreadyRegistered)
204
- {
205
- // logger.info("New registration - channelId: " + channelId + ",userId=" + user.id + " (" + user.name + ")");
206
-
198
+ // // if we were already registered, just callback
199
+ // // however, if "dirty" is set, then we always hand back membership
200
+ // if (!dirty && alreadyRegistered)
201
+ // {
202
+ // logger.info("Already registered, not dirty - channelId: " + channelId + ",userId=" + user.id + " (" + user.name + ")");
203
+ //
204
+ // return callback();
205
+ // }
206
+ //
207
+ // if (!alreadyRegistered)
208
+ // {
209
+ // logger.info("New registration - channelId: " + channelId + ",userId=" + user.id + " (" + user.name + ")");
210
+
211
+ //logger.info("Register - channelId: " + channelId + ", userId=" + user.id + " (" + user.name + ")");
207
212
  socket.join(channelId);
208
- }
213
+ //}
209
214
 
210
215
  discover(channelId, function(err, userArray) {
211
216
 
212
- if (!err) {
213
- logger.info("Discover - channelId: " + channelId + ", userId=" + user.id + " (" + user.name + ") handing back: " + userArray.length);
217
+ if (err)
218
+ {
219
+ logger.info("Discover - channelId: " + channelId + ", err: " + JSON.stringify(err));
220
+ }
221
+ else
222
+ {
223
+ //logger.info("Discover - channelId: " + channelId + ", userId=" + user.id + " (" + user.name + ") handing back: " + userArray.length);
214
224
  io.sockets.in(channelId).emit("membershipChanged", channelId, userArray);
215
225
  }
216
226
 
@@ -412,6 +422,8 @@ exports = module.exports = function()
412
422
  */
413
423
  var register = r.register = function(channelId, user, callback)
414
424
  {
425
+ //console.log("Awareness - heard register, channel: " + channelId + ", user: " + user.id);
426
+
415
427
  provider.register(channelId, user, callback);
416
428
  };
417
429
 
@@ -458,7 +470,12 @@ exports = module.exports = function()
458
470
  {
459
471
  // take out a cluster-wide lock on the "channelId"
460
472
  // so that two "threads" can't acquire/release at the same time for a given channel
461
- _LOCK(channelId, function (releaseLockFn) {
473
+ _LOCK(channelId, function (err, releaseLockFn) {
474
+
475
+ if (err) {
476
+ return callback(err);
477
+ }
478
+
462
479
  provider.acquireLock(channelId, user, function(err, success) {
463
480
  releaseLockFn();
464
481
  callback(err, success);
@@ -477,7 +494,12 @@ exports = module.exports = function()
477
494
  {
478
495
  // take out a cluster-wide lock on the "channelId"
479
496
  // so that two "threads" can't acquire/release at the same time for a given channel
480
- _LOCK(channelId, function (releaseLockFn) {
497
+ _LOCK(channelId, function (err, releaseLockFn) {
498
+
499
+ if (err) {
500
+ return callback(err);
501
+ }
502
+
481
503
  provider.releaseLock(channelId, userId, function(err, success) {
482
504
  releaseLockFn();
483
505
  callback(err, success);
@@ -43,7 +43,7 @@ exports.bindSocket = function(socket, provider)
43
43
  var acquireEditorialSession = function(socket, provider, sessionKey, repositoryId, branchId, force, callback)
44
44
  {
45
45
  // send an HTTP command to acquire an editorial session for this repository and branch
46
- var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + "/oneteam/editorial/session/acquire";
46
+ var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH) + "/oneteam/editorial/session/acquire";
47
47
 
48
48
  var headers = {};
49
49
  //headers["Authorization"] = socket.gitana.platform().getDriver().getHttpHeaders()["Authorization"];
@@ -101,7 +101,7 @@ exports.bindSocket = function(socket, provider)
101
101
  var releaseEditorialSession = function(socket, provider, sessionKey, repositoryId, branchId, callback)
102
102
  {
103
103
  // send an HTTP command to release the session
104
- var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + "/oneteam/editorial/session/release";
104
+ var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH) + "/oneteam/editorial/session/release";
105
105
 
106
106
  var json = {};
107
107
  json.repositoryId = repositoryId;
@@ -152,7 +152,7 @@ exports.bindSocket = function(socket, provider)
152
152
  */
153
153
  var commitEditorialSession = function(socket, provider, sessionKey, repositoryId, branchId, callback)
154
154
  {
155
- var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + "/oneteam/editorial/session/commit";
155
+ var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH) + "/oneteam/editorial/session/commit";
156
156
 
157
157
  var json = {};
158
158
  json.repositoryId = repositoryId;
@@ -202,7 +202,7 @@ exports.bindSocket = function(socket, provider)
202
202
  */
203
203
  var editorialSessionInfo = function(socket, provider, sessionKey, repositoryId, branchId, callback)
204
204
  {
205
- var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT) + "/oneteam/editorial/session/info";
205
+ var URL = util.asURL(process.env.GITANA_PROXY_SCHEME, process.env.GITANA_PROXY_HOST, process.env.GITANA_PROXY_PORT, process.env.GITANA_PROXY_PATH) + "/oneteam/editorial/session/info";
206
206
 
207
207
  var json = {};
208
208
  json.repositoryId = repositoryId;
@@ -14,28 +14,33 @@ class AbstractAsyncProvider extends AbstractProvider
14
14
  {
15
15
  super(config);
16
16
  }
17
-
17
+
18
+ _lock(lockKey, workFunction)
19
+ {
20
+ process.locks.lock(lockKey, workFunction);
21
+ }
22
+
18
23
  readOrCreateChannel(channelId, callback) {
19
24
 
20
25
  var self = this;
21
26
 
22
27
  self.readChannel(channelId, function(err, channel) {
23
-
28
+
24
29
  if (err) {
25
30
  return callback(err);
26
31
  }
27
-
32
+
28
33
  if (channel) {
29
34
  return callback(null, channel);
30
35
  }
31
36
 
32
37
  var channel = {};
33
38
  self.writeChannel(channelId, channel, function(err) {
34
-
39
+
35
40
  if (err) {
36
41
  return callback(err);
37
42
  }
38
-
43
+
39
44
  callback(null, channel);
40
45
  });
41
46
  });
@@ -46,26 +51,44 @@ class AbstractAsyncProvider extends AbstractProvider
46
51
  register(channelId, user, callback)
47
52
  {
48
53
  var self = this;
49
-
54
+
55
+ self.doRegister(channelId, user, function(err) {
56
+ callback(err);
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Workhorse method.
62
+ *
63
+ * @param channelId
64
+ * @param user
65
+ * @param callback
66
+ * @private
67
+ */
68
+ doRegister(channelId, user, callback)
69
+ {
70
+ var self = this;
71
+
50
72
  self.readOrCreateChannel(channelId, function (err, channel) {
51
-
73
+
52
74
  if (err) {
53
75
  return callback(err);
54
76
  }
55
-
77
+
56
78
  if (!channel.users) {
57
79
  channel.users = {};
58
80
  }
59
-
81
+
60
82
  channel.users[user.id] = {
61
83
  "user": user,
62
84
  "time": new Date().getTime()
63
85
  };
64
-
86
+
65
87
  self.writeChannel(channelId, channel, function (err) {
66
88
  callback(err);
67
89
  });
68
90
  });
91
+
69
92
  }
70
93
 
71
94
  discover(channelId, callback)
@@ -101,123 +124,121 @@ class AbstractAsyncProvider extends AbstractProvider
101
124
  });
102
125
  }
103
126
 
104
- expire(beforeMs, callback)
127
+ checkRegistered(channelId, userId, callback)
105
128
  {
106
129
  var self = this;
107
130
 
108
- self.listChannelIds(function(err, channelIds) {
131
+ self.readChannel(channelId, function(err, channel) {
109
132
 
110
133
  if (err) {
111
134
  return callback(err);
112
135
  }
113
136
 
137
+ if (!channel) {
138
+ return callback(null, false);
139
+ }
140
+
141
+ if (!channel.users) {
142
+ return callback(null, false);
143
+ }
144
+
145
+ if (channel.users[userId]) {
146
+ return callback(null, true);
147
+ }
148
+
149
+ callback(null, false);
150
+
151
+ });
152
+ }
153
+
154
+ expire(beforeMs, callback)
155
+ {
156
+ var self = this;
157
+
158
+ self.listChannelIds(function(err, channelIds) {
159
+
160
+ if (err) {
161
+ return callback(err);
162
+ }
163
+
114
164
  if (!channelIds || channelIds.length === 0) {
115
165
  return callback(null, [], {});
116
166
  }
117
-
167
+
118
168
  // a list of channel IDs whose memberships were updated
119
169
  var updatedMembershipChannelIds = [];
120
170
  var expiredUserIdsByChannelId = {};
121
-
171
+
122
172
  var fns = [];
123
-
173
+
124
174
  for (var i = 0; i < channelIds.length; i++)
125
175
  {
126
176
  var channelId = channelIds[i];
127
-
177
+
128
178
  var fn = function (channelId, updatedMembershipChannelIds, expiredUserIdsByChannelId, beforeMs) {
129
179
  return function (done) {
130
-
180
+
131
181
  self.readChannel(channelId, function(err, channel) {
132
-
182
+
133
183
  if (err) {
134
184
  return done(err);
135
185
  }
136
-
186
+
137
187
  if (!channel) {
138
188
  return done();
139
189
  }
190
+
191
+ if (!channel.users || Object.keys(channel.users).length === 0)
192
+ {
193
+ return done();
194
+ }
140
195
 
141
- var updatedMembership = false;
142
-
143
- if (channel.users)
196
+ // populate all of the user IDs that need to be removed
197
+ var userIdsToRemove = [];
198
+ for (var userId in channel.users)
144
199
  {
145
- // populate all of the user IDs that need to be removed
146
- var userIdsToRemove = [];
147
- for (var userId in channel.users)
200
+ var entry = channel.users[userId];
201
+ if (entry.time < beforeMs)
148
202
  {
149
- var entry = channel.users[userId];
150
- if (entry.time < beforeMs)
151
- {
152
- updatedMembership = true;
153
- userIdsToRemove.push(userId);
154
-
155
- var expiredUserIds = expiredUserIdsByChannelId[channelId]
156
- if (!expiredUserIds) {
157
- expiredUserIds = expiredUserIdsByChannelId[channelId] = [];
158
- }
159
-
160
- expiredUserIds.push(userId);
203
+ updatedMembershipChannelIds.push(channelId);
204
+ userIdsToRemove.push(userId);
205
+
206
+ var expiredUserIds = expiredUserIdsByChannelId[channelId]
207
+ if (!expiredUserIds) {
208
+ expiredUserIds = expiredUserIdsByChannelId[channelId] = [];
161
209
  }
162
- }
163
-
164
- // remove the user IDs
165
- for (var i = 0; i < userIdsToRemove.length; i++)
166
- {
167
- delete channel.users[userIdsToRemove[i]];
210
+
211
+ expiredUserIds.push(userId);
168
212
  }
169
213
  }
170
-
171
- if (updatedMembership)
214
+
215
+ // remove the user IDs
216
+ for (var i = 0; i < userIdsToRemove.length; i++)
172
217
  {
173
- updatedMembershipChannelIds.push(channelId);
218
+ delete channel.users[userIdsToRemove[i]];
174
219
  }
175
-
176
- done();
220
+
221
+ self.writeChannel(channelId, channel, function() {
222
+ done();
223
+ });
224
+
177
225
  });
178
226
  };
179
227
  }(channelId, updatedMembershipChannelIds, expiredUserIdsByChannelId, beforeMs);
180
228
  fns.push(fn);
181
229
  }
182
-
230
+
183
231
  async.parallel(fns, function(err) {
184
-
232
+
185
233
  if (err) {
186
234
  return callback(err);
187
235
  }
188
-
236
+
189
237
  callback(null, updatedMembershipChannelIds, expiredUserIdsByChannelId);
190
238
  });
191
239
  });
192
- }
193
-
194
- checkRegistered(channelId, userId, callback)
195
- {
196
- var self = this;
197
-
198
- self.readChannel(channelId, function(err, channel) {
199
-
200
- if (err) {
201
- return callback(err);
202
- }
203
-
204
- if (!channel) {
205
- return callback(null, false);
206
- }
207
-
208
- if (!channel.users) {
209
- return callback(null, false);
210
- }
211
-
212
- if (channel.users[userId]) {
213
- return callback(null, true);
214
- }
215
-
216
- callback(null, false);
217
-
218
- });
219
- }
220
-
240
+ };
241
+
221
242
  acquireLock(channelId, user, callback)
222
243
  {
223
244
  var self = this;
@@ -303,14 +324,16 @@ class AbstractAsyncProvider extends AbstractProvider
303
324
  callback(null, lock);
304
325
  });
305
326
  }
306
-
307
-
327
+
328
+
329
+
330
+
308
331
  //////////////////////////////////////////////////////////////////////////////////////////////////////////
309
332
  //
310
333
  // ABSTRACT METHODS
311
334
  //
312
335
  //////////////////////////////////////////////////////////////////////////////////////////////////////////
313
-
336
+
314
337
  // ABSTRACT
315
338
  readChannel(channelId, callback)
316
339
  {
@@ -328,7 +351,7 @@ class AbstractAsyncProvider extends AbstractProvider
328
351
  {
329
352
  throw new Error("listChannelIds() method is not implemented");
330
353
  }
331
-
354
+
332
355
  // ABSTRACT
333
356
  readLock(lockId, callback)
334
357
  {
@@ -2,7 +2,7 @@
2
2
  * Abstract class for an Awareness Provider.
3
3
  *
4
4
  * This class provides an interface or base functions that any implementation class must implement in order to
5
- * work with the Awareness Service. Any methods that
5
+ * work with the Awareness Service.
6
6
  *
7
7
  */
8
8
  class AbstractProvider