From 280cb75ca475f4fbec2b4013421732936be7ba92 Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Sun, 29 Jun 2025 23:00:52 +0800 Subject: [PATCH] api: cors in middleware (#1493) --- .../src/app/api/stripe/check/route.ts | 4 +-- .../src/app/api/stripe/webhook/route.ts | 29 +++++++++++++++++-- apps/readest-app/src/middleware.ts | 4 ++- apps/readest-app/src/utils/stripe.ts | 4 +-- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/apps/readest-app/src/app/api/stripe/check/route.ts b/apps/readest-app/src/app/api/stripe/check/route.ts index 7509084e..e98bc410 100644 --- a/apps/readest-app/src/app/api/stripe/check/route.ts +++ b/apps/readest-app/src/app/api/stripe/check/route.ts @@ -1,7 +1,7 @@ import Stripe from 'stripe'; import { NextResponse } from 'next/server'; import { getStripe } from '@/libs/stripe/server'; -import { createSubscription } from '@/utils/stripe'; +import { createOrUpdateSubscription } from '@/utils/stripe'; import { validateUserAndToken } from '@/utils/access'; export async function POST(request: Request) { @@ -19,7 +19,7 @@ export async function POST(request: Request) { if (session.payment_status === 'paid') { const customerId = session.customer as string; const subscriptionId = session.subscription as string; - await createSubscription(user.id, customerId, subscriptionId); + await createOrUpdateSubscription(user.id, customerId, subscriptionId); } return NextResponse.json({ session }); 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 e4afeef8..2f6ef568 100644 --- a/apps/readest-app/src/app/api/stripe/webhook/route.ts +++ b/apps/readest-app/src/app/api/stripe/webhook/route.ts @@ -1,7 +1,7 @@ import Stripe from 'stripe'; import { NextRequest, NextResponse } from 'next/server'; import { getStripe } from '@/libs/stripe/server'; -import { createSubscription } from '@/utils/stripe'; +import { createOrUpdateSubscription } from '@/utils/stripe'; import { createSupabaseAdminClient } from '@/utils/supabase'; export async function POST(request: NextRequest) { @@ -46,7 +46,7 @@ export async function POST(request: NextRequest) { } break; - case 'invoice.paid': + case 'invoice.payment_succeeded': await handleSuccessfulInvoice(event.data.object); break; @@ -54,6 +54,10 @@ export async function POST(request: NextRequest) { await handleFailedInvoice(event.data.object); break; + case 'customer.subscription.updated': + await handleSubscriptionUpdated(event.data.object); + break; + case 'customer.subscription.deleted': await handleSubscriptionCancelled(event.data.object); break; @@ -85,7 +89,7 @@ async function handleSuccessfulSubscription(session: Stripe.Checkout.Session, us const customerId = session.customer as string; const subscriptionId = session.subscription as string; - await createSubscription(userId, customerId, subscriptionId); + await createOrUpdateSubscription(userId, customerId, subscriptionId); } async function handleSuccessfulInvoice(invoice: Stripe.Invoice) { @@ -159,6 +163,25 @@ async function handleFailedInvoice(invoice: Stripe.Invoice) { .eq('id', customerData.user_id); } +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') + .eq('stripe_subscription_id', subscriptionId) + .single(); + + if (!subscriptionData) { + console.error('Subscription not found:', subscriptionId); + return; + } + const { user_id, stripe_customer_id } = subscriptionData; + await createOrUpdateSubscription(user_id, stripe_customer_id, subscriptionId); +} + async function handleSubscriptionCancelled(subscription: Stripe.Subscription) { const subscriptionId = subscription.id; diff --git a/apps/readest-app/src/middleware.ts b/apps/readest-app/src/middleware.ts index b025f12b..309a40dc 100644 --- a/apps/readest-app/src/middleware.ts +++ b/apps/readest-app/src/middleware.ts @@ -4,13 +4,15 @@ const allowedOrigins = [ 'https://web.readest.com', 'https://tauri.localhost', 'http://tauri.localhost', - 'tauri://localhost', 'http://localhost:3000', 'http://localhost:3001', + 'tauri://localhost', ]; const corsOptions = { 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': '*', + 'Access-Control-Max-Age': '86400', }; export function middleware(request: NextRequest) { diff --git a/apps/readest-app/src/utils/stripe.ts b/apps/readest-app/src/utils/stripe.ts index faf59ce1..fdb00dc0 100644 --- a/apps/readest-app/src/utils/stripe.ts +++ b/apps/readest-app/src/utils/stripe.ts @@ -3,7 +3,7 @@ import { getStripe } from '@/libs/stripe/server'; import { createSupabaseAdminClient } from './supabase'; import { UserPlan } from '@/types/user'; -export const createSubscription = async ( +export const createOrUpdateSubscription = async ( userId: string, customerId: string, subscriptionId: string, @@ -58,7 +58,7 @@ export const createSubscription = async ( await supabase .from('plans') .update({ - plan: plan, + plan: ['active', 'trialing'].includes(subscription.status) ? plan : 'free', status: subscription.status, }) .eq('id', userId);