0

I managed to include the user Role in the session token, but I'm sure there's is a better way (probably a more secure way) to implement this

callbacks: {
session: async ({ session, token }) => {
  if (session.user && token.sub) {
    session.user.id = token.sub
    const {role:userRole} = await prisma.user.findUnique({where:{id:session.user.id},select:{role:true}})
    session.user.role = userRole
  }
  return session
},  

additional infos for the wizards among you ‍♂️:

import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { type GetServerSidePropsContext } from "next";
import {
  getServerSession,
  type NextAuthOptions,
  type DefaultSession,
} from "next-auth";
import DiscordProvider from "next-auth/providers/discord";
import { env } from "~/env.mjs";
import { prisma } from "~/server/db";

/**
 * Module augmentation for `next-auth` types. Allows us to add custom properties to the `session`
 * object and keep type safety.
 *
 * @see https://next-auth.js.org/getting-started/typescript#module-augmentation
 */
declare module "next-auth" {
  interface Session extends DefaultSession {
    user: {
      id: string;
      role : 'admin' | 'basic'
      // ...other properties
      // role: UserRole;
    } & DefaultSession["user"];
  }

  interface User {
    // ...other properties
    role: 'admin' | 'basic';
  }
}

/**
 * Options for NextAuth.js used to configure adapters, providers, callbacks, etc.
 *
 * @see https://next-auth.js.org/configuration/options
 */
export const authOptions: NextAuthOptions = {
  session : {
    strategy:"jwt"
  },
  callbacks: {

    session: async ({ session, token }) => {
      console.log(session,token);
      
      if (session.user && token.sub) {
        session.user.id = token.sub
        // @ts-expect-error
        const {role:userRole} = await prisma.user.findUnique({where:{id:session.user.id},select:{role:true}})
        session.user.role = userRole
      }
      return session
    },
    
  },
  adapter: PrismaAdapter(prisma),
  providers: [
    DiscordProvider({
      clientId: env.DISCORD_CLIENT_ID,
      clientSecret: env.DISCORD_CLIENT_SECRET,
    }),
    /**
     * ...add more providers here.
     *
     * Most other providers require a bit more work than the Discord provider. For example, the
     * GitHub provider requires you to add the `refresh_token_expires_in` field to the Account
     * model. Refer to the NextAuth.js docs for the provider you want to use. Example:
     *
     * @see https://next-auth.js.org/providers/github
     */
  ],
};

/**
 * Wrapper for `getServerSession` so that you don't need to import the `authOptions` in every file.
 *
 * @see https://next-auth.js.org/configuration/nextjs
 */
export const getServerAuthSession = (ctx: {
  req: GetServerSidePropsContext["req"];
  res: GetServerSidePropsContext["res"];
}) => {
  return getServerSession(ctx.req, ctx.res, authOptions);
};

my fellow developers i seek your knowledge and help good references are welcomed to learn about next-auth and related topics

jps
  • 20,041
  • 15
  • 75
  • 79
Fadlo
  • 41
  • 5

0 Answers0