Pass next-auth session to prisma via nexus

355 views Asked by At

I'm wondering on how to pass the next-auth session as context to my nexus queries. The reson behind is that I want the sessions email to retrieve data from my database with nexus. I'm also using Apollo Server and next-connect here.

Here's what I tried:

The Apollo Server

import { ApolloServer } from "apollo-server-micro";
import { MicroRequest } from 'apollo-server-micro/dist/types';
import { ServerResponse } from 'http';
import { getRequestOrigin } from './../../server/get-request-origin';
import handler from "../../server/api-route";
import prisma from "../../server/db/prisma";
import { schema } from "../../server/graphql/schema";

export const config = {
  api: {
    bodyParser: false,
  },
};

export interface GraphQLContext {
  session?: {
    user: {
      name: string
      email: string
      image: string
    },
    expires: Date // This is the expiry of the session, not any of the tokens within the session
  };
  prisma: typeof prisma;
  origin: string;
}


const apolloServer = new ApolloServer({
  schema,
  context: ({ req }): GraphQLContext => ({
    session: req.user,
    origin: getRequestOrigin(req),
    prisma,
  }),

})

const startServer = apolloServer.start();

export default handler().use((req: MicroRequest, res: ServerResponse) => {
  startServer.then(() => {
    apolloServer.createHandler({
      path: "/api",
    })(req, res);
  });
});

My middleware to pass the session:

import { NextApiRequest, NextApiResponse } from "next";

import { Session } from 'next-auth';
import cookieSession from "cookie-session";
import { error } from "next/dist/build/output/log";
import { getSession } from 'next-auth/react';
import nc from "next-connect";
import { trustProxyMiddleware } from "./trust-proxy-middleware";

export interface Request extends NextApiRequest {
  user?: Session | null;
}

const COOKIE_SECRET = process.env.COOKIE_SECRET;

/**
 * Create an API route handler with next-connect and all the necessary middlewares
 *
 * @example
 * ```ts
 * export default handler().get((req, res) => { ... })
 * ```
 */
function handler() {
  if (!COOKIE_SECRET)
    throw new Error(`Please add COOKIE_SECRET to your .env.local file!`);

  return (
    nc<Request, NextApiResponse>({
      onError: (err, _, res) => {
        error(err);
        res.status(500).end(err.toString());
      },
    })
      // In order for authentication to work on Vercel, req.protocol needs to be set correctly.
      // However, Vercel's and Netlify's reverse proxy setup breaks req.protocol, which the custom
      // trustProxyMiddleware fixes again.
      .use(trustProxyMiddleware)
      .use(
        cookieSession({
          name: "session",
          keys: [COOKIE_SECRET],
          maxAge: 24 * 60 * 60 * 1000 * 30,
          // Do not change the lines below, they make cy.auth() work in e2e tests
          secure:
            process.env.NODE_ENV !== "development" &&
            !process.env.INSECURE_AUTH,
          signed:
            process.env.NODE_ENV !== "development" &&
            !process.env.INSECURE_AUTH,
        })
      )
      .use(async (req: Request, res: NextApiResponse) => {
        const session = await getSession({ req })
        if (session) {
          // Signed in
          console.log("Session", JSON.stringify(session, null, 2))
        } else {
          // Not Signed in
          res.status(401)
        }
        res.end()
      })
  );
}

export default handler;

And the nexus query

const queries = extendType({
  type: "Query",
  definition: (t) => {
    t.field("currentUser", {
      type: "User",
      resolve: (_, __, ctx) => {
        console.log(ctx);
        if (!ctx.session?.user.email) return null;

        return prisma.user.findUnique({
          where: {
            email: ctx.session?.user.email,
          },
        });
      },
    });
  },
});

0

There are 0 answers