@cocreate/socket-server 1.19.4 → 1.20.0

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 (3) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/package.json +1 -1
  3. package/src/index.js +114 -43
package/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ # [1.20.0](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.19.5...v1.20.0) (2023-10-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * delete data.socket ([4fd38ff](https://github.com/CoCreate-app/CoCreate-socket-server/commit/4fd38ffd9989502955eb73d7d21f90102ea41e69))
7
+ * improved error handling ([04be91f](https://github.com/CoCreate-app/CoCreate-socket-server/commit/04be91ffcc62c7270fc83cbb1c755125485496fb))
8
+
9
+
10
+ ### Features
11
+
12
+ * delay user deletion for potential reconnect ([34e3a14](https://github.com/CoCreate-app/CoCreate-socket-server/commit/34e3a143776a0e67f8cea56ab2f0334a1e349df2))
13
+ * If authinticated emit 'notification.user' ([ac4779f](https://github.com/CoCreate-app/CoCreate-socket-server/commit/ac4779f0773e5f9b906390648c536e654cc1f40a))
14
+
15
+ ## [1.19.5](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.19.4...v1.19.5) (2023-10-16)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * improved error handling ([a3e5d31](https://github.com/CoCreate-app/CoCreate-socket-server/commit/a3e5d314143f135816de7b51696626c53e6a88f0))
21
+
1
22
  ## [1.19.4](https://github.com/CoCreate-app/CoCreate-socket-server/compare/v1.19.3...v1.19.4) (2023-10-14)
2
23
 
3
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/socket-server",
3
- "version": "1.19.4",
3
+ "version": "1.20.0",
4
4
  "description": "CoCreate-socket-server",
5
5
  "keywords": [
6
6
  "cocreate-socket",
package/src/index.js CHANGED
@@ -31,8 +31,18 @@ class SocketServer extends EventEmitter {
31
31
  let organization_id = request.url.split('/')
32
32
  organization_id = organization_id[organization_id.length - 1]
33
33
 
34
- if (organization_id) {
35
- this.wss.handleUpgrade(request, socket, head, function (socket) {
34
+ this.wss.handleUpgrade(request, socket, head, function (socket) {
35
+ if (organization_id) {
36
+ let organization = self.organizations.get(organization_id)
37
+ if (organization && organization.status === false) {
38
+ let errors = {}
39
+ errors.serverOrganization = organization.serverOrganization
40
+ errors.serverStorage = organization.serverStorage
41
+ errors.organizationBalance = organization.organizationBalance
42
+ errors.error = organization.error
43
+ return socket.send(JSON.stringify({ method: 'Access Denied', error: errors }))
44
+ }
45
+
36
46
  let options = decodeURIComponent(request.headers['sec-websocket-protocol'])
37
47
  options = JSON.parse(options)
38
48
 
@@ -74,23 +84,25 @@ class SocketServer extends EventEmitter {
74
84
 
75
85
  self.emit('read.object', data);
76
86
 
77
- if (self.authenticate && options.token) {
78
- let { user_id, expires } = self.authenticate.decodeToken(options.token)
79
- // self.authenticate.decodeToken(options.token).then(({ user_id, expires }) => {
87
+ if (self.authenticate) {
88
+ const { user_id, expires } = self.authenticate.decodeToken(options.token)
89
+
80
90
  if (user_id) {
81
91
  socket.user_id = user_id;
82
92
  socket.expires = expires;
83
93
  self.emit('userStatus', { socket, method: 'userStatus', user_id, userStatus: 'on', organization_id });
94
+ self.emit("notification.user", socket)
84
95
  } else
85
- self.emit('userStatus', { socket, user_id, status: 'off', organization_id });
96
+ self.emit('userStatus', { socket, user_id: options.user_id, userStatus: 'off', organization_id });
86
97
 
87
98
  self.onWebSocket(socket);
88
- // })
89
- }
90
- else
99
+
100
+ } else
91
101
  self.onWebSocket(socket);
92
- })
93
- }
102
+ } else {
103
+ socket.send(JSON.stringify({ method: 'Access Denied', error: 'An organization_id is required' }))
104
+ }
105
+ })
94
106
  });
95
107
  }
96
108
 
@@ -140,11 +152,17 @@ class SocketServer extends EventEmitter {
140
152
  organization_id
141
153
  });
142
154
 
143
- }
155
+ } else
156
+ clearTimeout(organization.debounce);
157
+
144
158
 
145
159
  if (!this.clients.has(socket.clientId)) {
146
160
  this.clients.set(socket.clientId, []);
147
- organization.clients[socket.clientId] = []
161
+
162
+ if (!organization.clients)
163
+ organization.clients = { [socket.clientId]: [] }
164
+ else
165
+ organization.clients[socket.clientId] = []
148
166
  }
149
167
 
150
168
  if (!this.sockets.has(socket.id)) {
@@ -155,12 +173,13 @@ class SocketServer extends EventEmitter {
155
173
 
156
174
  if (socket.user_id) {
157
175
  this.emit('userStatus', { socket, user_id: socket.user_id, userStatus: 'on', organization_id });
176
+ let user = this.users.get(socket.user_id)
158
177
 
159
- if (!this.users.has(socket.user_id)) {
178
+ if (!Array.isArray(user)) {
179
+ clearTimeout(user)
160
180
  this.users.set(socket.user_id, [socket])
161
- } else {
162
- this.users.get(socket.user_id).push(socket)
163
- }
181
+ } else
182
+ user.push(socket)
164
183
  }
165
184
 
166
185
  }
@@ -179,9 +198,6 @@ class SocketServer extends EventEmitter {
179
198
  else
180
199
  sockets.push(...clients[client])
181
200
  }
182
- } else {
183
- // TODO: requires a messageQueue that expires
184
- console.log('organization could not be found', data)
185
201
  }
186
202
  } else if (data.broadcastSender !== false) {
187
203
  sockets.push(data.socket)
@@ -192,8 +208,9 @@ class SocketServer extends EventEmitter {
192
208
  delete(socket) {
193
209
  let organization_id = socket.organization_id
194
210
  if (this.organizations.has(organization_id)) {
195
- const clients = this.organizations.get(organization_id).clients;
196
-
211
+ let clients = this.organizations.get(organization_id)
212
+ if (clients)
213
+ clients.clients;
197
214
  // Check if the client exists
198
215
  if (clients && clients[socket.clientId]) {
199
216
  const client = clients[socket.clientId]
@@ -241,21 +258,43 @@ class SocketServer extends EventEmitter {
241
258
  }
242
259
 
243
260
  if (this.clients.size === 0) {
244
- this.organizations.delete(socket.organization_id);
245
- }
261
+ let organization = this.organizations.get(socket.organization_id)
262
+ let debounceTimer
263
+ if (organization)
264
+ debounceTimer = organization.debounce
265
+
266
+ clearTimeout(debounceTimer);
267
+ debounceTimer = setTimeout(() => {
268
+ this.organizations.delete(socket.organization_id);
269
+ }, 10000);
270
+
271
+ if (!organization)
272
+ this.organizations.set(socket.organization_id, { debounce: debounceTimer })
273
+ else
274
+ organization.debounce = debounceTimer
275
+
276
+ this.sockets.delete(socket.id);
277
+
278
+ if (socket.user_id) {
279
+ let sockets = this.users.get(socket.user_id)
280
+ if (sockets) {
281
+ if (Array.isArray(sockets) && sockets.length) {
282
+ const index = sockets.findIndex(item => item.id === socket.id);
283
+ if (index !== -1) {
284
+ sockets.splice(index, 1);
285
+ }
286
+ } else {
287
+ let userDebounceTimer = sockets
246
288
 
247
- this.sockets.delete(socket.id);
289
+ clearTimeout(userDebounceTimer);
290
+ userDebounceTimer = setTimeout(() => {
291
+ this.users.delete(socket.user_id);
292
+ this.emit('userStatus', { socket, user_id: socket.user_id, userStatus: 'off', organization_id });
293
+ }, 10000);
248
294
 
249
- if (socket.user_id) {
250
- let sockets = this.users.get(socket.user_id)
251
- if (sockets) {
252
- const index = sockets.findIndex(item => item.id === socket.id);
253
- if (index !== -1) {
254
- sockets.splice(index, 1);
255
- }
256
- if (!sockets.length) {
257
- this.users.delete(socket.user_id);
258
- this.emit('userStatus', { socket, user_id, status: 'off', organization_id });
295
+ this.users.set(socket.user_id, userDebounceTimer)
296
+
297
+ }
259
298
  }
260
299
  }
261
300
  }
@@ -271,11 +310,16 @@ class SocketServer extends EventEmitter {
271
310
  organization_id
272
311
  });
273
312
 
274
- if (this.organizations.has(organization_id) && !this.organizations.get(organization_id).status)
275
- return this.send({ socket, method: 'Access Denied', balance: 'Your balance has fallen bellow 0' })
276
313
 
277
314
  let data = JSON.parse(message)
278
315
  if (data.method) {
316
+ const organization = this.organizations.get(organization_id)
317
+ if (organization && organization.organizationBalance == false) {
318
+ data.organizationBalance = false
319
+ data.error = organization.error
320
+ return socket.send(JSON.stringify(data))
321
+ }
322
+
279
323
  if (data.method === 'region.added' || data.method === 'region.removed')
280
324
  console.log('data.method: ', data.method)
281
325
 
@@ -286,24 +330,51 @@ class SocketServer extends EventEmitter {
286
330
 
287
331
  if (this.authorize) {
288
332
  if (!this.sockets.has(socket.id)) {
289
- if (!this.organizations.get(organization_id).status)
290
- return this.send({ socket, method: 'Access Denied', balance: 'Your balance has fallen bellow 0' })
333
+ if (organization && organization.organizationBalance == false) {
334
+ data.organizationBalance = false
335
+ data.error = organization.error
336
+ return socket.send(JSON.stringify(data))
337
+ }
291
338
  }
292
339
 
293
340
  data.socket = socket
294
341
 
295
342
  const authorized = await this.authorize.check(data, socket.user_id)
296
- if (authorized.storage === false) {
343
+ let errors = {}
344
+ if (authorized.serverOrganization === false) {
345
+ organization.status = errors.status = false;
346
+ organization.serverOrganization = false;
347
+ organization.error = authorized.error
348
+ } else if (authorized.serverStorage === false) {
297
349
  data.database = process.env.organization_id
298
350
  data.organization_id = process.env.organization_id
299
351
 
300
352
  const authorized2 = await this.authorize.check(data, req, socket.user_id)
301
353
  if (!authorized2 || authorized2.error) {
302
- return this.send({ socket, method: 'Access Denied', authorized2, ...data })
354
+ organization.status = errors.status = false;
355
+ organization.error = errors.error = authorized.error
356
+ if (authorized2.serverOrganization === false) {
357
+ organization.serverOrganization = false;
358
+ }
359
+ if (authorized2.serverStorage === false) {
360
+ organization.serverStorage = false;
361
+ }
303
362
  }
304
- } else if (!authorized || authorized.error) {
305
- return this.send({ socket, method: 'Access Denied', authorized, ...data })
363
+ } else if (authorized.error) {
364
+ organization.status = false;
365
+ organization.error = authorized.error
306
366
  }
367
+
368
+ if (organization && organization.status === false) {
369
+ let errors = {}
370
+ data.serverOrganization = organization.serverOrganization
371
+ data.serverStorage = organization.serverStorage
372
+ data.organizationBalance = organization.organizationBalance
373
+ data.error = organization.error
374
+ delete data.socket
375
+ return socket.send(JSON.stringify(data))
376
+ }
377
+
307
378
  // dburl is true and db does not have 'keys' array
308
379
  // action: syncCollection data{array: 'keys', object[]}
309
380
  // actions: add keys as once keys are added admin user can do anything