0

I'm building a website using Typescript, Next and React. I'm using Prisma as ORM, tRPC to create the API, and Clerk for User Authentication.

My goal is to avoid any non-logged user to enter certain pages, but also to avoid users without active subscription.

I've achieved the first part with the clerk middleware:

import { getAuth, withClerkMiddleware } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import type { NextRequest } from 'next/server'

// Set the paths that don't require the user to be signed in
const publicPaths = ['/', '/api/stripe-webhook*', '/api/clerk-webhook*']

const isPublic = (path: string) => {
  return publicPaths.find(x =>
    path.match(new RegExp(`^${x}$`.replace('*$', '($|/)')))
  )
}

export default withClerkMiddleware((req: NextRequest) => {
  if (isPublic(req.nextUrl.pathname)) {
    return NextResponse.next()
  }

  console.log("middleware running");
  const { userId } = getAuth(req);
  if (!userId) {
    console.log('userId is null, undefined or empty');
    const indexUrl = new URL('/', req.url)
    indexUrl.searchParams.set('redirect_url', req.url)
    return NextResponse.redirect(indexUrl)
  }

  //ToDo: Verify if the user has subscription active

  return NextResponse.next();
});

// Stop Middleware running on static files
export const config = { matcher: '/((?!_next/image|_next/static|favicon.ico).*)', };

But I'm unable to achieve the second one, the part of avoiding users without Active Subscription. My way to check if user has a subscription enabled right now is calling this tRPC procedure:

import type { User } from '@prisma/client'
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";

export const userRouter = createTRPCRouter({
 
  subscriptionStatus: publicProcedure.query(async ({ ctx }) => {
    const { user, prisma } = ctx;

    if (!user?.id) {
      throw new Error("Not authenticated");
    }

    const data = await prisma.user.findUnique({
      where: {
        id: user?.id,
      },
      select: {
        stripeSubscriptionStatus: true,
      },
    });

    if (!data) {
      throw new Error("Could not find user");
    }

    return data.stripeSubscriptionStatus;
  }),
});

So basically in any page I can do api.user.subscriptionStatus.useQuery(); and it will return the active status for the current logged user.

But as you may guess, I can't do that call on the middlware because I received the error:

Error: PrismaClient is unable to be run in the browser.

So I know that should I use some Vanilla Client tRPC procedure, but I don't know how to set it all together, pass my context object, etc

Lotan
  • 4,078
  • 1
  • 12
  • 30

0 Answers0