Compare commits

..

2 Commits

Author SHA1 Message Date
boolemancer
1685571406 fix(downloads): Use mediaSource.Id instead of item.Id in direct download URL (#1666)
Some checks are pending
🏗️ Build Apps / 🤖 Build Android APK (Phone) (push) Waiting to run
🏗️ Build Apps / 🤖 Build Android APK (TV) (push) Waiting to run
🏗️ Build Apps / 🍎 Build iOS IPA (Phone) (push) Waiting to run
🏗️ Build Apps / 🍎 Build iOS IPA (Phone - Unsigned) (push) Waiting to run
🏗️ Build Apps / 🍎 Build tvOS IPA (push) Waiting to run
🏗️ Build Apps / 🍎 Build tvOS IPA (Unsigned) (push) Waiting to run
🔒 Lockfile Consistency Check / 🔍 Check bun.lock and package.json consistency (push) Waiting to run
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (actions) (push) Waiting to run
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (javascript-typescript) (push) Waiting to run
🏷️🔀Merge Conflict Labeler / 🏷️ Labeling Merge Conflicts (push) Waiting to run
🌐 Translation Sync / sync-translations (push) Waiting to run
🚦 Security & Quality Gate / 📝 Validate PR Title (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Vulnerable Dependencies (push) Waiting to run
🚦 Security & Quality Gate / 🚑 Expo Doctor Check (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (check) (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (format) (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (lint) (push) Waiting to run
🚦 Security & Quality Gate / 🔍 Lint & Test (typecheck) (push) Waiting to run
🛡️ Trivy Security Scan / 🔎 Filesystem scan (push) Waiting to run
Co-authored-by: lance chant <13349722+lancechant@users.noreply.github.com>
Co-authored-by: Gauvain <contact@uruk.dev>
2026-06-08 14:59:29 +02:00
Gauvain
36ed7539a2 ci(security): add Trivy filesystem scan to code scanning (#1644) 2026-06-08 14:05:23 +02:00
7 changed files with 178 additions and 118 deletions

60
.github/workflows/trivy-scan.yml vendored Normal file
View File

@@ -0,0 +1,60 @@
name: 🛡️ Trivy Security Scan
# Filesystem scan (Streamyfin ships no container image): finds vulnerable dependencies,
# leaked secrets and misconfigurations, and reports them to GitHub code scanning.
# Runs post-merge + weekly (not on PRs — dependency-review already gates PRs, and SARIF
# upload needs a write token that fork PRs don't get).
on:
push:
branches: [develop, master]
schedule:
- cron: "50 7 * * 5" # Weekly, Friday 07:50 UTC
workflow_dispatch:
permissions:
contents: read
concurrency:
group: trivy-${{ github.ref }}
cancel-in-progress: true
jobs:
trivy:
name: 🔎 Filesystem scan
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write # upload SARIF to code scanning
steps:
- name: 📥 Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Rotate the DB cache weekly (matches the scheduled scan): cache hits within the week
# instead of a fresh immutable entry per run, still refreshing the DB every week.
- name: 🗓️ Compute weekly Trivy cache key
id: trivy-cache-key
run: echo "value=trivy-db-${{ runner.os }}-$(date -u +%G-%V)" >> "$GITHUB_OUTPUT"
- name: 💾 Cache Trivy vulnerability DB
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.cache/trivy
key: ${{ steps.trivy-cache-key.outputs.value }}
restore-keys: trivy-db-${{ runner.os }}-
- name: 🔎 Run Trivy filesystem scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: .
scanners: vuln,secret,misconfig
ignore-unfixed: true
severity: CRITICAL,HIGH
format: sarif
output: trivy-results.sarif
- name: 📤 Upload results to code scanning
uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
with:
sarif_file: trivy-results.sarif
category: trivy-fs

View File

@@ -4,8 +4,8 @@
"error_title": "Fehler",
"login_title": "Anmelden",
"login_to_title": "Anmelden bei",
"select_user": "Benutzer zum Anmelden auswählen",
"add_user_to_login": "Zum Anmelden einen Benutzer hinzufügen",
"select_user": "Select a user to log in",
"add_user_to_login": "Add a user to log in",
"add_user": "Add User",
"username_placeholder": "Benutzername",
"password_placeholder": "Passwort",
@@ -47,9 +47,9 @@
"add_account": "Konto hinzufügen",
"remove_account_description": "Hiermit werden die gespeicherten Zugangsdaten für {{username}} entfernt.",
"remove_server": "Remove Server",
"remove_server_description": "Dies wird {{server}} und alle gespeicherten Konten aus Ihrer Liste entfernen.",
"remove_server_description": "This will remove {{server}} and all saved accounts from your list.",
"select_your_server": "Select Your Server",
"add_server_to_get_started": "Füge einen Server hinzu, um loszulegen",
"add_server_to_get_started": "Add a server to get started",
"add_server": "Add Server",
"change_server": "Change Server"
},
@@ -95,7 +95,7 @@
"oops": "Ups!",
"error_message": "Etwas ist schiefgelaufen.\nBitte melde dich ab und wieder an.",
"continue_watching": "Weiterschauen",
"continue": "Weiter",
"continue": "Continue",
"next_up": "Als nächstes",
"continue_and_next_up": "\"Weiterschauen\" und \"Als Nächstes\"",
"recently_added_in": "Kürzlich hinzugefügt in {{libraryName}}",
@@ -121,9 +121,9 @@
"log_out_button": "Abmelden",
"switch_user": {
"title": "Switch User",
"account": "Benutzerkonto",
"account": "Account",
"switch_user": "Switch User on This Server",
"current": "aktuell"
"current": "current"
},
"categories": {
"title": "Kategorien"
@@ -143,9 +143,9 @@
"show_series_poster_on_episode": "Show Series Poster on Episodes",
"theme_music": "Theme Music",
"display_size": "Display Size",
"display_size_small": "Klein",
"display_size_default": "Standard",
"display_size_large": "Groß",
"display_size_small": "Small",
"display_size_default": "Default",
"display_size_large": "Large",
"display_size_extra_large": "Extra Large"
},
"network": {
@@ -203,8 +203,8 @@
"title": "Buffer Settings",
"cache_mode": "Cache Mode",
"cache_auto": "Auto",
"cache_yes": "Aktiviert",
"cache_no": "Deaktiviert",
"cache_yes": "Enabled",
"cache_no": "Disabled",
"buffer_duration": "Buffer Duration",
"max_cache_size": "Max Cache Size",
"max_backward_cache": "Max Backward Cache"
@@ -212,7 +212,7 @@
"vo_driver": {
"title": "Video Output",
"vo_mode": "VO Driver",
"gpu_next": "gpu-next (empfohlen)",
"gpu_next": "gpu-next (Recommended)",
"gpu": "gpu"
},
"gesture_controls": {
@@ -299,20 +299,20 @@
"hardware_decode": "Hardware Decoding",
"hardware_decode_description": "Hardwarebeschleunigung für Video Decoding verwenden. Deaktivieren wenn Wiedergabeprobleme auftreten.",
"opensubtitles_title": "OpenSubtitles",
"opensubtitles_hint": "Geben Sie Ihren OpenSubtitles API-Schlüssel ein, um die Client-seitige Untertitelsuche als Fallback zu aktivieren, wenn Ihr Jellyfin-Server keinen Untertitelanbieter konfiguriert hat.",
"opensubtitles_hint": "Enter your OpenSubtitles API key to enable client-side subtitle search as a fallback when your Jellyfin server doesn't have a subtitle provider configured.",
"opensubtitles_api_key": "API Key",
"opensubtitles_api_key_placeholder": "API-Schüssel eingeben ...",
"opensubtitles_get_key": "Holen Sie sich Ihren kostenlosen API-Schlüssel unter opensubtitles.com/de/consumers",
"opensubtitles_api_key_placeholder": "Enter API key...",
"opensubtitles_get_key": "Get your free API key at opensubtitles.com/en/consumers",
"mpv_subtitle_scale": "Subtitle Scale",
"mpv_subtitle_margin_y": "Vertical Margin",
"mpv_subtitle_align_x": "Horizontal Align",
"mpv_subtitle_align_y": "Vertical Align",
"align": {
"left": "Links",
"center": "Mittig",
"right": "Rechts",
"top": "Oben",
"bottom": "Unten"
"left": "Left",
"center": "Center",
"right": "Right",
"top": "Top",
"bottom": "Bottom"
}
},
"vlc_subtitles": {
@@ -466,10 +466,10 @@
"downloaded_songs_deleted": "Heruntergeladene Titel gelöscht",
"clear_all_cache": "Clear All Cache",
"clear_all_cache_confirm": "Clear All Cache?",
"clear_all_cache_confirm_desc": "Sind Sie sicher, dass Sie alle zwischengespeicherten Daten löschen möchten? Dadurch werden alle zwischengespeicherten Bilder, Musikdateien, Untertitel und Abfrage-Caches gelöscht. Ihre Einstellungen und Login-Sitzung werden beibehalten.",
"clear_all_cache_confirm_desc": "Are you sure you want to clear all cached data? This will clear all cached images, music files, subtitles, and query caches. Your settings and login session will be kept.",
"clear_all_cache_success": "Cache Cleared",
"clear_all_cache_success_desc": "Der Cache wurde erfolgreich geleert.",
"clear_all_cache_error_desc": "Beim Löschen des Caches ist ein Fehler aufgetreten."
"clear_all_cache_success_desc": "All cache has been cleared successfully.",
"clear_all_cache_error_desc": "An error occurred while clearing the cache."
},
"intro": {
"title": "Einführung",
@@ -495,18 +495,18 @@
"background_downloads_disabled": "Hintergrunddownloads deaktiviert"
},
"security": {
"title": "Sicherheit",
"title": "Security",
"inactivity_timeout": {
"title": "Inactivity Timeout",
"description": "Automatische Abmeldung nach Inaktivität",
"disabled": "Deaktiviert",
"1_minute": "1 Minute",
"5_minutes": "5 Minuten",
"15_minutes": "15 Minuten",
"30_minutes": "30 Minuten",
"1_hour": "1 Stunde",
"4_hours": "4 Stunden",
"24_hours": "24 Stunden"
"description": "Auto logout after inactivity",
"disabled": "Disabled",
"1_minute": "1 minute",
"5_minutes": "5 minutes",
"15_minutes": "15 minutes",
"30_minutes": "30 minutes",
"1_hour": "1 hour",
"4_hours": "4 hours",
"24_hours": "24 hours"
}
}
},
@@ -591,8 +591,8 @@
"back": "Zurück",
"continue": "Fortsetzen",
"verifying": "Verifiziere...",
"login": "Anmelden",
"refresh": "Aktualisieren"
"login": "Login",
"refresh": "Refresh"
},
"search": {
"search": "Suchen...",
@@ -641,7 +641,7 @@
"movies": "Filme",
"series": "Serien",
"boxsets": "Boxsets",
"playlists": "Wiedergabelisten",
"playlists": "Playlists",
"items": "Elemente"
},
"options": {
@@ -653,7 +653,7 @@
"cover": "Cover",
"show_titles": "Titel anzeigen",
"show_stats": "Statistiken anzeigen",
"options_title": "Optionen"
"options_title": "Options"
},
"filters": {
"genres": "Genres",
@@ -662,10 +662,10 @@
"filter_by": "Filtern nach",
"sort_order": "Sortierreihenfolge",
"tags": "Tags",
"all": "Alle",
"reset": "Zurücksetzen",
"asc": "Aufsteigend",
"desc": "Absteigend"
"all": "All",
"reset": "Reset",
"asc": "Ascending",
"desc": "Descending"
}
},
"favorites": {
@@ -702,34 +702,34 @@
"downloaded_file_yes": "Ja",
"downloaded_file_no": "Nein",
"downloaded_file_cancel": "Abbrechen",
"swipe_down_settings": "Für Einstellungen nach unten wischen",
"swipe_down_settings": "Swipe down for settings",
"ends_at": "Endet um {{time}}",
"search_subtitles": "Search Subtitles",
"subtitle_tracks": "Titel",
"subtitle_tracks": "Tracks",
"subtitle_search": "Search & Download",
"download": "Herunterladen",
"subtitle_download_hint": "Heruntergeladene Untertitel werden in Ihrer Bibliothek gespeichert",
"download": "Download",
"subtitle_download_hint": "Downloaded subtitles will be saved to your library",
"using_jellyfin_server": "Using Jellyfin Server",
"language": "Sprache",
"results": "Ergebnisse",
"searching": "Suche ...",
"search_failed": "Suche fehlgeschlagen",
"no_subtitle_provider": "Kein Untertitelanbieter auf dem Server konfiguriert",
"no_subtitles_found": "Keine Untertitel gefunden",
"add_opensubtitles_key_hint": "OpenSubtitles API-Schlüssel in den Einstellungen für Client-seitigen Fallback hinzufügen",
"settings": "Einstellungen",
"language": "Language",
"results": "Results",
"searching": "Searching...",
"search_failed": "Search failed",
"no_subtitle_provider": "No subtitle provider configured on server",
"no_subtitles_found": "No subtitles found",
"add_opensubtitles_key_hint": "Add OpenSubtitles API key in settings for client-side fallback",
"settings": "Settings",
"skip_intro": "Skip Intro",
"skip_credits": "Skip Credits",
"stopPlayback": "Stop Playback",
"stopPlayingTitle": "Wiedergabe von \"{{title}}\" beenden?",
"stopPlayingConfirm": "Bist du sicher, dass du die Wiedergabe beenden möchtest?",
"downloaded": "Heruntergeladen"
"stopPlayingTitle": "Stop playing \"{{title}}\"?",
"stopPlayingConfirm": "Are you sure you want to stop playback?",
"downloaded": "Downloaded"
},
"chapters": {
"title": "Kapitel",
"chapter_number": "Kapitel {{number}}",
"open": "Kapitel öffnen",
"close": "Kapitel schließen"
"title": "Chapters",
"chapter_number": "Chapter {{number}}",
"open": "Open chapters",
"close": "Close chapters"
},
"item_card": {
"next_up": "Als Nächstes",
@@ -754,20 +754,20 @@
"quality": "Qualität",
"audio": "Audio",
"subtitles": {
"label": "Untertitel",
"none": "Keine",
"tracks": "Titel"
"label": "Subtitle",
"none": "None",
"tracks": "Tracks"
},
"show_more": "Mehr anzeigen",
"show_less": "Weniger anzeigen",
"left": "übrig",
"left": "left",
"more_info": "More Info",
"director": "Regisseur*in",
"cast": "Besetzung",
"director": "Director",
"cast": "Cast",
"technical_details": "Technical Details",
"appeared_in": "Erschien in",
"movies": "Filme",
"shows": "Serien",
"movies": "Movies",
"shows": "Shows",
"could_not_load_item": "Konnte Element nicht laden",
"none": "Keine",
"download": {
@@ -782,9 +782,9 @@
"mark_played": "Mark as Watched",
"mark_unplayed": "Mark as Unwatched",
"resume_playback": "Resume Playback",
"resume_playback_description": "Möchtest du dort fortfahren, wo du aufgehört hast oder von Anfang anfangen?",
"resume_playback_description": "Do you want to continue where you left off or start from the beginning?",
"play_from_start": "Play from Start",
"continue_from": "Weiter ab {{time}}"
"continue_from": "Continue from {{time}}"
},
"live_tv": {
"next": "Nächste",
@@ -796,16 +796,16 @@
"sports": "Sport",
"for_kids": "Für Kinder",
"news": "Nachrichten",
"page_of": "Seite {{current}} von {{total}}",
"no_programs": "Keine Programme verfügbar",
"no_channels": "Keine Kanäle verfügbar",
"page_of": "Page {{current}} of {{total}}",
"no_programs": "No programs available",
"no_channels": "No channels available",
"tabs": {
"programs": "Programme",
"guide": "Führer",
"channels": "Kanäle",
"recordings": "Aufzeichnungen",
"schedule": "Planung",
"series": "Serien"
"programs": "Programs",
"guide": "Guide",
"channels": "Channels",
"recordings": "Recordings",
"schedule": "Schedule",
"series": "Series"
}
},
"jellyseerr": {
@@ -851,12 +851,12 @@
"decline": "Ablehnen",
"requested_by": "Angefragt von {{user}}",
"unknown_user": "Unbekannter Nutzer",
"select": "Auswählen",
"select": "Select",
"request_all": "Request All",
"request_seasons": "Request Seasons",
"select_seasons": "Select Seasons",
"request_selected": "Request Selected",
"n_selected": "{{count}} ausgewählt",
"n_selected": "{{count}} selected",
"toasts": {
"jellyseer_does_not_meet_requirements": "Seerr-Server erfüllt nicht die minimalen Versionsanforderungen. Bitte den Seerr-Server auf mindestens 2.0.0 aktualisieren.",
"jellyseerr_test_failed": "Seerr-Test fehlgeschlagen. Bitte erneut versuchen.",
@@ -877,7 +877,7 @@
"library": "Bibliothek",
"custom_links": "Links",
"favorites": "Favoriten",
"settings": "Einstellungen"
"settings": "Settings"
},
"music": {
"title": "Musik",
@@ -1004,34 +1004,34 @@
}
},
"companion_login": {
"title": "Mit TV koppeln",
"align_qr": "Den QR-Code innerhalb des Rahmens ausrichten",
"enter_code_manually": "Code manuell eingeben",
"pairing_enter_credentials": "Anmeldedaten für TV eingeben",
"pairing_code_label": "Kopplungscode",
"title": "Pair with TV",
"align_qr": "Align the QR code within the frame",
"enter_code_manually": "Enter code manually",
"pairing_enter_credentials": "Enter credentials for TV",
"pairing_code_label": "Pairing code",
"server": "Server",
"authorize_button": "Autorisieren",
"authorizing": "Autorisieren...",
"authorize_button": "Authorize",
"authorizing": "Authorizing...",
"scan_again": "Scan Again",
"done": "Fertig",
"done": "Done",
"success_title": "Authorization Sent",
"pairing_tv_connecting": "Der Fernseher verbindet sich mit Ihrem Konto",
"pairing_tv_connecting": "The TV is connecting to your account",
"error_title": "Authorization Failed",
"error_invalid_qr": "Ungültiger QR-Code. Bitte scannen Sie den TV-Kopplungscode.",
"error_generic": "Etwas ist schiefgelaufen. Bitte versuche es erneut.",
"error_permission_denied": "Kameraberechtigung erforderlich zum Scannen von QR-Codes.",
"login_as": "Als {{username}} anmelden?",
"on_server": "auf {{server}}",
"use_different_user": "Verwende einen anderen Benutzer",
"open_settings": "Einstellungen öffnen"
"error_invalid_qr": "Invalid QR code. Please scan the TV pairing code.",
"error_generic": "Something went wrong. Please try again.",
"error_permission_denied": "Camera permission is required to scan QR codes.",
"login_as": "Log in as {{username}}?",
"on_server": "on {{server}}",
"use_different_user": "Use a different user",
"open_settings": "Open Settings"
},
"pairing": {
"pair_with_phone": "Pair with Phone",
"pair_with_phone_title": "Login TV",
"pair_with_phone_description": "Scannen Sie den QR-Code, der auf Ihrem Fernseher angezeigt wird, um sich anzumelden",
"waiting_for_phone": "Warte auf Telefon...",
"scan_with_phone": "Scanne mit der Streamyfin-App auf deinem Handy",
"logging_in": "Anmeldung...",
"logging_in_description": "Verbinde mit deinem Server"
"pair_with_phone_description": "Scan the QR code displayed on your TV to log in",
"waiting_for_phone": "Waiting for phone...",
"scan_with_phone": "Scan with the Streamyfin app on your phone",
"logging_in": "Logging in...",
"logging_in_description": "Connecting to your server"
}
}

View File

@@ -378,7 +378,7 @@
"caching_title": "Almacenando en caché",
"caching_description": "Cachear automáticamente las próximas canciones para una reproducción más suave.",
"lookahead_enabled": "Activar el look-Ahead Cache",
"lookahead_count": "Songs to pre-cache",
"lookahead_count": "",
"max_cache_size": "Tamaño máximo del caché"
},
"plugins": {

View File

@@ -4,8 +4,8 @@
"error_title": "Errore",
"login_title": "Accesso",
"login_to_title": "Accedi a",
"select_user": "Seleziona un utente per accedere",
"add_user_to_login": "Aggiungi un utente per accedere",
"select_user": "Select a user to log in",
"add_user_to_login": "Add a user to log in",
"add_user": "Add User",
"username_placeholder": "Nome utente",
"password_placeholder": "Password",
@@ -33,7 +33,7 @@
"connect_button": "Connetti",
"previous_servers": "server precedente",
"clear_button": "Cancella",
"swipe_to_remove": "Scorri per rimuovere",
"swipe_to_remove": "Swipe to remove",
"search_for_local_servers": "Ricerca dei server locali",
"searching": "Cercando...",
"servers": "Server",
@@ -41,21 +41,21 @@
"session_expired": "Session Expired",
"please_login_again": "La tua sessione è scaduta. Si prega di eseguire nuovamente l'accesso.",
"remove_saved_login": "Remove Saved Login",
"remove_saved_login_description": "Questo rimuoverà le tue credenziali salvate per questo server. Dovrai inserire nuovamente il tuo nome utente e la password la prossima volta.",
"accounts_count": "Account {{count}}",
"remove_saved_login_description": "This will remove your saved credentials for this server. You'll need to enter your username and password again next time.",
"accounts_count": "{{count}} accounts",
"select_account": "Select Account",
"add_account": "Add Account",
"remove_account_description": "Questo rimuoverà le credenziali salvate per {{username}}.",
"remove_account_description": "This will remove the saved credentials for {{username}}.",
"remove_server": "Remove Server",
"remove_server_description": "Questo rimuove {{server}} e tutti gli account salvati dall'elenco.",
"remove_server_description": "This will remove {{server}} and all saved accounts from your list.",
"select_your_server": "Select Your Server",
"add_server_to_get_started": "Aggiungi un server per iniziare",
"add_server_to_get_started": "Add a server to get started",
"add_server": "Add Server",
"change_server": "Change Server"
},
"save_account": {
"title": "Save Account",
"save_for_later": "Salva questo account",
"save_for_later": "Save this account",
"security_option": "Security Option",
"no_protection": "No protection",
"no_protection_desc": "Quick login without authentication",
@@ -150,7 +150,7 @@
},
"network": {
"title": "Network",
"local_network": "Local network",
"local_network": "",
"auto_switch_enabled": "Auto-switch when at home",
"auto_switch_description": "Automatically switch to local URL when connected to home WiFi",
"local_url": "Local URL",

View File

@@ -123,7 +123,7 @@
"title": "Switch User",
"account": "Account",
"switch_user": "Switch User on This Server",
"current": "nåværende"
"current": "current"
},
"categories": {
"title": "Categories"

View File

@@ -346,7 +346,7 @@
"PORTRAIT_DOWN": "Portrait Down",
"LANDSCAPE": "Landscape",
"LANDSCAPE_LEFT": "Landscape Left",
"LANDSCAPE_RIGHT": "Landscape right",
"LANDSCAPE_RIGHT": "",
"OTHER": "Other",
"UNKNOWN": "Unknown"
},

View File

@@ -50,7 +50,7 @@ export const getDownloadUrl = async ({
if (maxBitrate.key === "Max" && !streamDetails?.mediaSource?.TranscodingUrl) {
console.log("Downloading item directly");
return {
url: `${api.basePath}/Items/${item.Id}/Download?api_key=${api.accessToken}`,
url: `${api.basePath}/Items/${mediaSource.Id}/Download?api_key=${api.accessToken}`,
mediaSource: streamDetails?.mediaSource ?? null,
};
}