From 34b31577275b7e283ab94f579cf57f16c6694042 Mon Sep 17 00:00:00 2001 From: slarson Date: Tue, 24 Mar 2026 20:24:08 -0400 Subject: [PATCH 1/3] 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() } From eb30981a0f9ccef95968b45189d3ecdf15110840 Mon Sep 17 00:00:00 2001 From: mertbagt Date: Thu, 20 Aug 2026 19:47:37 -0400 Subject: [PATCH 2/3] fixage and prettier --- components/shared/FollowButton.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/shared/FollowButton.tsx b/components/shared/FollowButton.tsx index ec8e035d3..7a09057f5 100644 --- a/components/shared/FollowButton.tsx +++ b/components/shared/FollowButton.tsx @@ -120,7 +120,7 @@ export const BaseFollowButton = ({ const checkmark = isFollowing ? ( ) : null - const handleClick = (event: React.FormEvent) => { + const handleClick = (event: any) => { event.preventDefault() if (!uid) { const currentPath = router.asPath @@ -134,7 +134,7 @@ export const BaseFollowButton = ({ <> {!hide && (
- From cea5e07f918c623fbc44007ae33eded4a7684f95 Mon Sep 17 00:00:00 2001 From: mertbagt Date: Thu, 20 Aug 2026 19:53:55 -0400 Subject: [PATCH 3/3] moar prettier --- components/testimony/TestimonyDetailPage/PolicyActions.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/components/testimony/TestimonyDetailPage/PolicyActions.tsx b/components/testimony/TestimonyDetailPage/PolicyActions.tsx index ea506f02f..c0733e8e6 100644 --- a/components/testimony/TestimonyDetailPage/PolicyActions.tsx +++ b/components/testimony/TestimonyDetailPage/PolicyActions.tsx @@ -71,7 +71,6 @@ export const PolicyActions: FC> = ({ ? ballotQuestionTopicName(ballotQuestionTopic.court, ballotQuestionTopic.id) : billTopicName(bill.court, bill.id) - const { followStatus, setFollowStatus } = useContext(FollowContext) const [canEditBallotQuestionTestimony, setCanEditBallotQuestionTestimony] = useState(!ballotQuestionId)