Implement EventManager integration and enhance socket event handling

- Added EventManager to SocketHost and SocketUser for improved event handling.
- Introduced new socket event handlers for editing objects, listing objects, and subscribing to object actions.
- Refactored authentication logic to streamline host online status updates.
- Enhanced logging and callback mechanisms for better traceability and responsiveness in socket interactions.
This commit is contained in:
Tom Butcher 2025-09-05 23:30:35 +01:00
parent ab50a5261d
commit e1ba1f7871
2 changed files with 127 additions and 18 deletions

View File

@ -2,11 +2,12 @@ import log4js from 'log4js';
// Load configuration
import { loadConfig } from '../config.js';
import { CodeAuth, createAuthMiddleware } from '../auth/auth.js';
import { editObject, getObject } from '../database/database.js';
import { editObject, getObject, listObjects } from '../database/database.js';
import { hostModel } from '../database/schemas/management/host.schema.js';
import { UpdateManager } from '../updates/updatemanager.js';
import { ActionManager } from '../actions/actionmanager.js';
import { getModelByName } from '../utils.js';
import { EventManager } from '../events/eventmanager.js';
const config = loadConfig();
@ -23,6 +24,7 @@ export class SocketHost {
this.socketManager = socketManager;
this.updateManager = new UpdateManager(this);
this.actionManager = new ActionManager(this);
this.eventManager = new EventManager(this);
this.codeAuth = new CodeAuth();
this.setupSocketEventHandlers();
}
@ -32,6 +34,13 @@ export class SocketHost {
this.socket.on('authenticate', this.handleAuthenticate.bind(this));
this.socket.on('updateHost', this.handleUpdateHost.bind(this));
this.socket.on('getObject', this.handleGetObject.bind(this));
this.socket.on('editObject', this.handleEditObject.bind(this));
this.socket.on('listObjects', this.handleListObjects.bind(this));
this.socket.on(
'subscribeToObjectActions',
this.handleSubscribeToObjectActions.bind(this)
);
this.socket.on('objectEvent', this.handleObjectEventEvent.bind(this));
this.socket.on('disconnect', this.handleDisconnect.bind(this));
}
@ -40,6 +49,23 @@ export class SocketHost {
}
async handleAuthenticate(data, callback) {
const setHostOnline = async verifyResult => {
logger.info('Host authenticated and valid.');
this.host = verifyResult.host;
this.id = this.host._id.toString();
this.authenticated = true;
await editObject({
model: hostModel,
id: this.host._id,
updateData: {
online: true,
state: { type: 'online' },
connectedAt: new Date()
},
owner: this.host,
ownerType: 'host'
});
};
logger.trace('handleAuthenticateEvent');
const id = data.id || undefined;
const authCode = data.authCode || undefined;
@ -49,17 +75,7 @@ export class SocketHost {
logger.info('Authenticating host with id + authCode...');
const verifyResult = await this.codeAuth.verifyCode(id, authCode);
if (verifyResult.valid == true) {
logger.info('Host authenticated and valid.');
this.host = verifyResult.host;
this.id = this.host._id.toString();
this.authenticated = true;
await editObject({
model: hostModel,
id: this.host._id,
updateData: { online: true, state: { type: 'online' } },
owner: this.host,
ownerType: 'host'
});
await setHostOnline(verifyResult);
await this.initializeHost();
}
callback(verifyResult);
@ -71,8 +87,8 @@ export class SocketHost {
const verifyResult = await this.codeAuth.verifyOtp(otp);
if (verifyResult.valid == true) {
logger.info('Host authenticated and valid.');
this.host = verifyResult.host;
this.authenticated = true;
await setHostOnline(verifyResult);
await this.initializeHost();
}
callback(verifyResult);
return;
@ -91,6 +107,18 @@ export class SocketHost {
});
}
async handleEditObject(data, callback) {
const object = await editObject({
model: getModelByName(data.objectType),
id: data._id,
updateData: data.updateData,
populate: data.populate,
owner: this.host,
ownerType: 'host'
});
callback(object);
}
async handleGetObject(data, callback) {
const object = await getObject({
model: getModelByName(data.objectType),
@ -101,12 +129,45 @@ export class SocketHost {
callback(object);
}
async handleListObjects(data, callback) {
const object = await listObjects({
model: getModelByName(data.objectType),
id: data._id,
cached: data?.cached,
populate: data?.populate,
filter: data?.filter,
project: data?.project,
sort: data?.sort,
order: data?.order
});
callback(object);
}
async handleObjectEventEvent(data) {
await this.eventManager.sendObjectEvent(
data._id,
data.objectType,
data.event
);
}
async handleSubscribeToObjectActions(data) {
await this.actionManager.subscribeToObjectActions(
data._id,
data.objectType
);
}
async handleDisconnect() {
if (this.authenticated) {
await editObject({
model: hostModel,
id: this.host._id,
updateData: { online: false, state: { type: 'offline' } },
updateData: {
online: false,
state: { type: 'offline' },
connectedAt: null
},
owner: this.host,
ownerType: 'host'
});

View File

@ -6,6 +6,7 @@ import { generateHostOTP } from '../utils.js';
import { LockManager } from '../lock/lockmanager.js';
import { UpdateManager } from '../updates/updatemanager.js';
import { ActionManager } from '../actions/actionmanager.js';
import { EventManager } from '../events/eventmanager.js';
const config = loadConfig();
@ -23,6 +24,7 @@ export class SocketUser {
this.lockManager = new LockManager(this);
this.updateManager = new UpdateManager(this);
this.actionManager = new ActionManager(this);
this.eventManager = new EventManager(this);
this.templateManager = socketManager.templateManager;
this.keycloakAuth = new KeycloakAuth();
this.setupSocketEventHandlers();
@ -42,6 +44,22 @@ export class SocketUser {
'subscribeToObjectUpdate',
this.handleSubscribeToObjectUpdateEvent.bind(this)
);
this.socket.on(
'subscribeToObjectEvent',
this.handleSubscribeToObjectEventEvent.bind(this)
);
this.socket.on(
'unsubscribeObjectTypeUpdate',
this.handleUnsubscribeToObjectTypeUpdateEvent.bind(this)
);
this.socket.on(
'unsubscribeObjectUpdate',
this.handleUnsubscribeToObjectUpdateEvent.bind(this)
);
this.socket.on(
'unsubscribeObjectEvent',
this.handleUnsubscribeObjectEventEvent.bind(this)
);
this.socket.on(
'previewTemplate',
this.handlePreviewTemplateEvent.bind(this)
@ -60,6 +78,7 @@ export class SocketUser {
const result = await this.keycloakAuth.verifyToken(token);
if (result.valid == true) {
logger.info('User authenticated and valid.');
this.user = result.user;
this.id = this.user._id.toString();
this.authenticated = true;
@ -126,18 +145,47 @@ export class SocketUser {
}
async handleSubscribeToObjectTypeUpdateEvent(data, callback) {
const result = this.updateManager.subscribeToObjectNew(data.objectType);
callback(result);
await this.updateManager.subscribeToObjectNew(data.objectType);
await this.updateManager.subscribeToObjectDelete(data.objectType);
callback({ success: true });
}
async handleSubscribeToObjectUpdateEvent(data, callback) {
const result = this.updateManager.subscribeToObjectUpdate(
const result = await this.updateManager.subscribeToObjectUpdate(
data._id,
data.objectType
);
callback(result);
}
async handleSubscribeToObjectEventEvent(data) {
await this.eventManager.subscribeToObjectEvent(
data._id,
data.objectType,
data.eventType
);
}
async handleUnsubscribeToObjectTypeUpdateEvent(data) {
await this.updateManager.removeObjectNewListener(data.objectType);
await this.updateManager.removeObjectDeleteListener(data.objectType);
}
async handleUnsubscribeToObjectUpdateEvent(data) {
await this.updateManager.removeObjectUpdateListener(
data._id,
data.objectType
);
}
async handleUnsubscribeObjectEventEvent(data) {
await this.eventManager.removeObjectEventsListener(
data._id,
data.objectType,
data.eventType
);
}
async handlePreviewTemplateEvent(data, callback) {
const result = await this.templateManager.renderTemplate(
data._id,