@jcbuisson/express-x 2.1.4 → 2.1.6

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.4",
3
+ "version": "2.1.6",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "src/index.mjs",
@@ -1,15 +1,19 @@
1
1
 
2
2
  import bcrypt from 'bcryptjs'
3
3
 
4
+ import config from '#config'
4
5
 
6
+
7
+ /*
8
+ * Add a timestamp property of name `field` with current time as value
9
+ */
5
10
  export const addTimestamp = (field) => async (context) => {
6
11
  context.result[field] = (new Date()).toISOString()
7
12
  return context
8
13
  }
9
14
 
10
15
  /*
11
- * Hash password of user record
12
- * To be used as an 'after' hook for users service methods
16
+ * Hash password of the property `field`
13
17
  */
14
18
  export const hashPassword = (passwordField) => async (context) => {
15
19
  const user = context.result
@@ -17,7 +21,6 @@ export const hashPassword = (passwordField) => async (context) => {
17
21
  return context
18
22
  }
19
23
 
20
-
21
24
  /*
22
25
  * Remove `field` from `context.result`
23
26
  */
@@ -34,9 +37,13 @@ export function protect(field) {
34
37
  }
35
38
  }
36
39
 
37
- /*
38
- * Throw an error for a client service method call when socket.data.expiresAt is missing or overdue
39
- */
40
+ class NotAuthenticatedError extends Error {
41
+ constructor(message) {
42
+ super(message)
43
+ this.code = 'not-authenticated'
44
+ }
45
+ }
46
+
40
47
  export const isNotExpired = async (context) => {
41
48
  // do nothing if it's not a client call from a ws connexion
42
49
  if (!context.socket) return
@@ -45,12 +52,22 @@ export const isNotExpired = async (context) => {
45
52
  const expiresAtDate = new Date(expiresAt)
46
53
  const now = new Date()
47
54
  if (now > expiresAtDate) {
48
- // expiration date is met: clear socket.data & throw exception
55
+ // expiration date is met
56
+ // clear socket.data
49
57
  context.socket.data = {}
50
- throw new Error('session-expired')
58
+ // leave all rooms except socket#id
59
+ const rooms = new Set(context.socket.rooms)
60
+ for (const room of rooms) {
61
+ if (room === context.socket.id) continue
62
+ context.socket.leave(room)
63
+ }
64
+ // send an event to the client (typical client handling: logout)
65
+ context.socket.emit('expired')
66
+ // throw exception
67
+ throw new NotAuthenticatedError("Session expired")
51
68
  }
52
69
  } else {
53
- throw new Error('session-expired')
70
+ throw new NotAuthenticatedError("No expiresAt in socket.data")
54
71
  }
55
72
  }
56
73
 
@@ -60,5 +77,13 @@ export const isNotExpired = async (context) => {
60
77
  export const isAuthenticated = async (context) => {
61
78
  // do nothing if it's not a client call from a ws connexion
62
79
  if (!context.socket) return
63
- if (!context.socket.data.user) throw new Error('not-authenticated')
80
+ if (!context.socket.data.user) throw new NotAuthenticatedError('no user in socket.data')
64
81
  }
82
+
83
+ /*
84
+ * Extend value of socket.data.expiresAt
85
+ */
86
+ export const extendExpiration = async (context) => {
87
+ const now = new Date()
88
+ context.socket.data.expiresAt = new Date(now.getTime() + config.SESSION_EXPIRE_DELAY)
89
+ }
package/src/server.mjs CHANGED
@@ -8,7 +8,6 @@ import { Server } from "socket.io"
8
8
  export function expressX(config) {
9
9
 
10
10
  const services = {}
11
- let appHooks = []
12
11
  const socketConnectListeners = []
13
12
  const socketDisconnectingListeners = []
14
13
  const socketDisconnectListeners = []
@@ -115,7 +114,7 @@ export function expressX(config) {
115
114
  result,
116
115
  })
117
116
  } catch(err) {
118
- console.log('!!!!!!error', err)
117
+ console.log('!!!!!!error', err.code, err.message)
119
118
  app.log('verbose', err.stack)
120
119
  socket.emit('client-response', {
121
120
  uid,
@@ -180,10 +179,9 @@ export function expressX(config) {
180
179
  // and the client will get a rejected promise
181
180
 
182
181
  // call 'before' hooks, possibly modifying `context`
183
- const beforeAppHooks = appHooks?.before || []
184
182
  const beforeMethodHooks = service?._hooks?.before && service._hooks.before[methodName] || []
185
183
  const beforeAllHooks = service?._hooks?.before?.all || []
186
- for (const hook of [...beforeAppHooks, ...beforeMethodHooks, ...beforeAllHooks]) {
184
+ for (const hook of [...beforeAllHooks, ...beforeMethodHooks]) {
187
185
  await hook(context)
188
186
  }
189
187
 
@@ -195,8 +193,7 @@ export function expressX(config) {
195
193
  // call 'after' hooks, possibly modifying `context`
196
194
  const afterMethodHooks = service?._hooks?.after && service._hooks.after[methodName] || []
197
195
  const afterAllHooks = service?._hooks?.after?.all || []
198
- const afterAppHooks = appHooks?.after || []
199
- for (const hook of [...afterMethodHooks, ...afterAllHooks, ...afterAppHooks]) {
196
+ for (const hook of [...afterMethodHooks, ...afterAllHooks]) {
200
197
  await hook(context)
201
198
  }
202
199
 
@@ -255,11 +252,6 @@ export function expressX(config) {
255
252
  callback(app)
256
253
  }
257
254
 
258
- // set application hooks
259
- function hooks(hooks) {
260
- appHooks = hooks
261
- }
262
-
263
255
  // `app.service(name)` starts here!
264
256
  function service(name) {
265
257
  // get service from `services` cache
@@ -290,7 +282,6 @@ export function expressX(config) {
290
282
  createService,
291
283
  service,
292
284
  configure,
293
- hooks,
294
285
  joinChannel,
295
286
  leaveChannel,
296
287
  sendAppEvent,