(req: NextRequest)
| 21 | import type { NextRequest } from 'next/server' |
| 22 | |
| 23 | export async function GET(req: NextRequest) { |
| 24 | let userId: string | undefined |
| 25 | |
| 26 | // First, try Bearer token authentication (for CLI clients) |
| 27 | const apiKey = extractApiKeyFromHeader(req) |
| 28 | if (apiKey) { |
| 29 | const userIdFromToken = await getUserIdFromSessionToken(apiKey) |
| 30 | if (userIdFromToken) { |
| 31 | userId = userIdFromToken |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | // Fall back to NextAuth session authentication (for web clients) |
| 36 | if (!userId) { |
| 37 | const session = await getServerSession(authOptions) |
| 38 | userId = session?.user?.id |
| 39 | } |
| 40 | |
| 41 | if (!userId) { |
| 42 | return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) |
| 43 | } |
| 44 | |
| 45 | // Fetch user preference for always use a-la-carte |
| 46 | const [subscription, userPrefs] = await Promise.all([ |
| 47 | getActiveSubscription({ userId, logger }), |
| 48 | db.query.user.findFirst({ |
| 49 | where: eq(schema.user.id, userId), |
| 50 | columns: { fallback_to_a_la_carte: true }, |
| 51 | }), |
| 52 | ]) |
| 53 | |
| 54 | const fallbackToALaCarte = userPrefs?.fallback_to_a_la_carte ?? false |
| 55 | |
| 56 | if (!subscription || !subscription.tier) { |
| 57 | const response: NoSubscriptionResponse = { hasSubscription: false, fallbackToALaCarte } |
| 58 | return NextResponse.json(response) |
| 59 | } |
| 60 | |
| 61 | const [rateLimit, limits] = await Promise.all([ |
| 62 | checkRateLimit({ userId, subscription, logger }), |
| 63 | getSubscriptionLimits({ userId, logger, tier: subscription.tier }), |
| 64 | ]) |
| 65 | |
| 66 | const response: ActiveSubscriptionResponse = { |
| 67 | hasSubscription: true, |
| 68 | displayName: SUBSCRIPTION_DISPLAY_NAME, |
| 69 | subscription: { |
| 70 | id: subscription.stripe_subscription_id, |
| 71 | status: subscription.status, |
| 72 | billingPeriodEnd: subscription.billing_period_end.toISOString(), |
| 73 | cancelAtPeriodEnd: subscription.cancel_at_period_end, |
| 74 | canceledAt: subscription.canceled_at?.toISOString() ?? null, |
| 75 | tier: subscription.tier, |
| 76 | scheduledTier: subscription.scheduled_tier, |
| 77 | }, |
| 78 | rateLimit: { |
| 79 | limited: rateLimit.limited, |
| 80 | reason: rateLimit.reason, |
nothing calls this directly
no test coverage detected