Support periodic auth checks in SecurityContext on web socket connections
This commit is contained in:
@@ -17,6 +17,8 @@ import {WebSocketCloseEvent} from '../../http/lifecycle/WebSocketCloseEvent'
|
||||
import {apiEvent, error} from '../../http/response/api'
|
||||
import {AsyncResource, executionAsyncId} from 'async_hooks'
|
||||
import {Session} from '../../http/session/Session'
|
||||
import {Config} from '../../service/Config'
|
||||
import {WebSocketHealthCheckEvent} from '../../http/lifecycle/WebSocketHealthCheckEvent'
|
||||
|
||||
@Injectable()
|
||||
export class WebSocketBus implements EventBus, AwareOfContainerLifecycle {
|
||||
@@ -50,6 +52,9 @@ export class WebSocketBus implements EventBus, AwareOfContainerLifecycle {
|
||||
@Inject()
|
||||
protected readonly session!: Session
|
||||
|
||||
@Inject()
|
||||
protected readonly config!: Config
|
||||
|
||||
public readonly uuid = uuid4()
|
||||
|
||||
private connected = false
|
||||
@@ -125,7 +130,7 @@ export class WebSocketBus implements EventBus, AwareOfContainerLifecycle {
|
||||
}
|
||||
}
|
||||
|
||||
up(): void {
|
||||
async up(): Promise<void> {
|
||||
const resource = new AsyncResource('WebSocketBus', {
|
||||
triggerAsyncId: executionAsyncId(),
|
||||
requireManualDestroy: false,
|
||||
@@ -147,10 +152,53 @@ export class WebSocketBus implements EventBus, AwareOfContainerLifecycle {
|
||||
})
|
||||
})
|
||||
|
||||
this.ws.on('close', () => this.bus.push(new WebSocketCloseEvent()))
|
||||
this.ws.on('error', () => this.bus.push(new WebSocketCloseEvent()))
|
||||
|
||||
await this.registerHealthCheck()
|
||||
|
||||
this.connected = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up an interval that fires a `WebSocketHealthCheckEvent` on the request bus.
|
||||
* This can be used, e.g., to check if the user is still logged in.
|
||||
* You can control the interval by setting the `server.socket.healthCheckIntervalSeconds`
|
||||
* config option. Set the option to 0 to disable the interval.
|
||||
* @protected
|
||||
*/
|
||||
protected async registerHealthCheck(): Promise<void> {
|
||||
const interval = this.config.safe('server.socket.healthCheckIntervalSeconds')
|
||||
.or(60)
|
||||
.integer()
|
||||
|
||||
if ( interval === 0 ) {
|
||||
return
|
||||
}
|
||||
|
||||
const handle = setInterval(() => {
|
||||
if ( !this.isConnected() ) {
|
||||
return
|
||||
}
|
||||
|
||||
return this.bus.push(new WebSocketHealthCheckEvent())
|
||||
}, interval * 1000)
|
||||
|
||||
await this.bus.subscribe(WebSocketCloseEvent, () => {
|
||||
clearInterval(handle)
|
||||
})
|
||||
}
|
||||
|
||||
down(): void {
|
||||
if ( this.connected ) {
|
||||
try {
|
||||
this.ws.close()
|
||||
} catch (e) {
|
||||
this.logging.error('Error closing socket:')
|
||||
this.logging.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
this.connected = false
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user