next-auth icon indicating copy to clipboard operation
next-auth copied to clipboard

New Postgres adapter: getSessionAndUser() has undefined sessionToken for email auth

Open jakecoppinger opened this issue 3 years ago • 2 comments

Adapter type

Custom adapter

Environment

System: OS: macOS 12.4 CPU: (8) arm64 Apple M1 Memory: 86.27 MB / 16.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node Yarn: 1.22.10 - /opt/homebrew/bin/yarn npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm Browsers: Chrome: 103.0.5060.114 Firefox: 102.0.1 Safari: 15.5 Safari Technology Preview: 15.4 npmPackages: next: ^12.2.2 => 12.2.2 next-auth: ^4.9.0 => 4.9.0 react: 17.0.2 => 17.0.2

Reproduction URL

https://github.com/jakecoppinger/next-auth/blob/main/packages/adapter-postgres/src/index.ts

Describe the issue

Hello, I'm working on a "vanilla" Postgres adapter for NextAuth (no ORM, just SQL and pg). I previously used Prisma and had no issues, but I'm looking to remove Prisma.

The sign in flow works up to sending an email and receiving that email. When I click on an email sign in link, the getSessionAndUser() method receives an undefined sessionToken, meaning I'm unable to find the session in the DB, resulting in the app still being signed out.

I've looked through next-auth/packages/next-auth/src/core/routes/session.ts and next-auth/packages/next-auth/src/core/lib/callback-handler.ts and I can't figure out why this would be called with an undefined value.

I didn't have any luck yarn linking so I'm not sure how to find the stack trace.

Do you have any ideas of how I could debug this? Please see the adapter at https://github.com/jakecoppinger/next-auth/blob/main/packages/adapter-postgres/src/index.ts and example SQL schema at https://github.com/jakecoppinger/next-auth/blob/main/packages/adapter-postgres/example-schema.sql

The code is based on the public gist at https://gist.github.com/gue-ni/39751d1122822ee6cf21f756b34c2c5a/revisions

Thanks very much for your help.

My adapter is as below:

return NextAuth(req, res, {
    adapter: PrismaAdapter(prisma),
    pages: {
      signIn: '/',
      signOut: '/auth/signout',
      verifyRequest: '/auth/verify-request',
      error: '/auth/error'
    },
    providers: [
      EmailProvider({
        server: {
          host: process.env.EMAIL_SERVER_HOST,
          port: process.env.EMAIL_SERVER_PORT,
          auth: {
            user: process.env.EMAIL_SERVER_USER,
            pass: process.env.EMAIL_SERVER_PASSWORD
          }
        },
        from: process.env.EMAIL_FROM
      }),
    ],
    secret: process.env.NEXTAUTH_SECRET
  })

How to reproduce

Running npm run dev in a project with this adapter and schema.

Please let me know if you need a full example project to reproduce.

Expected behavior

Should sign in and not have an undefined argument in the params.

jakecoppinger avatar Jul 11 '22 07:07 jakecoppinger

Thanks, this sounds great!

Check out https://github.com/nextauthjs/next-auth/tree/main/packages/adapter-test to add adapter tests, and check for example https://github.com/nextauthjs/next-auth/tree/main/packages/adapter-prisma/tests on how to use it.

So you should be able to write an adapter with confidence, without even starting a Next.js app!

Hopefully, that helps identify the issue as well!

If you need a good dev app anyway, you can use https://github.com/nextauthjs/next-auth/tree/main/apps/dev which has pnpm email to start a fake email server for you that you can access on localhost:1080.

You can write your adapter code as part of the Next.js app while developing for HMR and a better DX overall.

balazsorban44 avatar Jul 11 '22 16:07 balazsorban44

Thanks! Fixing issues with my code on another branch - created a PR.

jakecoppinger avatar Jul 14 '22 11:07 jakecoppinger

@jakecoppinger I ran into this exact same issue while doing the exact same. It turns out node-postgres has some weird behaviors.

If you run

SELECT user_id AS userId 
FROM users
WHERE user_id = 'some_id'

or

SELECT userId
FROM users
WHERE userId = 'some_id'

, the resulting row object is

{userid: 'some_id'} rather than {userId: 'some_id'}.

So in this case, next auth isn't able to read & push the cookie with the correct values since you're returning {sessiontoken: '...'} from getSessionAndUser rather than {sessionToken: '...'}.

spluxx avatar Dec 22 '22 22:12 spluxx

@spluxx is there any chance you're able to fix the issue in this PR? https://github.com/nextauthjs/next-auth/pull/4933

I'm not having any luck fixing it based on your answer.

jakecoppinger avatar Feb 24 '23 05:02 jakecoppinger

Fixed in https://github.com/nextauthjs/next-auth/pull/4933/commits/9748530436f38fb45b6aae5c449200b9b7caee2d. Needed to return id (using SQL command RETURNING) when creating a new user.

jakecoppinger avatar Feb 24 '23 05:02 jakecoppinger