Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nayalsaurav/Akari-Art/llms.txt

Use this file to discover all available pages before exploring further.

Akari Art’s authentication is fully managed by NextAuth.js, which registers a catch-all route handler at app/api/auth/[...nextauth]/route.ts. You never need to call most of these endpoints directly — NextAuth’s client-side helpers (useSession, signIn, signOut) and the Next.js middleware handle the full authentication lifecycle. This page documents the underlying endpoints, session shape, and how to access the session in both client and server contexts.

Endpoints

These endpoints are automatically created by NextAuth.js. They handle every stage of the Google OAuth flow and session management.
MethodPathDescription
GET/api/auth/signinRedirect to the configured sign-in page (/signin)
POST/api/auth/signin/googleInitiate the Google OAuth flow
GET/api/auth/callback/googleOAuth callback handler — exchanges code for token and creates session
GET/api/auth/sessionReturn the current session data as JSON
POST/api/auth/signoutSign out the current user and clear the session cookie
All paths under /api/auth/* are marked as public in the middleware — no existing session is required to access them. This ensures the sign-in flow itself is never blocked.

Session Response Shape

Calling GET /api/auth/session (or using useSession()) returns a session object with the following structure. The user.id field is the MongoDB _id of the user document, injected by the jwt and session callbacks in lib/auth.ts.
{
  "user": {
    "id": "<mongodb-object-id>",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "image": "https://lh3.googleusercontent.com/..."
  },
  "expires": "2025-12-31T00:00:00.000Z"
}

Using the Session on the Client

Use the useSession() hook from next-auth/react in any Client Component:
"use client";

import { useSession, signIn, signOut } from "next-auth/react";

export default function UserMenu() {
  const { data: session, status } = useSession();

  if (status === "loading") return <p>Loading...</p>;

  if (!session) {
    return <button onClick={() => signIn("google")}>Sign in with Google</button>;
  }

  return (
    <div>
      <p>Welcome, {session.user.name}</p>
      <p>MongoDB ID: {session.user.id}</p>
      <button onClick={() => signOut()}>Sign out</button>
    </div>
  );
}

Using the Session on the Server

Use getServerSession(authOptions) in Server Components, Route Handlers, or Server Actions. Import authOptions from lib/auth.ts:
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";

export async function GET() {
  const session = await getServerSession(authOptions);

  if (!session) {
    return new Response("Unauthorized", { status: 401 });
  }

  // session.user.id is the MongoDB ObjectId string
  const userId = session.user.id;

  return Response.json({ userId });
}

Route Protection (Middleware)

middleware.ts uses NextAuth’s withAuth helper to enforce authentication across the entire application. The authorized callback runs on every request matched by the matcher config. Public paths (no token required):
  • / — landing page
  • /signin — sign-in page
  • /api/auth/* — all NextAuth internal endpoints
All other paths require a valid JWT token. If the request has no token, the user is redirected to /signin. The middleware matches all routes except static assets (_next/static, _next/image, favicon.ico).
import { withAuth } from "next-auth/middleware";
import { NextResponse } from "next/server";

export default withAuth(
  function middleware() {
    return NextResponse.next();
  },
  {
    callbacks: {
      authorized({ req, token }) {
        const { pathname } = req.nextUrl;
        // Allow unauthenticated access to these paths
        if (
          pathname.startsWith("/api/auth/*") ||
          pathname === "/signin" ||
          pathname === "/"
        ) {
          return true;
        }

        const isAuthorized = !!token;
        if (!isAuthorized) console.warn(`Unauthorized access to ${pathname}`);
        return isAuthorized;
      },
    },
  }
);

export const config = {
  matcher: [
    // Protect all routes except static files and public assets
    "/((?!_next/static|_next/image|favicon.ico).*)",
  ],
};

Auth Configuration — lib/auth.ts

The authOptions object configures the Google provider, three JWT/session callbacks, and the custom sign-in page. The signIn callback automatically creates a new MongoDB User document on first login. The jwt callback embeds the MongoDB _id into the token, and the session callback forwards it to session.user.id.
import GoogleProvider from "next-auth/providers/google";
import { NextAuthOptions } from "next-auth";
import { dbConnect } from "./database";
import User from "@/model/user";

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],

  callbacks: {
    async signIn({ user, account }) {
      await dbConnect();
      const existingUser = await User.findOne({ email: user.email });

      if (!existingUser) {
        await User.create({
          name: user.name,
          email: user.email,
          image: user.image,
          provider: account?.provider,
        });
      }

      return true;
    },

    async jwt({ token, user }) {
      await dbConnect();
      if (user) {
        const existingUser = await User.findOne({ email: user.email });
        if (existingUser) {
          token.id = existingUser._id.toString();
          token.name = existingUser.name;
        }
      }
      return token;
    },

    async session({ session, token }) {
      if (token && session.user) {
        session.user.id = token.id as string;
        session.user.name = token.name as string;
      }

      return session;
    },

    async redirect({ baseUrl }) {
      return baseUrl;
    },
  },
  pages: {
    signIn: "/signin",
    error: "/signin",
  },
  session: {
    strategy: "jwt",
  },
  secret: process.env.NEXTAUTH_SECRET,
};

Route Handler Source

import { authOptions } from "@/lib/auth";
import NextAuth from "next-auth";

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

Required Environment Variables

VariableDescription
GOOGLE_CLIENT_IDOAuth client ID from Google Cloud Console
GOOGLE_CLIENT_SECRETOAuth client secret from Google Cloud Console
NEXTAUTH_SECRETRandom secret used to sign and encrypt JWT tokens
NEXTAUTH_URLCanonical URL of your deployment (e.g. https://your-domain.com)
Keep NEXTAUTH_SECRET confidential. It is used to sign all JWT session tokens. If it is exposed, an attacker can forge session cookies and impersonate any user. If you suspect it has been compromised, rotate it immediately — this will invalidate all existing sessions and sign out all users.

Build docs developers (and LLMs) love