Skip to content

Commit 32f249f

Browse files
author
John Rogers
committed
broken currently don't use OBS WON'T CHOOCH
1 parent a53a398 commit 32f249f

File tree

5 files changed

+112
-0
lines changed

5 files changed

+112
-0
lines changed

backend/.env.template

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ PORT=5001
33
DATABASE_URL=postgresql://colourstream:your_secure_password_here@colourstream-postgres:5432/colourstream
44
OME_API_URL=http://origin:8081
55
OME_API_ACCESS_TOKEN=your_ovenmedia_api_token_here
6+
OME_WEBHOOK_SECRET=your_ovenmedia_webhook_secret_here
67
OBS_WS_HOST=localhost
78
OBS_WS_PORT=4455
89
JWT_SECRET=your_jwt_secret_here

backend/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import obsRoutes from './routes/obs';
1010
import omenRoutes from './routes/omen';
1111
import securityRoutes from './routes/security';
1212
import healthRoutes from './routes/health';
13+
import omeWebhookRoutes from './routes/omeWebhook';
1314
import { logger } from './utils/logger';
1415
import { initializePassword } from './utils/initPassword';
1516
import mirotalkRoutes from './routes/mirotalk';
@@ -71,6 +72,7 @@ app.use(`${basePath}/obs`, obsRoutes);
7172
app.use(`${basePath}/omen`, omenRoutes);
7273
app.use(`${basePath}/security`, securityRoutes);
7374
app.use('/api/mirotalk', mirotalkRoutes);
75+
app.use(`${basePath}/ome-webhook`, omeWebhookRoutes);
7476

7577
// Error handling
7678
app.use(errorHandler);

backend/src/routes/omeWebhook.ts

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { Request, Response } from 'express';
2+
import express from 'express';
3+
import prisma from '../lib/prisma';
4+
import { logger } from '../utils/logger';
5+
// import crypto from 'crypto';
6+
7+
const router = express.Router();
8+
9+
/**
10+
* Generate a signature for stream authentication
11+
* Kept for future use but currently not used
12+
*/
13+
/*
14+
function generateSignature(streamKey: string): string {
15+
const secret = process.env.OME_SIGNATURE_SECRET || 'colourstream-signature-key';
16+
return crypto.createHmac('sha1', secret).update(streamKey).digest('hex');
17+
}
18+
*/
19+
20+
/**
21+
* OvenMediaEngine Webhook for validating stream keys
22+
* For details see: https://airensoft.gitbook.io/ovenmediaengine/access-control/admission-webhooks
23+
*/
24+
router.post('/admission', async (req: Request, res: Response) => {
25+
try {
26+
const body = req.body;
27+
logger.info('AdmissionWebhook received request', { body });
28+
29+
// Protocol and URL analysis
30+
if (
31+
body.request &&
32+
body.request.url &&
33+
body.request.direction === 'incoming' &&
34+
body.request.status === 'opening'
35+
) {
36+
const request = body.request;
37+
const url = new URL(request.url);
38+
const pathParts = url.pathname.split('/');
39+
const streamKey = pathParts[pathParts.length - 1];
40+
41+
logger.info('Processing stream key', { streamKey });
42+
43+
// Development mode bypass - allow any stream key
44+
if (process.env.NODE_ENV !== 'production') {
45+
logger.warn('DEVELOPMENT MODE: Allowing any stream key for testing', { streamKey });
46+
47+
return res.json({
48+
allowed: true,
49+
new_url: request.url,
50+
lifetime: 3600,
51+
reason: 'Development mode - all streams allowed'
52+
});
53+
}
54+
55+
// Find an active room with this stream key
56+
const room = await prisma.room.findFirst({
57+
where: {
58+
streamKey: streamKey,
59+
expiryDate: {
60+
gt: new Date()
61+
}
62+
}
63+
});
64+
65+
if (!room) {
66+
logger.warn('Stream key not found in database', { streamKey });
67+
return res.json({
68+
allowed: false,
69+
reason: 'Invalid stream key'
70+
});
71+
}
72+
73+
logger.info('Valid stream key for room', { roomId: room.id, streamKey });
74+
75+
return res.json({
76+
allowed: true,
77+
new_url: request.url
78+
});
79+
} else if (body.request && body.request.status === 'closing') {
80+
// Stream is closing - just acknowledge
81+
return res.json({ allowed: true });
82+
} else {
83+
logger.warn('Invalid webhook request format', { body });
84+
return res.status(400).json({
85+
allowed: false,
86+
reason: 'Invalid request format'
87+
});
88+
}
89+
} catch (error) {
90+
logger.error('Error in admission webhook', { error });
91+
return res.status(500).json({
92+
allowed: false,
93+
reason: 'Internal server error'
94+
});
95+
}
96+
});
97+
98+
export default router;

global.env.template

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ BASE_PATH=/api
2424
OME_LIVE_DOMAIN=live.colourstream.example.com
2525
OME_VIDEO_DOMAIN=video.colourstream.example.com
2626
OME_API_ACCESS_TOKEN=your_ome_api_token_here
27+
OME_WEBHOOK_SECRET=your_ome_webhook_secret_here
2728

2829
# MiroTalk Configuration
2930
HOST_PROTECTED=true

ovenmediaengine/origin_conf/Server.xml

+10
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@
119119
</TLS>
120120
</Host>
121121

122+
<AdmissionWebhooks>
123+
<ControlServerUrl>http://backend:5001/api/ome-webhook/admission</ControlServerUrl>
124+
<SecretKey>${env:OME_WEBHOOK_SECRET:}</SecretKey>
125+
<Timeout>3000</Timeout>
126+
<Enables>
127+
<Providers>rtmp,webrtc,srt</Providers>
128+
<Publishers>webrtc,llhls,thumbnail</Publishers>
129+
</Enables>
130+
</AdmissionWebhooks>
131+
122132
<CrossDomains>
123133
<Url>*</Url>
124134
</CrossDomains>

0 commit comments

Comments
 (0)