From 237b08fb6c480b42e33385068f994a8828e87ce4 Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Wed, 13 May 2026 20:25:46 -0600 Subject: [PATCH 1/6] fix opengraph returning back full video when a cropped version exists --- app/server/fireshare/templates/metadata.html | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/server/fireshare/templates/metadata.html b/app/server/fireshare/templates/metadata.html index bb368ee2..0cd430e5 100644 --- a/app/server/fireshare/templates/metadata.html +++ b/app/server/fireshare/templates/metadata.html @@ -20,8 +20,13 @@ {% if not password_protected %} - - + {% if video.info.has_crop %} + {% set og_video_url = domain + "/_content/derived/" + video.video_id + "/" + video.video_id + "-cropped.mp4" %} + {% else %} + {% set og_video_url = domain + "/_content/video/" + video.video_id + video.extension %} + {% endif %} + + {% endif %} From 8f31f45acc472fed696daa01555f228f36dbfa9e Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Wed, 13 May 2026 20:28:50 -0600 Subject: [PATCH 2/6] use nginx rather than metadata.html logic --- app/nginx/prod.conf | 8 +++++--- app/server/fireshare/templates/metadata.html | 9 ++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/nginx/prod.conf b/app/nginx/prod.conf index bb3fd08c..723e928b 100644 --- a/app/nginx/prod.conf +++ b/app/nginx/prod.conf @@ -113,7 +113,7 @@ http { add_header Cache-Control "public, max-age=31536000, immutable"; } - location /_content/video/ { + location ~ ^/_content/video/([\w-]+)(\.[^/]+)$ { auth_request /internal/video-auth; mp4; @@ -129,8 +129,10 @@ http { limit_rate_after 5m; - rewrite ^/_content/video/(.*)$ /$1 break; - root /processed/video_links/; + set $video_id $1; + set $video_ext $2; + root /processed/; + try_files /derived/$video_id/$video_id-cropped.mp4 /video_links/$video_id$video_ext =404; } location /_content/image/ { diff --git a/app/server/fireshare/templates/metadata.html b/app/server/fireshare/templates/metadata.html index 0cd430e5..bb368ee2 100644 --- a/app/server/fireshare/templates/metadata.html +++ b/app/server/fireshare/templates/metadata.html @@ -20,13 +20,8 @@ {% if not password_protected %} - {% if video.info.has_crop %} - {% set og_video_url = domain + "/_content/derived/" + video.video_id + "/" + video.video_id + "-cropped.mp4" %} - {% else %} - {% set og_video_url = domain + "/_content/video/" + video.video_id + video.extension %} - {% endif %} - - + + {% endif %} From a7897778308d7808639188d11164aa2478ab18c0 Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Wed, 13 May 2026 20:32:47 -0600 Subject: [PATCH 3/6] fix suggested videos not working when in the /games/* pages --- app/client/src/views/GameVideos.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/client/src/views/GameVideos.js b/app/client/src/views/GameVideos.js index 08332ba8..7eb70460 100644 --- a/app/client/src/views/GameVideos.js +++ b/app/client/src/views/GameVideos.js @@ -460,6 +460,7 @@ const GameVideos = ({ cardSize, authenticated, searchText }) => { feedView={false} authenticated={authenticated} updateCallback={handleVideoUpdate} + onSuggestionSelect={(id) => setVideoModal({ open: true, id })} onNext={() => { const videoItems = sortedMedia.filter((m) => m.type === 'video').map((m) => m.item) const i = videoItems.findIndex((v) => v.video_id === videoModal.id) From e129aff717d9e4ccd42b85b54420dedc08868d67 Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Wed, 13 May 2026 20:46:39 -0600 Subject: [PATCH 4/6] add a video raw route for authed users which returns back the exact video by id --- app/client/src/common/utils.js | 17 ++++++----- app/client/src/components/modal/VideoModal.js | 3 +- app/nginx/prod.conf | 30 +++++++++++++++++++ app/server/fireshare/api/video.py | 8 +++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/app/client/src/common/utils.js b/app/client/src/common/utils.js index 71aa8506..b896f5f1 100644 --- a/app/client/src/common/utils.js +++ b/app/client/src/common/utils.js @@ -206,7 +206,7 @@ export const getImageUrl = (imageId) => { * @param {string} extension - Video file extension (e.g., '.mp4', '.mkv') * @returns {Array} Array of video sources for Video.js */ -export const getVideoSources = (videoId, videoInfo, extension) => { +export const getVideoSources = (videoId, videoInfo, extension, { forceOriginal = false } = {}) => { const sources = [] const URL = getUrl() const SERVED_BY = getServedBy() @@ -216,12 +216,15 @@ export const getVideoSources = (videoId, videoInfo, extension) => { const has1080p = videoInfo?.has_1080p const hasCrop = videoInfo?.has_crop - // When a cropped version exists, point "Source" at the cropped file instead of the original - const sourceUrl = hasCrop - ? SERVED_BY === 'nginx' - ? `${URL}/_content/derived/${videoId}/${videoId}-cropped.mp4` - : `${URL}/api/video?id=${videoId}&quality=cropped` - : getVideoUrl(videoId, 'original', extension) + // forceOriginal bypasses the crop — used by the editor so admins see the full uncut video + const sourceUrl = + forceOriginal && SERVED_BY === 'nginx' + ? `${URL}/_content/video-raw/${videoId}${extension}` + : hasCrop + ? SERVED_BY === 'nginx' + ? `${URL}/_content/derived/${videoId}/${videoId}-cropped.mp4` + : `${URL}/api/video?id=${videoId}&quality=cropped` + : getVideoUrl(videoId, 'original', extension) sources.push({ src: sourceUrl, diff --git a/app/client/src/components/modal/VideoModal.js b/app/client/src/components/modal/VideoModal.js index 62a0102e..058cda37 100644 --- a/app/client/src/components/modal/VideoModal.js +++ b/app/client/src/components/modal/VideoModal.js @@ -778,8 +778,9 @@ const VideoModal = ({ key={`${vid.video_id}-${playerVersion}`} sources={getVideoSources( vid.video_id, - editMode ? { ...vid?.info, has_crop: false } : vid?.info, + vid?.info, vid.extension, + { forceOriginal: editMode }, )} poster={getPosterUrl()} autoplay={autoplay} diff --git a/app/nginx/prod.conf b/app/nginx/prod.conf index 723e928b..4bf5ed33 100644 --- a/app/nginx/prod.conf +++ b/app/nginx/prod.conf @@ -99,6 +99,14 @@ http { proxy_set_header Cookie $http_cookie; } + location = /internal/video-auth-admin { + internal; + proxy_pass http://127.0.0.1:5000/api/video/nginx-auth-admin; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_set_header Cookie $http_cookie; + } + location ~ ^/_content/derived/([^/]+)/thumbnail$ { set $video_id $1; root /processed/; @@ -135,6 +143,28 @@ http { try_files /derived/$video_id/$video_id-cropped.mp4 /video_links/$video_id$video_ext =404; } + location ~ ^/_content/video-raw/([\w-]+)(\.[^/]+)$ { + auth_request /internal/video-auth-admin; + + mp4; + mp4_buffer_size 2m; + mp4_max_buffer_size 50m; + + directio 4m; + directio_alignment 512; + output_buffers 2 2m; + + add_header Cache-Control "no-store"; + add_header Accept-Ranges bytes; + + limit_rate_after 5m; + + set $video_id $1; + set $video_ext $2; + root /processed/; + try_files /video_links/$video_id$video_ext =404; + } + location /_content/image/ { add_header Cache-Control "public, max-age=86400"; rewrite ^/_content/image/(.*)$ /$1 break; diff --git a/app/server/fireshare/api/video.py b/app/server/fireshare/api/video.py index e0a1e4d7..6008cee6 100644 --- a/app/server/fireshare/api/video.py +++ b/app/server/fireshare/api/video.py @@ -787,6 +787,14 @@ def unlock_video(video_id): return jsonify({"error": "Incorrect password"}), 403 +@api.route('/api/video/nginx-auth-admin') +def nginx_video_auth_admin(): + """Internal endpoint called by nginx auth_request to gate the raw (uncropped) video path.""" + if current_user.is_authenticated: + return '', 200 + return '', 403 + + @api.route('/api/video/nginx-auth') def nginx_video_auth(): """Internal endpoint called by nginx auth_request to gate password-protected video files.""" From db22c9f7a8d561c7272c75f5565e7e675b82a644 Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Sat, 16 May 2026 10:24:51 -0600 Subject: [PATCH 5/6] nginx's sendfile on directive fails with EINVAL (22: Invalid argument) when serving files through symlinks on certain filesystems --- app/nginx/prod.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/nginx/prod.conf b/app/nginx/prod.conf index 4bf5ed33..54cc7b28 100644 --- a/app/nginx/prod.conf +++ b/app/nginx/prod.conf @@ -124,6 +124,8 @@ http { location ~ ^/_content/video/([\w-]+)(\.[^/]+)$ { auth_request /internal/video-auth; + sendfile off; + mp4; mp4_buffer_size 2m; mp4_max_buffer_size 50m; @@ -146,6 +148,8 @@ http { location ~ ^/_content/video-raw/([\w-]+)(\.[^/]+)$ { auth_request /internal/video-auth-admin; + sendfile off; + mp4; mp4_buffer_size 2m; mp4_max_buffer_size 50m; @@ -166,6 +170,7 @@ http { } location /_content/image/ { + sendfile off; add_header Cache-Control "public, max-age=86400"; rewrite ^/_content/image/(.*)$ /$1 break; root /processed/image_links/; From 7129216cd6ae3dff23fda8a7cc2d75c722bd2ba8 Mon Sep 17 00:00:00 2001 From: Shane Israel Date: Sun, 17 May 2026 12:15:58 -0600 Subject: [PATCH 6/6] bump version --- app/client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/package.json b/app/client/package.json index b55ed73e..ba99922f 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -1,6 +1,6 @@ { "name": "fireshare", - "version": "1.6.10", + "version": "1.6.11", "private": true, "dependencies": { "@emotion/react": "^11.9.0",