Skip to content

Commit

Permalink
add support for specifying a logout url
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeblackshear committed May 18, 2024
1 parent e451a1d commit 56e257b
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 23 deletions.
13 changes: 7 additions & 6 deletions frigate/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
from datetime import datetime
from pathlib import Path

from flask import Blueprint, current_app, jsonify, make_response, request
from flask import Blueprint, current_app, jsonify, make_response, redirect, request
from flask_limiter import Limiter
from joserfc import jwt
from peewee import DoesNotExist

from frigate.config import AuthModeEnum
from frigate.config import AuthConfig, AuthModeEnum
from frigate.const import CONFIG_DIR, JWT_SECRET_ENV_VAR, PASSWORD_HASH_ALGORITHM
from frigate.models import User

Expand Down Expand Up @@ -167,6 +167,7 @@ def set_jwt_cookie(response, cookie_name, encoded_jwt, expiration):
)


# Endpoint for use with nginx auth_request
@AuthBp.route("/auth")
def auth():
success_response = make_response({}, 202)
Expand Down Expand Up @@ -271,11 +272,11 @@ def profile():
return jsonify({"username": username})


@AuthBp.route("/logout", methods=["POST"])
@AuthBp.route("/logout")
def logout():
JWT_COOKIE_NAME = current_app.frigate_config.auth.cookie_name
response = make_response({}, 200)
response.delete_cookie(JWT_COOKIE_NAME)
auth_config: AuthConfig = current_app.frigate_config.auth
response = make_response(redirect("/login", code=303))
response.delete_cookie(auth_config.cookie_name)
return response


Expand Down
9 changes: 6 additions & 3 deletions frigate/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,21 @@ class AuthConfig(FrigateBaseModel):
title="Refresh the session if it is going to expire in this many seconds",
ge=30,
)
header_map: Optional[HeaderMappingConfig] = Field(
header_map: HeaderMappingConfig = Field(
default_factory=HeaderMappingConfig,
title="Header mapping definitions for proxy auth mode.",
)
failed_login_rate_limit: Optional[str] = Field(
failed_login_rate_limit: str = Field(
default="1/second;5/minute;20/hour",
title="Rate limits for failed login attempts.",
)
trusted_proxies: Optional[List[str]] = Field(
trusted_proxies: List[str] = Field(
default=[],
title="Trusted proxies for determining IP address to rate limit",
)
logout_url: Optional[str] = Field(
default=None, title="Redirect url for logging out in proxy mode."
)
# As of Feb 2023, OWASP recommends 600000 iterations for PBKDF2-SHA256
hash_iterations: int = Field(default=600000, title="Password hash iterations")

Expand Down
21 changes: 7 additions & 14 deletions web/src/components/menu/AccountSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,15 @@ import {
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 { data: config } = useSWR("config");
const logoutUrl = config?.auth.logout_url || "/api/logout";

const Container = isDesktop ? DropdownMenu : Drawer;
const Trigger = isDesktop ? DropdownMenuTrigger : DrawerTrigger;
Expand Down Expand Up @@ -75,17 +67,18 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
>
<div className="w-full flex-col overflow-y-auto overflow-x-hidden">
<DropdownMenuLabel>
Current User: {profile?.username}
Current User: {profile?.username || "anonymous"}
</DropdownMenuLabel>
<DropdownMenuSeparator className={isDesktop ? "mt-3" : "mt-1"} />
<MenuItem
className={
isDesktop ? "cursor-pointer" : "flex items-center p-2 text-sm"
}
onClick={() => handleLogout()}
>
<LuLogOut className="mr-2 size-4" />
<span>Logout</span>
<a className="flex" href={logoutUrl}>
<LuLogOut className="mr-2 size-4" />
<span>Logout</span>
</a>
</MenuItem>
</div>
</Content>
Expand Down

0 comments on commit 56e257b

Please sign in to comment.