Merge remote-tracking branch 'origin/master' into dev
CI / AMD64 Build (push) Waiting to run
CI / AMD64 Smoke Test (push) Blocked by required conditions
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions

Brings the go2rtc security fixes from #24658 to dev. Dev-specific changes
in the merge:
- frigate/config/env.py stays deleted; the environment_vars protection for
  GO2RTC_ALLOW_ARBITRARY_EXEC moves to apply_config_env_vars in
  frigate/util/env.py, so the value never reaches os.environ
- services.py imports substitute_frigate_vars from frigate.util.env and
  maps UnknownVariableError to the unknown variable message
- go2rtc stream tests patch dev's import-time exec override snapshot and
  its FRIGATE_* variable sources
- test_http_media.py keeps dev's _insert_recording helper; the one added
  on master replaced it and broke the dev tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Blake Blackshear
2026-10-14 14:30:11 -05:00
co-authored by Claude Opus 5.5
39 changed files with 1524 additions and 152 deletions
@@ -1116,6 +1116,7 @@
"title": "Create New User",
"desc": "Add a new user account and specify a role for access to areas of the Frigate UI.",
"usernameOnlyInclude": "Username may only include letters, numbers, . or _",
"usernameOnlyDots": "Username cannot contain only periods",
"confirmPassword": "Please confirm your password"
},
"deleteUser": {
@@ -91,7 +91,7 @@ export default function CameraInfoDialog({
open={showCameraInfoDialog}
onOpenChange={setShowCameraInfoDialog}
>
<DialogContent>
<DialogContent className="scrollbar-container max-h-[90dvh] overflow-y-auto">
<DialogHeader>
<DialogTitle className="smart-capitalize">
{t("cameras.info.cameraProbeInfo", {
@@ -82,6 +82,9 @@ export default function CreateUserDialog({
.min(1, t("users.dialog.form.usernameIsRequired"))
.regex(/^[A-Za-z0-9._]+$/, {
message: t("users.dialog.createUser.usernameOnlyInclude"),
})
.regex(/[^.]/, {
message: t("users.dialog.createUser.usernameOnlyDots"),
}),
password: z
.string()
+1 -1
View File
@@ -489,7 +489,7 @@ function MSEPlayer({
if (sb.buffered && sb.buffered.length) {
const end = sb.buffered.end(sb.buffered.length - 1) - 15;
const start = sb.buffered.start(0);
if (end > start) {
if (end - start > 1) {
sb.remove(start, end);
msRef.current?.setLiveSeekableRange(end, end + 15);
}
+3 -1
View File
@@ -33,6 +33,7 @@ import { ASPECT_WIDE_LAYOUT } from "@/types/record";
import { Skeleton } from "@/components/ui/skeleton";
import { isEqual } from "lodash";
import useSWR from "swr";
import { useIsAdmin } from "@/hooks/use-is-admin";
import { isDesktop, isMobile, isMobileOnly } from "react-device-detect";
import BirdseyeLivePlayer from "@/components/player/BirdseyeLivePlayer";
import LivePlayer from "@/components/player/LivePlayer";
@@ -133,6 +134,7 @@ export default function DraggableGridLayout({
}: DraggableGridLayoutProps) {
const { t } = useTranslation(["views/live"]);
const { data: config } = useSWR<FrigateConfig>("config");
const isAdmin = useIsAdmin();
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
const aspectRatios = useMemo(() => {
@@ -884,7 +886,7 @@ export default function DraggableGridLayout({
</Tooltip>
{!isEditMode && (
<>
{!fullscreen && (
{!fullscreen && isAdmin && (
<Tooltip>
<TooltipTrigger asChild>
<div