nextauthjs / next-auth

Authentication for the Web.
https://authjs.dev
ISC License
24.31k stars 3.39k forks source link

Cannot login after signout using Drizzle Adapter with Turso #8377

Open kyujulian opened 1 year ago

kyujulian commented 1 year ago

Environment

System: OS: Linux 6.1 Manjaro Linux CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz Memory: 10.74 GB / 15.51 GB Container: Yes Shell: 5.9 - /bin/zsh Binaries: Node: 20.5.1 - ~/.nvm/versions/node/v20.5.1/bin/node Yarn: 1.22.19 - /usr/bin/yarn npm: 9.8.0 - ~/.nvm/versions/node/v20.5.1/bin/npm pnpm: 8.6.12 - /usr/bin/pnpm

Reproduction URL

https://github.com/kyujulian/next-auth-login-issue

Describe the issue

When using drizzle-adapter package the adapter cannot retrieve the 'provider' and 'providerAccountId' on the database, causing the auth to throw OAuthAccountNotLinked Error when trying to login after a signout, even though there's only one provider.

DeepinScreenshot_select-area_20230821164958

How to reproduce

After going through the setup process on the reproduction URL,

Login with a given provider, signout then try to login again (with the same provider I configured only github for that reason) .

Expected behavior

Expected the adapter to link correctly to the account stored in the db.

levinuncu commented 1 year ago

I had the same issue but managed to fix it. So this works until #8379 is merged.

function getAdapter(): Adapter {
  return {
    ...DrizzleAdapter(db),
    async getUserByAccount(providerAccountId) {
      const results = await db
        .select()
        .from(accounts)
        .leftJoin(users, eq(users.id, accounts.userId))
        .where(
          and(
            eq(accounts.provider, providerAccountId.provider),
            eq(accounts.providerAccountId, providerAccountId.providerAccountId),
          ),
        )
        .get();

      return results?.user ?? null;
    },
  };
}

...
NextAuth({
  adapter: getAdapter(),
});
appjitsu commented 1 year ago

I had the same issue but managed to fix it. So this works until #8379 is merged.

function getAdapter(): Adapter {
  return {
    ...DrizzleAdapter(db),
    async getUserByAccount(providerAccountId) {
      const results = await db
        .select()
        .from(accounts)
        .leftJoin(users, eq(users.id, accounts.userId))
        .where(
          and(
            eq(accounts.provider, providerAccountId.provider),
            eq(accounts.providerAccountId, providerAccountId.providerAccountId),
          ),
        )
        .get();

      return results?.user ?? null;
    },
  };
}

...
NextAuth({
  adapter: getAdapter(),
});

Much appreciated! This was kicking my ass until I found your post. ;)

viztor commented 1 year ago

duplicate of #8335