Pre-release. This is a test build for Bulwark Lite. Not recommended for production. The latest Docker tag stays on 1.10.0. To try the server build, use ghcr.io/bulwarkmail/webmail:1.11.0-beta.2.
Bulwark Lite
bulwark-lite-1.11.0-beta.2.zip: unpack it on any static web host and set your JMAP server in config.json. The JMAP server must allow CORS from the webmail origin.
bulwark-lite-stalwart.zip: a Stalwart Application bundle that serves itself under the configured prefix (e.g. /webmail).
The Lite zips are attached once the Build Static Lite workflow finishes (a few minutes after publishing).
Changes since beta.1
Toasts for mail actions that had no feedback, plus an "email sent" toast after immediate sends
Toasts show again
Deep links resolve to the local instance
A staged attachment is kept until its upload finishes
After upgrade, you need to run php bin/console doctrine:migrations:migrate (or equivalent) as webserver user after upgrade.. If you are running a docker container, use sudo docker exec --user=www-data partdb php bin/console doctrine:migrations:migrate, or sudo -E inside the docker container, to ensure that the migrations are applied to the correct database.
Note
If you are using Part-DB it would be helpful if you fill out this short survey on your usage of Part-DB (Google Forms): https://forms.gle/Q15twx3YYq3qCNfe8
Part-DB 2.18.0
New features
Added generic AI client, that can be used for any OpenAI compatible LLM API (#1551)
Allow to specify a color for custom part states by @killecaptron in #1537
Retrieve and store stock levels from info providers for parts by @killecaptron in #1538
Allow to configure which field groups are exported to KiCad by @lukas-runge in #1533
Show DEFAULT_URI value in server info page
Report an AI provider error instead of ending the request with a 500 by @killecaptron in #1539
Added an debug_vars() twig functions in the twig label sandbox to list all available variables
Do not download non-downloadable attachments and improve handling changing URLs on attachment merge by @killecaptron in #1531
This release adds richer log controls, Telegram topic destinations, bulk container updates, retained logs, and project editor preferences.
It also improves update workflows, registry handling, UI behavior, and performance across projects, activity, and image updates.
Features
Added a stream label toggle for distinguishing STDOUT and STDERR in logs. (#3976, 4f10dee49f7a3c4b32a695cc9f05584403ea674d) β @kmendell
Added Telegram topic destinations for notifications. (#3978, e47164421a22b8a9f12714a923be566889d2cbe1) β @kmendell
Added a timestamp toggle to the log viewer controls. (#3979, 9fa57c867b1085a7142d7e755f87ddd9318b1a1d) β @kmendell
Added personal defaults for the project editor layout. (#3986, 67b34b9c032d8f56379ed60322839d39dc5af855) β @kmendell
Added bulk updates for selected containers. (#3971, 0365c6861d50ef5fc5aaf7f816e370955eadc398) β @mewajda
Skipped repeated per-message visibility reads and source lookups on the local activity stream. (#4105, 423cd549b74271f8a4b3992cf04e5920d6a06dc5) β @kmendell
Resolved GitOps Compose paths once per project list request. (#4106, f5d6f37dba1c9cab72271d6e9d183cbe1f7fd79e) β @kmendell
Enriched filtered project lists after pagination. (#4108, 92349aa97949e54ee2409a1c4a3c35758df60e8a) β @kmendell
Deduplicated and parallelized container tag checks. (#4109, 57812f8f0511e9f2d3f6b6fa17242da6db98d592) β @kmendell
Pre-release. This is a test build for Bulwark Lite. Not recommended for production. The latest Docker tag stays on 1.10.0. To try the server build, use ghcr.io/bulwarkmail/webmail:1.11.0-beta.1.
Bulwark Lite
Bulwark Lite is a static build of the webmail. It has no Node server: the browser talks to your JMAP server directly.
bulwark-lite-1.11.0-beta.1.zip: unpack it on any static web host (nginx, Caddy, S3, Pagesβ¦). Set your JMAP server in config.json. The JMAP server must allow CORS from the webmail origin.
bulwark-lite-stalwart.zip: a Stalwart Application bundle. Install it as an Application in Stalwart and it serves itself under the configured prefix (e.g. /webmail).
The Lite zips are attached once the Build Static Lite workflow finishes (a few minutes after publishing).
Please report problems with the Lite build in the issue tracker.
Also in this pre-release
New "Flat fields" theme
Icon set migrated from Lucide to Tabler Icons
Hardened Lite login, deep-link replay and settings gating
Device addresses can now be configured using a fully qualified domain name instead of an IPv4 address. UpSnap resolves regular hostnames through DNS and .local hostnames through mDNS before pinging, waking, shutting down, or putting a device to sleep.
Changelog
Others
9f05b1c: Docker - add line in compose for dbus if using fqdn with .local domain (#1772) (@invario)
b17b091: feature: Support use of FQDN resolution with DNS and mDNS (#1760) (@invario)
This release fixes six vulnerabilities reported by Jan Kahmen (turingpoint). Please update.
Mail: HTML mail could run script in the webmail origin. cid: references were rewritten to blob: URLs that kept the sender's Content-Type, and the reverse proxy skipped every security header β CSP included β on app paths whose last segment contains a dot, although the signed-in mail, calendar, contacts and files routes render there. Blob URLs are now retyped as inert, link clicks from the message frame are gated by scheme, and the proxy only skips headers for an explicit static-asset allowlist (GHSA-xvjh-v9c6-qcvc, thanks @kah-ja)
Auth: POST /api/auth/session and POST /api/auth/stalwart-context minted identity cookies without checking the supplied credentials against the JMAP server, so anyone could obtain a cookie for an arbitrary username and read that user's server-side settings. Credentials are now verified upstream before a cookie is issued: Basic credentials are bound to the account they authenticate, Bearer tokens to the session's username and identity. Deployments whose webmail container cannot reach the JMAP server no longer receive identity cookies, so cross-device settings sync stops working there (GHSA-wxcm-j4jc-9fxq, thanks @kah-ja)
Plugins: The /plugin-sandbox runtime trusted whichever window posted the first message, so a foreign site could window.open() it, post its own init, and run code under the route's unsafe-eval CSP in the app origin β with or without plugins enabled. The sandbox now only accepts its framing window, and the proxy refuses to serve the route outside an iframe or when plugins are disabled (GHSA-96cx-gx36-3g79, thanks @kah-ja)
Auth: Encrypted payloads now carry a purpose, so a WOPI editor access token can no longer be presented as a jmap_stalwart_ctx session cookie (GHSA-cqqx-mjcf-mh55, thanks @kah-ja)
Auth: Reject cross-site requests to /api/auth/*. A malicious page could POST the victim's browser into an attacker-controlled account (session fixation) (GHSA-qvr9-m8cq-7wvg, thanks @kah-ja)
Mail: Strip CR/LF and other control characters from the header values of generated read receipts. A crafted, RFC 2047-encoded subject could inject additional headers into the receipt (GHSA-w38p-hpqv-g89c, thanks @kah-ja)
Auth / Branding: Pin the resolved IP at connect time for stored custom JMAP endpoints and branding URLs too, closing the DNS-rebinding gap left after GHSA-24w9-8r42-8jwm
Features
Search: Global search across mail, contacts, calendar and files β query parser, ranking and cross-account providers, a search palette, and a search tab in the Pro shell with avatars, tinted icons and structured previews (#641); hits open through the owning login on every surface (#847)
Files: Office document editing through WOPI β Collabora Online, OnlyOffice and EuroOffice (#425); the demo Files drive ships office document fixtures and a word-processor icon
Calendar: Freely scrolling month, week and day views (#759), infinite scroll in the agenda view, and a setting to turn free scrolling off
Calendar: Recurring occurrences use Stalwart's synthetic ids (#140)
Calendar: Attendee free/busy via Principal/getAvailability
Calendar: Invitations and updates surface from CalendarEventNotification, and invitations are organized as the default ParticipantIdentity
Mail: Per-message HTML / plain-text toggle (#1022)
Mail: Share mail folders with other users via mail:share; share notifications appear as toasts
Mail: Search hits are highlighted with SearchSnippet/get
Mail: Pushes are resolved with Email/changes and Mailbox/changes deltas instead of refetching the list
Mail: Attachments show on list rows and open from there (#947, thanks @shukiv)
Mail: Filter advanced search by message size
Mail: Deleting a non-empty folder offers to delete its messages along with it
Mail: "Clear search when switching folders" setting (#852, thanks @shukiv)
CI: The test suite runs on every push and pull request (#647)
Dev: FileNode and blob round-trip in the mock JMAP server, and WOPI on the same-origin dev server
Changes
Docs: Installer section removed from the README and formatting cleaned up
Security policy: New vulnerability report email address
Fixes
Filters: Render the "Keep" action as fileinto "INBOX" (#1027)
Mail: List tagged mail from every account in the tag view, not just the selected folder's account (#1038)
Mail: Dragging a message out of the list could hang the tab when generated .eml file names collided (#1039)
Mail: Preserve label filtering during mailbox refreshes (#1017, thanks @ctaoist)
Mail: Hide body-embedded cid: parts declared as application/octet-stream from the attachment list (#1005, thanks @dealerweb)
Mail: Stop stretching images that carry their own max-width (#1034, thanks @shukiv), and let sender tables keep theirs (#790)
Mail: Refetch the body when JMAP truncates the displayed part instead of rendering a blank message (#928, thanks @hildebrandttk)
Mail: Auto-detect text direction in the read, print, plain-text, thread and .eml preview views (#663, thanks @shukiv)
Mail: Open search hits from shared folders in the right account (#923)
Mail: Collapse search hits for the same server object reached through several logins (#641)
Mail: Guard quick search against stale responses (#872, thanks @vj1235432)
Mail: Only show the unified mailbox section when it can be populated (#843), and stop it missing accounts that had not connected yet (#959, thanks @hildebrandttk)
Mail: Surface Email/set failures on delete and move (#956)
Mail: Report a missing archive mailbox instead of failing silently (#578), and archive shared-inbox mail into the owner's archive (#889)
Mail: Mark as spam from the viewer after the message left the list (#695)
Mail: Sort folders in the role assignment dropdown (#984)
Mail: Add the missing "Scheduled" folder role label (#495)
Mail: Wire the x shortcut to thread expansion (#683)
Mail: Keep the reading-mode toggle mounted so toolbar buttons stop jumping (#964)
Mail: Stop the batch toolbar hiding the message you just selected (#948, thanks @shukiv), keep rows in place when it opens, and drop the duplicate selection checkbox
Mail: Align the unread dot with the first line (#715, thanks @lucletoffe) and centre the sender avatar against the row (#953, thanks @shukiv)
Mail: Use Simplified Chinese for the selected-messages label (#786)
Send: Send from the address a message was delivered to (#991, thanks @rotterp)
Send: Set the answered flag when a reply goes out with a send delay (#985)
Composer: Upload attachments through the composing identity's account (#943)
Composer: Pro compose tabs default their From to the open mailbox (#990, thanks @rotterp)
Calendar: Jump to the day picked in the mini calendar (#1037, thanks @dealerweb)
Calendar: Wait for the JMAP client before loading the account principal, and recognise a refused principal read by its JMAP error type (#1036, thanks @dealerweb)
Calendar: Dedupe participants, resolve contact names across alias domains, and show the organizer's status (#986, thanks @ibayue)
Calendar: Linkify URLs in the event description (#968, thanks @lucletoffe)
Calendar: Normalize task progress states (#994, thanks @mulatta) and omit progressUpdated from the task completion payload (#958, thanks @sanitz)
Calendar: Preserve task alarms that the edit dialog does not show (#504)
Calendar: Report calendar clear failures instead of counting zero (#434)
Calendar: Make the iCal subscription size limit configurable and show the real error (#692)
Calendar: Paginate the event fetch on import so UID deduplication sees all existing events (#113)
Contacts: Strip the local-account prefix from address-book ids on contact update (#1043)
Contacts: Set name.full on all write paths so vCards carry the mandatory FN (#430)
Contacts: Create new contacts in the selected address book (#940, thanks @ponchofiesta)
Accounts: Detect HTTP/2 from the initial navigation timing so accounts are not capped at five (#1003, thanks @lucamzanon)
Auth: Reject wrong passwords server-side so the browser never shows its Basic Auth dialog (#969)
Auth: Stop retrying token refreshes that fail permanently (#972)
Auth: Normalize the OAuth discovery base so a session JMAP_SERVER_URL refreshes (#971, thanks @thejdubb02)
Auth: Use the selected server's issuer for SSO discovery (#952)
Auth: Retry the JMAP session fetch when a redirect drops the auth header (#892)
Auth: Drop max_age=0 from OIDC re-authentication requests (#938)
Auth: Require a session for the translate API (#903)
Mobile: Keep the actions panel below the status bar and pad attachment preview overlays for the iOS PWA safe area (#936)
Mobile: Render plain-text-only mail as text in the thread view (#489)
Mobile: Stop the More menu flashing open when a message is opened
Mobile: Dismiss the search panel once a search runs, open the folder drawer from the right in RTL (#944, thanks @shukiv), and keep the account switcher header on screen
PWA: Focus the client before navigating on notification click (#914, thanks @bitfactory-dk)
Push: Resolve push previews for shared and group mailboxes (#839)
Plugins: Allow sandbox chunk loading with CORS (#922, thanks @mulatta)
Plugins: Fail fast when the plugin storage database is blocked (#840)
Plugins: Refill missing managed bundles from the server (#636)
Plugins: Translations for plugins installed from the marketplace (#939, thanks @paulhenry46)
Settings: Index newer settings and the flat calendar toggles in the settings search
Settings: Invalidate the persisted update status after an upgrade
UI: Readable native <select> option lists in dark themes (#999)
i18n: German update (#1031, thanks @GyroGearl00se), "Forward as attachment" in more languages (#1016, thanks @dulinux), toolbar keys for nb and zh-TW (thanks @ibayue), and managed sidebar-app keys for zh-TW
i18n: Preserve locale cookie precedence and normalize Chinese proxy locale detection (thanks @kchuang1015); keep basePath when normalizing a Chinese Accept-Language
If your instance has many videos (local or federated) in the database, automatic migrations at next startup can take several minutes to finish. Plan for a short period of downtime during this upgrade
You need to manually execute a migration script after upgrading, while PeerTube is running and the database migration is complete (Migrations finished. New migration version schema: 1125 in PeerTube startup logs):
Comment API change: GET /api/v1/videos/{id}/comment-threads/{threadId} no longer returns the full comment tree
It now returns at most 10 direct replies per comment, down to 5 levels of nesting, by default
Each node in the returned tree now has a totalChildren field: compare it against children.length to know if replies were cut off
To fetch the rest, call the new endpoint: GET /api/v1/videos/{id}/comments/{commentId}/replies
If you're a plugin author: filter:api.video-thread-comments.list.result now sees only the truncated tree. Two new hooks, filter:api.video-comment-replies.list.params / .result, cover the new replies endpoint
v8.3.0-rc.1 introduced a bug in the upgrade script: the database backup step fails, which stops the upgrade. To upgrade from v8.3.0-rc.1 (classic installation):
Replace the upgrade script with the fixed one: cd /var/www/peertube/peertube-latest && sudo -H -u peertube curl -fsSL -o dist/scripts/upgrade.sh https://raw.githubusercontent.com/Chocobozzz/PeerTube/13c16ec0e80a16f3d98b6d0e2c2942c1c22513dc/server/scripts/upgrade.sh and then run the upgrade script as usual
Prevent a moderator to change user role. Thanks to Infinit3i for reporting it
Security hardening:
Time safe comparison when checking email verification strings
Prevent replaying an email check request
Don't leak account existence in the login endpoint
Introduce per-account rate limiting for abuse creation and comment creation
Add specific rate limit for "Confirm token" endpoints (reset password, verify email, confirm 2FA)
Introduce account login lockout, disabled by default, when there are too many failed attempts for a specific account across multiple IPs. An email is sent to the account owner when the account login is locked
filter:api.video-comment-replies.list.params and filter:api.video-comment-replies.list.result for the new /api/v1/videos/{id}/comments/{commentId}/replies comment endpoint
filter:api.video-watch.video-comment-replies.list.params and filter:api.video-watch.video-comment-replies.list.result when loading more replies of a comment
Add server plugin helpers:
peertubeHelpers.email.createJob({ ... }) to send an email
peertubeHelpers.videos.updateVideo({ ... }) to update video metadata
peertubeHelpers.videos.withFile({ ... }) to fetch a video file
Add server registration features to add automatic tags to videos or comments:
Add support for externalId when returning the user from an auth plugin, so it no longer needs to rely on the user's email to map the auth provider user to a PeerTube user
Add support for language when returning the user from an auth plugin
Expose req.cookies in the onLogout hook of the registerExternalAuth plugin helper
Features
π Add ability to subscribe to a remote blocklist to automatically mute/unmute accounts and servers π
New Moderation β Blocklist β Subscriptions admin page to add/remove blocklist subscriptions and see their sync state
Subscriptions are periodically refreshed, automatically muting/unmuting accounts and servers to match the remote list
Add a notification when a subscription sync mutes or unmutes accounts/servers
Expose your own instance's blocklist as a public log (blocklist.public_log.enabled configuration) so other admins can subscribe to it
π Add ability to subscribe to a remote watched words list, at both the platform and account level π
New Moderation β Watched words β Subscriptions admin page (instance-wide lists) and a matching subscriptions page in My library (per-account lists) to add/remove subscriptions and see their sync state and imported word count
Subscribed lists are periodically fetched and synchronized, automatically adding/removing words
Existing videos and comments are automatically re-tagged in the background when a subscribed list changes
π Admins can configure automatic tag policies to automatically block videos with a specific label π
Add ability for moderators to set an internal note on blocked videos
Send an email notification on account login from a new device #7737
Add bulk actions to add/remove videos in a playlist in My Videos
Add ability to bulk update some video metadata in My Videos and Admin Videos Overview
Add ability for users to retry video imports and filter them by State
Users can specify the default privacy for imported videos of a channel synchronization
Admins/moderators have a special channel picker when updating a video, so they can easily move any local video to another user's channel
Admins can cancel a local transcoding job
Allow users to choose the stats interval when listing their channels #7750
Add "Nobody can embed this video" setting to videos #7716
Improve local video search by allowing search through the first 1000 characters of descriptions #7612
Various SEO improvements, including a lastmod field in sitemap entries #7738
Support the host-meta well-known endpoint for remote subscriptions
Transcription widget:
Make the transcription widget header sticky to ensure the search function remains easily accessible
Don't auto-scroll transcription to the current segment after a manual user scroll
Add a "Sync with video" button after a manual user scroll to restore auto scroll
Restore transcription widget when refreshing the page
Improve podcast UX for channels:
Add a new "Podcast" page when managing a channel to display podcast URLs and information
The channel now accepts a "Public email" configuration so that the user's email address is not used
UI & accessibility:
Improve video stats styling and add quick date filters
Fade player when video is paused and user becomes inactive #7725
Underline badges that are filters or links
Improve video miniature accessibility when listing videos
Add ... suffix to actions that lead to another step
Improve notifier error message when server returns a 502 HTTP status
Hide non-existing metadata in the video watch page
Performance:
Faster comment rendering in the web browser
Limit the number of replies when fetching replies of a thread
Reduce number of rows returned by the user SQL query
Reduce server CPU usage when handling multiple lives with a large DVR window
Bug fixes
Stick live to 1x playback rate
Correctly cleanup lives on error
Prevent memory leak in the live segment sha store
Use correct CSS variable for big play button color #7733
Fix juddery video with variable fps input
Abort ffmpeg and HTTP requests on job timeout
Fix broken byte range request support for video download endpoints when throttling is enabled
Owner/admin can bypass the download enabled setting
Fix S3 base url with forced path style
Prevent duplicated thumbnails
Support federation to other fediverse platforms that do not support the shared inbox
More robust channel sync: don't miss videos on the next sync when the previous one was aborted because of a sync error
Fix videos feed sort for playlists and respect originallyPublishedAt for videos
Fix broken views on an instance if the GeoIP request is stuck
Don't notify again when a video is re-published
Allow admin to update the default "Prevent email from being sent to the user" behaviour when processing a registration request
Add all user attributes to audit logs on create/update #7695
Correctly hide the mobile message if disabled by the admin
If your instance has many videos (local or federated) in the database, automatic migrations at next startup can take several minutes to finish. Plan for a short period of downtime during this upgrade
You need to manually execute a migration script after upgrading, while PeerTube is running and the database migration is complete (Migrations finished. New migration version schema: 1125 in PeerTube startup logs):
Comment API change: GET /api/v1/videos/{id}/comment-threads/{threadId} no longer returns the full comment tree
It now returns at most 10 direct replies per comment, down to 5 levels of nesting, by default
Each node in the returned tree now has a totalChildren field: compare it against children.length to know if replies were cut off
To fetch the rest, call the new endpoint: GET /api/v1/videos/{id}/comments/{commentId}/replies
If you're a plugin author: filter:api.video-thread-comments.list.result now sees only the truncated tree. Two new hooks, filter:api.video-comment-replies.list.params / .result, cover the new replies endpoint
SECURITY
Security hardening:
Time safe comparison when checking email verification strings
Prevent replaying an email check request
Don't leak account existence in the login endpoint
Introduce per-account rate limiting for abuse creation and comment creation
Add specific rate limit for "Confirm token" endpoints (reset password, verify email, confirm 2FA)
Introduce account login lockout, disabled by default, when there are too many failed attempts for a specific account across multiple IPs. An email is sent to the account owner when the account login is locked
filter:api.video-comment-replies.list.params and filter:api.video-comment-replies.list.result for the new /api/v1/videos/{id}/comments/{commentId}/replies comment endpoint
filter:api.video-watch.video-comment-replies.list.params and filter:api.video-watch.video-comment-replies.list.result when loading more replies of a comment
Add server plugin helpers:
peertubeHelpers.email.createJob({ ... }) to send an email
peertubeHelpers.videos.updateVideo({ ... }) to update video metadata
peertubeHelpers.videos.withFile({ ... }) to fetch a video file
Add server registration features to add automatic tags to videos or comments:
Add support for externalId when returning the user from an auth plugin, so it no longer needs to rely on the user's email to map the auth provider user to a PeerTube user
Add support for language when returning the user from an auth plugin
Expose req.cookies in the onLogout hook of the registerExternalAuth plugin helper
Features
π Add ability to subscribe to a remote blocklist to automatically mute/unmute accounts and servers π
New Moderation β Blocklist β Subscriptions admin page to add/remove blocklist subscriptions and see their sync state
Subscriptions are periodically refreshed, automatically muting/unmuting accounts and servers to match the remote list
Add a notification when a subscription sync mutes or unmutes accounts/servers
Expose your own instance's blocklist as a public log (blocklist.public_log.enabled configuration) so other admins can subscribe to it
π Add ability to subscribe to a remote watched words list, at both the platform and account level π
New Moderation β Watched words β Subscriptions admin page (instance-wide lists) and a matching subscriptions page in My library (per-account lists) to add/remove subscriptions and see their sync state and imported word count
Subscribed lists are periodically fetched and synchronized, automatically adding/removing words
Existing videos and comments are automatically re-tagged in the background when a subscribed list changes
π Admins can configure automatic tag policies to automatically block videos with a specific label π
Add ability for moderators to set an internal note on blocked videos
Send an email notification on account login from a new device #7737
Add bulk actions to add/remove videos in a playlist in My Videos
Add ability to bulk update some video metadata in My Videos and Admin Videos Overview
Add ability for users to retry video imports and filter them by State
Users can specify the default privacy for imported videos of a channel synchronization
Admins/moderators have a special channel picker when updating a video, so they can easily move any local video to another user's channel
Admins can cancel a local transcoding job
Allow users to choose the stats interval when listing their channels #7750
Add "Nobody can embed this video" setting to videos #7716
Improve local video search by allowing search through the first 1000 characters of descriptions #7612
Various SEO improvements, including a lastmod field in sitemap entries #7738
Support the host-meta well-known endpoint for remote subscriptions
Transcription widget:
Make the transcription widget header sticky to ensure the search function remains easily accessible
Don't auto-scroll transcription to the current segment after a manual user scroll
Add a "Sync with video" button after a manual user scroll to restore auto scroll
Restore transcription widget when refreshing the page
Improve podcast UX for channels:
Add a new "Podcast" page when managing a channel to display podcast URLs and information
The channel now accepts a "Public email" configuration so that the user's email address is not used
UI & accessibility:
Improve video stats styling and add quick date filters
Fade player when video is paused and user becomes inactive #7725
Underline badges that are filters or links
Improve video miniature accessibility when listing videos
Add ... suffix to actions that lead to another step
Improve notifier error message when server returns a 502 HTTP status
Hide non-existing metadata in the video watch page
Performance:
Faster comment rendering in the web browser
Limit the number of replies when fetching replies of a thread
Reduce number of rows returned by the user SQL query
Reduce server CPU usage when handling multiple lives with a large DVR window
Bug fixes
Stick live to 1x playback rate
Correctly cleanup lives on error
Prevent memory leak in the live segment sha store
Use correct CSS variable for big play button color #7733
Fix juddery video with variable fps input
Abort ffmpeg and HTTP requests on job timeout
Fix broken byte range request support for video download endpoints when throttling is enabled
Owner/admin can bypass the download enabled setting
Fix S3 base url with forced path style
Prevent duplicated thumbnails
Support federation to other fediverse platforms that do not support the shared inbox
More robust channel sync: don't miss videos on the next sync when the previous one was aborted because of a sync error
Fix videos feed sort for playlists and respect originallyPublishedAt for videos
Fix broken views on an instance if the GeoIP request is stuck
Don't notify again when a video is re-published
Allow admin to update the default "Prevent email from being sent to the user" behaviour when processing a registration request
Add all user attributes to audit logs on create/update #7695
Correctly hide the mobile message if disabled by the admin
This release addresses vulnerabilities ranging from medium to high severity affecting PeerTube <= 8.2.3. Security hardening is also included.
critical Unauthenticated ActivityPub Actor URL/key rebinding enables local playlist takeover in PeerTube GHSA-37jf-59fg-9hpr. Thanks to D0HY30N for the report
medium Email-verification bypass via client-controlled isPendingEmail parameter GHSA-wp9f-cmff-p8r2. Thanks to Felipe Faria from BluckerTV for the report
Add more security checks and receiving remote views/downloads
Refuse to display channel stats using withStats query parameter to other users/anonymous
Remove NodeJS 20 support. Please upgrade to NodeJS 22 (>= 22.12) before upgrading PeerTube
The public access of /api/v1/accounts API endpoint is deprecated for privacy reasons and will be behind an admin/moderator auth access in PeerTube v9, planned for the end of 2027
iOS versions < 15.4 are not supported anymore
NGINX
Fix an important NGINX I/O issue when users download a video: 5fa456e
Please upgrade your NGINX configuration
Add video privacy tag for peertube_videos_total OTEL metric
Configuration
This section is not exhaustive
Add download.max_total_bytes_per_second and download.max_bytes_per_ip_per_second configuration keys to throttle video downloads.
These new keys help prevent instability when botnets download the entire PeerTube catalog
Increase the default refresh token lifetime oauth2.token_lifetime.refresh_token to 4 weeks (instead of 2 weeks)
Allow admins to configure the default state of the Automatically publish a replay when your live ends option #7414
Docker
The entire PeerTube configuration can be set using environment variables.
Keep in mind that environment variable configuration keys override web admin configuration
Introduce a new table filter component that is simpler to use
Default runner job route is the page that lists runner jobs
Clicking on a type/state tag automatically filters data for local/runner job states and types, follow states, registration states, and user roles
Add video tag information and filter when listing my videos
Add ability to bulk accept/reject registration requests
Add ability to filter users by role in users overview
Improve comments UI on mobile
Display subscribe button when subscription state is loaded
Add g p hotkeys to go to My playlists page
Improve videos overview for admins:
Add ability to filter videos by state
Add a mute badge if the video owner is muted by the instance
Add ability to filter out videos from muted accounts
Improve video blocks overview for admins:
Add video privacy column
Add bulk actions to unblock, switch to manual block or delete the selected videos
Add a mute badge if the video owner is muted by the instance
Improve abuses overview for admins:
Add bulk action to update internal note, mark as accepted/rejected, delete report, mute reporter/reportee, block/unblock the video, delete the video/comment
Add a mute badge if the reporter/reportee is muted by the instance
Improve comments overview for admins and users:
Clicking on account name filters comments
Add a mute badge if the account that commented the video is muted by the instance
Add ability to filter out comments from muted accounts
Performance:
Reduce SQL joins when loading a video from the database
Faster video SQL query to retrieve my videos
Faster video comments SQL queries for users that list comments on their videos
Faster video redundancies SQL queries
Reduce number of rows returned by video SQL queries
Reduce number of rows returned by comments SQL queries
Faster loading of My channels page
Add /about endpoint caching in the client to reduce unnecessary API calls
Process ActivityPub View and Download activities in parallel
Forward ActivityPub View using parallel broadcast
Support ActivityPub indexable field for actors
Expose runner and runner job queue OpenTelemetry metrics #7469
Prevent stale follows by periodically re-sending Follow ActivityPub requests to remote instances
Improve follows reliability algorithm to reject followers that have been consistently down for ~7 days
Add .m4b audio file support
Bug fixes
Fix plugin settings to display default values when not configured in the DB #7484
Fix actor host link in miniature instance dropdown if search index is disabled
Fix missing stream error handling in web video object storage proxy #7535
Fix caption filename overflow
Fix setting a thumbnail from a video that is stored in object storage
Fix instance redundancies pagination
Filter out non-text languages for captions
Increase lazy static files cache time (thumbnails, captions, actor avatars/banners, etc.) to 1 year
Correctly log uncaught exceptions or unhandled promise rejections in file logger
Prevent page scrolling when applying filters while browsing instance/account/channel videos
Fix infinite scroll when listing my followers
Handle errors when updating a video playlist
Fix download filename if the video contains non-Latin characters
Fix font colors in emails by only injecting custom admin colors when the default theme is light-beige or dark-brown, to prevent accessibility issues
Fix broken audio stream P2P for lives
Fix broke HLS transcoding on concurrent video privacy change
Don't unpause the player when clicking on a transcription segment
Fix table page navigation on registration action
More robust playlist thumbnails updater
Fix concurrency issue when writing live sha segments
Fix concurrency issue when uploading the same torrent filename
We have learned that the SQL injection vulnerability fixed in v8.1.6 has been exploited at scale since at least May 18, 2026 and so before the v8.1.6 release.
According to our investigation, the attacker exploited this SQL injection to generate a token for the root user and install the peertube-plugin-google-analytics-js plugin. This plugin imports a client script from hxxps://www.googie-anaiytics.com/jquery.ui.js that currently only logs a line in the web browser.
Actions taken by this release:
Automatically remove peertube-plugin-google-analytics-js in v8.1.8
Invalidate OAuth tokens in v8.1.8 (all users must log in again)
Add a new user.disable_root_auth config key to disable root token usage
Remove the plugin from the plugin registry
Actions taken by Framasoft:
Report googie-anaiytics.com to the registrar
Send a contact-form message to public PeerTube instances
Release additional versions if we observe other attack vectors
A CVE is being requested for the SQL injection
Actions admins must take:
Upgrade to v8.1.8 as soon as possible
Review newly created users and videos
Review your instance configuration, especially Configuration -> Customization -> JavaScript/CSS
Review installed plugins
Generate new tokens for your runners
If you cannot upgrade to v8.1.8:
Remove actor follows that contain the 20.240.202.159 URL:
Find them: SELECT * FROM "actorFollow" WHERE "url" LIKE '%20.240.202.159%'
Delete them: DELETE FROM "actorFollow" WHERE "id" = ...
Remove actors that contain a ' character in inboxUrl:
Find them: SELECT * FROM "actor" WHERE "inboxUrl" LIKE '%''%'
Delete them: DELETE FROM "actor" WHERE "id" = ...
Invalidate OAuth tokens: UPDATE "oAuthToken" SET "accessTokenExpiresAt" = NOW(), "refreshTokenExpiresAt" = NOW() WHERE "accessTokenExpiresAt" > NOW() OR "refreshTokenExpiresAt" > NOW()
Remove peertube-plugin-google-analytics-js from instance plugins
Disable federation in production.yaml by setting federation.enabled to false
We've been heads-down on this for months, and it's the change we're most excited to put in your hands: the redesigned Media Library is now the default for everyone in version 5.54.0.
This isn't a fresh coat of paint. We rebuilt the Media Library entirely around how people actually work with assets:
A completely revamped UI and UX β rebuilt from the ground up, with every screen, interaction and flow reworked to make managing your assets faster and far less fiddly
A folder tree that's always visible β no more breadcrumb archaeology to work out where you are
Uploads that don't hold you hostage β the progress panel stays out of your way and keeps running while you carry on working. Browse folders, edit an entry, leave the Media Library entirely; your upload keeps going, file by file, and tells you when it's done
Drag and drop that just works β drop assets onto any folder, in the list or the sidebar
Infinite scroll instead of pagination, so browsing a large library is finally a scroll rather than a chore
A details panel that doesn't get in your way β keep browsing the list while it's open
Bulk move and delete, plus AI-generated captions and alt text on Growth plans
Faster search, filters and sorting across your whole library, including now a sorting by file size
This release adds more flexible Git-based backups, improved vulnerability scanning, and expanded container and network visibility. It also fixes several authentication, permissions, deployment, and agent-related issues.
Backups and Git sync
Added Back up to Git sync mode and the ability to link existing projects to syncs β dadf87f93d9214dcd741c7ed503dfbf504c9df54 (#3932) (@kmendell)
Added configurable Git identity for pushes β 372f168940702645d63d34d0d6d80b742a7cb8da (#3935) (@kmendell)
Added an explicit environment-backup switch with a warning for project backups β 9ba395d5272ee5a3506682e61b9d1e06c4752f16 (#3937) (@kmendell)
Added support for binary files in Git backups and reused the editor file tree in the sync dialog β b80880fab4146572c02f071126d44751391031b9 (#3946) (@kmendell)
Preserved pre-deploy hooks and deployment options when importing GitOps syncs β da22a65fac881f7b6ff6048bae91399608d2eeab (#3952) (@kmendell)
Added S3 backup discovery and re-keyed volume backups to the recovery key β 02208f5cd24e028dfb0e2221305febbf3ee58837 (#3885) (@neurekadev)
Security and vulnerability scanning
Added CSV export to the security vulnerabilities table β af5538dde929bcc0e94053fd9ad4f3d263820da7 (#3936) (@kmendell)
Added a Fix available filter to the security vulnerabilities table β bf48ce6eebebca249607b02dcebb7df37079ab90 (#3944) (@kmendell)
Added vulnerability-count sorting to the images table β 9f89ceefbfcd6dd16581cf520b40d4b201d41801 (#3945) (@kmendell)
Added Trivy configuration and ignore-file settings for vulnerability scans β eff16eb5688e981b36847f55995d92990d02d30c (#3949) (@kmendell)
Added support for decimal CPU limits in Trivy scans β 02225a2d03529ef14ec7e4009f6f4b746feca2b6 (#3972) (@kmendell)
Containers and networks
Added subnet and gateway columns to the networks table β 146b4b9658d163c1290453203172b3cd286bdf3f (#3942) (@kmendell)
Added IPv6 addresses for containers and network members β 8345e5669ac2580a0b67385fbb9868ab6468e97e (#3957) (@kmendell)
Added optional IP ranges when creating networks β 38d3ed8c19faea20e4d9457395519196f074ce6a (#3959) (@kmendell)
Linked container overview volume and network counts to their respective tabs β f9988528d1a94e3440d2d295bfcd1c658aff1798 (#3958) (@kmendell)
Added support for downloading container logs β 9a83c5ac02944dc72c3fc4a39691eb8a1a832403 (#3960) (@kmendell)
Interface and settings
Added Shift-select range support to selectable tables β 472b01f5855c642afe192be448fe6339f6a6f74c (#3943) (@kmendell)
Clarified ntfy token authentication, required Matrix credentials, and cleaned up test menu labels β e68ab5ab4b8e3df7528b6f365846c383a49d381e (#3951) (@kmendell)
Updated theme colors and added support for inheriting theme colors β eee8a84bd5d467ca5f1f6dac4ca20768a377dcf4 (#3965) (@kmendell)
Authentication, permissions, and reliability
Surfaced OIDC and settings errors, allowed clearing the OIDC secret, and required it while OIDC is enabled β 70cf8a2596d32f2fd84685e5827bc79f95e2a3b7 (#3954) (@kmendell)
Hid the Automations tab and stopped job polling without jobs:manage permission β 94d6d79d533cd941d46d2cacaba391167d570c96 (#3963) (@kmendell)
Updated the legacy users.roles backfill to run only once β a4ae1a0f20463c7dc018f7bae4996e3cab2e34ac (#3964) (@kmendell)
Agents and edge tunnel
Fixed Docker snippets to use the port number from the agent address input β 2c34ade39db5f8686f73e7f76bb8df691f39cebc (#3955) (@tinkrynite)
Added missing job commands to the edge tunnel β 6af4589a12376f7fe40a9f1d8778fbbe6e5afbf4 (@kmendell)
This is a security release which addresses a vulnerability related to social login accounts, to prevent accounts from different services being potentially mis-matched.
Upgrading is strongly advised if the instance has ever used more than one third-party/social login option (including previously used options which are no longer active).
Thanks to Google and Ada Logics for the discovery and responsible disclosure of this issue.
Full List of Changes
Updated social logins to scope social account queries to social system.