Improve video access security by adding signed URL support from Bunny.net
Implements signed URLs for secure video and thumbnail delivery using the BUNNY_SECURITY_KEY environment variable in bunny.ts. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 50814a1e-92e4-4968-856f-7bc7eedf5e8f Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/50814a1e-92e4-4968-856f-7bc7eedf5e8f/3tWpY1N
This commit is contained in:
parent
16cf7dd5a8
commit
f286638b19
@ -1,4 +1,5 @@
|
|||||||
import { type Video, type InsertVideo } from "@shared/schema";
|
import { type Video, type InsertVideo } from "@shared/schema";
|
||||||
|
import crypto from 'crypto';
|
||||||
|
|
||||||
interface BunnyVideo {
|
interface BunnyVideo {
|
||||||
guid: string;
|
guid: string;
|
||||||
@ -22,11 +23,13 @@ export class BunnyService {
|
|||||||
private apiKey: string;
|
private apiKey: string;
|
||||||
private libraryId: string;
|
private libraryId: string;
|
||||||
private hostname: string;
|
private hostname: string;
|
||||||
|
private securityKey: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.apiKey = process.env.BUNNY_API_KEY!;
|
this.apiKey = process.env.BUNNY_API_KEY!;
|
||||||
this.libraryId = process.env.BUNNY_LIBRARY_ID!;
|
this.libraryId = process.env.BUNNY_LIBRARY_ID!;
|
||||||
this.hostname = process.env.BUNNY_HOSTNAME!;
|
this.hostname = process.env.BUNNY_HOSTNAME!;
|
||||||
|
this.securityKey = process.env.BUNNY_SECURITY_KEY || ''; // CDN security key for signing URLs
|
||||||
|
|
||||||
if (!this.apiKey || !this.libraryId || !this.hostname) {
|
if (!this.apiKey || !this.libraryId || !this.hostname) {
|
||||||
throw new Error("Missing Bunny.net configuration");
|
throw new Error("Missing Bunny.net configuration");
|
||||||
@ -51,18 +54,32 @@ export class BunnyService {
|
|||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private generateSignedUrl(path: string, expiryHours: number = 1): string {
|
||||||
|
if (!this.securityKey) {
|
||||||
|
// If no security key, return iframe embed as fallback
|
||||||
|
const videoId = path.split('/')[1];
|
||||||
|
return `https://iframe.mediadelivery.net/embed/${this.libraryId}/${videoId}?controls=true&autoplay=false`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const expireTimestamp = Math.floor(Date.now() / 1000) + (expiryHours * 3600);
|
||||||
|
const tokenContent = `${this.securityKey}${path}${expireTimestamp}`;
|
||||||
|
|
||||||
|
const hash = crypto.createHash('md5').update(tokenContent).digest();
|
||||||
|
const token = Buffer.from(hash).toString('base64')
|
||||||
|
.replace(/\+/g, '-')
|
||||||
|
.replace(/\//g, '_')
|
||||||
|
.replace(/=/g, '');
|
||||||
|
|
||||||
|
return `https://${this.hostname}${path}?token=${token}&expires=${expireTimestamp}`;
|
||||||
|
}
|
||||||
|
|
||||||
private bunnyVideoToVideo(bunnyVideo: BunnyVideo): Video {
|
private bunnyVideoToVideo(bunnyVideo: BunnyVideo): Video {
|
||||||
// Use proxy endpoint for thumbnails to handle private access
|
// Generate signed URLs for private video access
|
||||||
const thumbnailUrl = `/thumbnail/${bunnyVideo.guid}`;
|
const videoPath = `/${bunnyVideo.guid}/playlist.m3u8`;
|
||||||
|
const thumbnailPath = `/${bunnyVideo.guid}/${bunnyVideo.thumbnailFileName || 'thumbnail.jpg'}`;
|
||||||
|
|
||||||
// Try direct CDN URL first - some videos might be accessible
|
const videoUrl = this.generateSignedUrl(videoPath);
|
||||||
const directUrl = `https://${this.hostname}/${bunnyVideo.guid}/playlist.m3u8`;
|
const thumbnailUrl = this.generateSignedUrl(thumbnailPath);
|
||||||
|
|
||||||
// Fallback iframe embed for private videos
|
|
||||||
const iframeUrl = `https://iframe.mediadelivery.net/embed/${this.libraryId}/${bunnyVideo.guid}?controls=true&autoplay=false`;
|
|
||||||
|
|
||||||
// Use direct URL for HLS streaming
|
|
||||||
const videoUrl = directUrl;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: bunnyVideo.guid,
|
id: bunnyVideo.guid,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user