trpc context not passed correctly

I will include my setup at the end. My problem is that I am using nextauth with database sessions and passing the session as context into the procedures; however, everything that I have added myself isn't being included in the context for some reason (user.id and user.role) This is my session type I declared,
declare module "next-auth" {
interface Session extends DefaultSession {
user: DefaultSession["user"] & {
id: string;
image: string;
role: string;
};
}

interface User {
id: string;
image: string;
role: string;
}
}
declare module "next-auth" {
interface Session extends DefaultSession {
user: DefaultSession["user"] & {
id: string;
image: string;
role: string;
};
}

interface User {
id: string;
image: string;
role: string;
}
}
This is the session callback I am using.
session: async ({ session, user }) => {
if (!gymId) {
return {
expires: session.expires,
user: {
id: user.id,
role: "user",
image: user.image,
},
};
}
const role = await prisma.roles.findUnique({
where: {
gymId_userId: {
gymId: gymId.id,
userId: user.id,
},
},
});
session = {
expires: session.expires,
user: {
id: user.id,
role: role?.name ?? "user",
image: user.image,
},
};
console.log("Fetching session: ")
console.log(session)
return session;
}

// This is a function that I will use when creating the context
export const getServerAuthSession = (ctx: {
req: GetServerSidePropsContext["req"];
res: GetServerSidePropsContext["res"];
}) => {
return getServerSession(ctx.req, ctx.res, authOptions);
};
session: async ({ session, user }) => {
if (!gymId) {
return {
expires: session.expires,
user: {
id: user.id,
role: "user",
image: user.image,
},
};
}
const role = await prisma.roles.findUnique({
where: {
gymId_userId: {
gymId: gymId.id,
userId: user.id,
},
},
});
session = {
expires: session.expires,
user: {
id: user.id,
role: role?.name ?? "user",
image: user.image,
},
};
console.log("Fetching session: ")
console.log(session)
return session;
}

// This is a function that I will use when creating the context
export const getServerAuthSession = (ctx: {
req: GetServerSidePropsContext["req"];
res: GetServerSidePropsContext["res"];
}) => {
return getServerSession(ctx.req, ctx.res, authOptions);
};
The console.log is just to see what is happening where (I will include it at the end) I will include the rest of the information in the next message as I reached the character limit.
2 Replies
Codex
CodexOP7mo ago
Finally this is what is creating the session.
const createInnerTRPCContext = (opts: CreateContextOptions) => {
return {
session: opts.session,
prisma,
};
};

export const createTRPCContext = async (opts: CreateNextContextOptions) => {
const { req, res } = opts;
// Get the session from the server using the getServerSession wrapper function
const session = await getServerAuthSession({ req, res });
return createInnerTRPCContext({
session,
});
};
const createInnerTRPCContext = (opts: CreateContextOptions) => {
return {
session: opts.session,
prisma,
};
};

export const createTRPCContext = async (opts: CreateNextContextOptions) => {
const { req, res } = opts;
// Get the session from the server using the getServerSession wrapper function
const session = await getServerAuthSession({ req, res });
return createInnerTRPCContext({
session,
});
};
What is happening is that when the front end calls the session I properly get the role inside session.user.role. Moving from the front end to the actual API calls, the first time it creates the session in the middleware it is going through my session callback, and the session when logged DOES come with role and userId, However once it is returned it somehow loses those two values, and the context is set without those two. Any help is much appreciated thanks in advance. Setup: T3: Nextauth, Nextjs pages router, trpc, typescript and prisma. Node version: 18.18.1
JulieCezar
JulieCezar7mo ago
The problem you have is with NextAuth... becuase of the way it passes the session props through. I am writing this from memory so you have to check it for yourself... You have like 4 callbacks you can use,(), jwt(), session() and redirect(). For every request that comes through NextAuth, they pipe the return of one callback into the other, smth like: request comes > session() > jwt() > session() .... And you have to handle each of the callback return props you would want in the next callback... For example, you handled session() but what if jwt() is invoked after and it doesn't pass role and ID, then the 2nd session() callback will not have role and ID to use. Also, sometimes jwt is called twice in a row, which you will have to handle as well. I recommend to go through the docs, and write out console.logs() for every callback so you can actually see how they are called one after the other and then you will know what to handle where.
Want results from more Discord servers?
Add your server