Default authentication methods

Shipit comes with a default authentication system that uses NextAuth.js. This system allows you to authenticate users using different providers like Google, GitHub, Facebook, etc.

By default, shipit comes configured to work with Magic Link, Google, and GitHub authentication.

For this to work you will need to fill the neccesary environment variables.

Protecting routes

Protect routes for authenticated users

In your project, you will find a folder called (authenticated). All routes inside this folder are protected and require the user to be authenticated to access them.

Protect routes for subscribers

In your project, you will find a folder called (subscribed). All routes inside this folder are protected and require the user to be authenticated and subscribed to access them.

Note that, since the authenticated and subscribed folders are wrapped in parentheses, it won’t affect the url. if you have a dashboard folder inside the subscribed folder, the url will be /dashboard and not /subscribed/dashboard.

The protection is possible thanks to the layout.tsx file located in each of the folders.

Protecting routes for a specific subscription plan

Besides you would usually have the same routes for all the subscribers, but with different functionalities, there are cases where you would like to have different routes for different subscription plans. To achieve this, create a folder with the name of the plan inside the (subscribed) folder. you can wrap the folder with parentheses to avoid URL changes.

📦(suscribed)
 ┣ 📦(premium)
    ┣ 📜page.tsx
    ┣ 📜layout.tsx

Now we can use the layout to protect all the routes within the folder for the premium plan.

src/app/suscribed/premium/layout.tsx
import StripeServer from "stripe";
import { redirect } from "next/navigation";
import { NON_AUTHENTICATED_REDIRECT_URL, NON_SUSCRIBED_REDIRECT_URL } from "@/app_settings";
import { authOptions } from "@/server/auth/options"
import { getServerSession } from "next-auth"
import { redirect } from "next/navigation";
import { env } from "@/env";
import { getPlanName } from "@/server/helpers/stripe/subscriptions/get-plan-name";

export default async function Layout({ children }: Readonly<{ children: React.ReactNode }>) {
    const session = await getServerSession(authOptions);
    const planName = await getPlanName({ subscriptionId });
    if (!session?.user || planName.toLowerCase() !== "premium"{
        return redirect(NON_AUTHENTICATED_REDIRECT_URL)
    }

    const subscriptionId = session?.user?.subscriptionId;

    if (!subscriptionId) {
        // user has no subscription, redirect to the non subscribed page
        return redirect(NON_SUSCRIBED_REDIRECT_URL)
    }

    // user has a subscription, check if it's active

    const stripe = new StripeServer(env.STRIPE_SECRET_KEY);
    const subscription = await stripe.subscriptions.retrieve(subscriptionId as string);

    if (subscription.status !== "active") {
        // subscription is not active, redirect to the non subscribed page
        return redirect(NON_SUSCRIBED_REDIRECT_URL)
    }

    // subscription is active, render the children
    else {
        return children
    }

}

Change the redirects URL

In the app_settings.ts file located at the src folder, you can change the redirects URL for the authentication system. Just go to the Auth settings section and you will find the following settings:

src/app_settings.ts
// ****** Auth settings ******
export const AFTER_SIGNIN_REDIRECT_URL = "/profile";
export const AFTER_SIGNUP_REDIRECT_URL = AFTER_SIGNIN_REDIRECT_URL; // or "/onboarding", etc.
export const AFTER_SIGNOUT_REDIRECT_URL = "/";
export const NON_AUTHENTICATED_REDIRECT_URL = "/signin"; // where to redirect if the user is not authenticated and tries to access a page that requires authentication
export const NON_SUSCRIBED_REDIRECT_URL = "/pricing"; // where to redirect if the user is authenticated but is not subscribed
// ****** / Auth settings / ******

This is pretty much self-explanatory, but you can check more details about each setting in the Auth Settings.

Remove one of the default authentication providers

The authentication providers are set in src/server/auth/providers.ts.

src/server/auth/providers.ts
export const providers: Provider[] = [
  GoogleProvider({
    clientId: env.GOOGLE_CLIENT_ID,
    clientSecret: env.GOOGLE_CLIENT_SECRET,
  }),
  GithubProvider({
    clientId: env.GITHUB_CLIENT_ID,
    clientSecret: env.GITHUB_CLIENT_SECRET,
  }),
  EmailProvider({
    async sendVerificationRequest({ identifier: email, url }) {
      await resend.emails.send({
        from: env.EMAIL_FROM,
        to: email,
        subject: `Sign in to ${APP_NAME}`,
        react: MagicLinkTemplate({ link: url }),
        html: ""
      })
    },
  }),

Those are the default providers, to remove one of them, just remove the provider from the array. If you remove an Oauth provider, like Google or Github, you will also need to remove the typesafe environment variables from the src/env.ts file.

Extending the authentication providers

The authentication providers are set in src/server/auth/providers.ts. Since Shipit use next-auth as the authentication system, you can easily extend the authentication providers by following the next-auth documentation.