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 ;
0 commit comments