@jcbuisson/express-x 2.1.1 → 2.1.4

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jcbuisson/express-x",
3
- "version": "2.1.1",
3
+ "version": "2.1.4",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "src/index.mjs",
@@ -35,25 +35,30 @@ export function protect(field) {
35
35
  }
36
36
 
37
37
  /*
38
- * Does nothing for calls which are not client-side
39
- * Check if the 'expireAt' key in socket.data is met
40
- * If it is met, throw an error (which will be sent back to the calling server or client) and reset socket.data
41
- * If not, do nothing. If needed, an application-level hook may automatically extend the expiration data at each service call
38
+ * Throw an error for a client service method call when socket.data.expiresAt is missing or overdue
42
39
  */
43
40
  export const isNotExpired = async (context) => {
44
- if (context.caller !== 'client') return
45
-
46
- const expireAt = context.socket.data.expireAt
47
- if (expireAt) {
48
- const expireAtDate = new Date(expireAt)
41
+ // do nothing if it's not a client call from a ws connexion
42
+ if (!context.socket) return
43
+ const expiresAt = context.socket.data.expiresAt
44
+ if (expiresAt) {
45
+ const expiresAtDate = new Date(expiresAt)
49
46
  const now = new Date()
50
- if (now > expireAtDate) {
47
+ if (now > expiresAtDate) {
51
48
  // expiration date is met: clear socket.data & throw exception
52
- const { clientIP } = socket.data
53
- socket.data = { clientIP }
49
+ context.socket.data = {}
54
50
  throw new Error('session-expired')
55
51
  }
56
52
  } else {
57
53
  throw new Error('session-expired')
58
54
  }
59
55
  }
56
+
57
+ /*
58
+ * Throw an error for a client service method call when socket.data does not contain user
59
+ */
60
+ export const isAuthenticated = async (context) => {
61
+ // do nothing if it's not a client call from a ws connexion
62
+ if (!context.socket) return
63
+ if (!context.socket.data.user) throw new Error('not-authenticated')
64
+ }
package/src/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  import { expressX } from './server.mjs'
3
- import { addTimestamp, hashPassword, protect, isNotExpired } from './common-hooks.mjs'
3
+ import { addTimestamp, hashPassword, protect, isAuthenticated, isNotExpired } from './common-hooks.mjs'
4
4
 
5
5
  export {
6
6
  expressX,
@@ -8,5 +8,6 @@ export {
8
8
  addTimestamp,
9
9
  hashPassword,
10
10
  protect,
11
+ isAuthenticated,
11
12
  isNotExpired,
12
13
  }
package/src/server.mjs CHANGED
@@ -3,14 +3,27 @@ import { createServer } from "http"
3
3
  import { Server } from "socket.io"
4
4
 
5
5
 
6
+ // UTILISER L'ACKNOWLEDGEMENT : https://socket.io/docs/v4/#acknowledgements
7
+
6
8
  export function expressX(config) {
7
9
 
8
10
  const services = {}
9
11
  let appHooks = []
10
- let socketConnectHandler = null
12
+ const socketConnectListeners = []
13
+ const socketDisconnectingListeners = []
14
+ const socketDisconnectListeners = []
15
+
16
+
17
+ function addConnectListener(func) {
18
+ socketConnectListeners.push(func)
19
+ }
20
+
21
+ function addDisconnectingListener(func) {
22
+ socketDisconnectingListeners.push(func)
23
+ }
11
24
 
12
- function onSocketConnect(func) {
13
- socketConnectHandler = func
25
+ function addDisconnectListener(func) {
26
+ socketDisconnectListeners.push(func)
14
27
  }
15
28
 
16
29
  const app = express()
@@ -29,6 +42,9 @@ export function expressX(config) {
29
42
  }
30
43
  })
31
44
 
45
+ // so that io server is accessible to hooks & services
46
+ app.set('io', io)
47
+
32
48
  // logging function - a winston logger must be configured first
33
49
  app.log = (severity, message) => {
34
50
  const logger = app.get('logger')
@@ -43,21 +59,26 @@ export function expressX(config) {
43
59
  } else {
44
60
  // new or unrecoverable connection
45
61
  // (page open, page refresh/reload)
46
- socket.data.clientIP = socket.handshake.address
47
62
  }
48
63
 
49
64
  app.log('verbose', `Client connected ${socket.id}`)
50
65
 
51
- // emit 'connection' event for app (expressjs extends EventEmitter)
52
- app.emit('connection', socket)
66
+ // // emit 'connection' event for app (expressjs extends EventEmitter)
67
+ // app.emit('connection', socket)
68
+
69
+ socketConnectListeners.forEach(listener => listener(socket))
53
70
 
54
- if (socketConnectHandler) socketConnectHandler(socket)
71
+ // // send 'connected' event to client
72
+ // socket.emit('connected', socket.id)
55
73
 
56
- // send 'connected' event to client
57
- socket.emit('connected', socket.id)
74
+ socket.on('disconnecting', (reason) => {
75
+ app.log('verbose', `Client disconnecting ${socket.id}, ${reason}`)
76
+ socketDisconnectingListeners.forEach(listener => listener(socket, reason))
77
+ })
58
78
 
59
- socket.on('disconnect', () => {
60
- app.log('verbose', `Client disconnected ${socket.id}`)
79
+ socket.on('disconnect', (reason) => {
80
+ app.log('verbose', `Client disconnect ${socket.id}, ${reason}`)
81
+ socketDisconnectListeners.forEach(listener => listener(socket, reason))
61
82
  })
62
83
 
63
84
  /*
@@ -94,13 +115,14 @@ export function expressX(config) {
94
115
  result,
95
116
  })
96
117
  } catch(err) {
97
- console.log('!!!!!!error', err.code, err)
118
+ console.log('!!!!!!error', err)
98
119
  app.log('verbose', err.stack)
99
120
  socket.emit('client-response', {
100
121
  uid,
101
122
  error: {
102
123
  code: err.code || 'unknown-error',
103
- message: err.stack,
124
+ message: err.message,
125
+ stack: err.stack,
104
126
  }
105
127
  })
106
128
  }
@@ -120,8 +142,9 @@ export function expressX(config) {
120
142
  uid,
121
143
  error: {
122
144
  code: err.code || 'unknown-error',
123
- message: err.stack,
124
- }
145
+ message: err.message,
146
+ stack: err.stack,
147
+ }
125
148
  })
126
149
  }
127
150
  } else {
@@ -153,8 +176,8 @@ export function expressX(config) {
153
176
  // put args into context
154
177
  context.args = args
155
178
 
156
- // if a hook or the method throws an error, it will be caught by `socket.on('client-request'` (ws)
157
- // or by express (http) and the client will get a rejected promise
179
+ // if a hook or the method throws an error, it will be caught by `socket.on('client-request'`
180
+ // and the client will get a rejected promise
158
181
 
159
182
  // call 'before' hooks, possibly modifying `context`
160
183
  const beforeAppHooks = appHooks?.before || []
@@ -271,7 +294,9 @@ export function expressX(config) {
271
294
  joinChannel,
272
295
  leaveChannel,
273
296
  sendAppEvent,
274
- onSocketConnect,
297
+ addConnectListener,
298
+ addDisconnectingListener,
299
+ addDisconnectListener,
275
300
  })
276
301
 
277
302
  }