From 19d1aa1f7911b98b3c0bd60faa551733edf1eea5 Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Wed, 15 May 2024 07:33:29 -0500 Subject: [PATCH] implement logout and profile --- .devcontainer/devcontainer.json | 8 +- frigate/api/auth.py | 14 +++ web/src/components/menu/AccountSettings.tsx | 96 +++++++++++++++---- .../components/settings/Authentication.tsx | 12 +-- web/vite.config.ts | 14 +-- 5 files changed, 110 insertions(+), 34 deletions(-) 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

-
-
-
+
+ + Current User: {profile?.username} + + + handleLogout()} + > + + Logout + +
+ + + ); } diff --git a/web/src/components/settings/Authentication.tsx b/web/src/components/settings/Authentication.tsx index 15baca614..64119ab49 100644 --- a/web/src/components/settings/Authentication.tsx +++ b/web/src/components/settings/Authentication.tsx @@ -34,15 +34,13 @@ export default function Authentication() { }) .then((response) => { if (response.status == 200) { - // console.log("saved"); + setShowSetPassword(false); } }) - .catch((error) => { - if (error.response?.data?.message) { - // console.log("error"); - } else { - // console.log("error"); - } + .catch((_error) => { + toast.error("Error setting password", { + position: "top-center", + }); }); }, []); diff --git a/web/vite.config.ts b/web/vite.config.ts index 11e221116..6a2c05fb8 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -4,6 +4,8 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; import monacoEditorPlugin from "vite-plugin-monaco-editor"; +const proxyHost = "localhost:5000"; + // https://vitejs.dev/config/ export default defineConfig({ define: { @@ -12,24 +14,24 @@ export default defineConfig({ server: { proxy: { "/api": { - target: "http://localhost:5000", + target: `http://${proxyHost}`, ws: true, }, "/vod": { - target: "http://localhost:5000", + target: `http://${proxyHost}`, }, "/clips": { - target: "http://localhost:5000", + target: `http://${proxyHost}`, }, "/exports": { - target: "http://localhost:5000", + target: `http://${proxyHost}`, }, "/ws": { - target: "ws://localhost:5000", + target: `ws://${proxyHost}`, ws: true, }, "/live": { - target: "ws://localhost:5000", + target: `ws://${proxyHost}`, changeOrigin: true, ws: true, },