Add input validation and shell argument escaping to prevent OS command
injection via the 'show' parameter in web/views/image.php. The parameter
is now validated against an allowlist and all values passed to exec()
are wrapped with escapeshellarg().
Also fix PHP operator precedence bug in shutdown.php where 'and' was
used instead of '&&', causing the 'when' parameter validation to not
work as intended.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The CURLE_PEER_FAILED_VERIFICATION constant may not be defined in all PHP curl versions. Use the numeric value (51) instead for better compatibility.
refs #TBD
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
Enable TLS peer certificate verification by default in all components that communicate over HTTPS. If SSL verification fails, log a warning and retry without verification to maintain backward compatibility with cameras using self-signed certificates.
Changes:
- C++ (zm_monitor_go2rtc.cpp): Enable SSL verification for all curl operations (3 locations)
- C++ (zm_monitor_rtsp2web.cpp): Enable SSL verification for all curl operations (3 locations)
- PHP (monitor_probe.php): Enable SSL verification with fallback logic
- Perl (Dahua.pm): Enable SSL verification with LWP::UserAgent
- Perl (TapoC520WS_ONVIF.pm): Enable SSL verification with retry logic in request methods
refs #TBD
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
Two issues caused monitors to stream from wrong channel:
1. In setChannelStream(), the expression `StreamChannel && SecondPath`
returned SecondPath (often empty) instead of StreamChannel. Now
correctly uses the monitor's configured StreamChannel.
2. In MonitorStream.start(), default channel only checked for
CameraDirectSecondary and defaulted everything else to Restream.
Now respects the actual StreamChannel setting.
Also improved fallback when selected option is disabled to find first
enabled option rather than always defaulting to Restream.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The manageChannelStream() function expected Path and Restream fields
in monitorData to enable/disable StreamChannel options, but these
fields were not being populated. This caused CameraDirectPrimary and
Restream options to always be disabled on the watch view.
Also updated SecondPath to use validJsStr() for proper escaping.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rename applies to Go2RTC, Janus, and RTSP2Web streaming options.
Update enum values from Primary/Secondary to Restream/CameraDirectPrimary/CameraDirectSecondary.
- Add db migration zm_update-1.37.79.sql to rename column and migrate data
- Update C++ enum StreamChannelOption and member stream_channel
- Update PHP getStreamChannelOptions() method
- Update all JavaScript references
- Auto-select CameraDirectPrimary when Restream option becomes disabled
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rename Janus-specific restream fields to be more generic since they are
now used by Go2RTC and RTSP2Web as well:
- Janus_Use_RTSP_Restream → Restream
- Janus_RTSP_User → RTSP_User
Update visibility logic so the Restream checkbox appears when RTSPServer
is enabled AND any streaming service (Janus, Go2RTC, or RTSP2Web) is
selected, rather than only when Janus is enabled.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Port() method now tries to extract the port from HTTP_HOST header
before falling back to SERVER_PORT, which can be incorrect with nginx
and PHP-FPM configurations. Also adds a sensible default (80/443) when
no port can be determined.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to view motion analysis frames on the watch view, similar
to the existing functionality in the zone edit view. Includes a toggle
button that switches between raw and analysis frames using the existing
MonitorStream.show_analyse_frames() method.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The edit button overlay on the montage view stream is now conditionally
displayed based on the user's edit permission for that monitor.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Add New Role button was not working because the AddNewRole
JavaScript function was missing from options.js. Added the handler
function following the same pattern as AddNewUser.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a User Roles system where roles define reusable permission templates.
When a user has a role assigned, the role provides fallback permissions
(user's direct permissions take precedence; role is used when user has 'None').
Database changes:
- Add User_Roles table with same permission fields as Users
- Add Role_Groups_Permissions table for per-role group overrides
- Add Role_Monitors_Permissions table for per-role monitor overrides
- Add RoleId foreign key to Users table
Permission resolution order:
1. User's direct Monitor/Group permissions (if not 'Inherit')
2. Role's Monitor/Group permissions (if user has role)
3. Role's base permission (if user's is 'None')
4. User's base permission (fallback)
Includes:
- PHP models: User_Role, Role_Group_Permission, Role_Monitor_Permission
- Role management UI in Options > Roles tab
- Role selector in user edit form
- REST API endpoints for roles CRUD
- Translation strings for en_gb
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated all three video creation functions in thumbnail overlays to
respect the user's mute preference stored in the zmWatchMuted cookie:
- go2rtc streams (video-stream element)
- RTSP2Web HLS streams
- MP4 video playback for recorded events
Default behavior remains muted unless user has explicitly set the
cookie to 'false' via the watch page volume controls.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Increase font size ~28% for better readability
- Add more spacing between video and status bar
- Enlarge LIVE dot with glow effect
- Make pulse animation more pronounced (scale 1.0 to 1.4)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add status bar below video with LIVE indicator for live streams
- Show pulsing red dot animation for live streams
- Display wall clock time that updates as recorded video plays
- Add event start time data attribute to console and events pages
- Hide status bar when no content to display
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Support go2rtc, RTSP2Web, and Janus streaming in thumbnail popups
- Separate still thumbnail logic from hover overlay streaming
- Still thumbnails use event snapshot when not decoding
- Hover overlay prioritizes live streaming over recorded video
- Refactor thumbnail JS into focused helper functions
- Fix video-stream.js path for dynamic import
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Go2rtc, rtsp2web, and janus work independently of ZM's decode/analyze
processes. Check for these external streaming methods before checking
Analysing/Decoding state to ensure live streaming is used when available.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 'PreviewRate' translation to 24 language files for the new
Preview Rate dropdown feature on the events page.
Note: Translations were generated via AI and may need review by
native speakers for accuracy.
Languages updated:
- Bosnian, Chinese (Simplified/Traditional/Big5), Czech, Danish
- Dutch, Estonian, French, German, Hebrew, Hungarian, Italian
- Japanese, Norwegian, Polish, Portuguese (BR), Romanian, Russian
- Spanish (ES/LA/AR), Swedish, Turkish
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a Preview Rate dropdown control that allows users to adjust the
playback speed of thumbnail hover preview videos on the events page.
- Add previewRateHtml() helper method to Filter class
- Add Preview Rate to simple_widget() filter bar with matching term styling
- Add getPreviewRate() and changePreviewRate() JS functions in skin.js
- Add helper functions in _monitor_filters.php for rate options
- Store selected rate in zmPreviewRate cookie (values: 100-1600 for 1x-16x)
- Add PreviewRate translation to en_gb.php
- Add CSS styling for preview rate control
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a monitor is not analyzing or decoding, the console thumbnail now
shows the most recent event's snapshot instead of attempting a live
stream. The hover overlay plays the event replay (with mp4 support if
available).
For active monitors with go2rtc enabled, the hover overlay now uses
go2rtc WebRTC streaming via the video-stream custom element, with a
3-second fallback to MJPEG if the connection fails.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix chained assignment creating implicit globals (shifted/ctrled/alted)
- Fix .done() callback executing immediately instead of on success
- Fix XOR operator (^) used instead of exponentiation in human_filesize()
- Fix invalid destructuring assignment in applyChosen()
- Fix implicit global creation in closeMbExtruder() call
- Add missing var declarations for runstate, length, modal variables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>