Search code examples
javascriptnext-auth

nextauth session doesn't query for additional fields


I've added a username field to my users model, but when using getServerSession(authOptions) the query doesn't contain username:

Query: select "session"."sessionToken", "session"."userId", "session"."expires", "user"."id", "user"."name", "user"."email", "user"."emailVerified", "user"."image" from "session" inner join "user" on "user"."id" = "session"."userId" where "session"."sessionToken" = $1

I have confirmed that when I run my own select().from(users) query with drizzle that it includes the username field:

Query: select "id", "name", "email", "emailVerified", "image", "username" from "user"

Here is how my AuthOptions object is set up:

import NextAuth, { AuthOptions } from "next-auth"
import GoogleProvider from "next-auth/providers/google";
import { DrizzleAdapter } from "@auth/drizzle-adapter"
import { db } from "@/db/connection";
import { User } from "@/db/schema";

export const authOptions: AuthOptions = {
    adapter: DrizzleAdapter(db),
    providers: [
        GoogleProvider({
            clientId: process.env.GOOGLE_CLIENT_ID!,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET!
          }),
    ],
    callbacks: {
        async session({ session, user }) {
            session.user.username = (user as User).username;
            return session
        }
    }
}

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST }

Solution

  • The issue is that the drizzle adapter references a default schema. Here's a temporary solution. Typescript complains a bit, but as far as I can tell the kinds of problems the error guards against aren't relevant here.The second (optional) argument to the adapter is a function for constructing the tables, so we can just replace the default tables with our own:

    import { User, accounts, sessions, users, verificationTokens } from "@/db/schema";
    import { PgTableFn, pgTable } from "drizzle-orm/pg-core";
    
    
    const pgTableHijack: PgTableFn = (name, columns, extraConfig) => {
    
        switch(name){
            case "user":
                return users;
            case "account":
                return accounts;
            case "session":
                return sessions;
            case "verificationToken":
                return verificationTokens;
            default:
                return pgTable(name, columns, extraConfig);
        }
    }
    
    export const authOptions: AuthOptions = {
        adapter: DrizzleAdapter(db, pgTableHijack),
        ...
    }