From bf0bb800099956ed16a15517994efa283d34bd0d Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Mon, 30 Jun 2025 21:08:53 +0800 Subject: [PATCH] api: fix for supabase RLS (#1501) --- apps/readest-app/src/app/api/stripe/checkout/route.ts | 3 ++- apps/readest-app/src/app/api/stripe/portal/route.ts | 3 ++- apps/readest-app/src/app/api/stripe/webhook/route.ts | 1 - apps/readest-app/src/app/user/page.tsx | 11 +++++++---- .../src/app/user/subscription/success/page.tsx | 7 +++++++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/apps/readest-app/src/app/api/stripe/checkout/route.ts b/apps/readest-app/src/app/api/stripe/checkout/route.ts index 7c3a1556..318839e7 100644 --- a/apps/readest-app/src/app/api/stripe/checkout/route.ts +++ b/apps/readest-app/src/app/api/stripe/checkout/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; import { getStripe } from '@/libs/stripe/server'; import { validateUserAndToken } from '@/utils/access'; -import { supabase } from '@/utils/supabase'; +import { createSupabaseAdminClient } from '@/utils/supabase'; export async function POST(request: NextRequest) { const { priceId, embedded = true, metadata = {} } = await request.json(); @@ -17,6 +17,7 @@ export async function POST(request: NextRequest) { }; try { + const supabase = createSupabaseAdminClient(); const { data: customerData } = await supabase .from('customers') .select('stripe_customer_id') diff --git a/apps/readest-app/src/app/api/stripe/portal/route.ts b/apps/readest-app/src/app/api/stripe/portal/route.ts index 459feac5..fcead7d8 100644 --- a/apps/readest-app/src/app/api/stripe/portal/route.ts +++ b/apps/readest-app/src/app/api/stripe/portal/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; import { getStripe } from '@/libs/stripe/server'; import { validateUserAndToken } from '@/utils/access'; -import { supabase } from '@/utils/supabase'; +import { createSupabaseAdminClient } from '@/utils/supabase'; export async function POST(request: NextRequest) { const { user, token } = await validateUserAndToken(request.headers.get('authorization')); @@ -10,6 +10,7 @@ export async function POST(request: NextRequest) { } try { + const supabase = createSupabaseAdminClient(); const { data: customerData } = await supabase .from('customers') .select('stripe_customer_id') diff --git a/apps/readest-app/src/app/api/stripe/webhook/route.ts b/apps/readest-app/src/app/api/stripe/webhook/route.ts index 2f6ef568..c0c4ab84 100644 --- a/apps/readest-app/src/app/api/stripe/webhook/route.ts +++ b/apps/readest-app/src/app/api/stripe/webhook/route.ts @@ -167,7 +167,6 @@ async function handleSubscriptionUpdated(subscription: Stripe.Subscription) { const subscriptionId = subscription.id; const supabase = createSupabaseAdminClient(); - const { data: subscriptionData } = await supabase .from('subscriptions') .select('user_id, stripe_customer_id') diff --git a/apps/readest-app/src/app/user/page.tsx b/apps/readest-app/src/app/user/page.tsx index cde5e406..6f755fcd 100644 --- a/apps/readest-app/src/app/user/page.tsx +++ b/apps/readest-app/src/app/user/page.tsx @@ -150,10 +150,13 @@ const ProfilePage = () => { } }; - const handleCheckoutSuccess = useCallback((sessionId: string) => { - setShowEmbeddedCheckout(false); - router.push(`/user/subscription/success?session_id=${sessionId}`); - }, []); + const handleCheckoutSuccess = useCallback( + (sessionId: string) => { + setShowEmbeddedCheckout(false); + router.push(`/user/subscription/success?session_id=${sessionId}`); + }, + [router], + ); const handleManageSubscription = async () => { const token = await getAccessToken(); diff --git a/apps/readest-app/src/app/user/subscription/success/page.tsx b/apps/readest-app/src/app/user/subscription/success/page.tsx index 92399efb..0c7a51d1 100644 --- a/apps/readest-app/src/app/user/subscription/success/page.tsx +++ b/apps/readest-app/src/app/user/subscription/success/page.tsx @@ -29,6 +29,9 @@ const SuccessPageWithSearchParams = () => { const router = useRouter(); const sessionId = searchParams?.get('session_id'); + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); + async function fetchSessionStatus() { try { const token = await getAccessToken(); @@ -111,6 +114,10 @@ const SuccessPageWithSearchParams = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [sessionStatus.status, retryCount]); + if (!mounted) { + return null; + } + // Loading state if (sessionStatus.status === 'loading') { return (