63 lines
2.3 KiB
TypeScript
63 lines
2.3 KiB
TypeScript
import * as plugins from '../../plugins.ts';
|
|
import { logger } from '../../logging.ts';
|
|
import type { OpsServer } from '../classes.opsserver.ts';
|
|
import * as interfaces from '../../../ts_interfaces/index.ts';
|
|
|
|
export class WebhookHandler {
|
|
constructor(private opsServerRef: OpsServer) {}
|
|
|
|
public registerRoutes(typedserver: plugins.typedserver.TypedServer): void {
|
|
typedserver.addRoute('/webhook/:connectionId', 'POST', async (ctx) => {
|
|
const connectionId = ctx.params.connectionId;
|
|
|
|
// Validate connection exists
|
|
const connection = this.opsServerRef.gitopsAppRef.connectionManager.getConnection(connectionId);
|
|
if (!connection) {
|
|
return new Response(JSON.stringify({ error: 'Connection not found' }), {
|
|
status: 404,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
}
|
|
|
|
// Parse event type from provider-specific headers
|
|
const giteaEvent = ctx.headers.get('X-Gitea-Event');
|
|
const gitlabEvent = ctx.headers.get('X-Gitlab-Event');
|
|
const event = giteaEvent || gitlabEvent || 'unknown';
|
|
const provider = giteaEvent ? 'gitea' : gitlabEvent ? 'gitlab' : 'unknown';
|
|
|
|
logger.info(`Webhook received: ${provider}/${event} for connection ${connection.name} (${connectionId})`);
|
|
|
|
// Broadcast to all connected frontends via TypedSocket
|
|
try {
|
|
const typedsocket = this.opsServerRef.server.typedserver.typedsocket;
|
|
if (typedsocket) {
|
|
const connections = await typedsocket.findAllTargetConnectionsByTag('allClients');
|
|
for (const conn of connections) {
|
|
const req = typedsocket.createTypedRequest<interfaces.requests.IReq_WebhookNotification>(
|
|
'webhookNotification',
|
|
conn,
|
|
);
|
|
req.fire({
|
|
connectionId,
|
|
provider,
|
|
event,
|
|
timestamp: Date.now(),
|
|
}).catch((err: any) => {
|
|
logger.warn(`Failed to notify client: ${err.message || err}`);
|
|
});
|
|
}
|
|
}
|
|
} catch (err: any) {
|
|
logger.warn(`Failed to broadcast webhook event: ${err.message || err}`);
|
|
}
|
|
|
|
return new Response(JSON.stringify({ ok: true }), {
|
|
status: 200,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
});
|
|
|
|
logger.info('WebhookHandler routes registered');
|
|
}
|
|
}
|