mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-06 03:51:14 +03:00
restrict debug replay UI entry points to admin users
This commit is contained in:
parent
ae987c0964
commit
ee73da655c
@ -130,9 +130,15 @@ export default function SearchResultActions({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
toast.error(t("dialog.toast.error", { error: errorMessage }), {
|
toast.error(
|
||||||
position: "top-center",
|
t("dialog.toast.error", {
|
||||||
});
|
ns: "views/replay",
|
||||||
|
error: errorMessage,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
position: "top-center",
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@ -206,7 +212,7 @@ export default function SearchResultActions({
|
|||||||
<span>{t("itemMenu.addTrigger.label")}</span>
|
<span>{t("itemMenu.addTrigger.label")}</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{searchResult.has_clip && (
|
{isAdmin && searchResult.has_clip && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
aria-label={t("itemMenu.debugReplay.aria")}
|
aria-label={t("itemMenu.debugReplay.aria")}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { FaFilm } from "react-icons/fa6";
|
import { FaFilm } from "react-icons/fa6";
|
||||||
|
|
||||||
type ActionsDropdownProps = {
|
type ActionsDropdownProps = {
|
||||||
onDebugReplayClick: () => void;
|
onDebugReplayClick?: () => void;
|
||||||
onExportClick: () => void;
|
onExportClick: () => void;
|
||||||
onShareTimestampClick: () => void;
|
onShareTimestampClick: () => void;
|
||||||
};
|
};
|
||||||
@ -42,9 +42,11 @@ export default function ActionsDropdown({
|
|||||||
<DropdownMenuItem onClick={onShareTimestampClick}>
|
<DropdownMenuItem onClick={onShareTimestampClick}>
|
||||||
{t("recording.shareTimestamp.label", { ns: "components/dialog" })}
|
{t("recording.shareTimestamp.label", { ns: "components/dialog" })}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem onClick={onDebugReplayClick}>
|
{onDebugReplayClick && (
|
||||||
{t("title", { ns: "views/replay" })}
|
<DropdownMenuItem onClick={onDebugReplayClick}>
|
||||||
</DropdownMenuItem>
|
{t("title", { ns: "views/replay" })}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { StartExportResponse } from "@/types/export";
|
import { StartExportResponse } from "@/types/export";
|
||||||
import { ShareTimestampContent } from "./ShareTimestampDialog";
|
import { ShareTimestampContent } from "./ShareTimestampDialog";
|
||||||
|
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||||
|
|
||||||
type DrawerMode =
|
type DrawerMode =
|
||||||
| "none"
|
| "none"
|
||||||
@ -109,6 +110,7 @@ export default function MobileReviewSettingsDrawer({
|
|||||||
"views/replay",
|
"views/replay",
|
||||||
"common",
|
"common",
|
||||||
]);
|
]);
|
||||||
|
const isAdmin = useIsAdmin();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [drawerMode, setDrawerMode] = useState<DrawerMode>("none");
|
const [drawerMode, setDrawerMode] = useState<DrawerMode>("none");
|
||||||
const [exportTab, setExportTab] = useState<ExportTab>("export");
|
const [exportTab, setExportTab] = useState<ExportTab>("export");
|
||||||
@ -388,7 +390,7 @@ export default function MobileReviewSettingsDrawer({
|
|||||||
{t("filter")}
|
{t("filter")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{features.includes("debug-replay") && (
|
{isAdmin && features.includes("debug-replay") && (
|
||||||
<Button
|
<Button
|
||||||
className="flex w-full items-center justify-center gap-2"
|
className="flex w-full items-center justify-center gap-2"
|
||||||
aria-label={t("title", { ns: "views/replay" })}
|
aria-label={t("title", { ns: "views/replay" })}
|
||||||
|
|||||||
@ -95,9 +95,15 @@ export default function DetailActionsMenu({
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
toast.error(t("dialog.toast.error", { error: errorMessage }), {
|
toast.error(
|
||||||
position: "top-center",
|
t("dialog.toast.error", {
|
||||||
});
|
ns: "views/replay",
|
||||||
|
error: errorMessage,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
position: "top-center",
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@ -229,7 +235,7 @@ export default function DetailActionsMenu({
|
|||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{search.has_clip && (
|
{isAdmin && search.has_clip && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
aria-label={t("itemMenu.debugReplay.aria")}
|
aria-label={t("itemMenu.debugReplay.aria")}
|
||||||
|
|||||||
@ -94,9 +94,15 @@ export default function EventMenu({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
toast.error(t("dialog.toast.error", { error: errorMessage }), {
|
toast.error(
|
||||||
position: "top-center",
|
t("dialog.toast.error", {
|
||||||
});
|
ns: "views/replay",
|
||||||
|
error: errorMessage,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
position: "top-center",
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@ -177,7 +183,7 @@ export default function EventMenu({
|
|||||||
{t("itemMenu.findSimilar.label")}
|
{t("itemMenu.findSimilar.label")}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
{event.has_clip && (
|
{isAdmin && event.has_clip && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
disabled={isStarting}
|
disabled={isStarting}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ import {
|
|||||||
import { IoMdArrowRoundBack } from "react-icons/io";
|
import { IoMdArrowRoundBack } from "react-icons/io";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { Toaster } from "@/components/ui/sonner";
|
import { Toaster } from "@/components/ui/sonner";
|
||||||
|
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { TimeRange, TimelineType } from "@/types/timeline";
|
import { TimeRange, TimelineType } from "@/types/timeline";
|
||||||
import MobileCameraDrawer from "@/components/overlay/MobileCameraDrawer";
|
import MobileCameraDrawer from "@/components/overlay/MobileCameraDrawer";
|
||||||
@ -109,6 +110,7 @@ export function RecordingView({
|
|||||||
}: RecordingViewProps) {
|
}: RecordingViewProps) {
|
||||||
const { t } = useTranslation(["views/events", "components/dialog"]);
|
const { t } = useTranslation(["views/events", "components/dialog"]);
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
const isAdmin = useIsAdmin();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const contentRef = useRef<HTMLDivElement | null>(null);
|
const contentRef = useRef<HTMLDivElement | null>(null);
|
||||||
@ -723,13 +725,17 @@ export function RecordingView({
|
|||||||
setCustomShareTimestamp(initialTimestamp);
|
setCustomShareTimestamp(initialTimestamp);
|
||||||
setShareTimestampOpen(true);
|
setShareTimestampOpen(true);
|
||||||
}}
|
}}
|
||||||
onDebugReplayClick={() => {
|
onDebugReplayClick={
|
||||||
setDebugReplayRange({
|
isAdmin
|
||||||
after: timeRange.before - 60,
|
? () => {
|
||||||
before: timeRange.before,
|
setDebugReplayRange({
|
||||||
});
|
after: timeRange.before - 60,
|
||||||
setDebugReplayMode("select");
|
before: timeRange.before,
|
||||||
}}
|
});
|
||||||
|
setDebugReplayMode("select");
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
onExportClick={() => {
|
onExportClick={() => {
|
||||||
const now = new Date(timeRange.before * 1000);
|
const now = new Date(timeRange.before * 1000);
|
||||||
now.setHours(now.getHours() - 1);
|
now.setHours(now.getHours() - 1);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user