diff --git a/base-server/index.d.ts b/base-server/index.d.ts index 41c204cd..a00da0de 100644 --- a/base-server/index.d.ts +++ b/base-server/index.d.ts @@ -505,6 +505,7 @@ interface AuthenticationReporter { interface ReportersArguments { add: ActionReporter + addClean: ActionReporter authenticated: AuthenticationReporter clean: CleanReporter clientError: { @@ -975,7 +976,7 @@ export class BaseServer< * @param listener Client listener. */ on( - event: 'authenticated', + event: 'authenticated' | 'unauthenticated', listener: (client: ServerClient, latencyMilliseconds: number) => void ): Unsubscribe @@ -1009,8 +1010,9 @@ export class BaseServer< event: 'unsubscribed', listener: ( action: LoguxUnsubscribeAction, - meta: Readonly - ) => void + meta: Readonly, + clientNodeId: string, + ) => void, ): Unsubscribe /** diff --git a/base-server/index.js b/base-server/index.js index 2fec1017..1202e2ba 100644 --- a/base-server/index.js +++ b/base-server/index.js @@ -657,7 +657,7 @@ export class BaseServer { } } } - this.emitter.emit('unsubscribed', action, meta) + this.emitter.emit('unsubscribed', action, meta, clientNodeId) this.emitter.emit('report', 'unsubscribed', { actionId: meta.id, channel: action.channel diff --git a/server-client/index.js b/server-client/index.js index ec8a025d..d1ed3d2c 100644 --- a/server-client/index.js +++ b/server-client/index.js @@ -77,6 +77,7 @@ export class ServerClient { } if (nodeId === 'server' || userId === 'server') { + this.app.emitter.emit('unauthenticated', this, 0) this.app.emitter.emit('report', 'unauthenticated', reportDetails(this)) return false } @@ -133,6 +134,7 @@ export class ServerClient { this.app.emitter.emit('authenticated', this, Date.now() - start) this.app.emitter.emit('report', 'authenticated', reportDetails(this)) } else { + this.app.emitter.emit('unauthenticated', this, Date.now() - start) this.app.emitter.emit('report', 'unauthenticated', reportDetails(this)) this.app.rememberBadAuth(this.remoteAddress) } @@ -162,9 +164,6 @@ export class ServerClient { } } if (this.clientId) { - this.app.clientIds.delete(this.clientId) - this.app.nodeIds.delete(this.nodeId) - for (let channel in this.app.subscribers) { let subscriber = this.app.subscribers[channel][this.nodeId] if (subscriber) { @@ -174,6 +173,8 @@ export class ServerClient { this.app.performUnsubscribe(this.nodeId, action, meta) } } + this.app.clientIds.delete(this.clientId) + this.app.nodeIds.delete(this.nodeId) } if (!this.app.destroying) { this.app.emitter.emit('disconnected', this) diff --git a/server-client/index.test.ts b/server-client/index.test.ts index 07e3ac4d..291888b7 100644 --- a/server-client/index.test.ts +++ b/server-client/index.test.ts @@ -257,9 +257,15 @@ it('removes itself on destroy', async () => { '10:client2': { filters: { '{}': true } } } } + let unsubscribedClientNodeIds: string[] = [] + test.app.on('unsubscribed', (action, meta, clientNodeId) => { + unsubscribedClientNodeIds.push(clientNodeId) + expect(test.app.nodeIds.get(clientNodeId)).toBeDefined() + }) client1.destroy() await delay(1) + expect(unsubscribedClientNodeIds).toEqual(['10:client1']) expect(Array.from(test.app.userIds.keys())).toEqual(['10']) expect(test.app.subscribers).toEqual({ 'user/10': { '10:client2': { filters: { '{}': true } } } @@ -272,6 +278,8 @@ it('removes itself on destroy', async () => { client2.destroy() await delay(1) + + expect(unsubscribedClientNodeIds).toEqual(['10:client1', '10:client2']) expect(pullNewReports()).toMatchObject([ ['unsubscribed', { channel: 'user/10' }], ['disconnect', { nodeId: '10:client2' }]