@@ -15,13 +15,16 @@ limitations under the License.
1515*/
1616
1717import {
18- Bridge , BridgeBlocker , PrometheusMetrics , StateLookup ,
18+ Bridge , BridgeBlocker , PrometheusMetrics , StateLookup , MediaProxy ,
1919 Logger , Intent , UserMembership , WeakEvent , PresenceEvent ,
2020 AppService , AppServiceRegistration , UserActivityState , UserActivityTracker ,
21- UserActivityTrackerConfig , MembershipQueue , PowerLevelContent , StateLookupEvent } from "matrix-appservice-bridge" ;
21+ UserActivityTrackerConfig , MembershipQueue , PowerLevelContent , StateLookupEvent ,
22+ } from "matrix-appservice-bridge" ;
2223import { Gauge , Counter } from "prom-client" ;
2324import * as path from "path" ;
25+ import * as fs from "fs" ;
2426import * as randomstring from "randomstring" ;
27+ import { webcrypto } from "node:crypto" ;
2528import { WebClient } from "@slack/web-api" ;
2629import { IConfig , CACHING_DEFAULTS } from "./IConfig" ;
2730import { OAuth2 } from "./OAuth2" ;
@@ -148,6 +151,8 @@ export class Main {
148151 public slackRtm ?: SlackRTMHandler ;
149152 private slackHookHandler ?: SlackHookHandler ;
150153
154+ public mediaProxy ?: MediaProxy ;
155+
151156 private provisioner : Provisioner ;
152157
153158 private bridgeBlocker ?: BridgeBlocker ;
@@ -333,6 +338,22 @@ export class Main {
333338 ) ;
334339 }
335340
341+ private async initialiseMediaProxy ( config : IConfig [ 'mediaProxy' ] ) : Promise < void > {
342+ const jwk = JSON . parse ( fs . readFileSync ( config . signingKeyPath , "utf8" ) . toString ( ) ) ;
343+ const signingKey = await webcrypto . subtle . importKey ( 'jwk' , jwk , {
344+ name : 'HMAC' ,
345+ hash : 'SHA-512' ,
346+ } , true , [ 'sign' , 'verify' ] ) ;
347+ const publicUrl = new URL ( config . publicUrl ) ;
348+
349+ this . mediaProxy = new MediaProxy ( {
350+ publicUrl,
351+ signingKey,
352+ ttl : config . ttlSeconds * 1000
353+ } , this . bridge . getIntent ( ) . matrixClient ) ;
354+ await this . mediaProxy . start ( config . bindPort ) ;
355+ }
356+
336357 public teamIsUsingRtm ( teamId : string ) : boolean {
337358 return ( this . slackRtm !== undefined ) && this . slackRtm . teamIsUsingRtm ( teamId ) ;
338359 }
@@ -1142,6 +1163,14 @@ export class Main {
11421163 path : "/ready" ,
11431164 } ) ;
11441165
1166+ if ( this . config . mediaProxy ) {
1167+ await this . initialiseMediaProxy ( this . config . mediaProxy ) . catch ( err => {
1168+ throw Error ( `Failed to start Media Proxy: ${ err } ` ) ;
1169+ } ) ;
1170+ } else {
1171+ log . warn ( "Media Proxy not configured: media bridging to Slack won't work on servers requiring authenticated media (default since Synapse v1.120.0)" ) ;
1172+ }
1173+
11451174
11461175 await this . pingBridge ( ) ;
11471176
0 commit comments