From 34b31577275b7e283ab94f579cf57f16c6694042 Mon Sep 17 00:00:00 2001 From: slarson Date: Tue, 24 Mar 2026 20:24:08 -0400 Subject: [PATCH] fix: redirect logged-out users to login when clicking Follow button When a logged-out user clicks the Follow button on the Testimony Detail page, the action silently fails because uid is undefined and Firestore rejects the operation with "Missing or insufficient permissions." This adds an auth guard that redirects to /login?redirect=currentPath, matching the existing auth redirect pattern used elsewhere in the app. Closes #2059 Co-authored-with: Claude Code --- components/shared/FollowButton.tsx | 7 +++++++ components/testimony/TestimonyDetailPage/PolicyActions.tsx | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/components/shared/FollowButton.tsx b/components/shared/FollowButton.tsx index 87fa5ec81..0d227d1a9 100644 --- a/components/shared/FollowButton.tsx +++ b/components/shared/FollowButton.tsx @@ -1,5 +1,6 @@ import { StyledImage } from "components/ProfilePage/StyledProfileComponents" import { useTranslation } from "next-i18next" +import { useRouter } from "next/router" import { useEffect, useContext } from "react" import { Button } from "react-bootstrap" import { useAuth } from "../auth" @@ -22,6 +23,7 @@ export const BaseFollowButton = ({ const { user } = useAuth() const uid = user?.uid + const router = useRouter() const { followStatus, setFollowStatus } = useContext(FollowContext) @@ -52,6 +54,11 @@ export const BaseFollowButton = ({ ) : null const handleClick = (event: React.FormEvent) => { event.preventDefault() + if (!uid) { + const currentPath = router.asPath + router.push(`/login?redirect=${encodeURIComponent(currentPath)}`) + return + } isFollowing ? UnfollowClick() : FollowClick() } diff --git a/components/testimony/TestimonyDetailPage/PolicyActions.tsx b/components/testimony/TestimonyDetailPage/PolicyActions.tsx index 90d8c4d52..bd979c465 100644 --- a/components/testimony/TestimonyDetailPage/PolicyActions.tsx +++ b/components/testimony/TestimonyDetailPage/PolicyActions.tsx @@ -5,6 +5,7 @@ import { formUrl } from "components/publish" import { FC, ReactElement, useContext, useEffect } from "react" import { useCurrentTestimonyDetails } from "./testimonyDetailSlice" import { useTranslation } from "next-i18next" +import { useRouter } from "next/router" import { useAuth } from "components/auth" import { TopicQuery } from "components/shared/FollowingQueries" import { StyledImage } from "components/ProfilePage/StyledProfileComponents" @@ -39,6 +40,7 @@ export const PolicyActions: FC> = ({ const { user } = useAuth() const uid = user?.uid + const router = useRouter() const { followStatus, setFollowStatus } = useContext(FollowContext) @@ -69,6 +71,11 @@ export const PolicyActions: FC> = ({ ) : null const handleClick = (event: React.MouseEvent) => { event.preventDefault() + if (!uid) { + const currentPath = router.asPath + router.push(`/login?redirect=${encodeURIComponent(currentPath)}`) + return + } isFollowing ? UnfollowClick() : FollowClick() }