diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index d0c1f2c9a..223112a7d 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -10,10 +10,14 @@
"features": {
"ghcr.io/devcontainers/features/common-utils:1": {}
},
- "forwardPorts": [5000, 5001, 5173, 8554, 8555],
+ "forwardPorts": [8080, 5000, 5001, 5173, 8554, 8555],
"portsAttributes": {
+ "8080": {
+ "label": "External NGINX",
+ "onAutoForward": "silent"
+ },
"5000": {
- "label": "NGINX",
+ "label": "Internal NGINX",
"onAutoForward": "silent"
},
"5001": {
diff --git a/frigate/api/auth.py b/frigate/api/auth.py
index 95eb1939f..5b998d04c 100644
--- a/frigate/api/auth.py
+++ b/frigate/api/auth.py
@@ -252,6 +252,20 @@ def auth():
return fail_response
+@AuthBp.route("/profile")
+def profile():
+ username = request.headers.get("remote-user", type=str)
+ return jsonify({"username": username})
+
+
+@AuthBp.route("/logout", methods=["POST"])
+def logout():
+ JWT_COOKIE_NAME = current_app.frigate_config.auth.cookie_name
+ response = make_response({}, 200)
+ response.delete_cookie(JWT_COOKIE_NAME)
+ return response
+
+
@AuthBp.route("/login", methods=["POST"])
@limiter.limit(get_rate_limit, deduct_when=lambda response: response.status_code == 400)
def login():
diff --git a/web/src/components/menu/AccountSettings.tsx b/web/src/components/menu/AccountSettings.tsx
index 9954c3afc..87dcb3fb2 100644
--- a/web/src/components/menu/AccountSettings.tsx
+++ b/web/src/components/menu/AccountSettings.tsx
@@ -7,31 +7,89 @@ import { cn } from "@/lib/utils";
import { TooltipPortal } from "@radix-ui/react-tooltip";
import { isDesktop } from "react-device-detect";
import { VscAccount } from "react-icons/vsc";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "../ui/dropdown-menu";
+import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
+import { DialogClose } from "../ui/dialog";
+import { LuLogOut } from "react-icons/lu";
+import { useCallback } from "react";
+import axios from "axios";
+import useSWR from "swr";
type AccountSettingsProps = {
className?: string;
};
export default function AccountSettings({ className }: AccountSettingsProps) {
+ const { data: profile } = useSWR("profile");
+
+ const handleLogout = useCallback(() => {
+ axios.post(`logout`).then((response) => {
+ if (response.status == 200) {
+ window.location.href = "/";
+ }
+ });
+ }, []);
+
+ const Container = isDesktop ? DropdownMenu : Drawer;
+ const Trigger = isDesktop ? DropdownMenuTrigger : DrawerTrigger;
+ const Content = isDesktop ? DropdownMenuContent : DrawerContent;
+ const MenuItem = isDesktop ? DropdownMenuItem : DialogClose;
+
return (
- Account Account