import { useCallback, useEffect, useState } from "react"; import ActivityIndicator from "@/components/indicators/activity-indicator"; import { FrigateConfig } from "@/types/frigateConfig"; import { Toaster } from "@/components/ui/sonner"; import useSWR from "swr"; import Heading from "@/components/ui/heading"; import { User } from "@/types/user"; import { Button } from "@/components/ui/button"; import SetPasswordDialog from "@/components/overlay/SetPasswordDialog"; import axios from "axios"; import CreateUserDialog from "@/components/overlay/CreateUserDialog"; import { toast } from "sonner"; import DeleteUserDialog from "@/components/overlay/DeleteUserDialog"; import { HiTrash } from "react-icons/hi"; import { FaUserEdit } from "react-icons/fa"; import { LuPlus, LuShield, LuUserCog } from "react-icons/lu"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import RoleChangeDialog from "@/components/overlay/RoleChangeDialog"; export default function AuthenticationView() { const { data: config } = useSWR("config"); const { data: users, mutate: mutateUsers } = useSWR("users"); const [showSetPassword, setShowSetPassword] = useState(false); const [showCreate, setShowCreate] = useState(false); const [showDelete, setShowDelete] = useState(false); const [showRoleChange, setShowRoleChange] = useState(false); const [selectedUser, setSelectedUser] = useState(); const [selectedUserRole, setSelectedUserRole] = useState< "admin" | "viewer" >(); useEffect(() => { document.title = "Authentication Settings - Frigate"; }, []); const onSavePassword = useCallback((user: string, password: string) => { axios .put(`users/${user}/password`, { password }) .then((response) => { if (response.status === 200) { setShowSetPassword(false); toast.success("Password updated successfully", { position: "top-center", }); } }) .catch((error) => { const errorMessage = error.response?.data?.message || error.response?.data?.detail || "Unknown error"; toast.error(`Failed to save password: ${errorMessage}`, { position: "top-center", }); }); }, []); const onCreate = ( user: string, password: string, role: "admin" | "viewer", ) => { axios .post("users", { username: user, password, role }) .then((response) => { if (response.status === 200 || response.status === 201) { setShowCreate(false); mutateUsers((users) => { users?.push({ username: user, role: role }); return users; }, false); toast.success(`User ${user} created successfully`, { position: "top-center", }); } }) .catch((error) => { const errorMessage = error.response?.data?.message || error.response?.data?.detail || "Unknown error"; toast.error(`Failed to create user: ${errorMessage}`, { position: "top-center", }); }); }; const onDelete = (user: string) => { axios .delete(`users/${user}`) .then((response) => { if (response.status === 200) { setShowDelete(false); mutateUsers( (users) => users?.filter((u) => u.username !== user), false, ); toast.success(`User ${user} deleted successfully`, { position: "top-center", }); } }) .catch((error) => { const errorMessage = error.response?.data?.message || error.response?.data?.detail || "Unknown error"; toast.error(`Failed to delete user: ${errorMessage}`, { position: "top-center", }); }); }; const onChangeRole = (user: string, newRole: "admin" | "viewer") => { if (user === "admin") return; // Prevent role change for 'admin' axios .put(`users/${user}/role`, { role: newRole }) .then((response) => { if (response.status === 200) { setShowRoleChange(false); mutateUsers( (users) => users?.map((u) => u.username === user ? { ...u, role: newRole } : u, ), false, ); toast.success(`Role updated for ${user}`, { position: "top-center", }); } }) .catch((error) => { const errorMessage = error.response?.data?.message || error.response?.data?.detail || "Unknown error"; toast.error(`Failed to update role: ${errorMessage}`, { position: "top-center", }); }); }; if (!config || !users) { return (
); } return (
User Management

Manage this Frigate instance's user accounts.

Username Role Actions {users.length === 0 ? ( No users found. ) : ( users.map((user) => (
{user.username === "admin" ? ( ) : ( )} {user.username}
{user.role || "viewer"}
{user.username !== "admin" && (

Change user role

)}

Update password

{user.username !== "admin" && (

Delete user

)}
)) )}
setShowSetPassword(false)} onSave={(password) => onSavePassword(selectedUser!, password)} /> setShowDelete(false)} onDelete={() => onDelete(selectedUser!)} /> setShowCreate(false)} /> {selectedUser && selectedUserRole && ( onChangeRole(selectedUser, role)} onCancel={() => setShowRoleChange(false)} /> )}
); }