nextauthjs / next-auth

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

Can't link account to a twitch multiple email one #6320

Closed Geczy closed 1 year ago

Geczy commented 1 year ago

Adapter type

@next-auth/prisma-adapter

Environment

https://github.com/dotabod/frontend/blob/master/package.json

{
  "name": "dotabod-frontend",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "doppler run -- next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "postinstall": "prisma generate"
  },
  "browserslist": "defaults, not ie <= 11",
  "dependencies": {
    "@emotion/react": "^11.10.5",
    "@geist-ui/core": "^2.3.8",
    "@headlessui/react": "^1.7.4",
    "@heroicons/react": "^2.0.13",
    "@mantine/core": "^5.9.0",
    "@mantine/form": "^5.9.0",
    "@mantine/hooks": "^5.9.0",
    "@mantine/notifications": "^5.9.5",
    "@next-auth/prisma-adapter": "^1.0.5",
    "@prisma/client": "^4.7.1",
    "@radix-ui/react-avatar": "^1.0.1",
    "@radix-ui/react-dropdown-menu": "^2.0.1",
    "@sentry/nextjs": "^7.23.0",
    "@tailwindcss/forms": "^0.5.3",
    "@twurple/api": "^5.2.7",
    "@twurple/auth": "^5.2.7",
    "@vercel/analytics": "^0.1.4",
    "autoprefixer": "^10.4.13",
    "clsx": "^1.2.1",
    "focus-visible": "^5.2.0",
    "framer-motion": "^8.1.5",
    "lucide-react": "^0.103.0",
    "next": "13.0.6",
    "next-auth": "4.17.0",
    "postcss-focus-visible": "^7.1.0",
    "react": "18.2.0",
    "react-countdown": "^2.3.5",
    "react-countdown-circle-timer": "^3.1.0",
    "react-dom": "18.2.0",
    "socket.io-client": "^4.5.4",
    "swr": "^1.3.0",
    "tailwindcss": "^3.2.3",
    "tmi-emote-parse": "^2.0.0",
    "twitch-fetcher": "https://github.com/dotabod/twitch-fetcher.git",
    "use-debounce": "^9.0.2",
    "zod": "^3.19.1"
  },
  "devDependencies": {
    "@types/node": "18.11.10",
    "@types/obs-studio": "^2.17.0",
    "@types/react": "18.0.26",
    "eslint": "8.29.0",
    "eslint-config-next": "13.0.6",
    "eslint-plugin-unused-imports": "^2.0.0",
    "prettier": "^2.8.0",
    "prettier-plugin-tailwindcss": "^0.2.0",
    "prisma": "^4.7.1",
    "styled-jsx-plugin-postcss": "^4.0.1",
    "typescript": "4.9.3"
  }
}

Reproduction URL

https://github.com/dotabod/frontend/blob/master/prisma/schema.prisma

Describe the issue

as you can see, twitch allows multiple users with the same email address. so prisma adapter his to be updated to allow multiple linked accounts with same email

image

linkAccount: (data) => p.account.create({ data }),

[next-auth][error][adapter_error_linkAccount]
https://next-auth.js.org/errors#adapter_error_linkaccount
Invalid `p.account.create()` invocation in
C:\Users\matt\Documents\GitHub\njs13\tailwindui-pocket\node_modules\@next-auth\prisma-adapter\dist\index.js:19:42

  16 },
  17 updateUser: ({ id, ...data }) => p.user.update({ where: { id }, data }),
  18 deleteUser: (id) => p.user.delete({ where: { id } }),
→ 19 linkAccount: (data) => p.account.create(
Unique constraint failed on the fields: (`userId`) {
  message: '\n' +
    'Invalid `p.account.create()` invocation in\n' +
    'C:\\Users\\matt\\Documents\\GitHub\\njs13\\tailwindui-pocket\\node_modules\\@next-auth\\prisma-adapter\\dist\\index.js:19:42\n' +
    '\n' +
    '  16 },\n' +
    '  17 updateUser: ({ id, ...data }) => p.user.update({ where: { id }, data }),\n' +
    '  18 deleteUser: (id) => p.user.delete({ where: { id } }),\n' +
    '→ 19 linkAccount: (data) => p.account.create(\n' +
    'Unique constraint failed on the fields: (`userId`)',
  stack: 'Error: \n' +
    'Invalid `p.account.create()` invocation in\n' +
    'C:\\Users\\matt\\Documents\\GitHub\\njs13\\tailwindui-pocket\\node_modules\\@next-auth\\prisma-adapter\\dist\\index.js:19:42\n' +
    '\n' +
    '  16 },\n' +
    '  17 updateUser: ({ id, ...data }) => p.user.update({ where: { id }, data }),\n' +
    '  18 deleteUser: (id) => p.user.delete({ where: { id } }),\n' +
    '→ 19 linkAccount: (data) => p.account.create(\n' +
    'Unique constraint failed on the fields: (`userId`)\n' +
    '    at RequestHandler.handleRequestError (C:\\Users\\matt\\Documents\\GitHub\\njs13\\tailwindui-pocket\\node_modules\\@prisma\\client\\runtime\\index.js:35024:13)\n' +
    '    at RequestHandler.handleAndLogRequestError (C:\\Users\\matt\\Documents\\GitHub\\njs13\\tailwindui-pocket\\node_modules\\@prisma\\client\\runtime\\index.js:34996:12)\n' +
    '    at RequestHandler.request (C:\\Users\\matt\\Documents\\GitHub\\njs13\\tailwindui-pocket\\node_modules\\@prisma\\client\\runtime\\index.js:34991:12)\n' +
    '    at async PrismaClient._request (C:\\Users\\matt\\Documents\\GitHub\\njs13\\tailwindui-pocket\\node_modules\\@prisma\\client\\runtime\\index.js:36082:16)',
  name: 'Error'
}
[next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR]
https://next-auth.js.org/errors#oauth_callback_handler_error
Invalid `p.account.create()` invocation in
C:\Users\matt\Documents\GitHub\njs13\tailwindui-pocket\node_modules\@next-auth\prisma-adapter\dist\index.js:19:42

  16 },
  17 updateUser: ({ id, ...data }) => p.user.update({ where: { id }, data }),
  18 deleteUser: (id) => p.user.delete({ where: { id } }),
→ 19 linkAccount: (data) => p.account.create(
Unique constraint failed on the fields: (`userId`) Error:
Invalid `p.account.create()` invocation in
C:\Users\matt\Documents\GitHub\njs13\tailwindui-pocket\node_modules\@next-auth\prisma-adapter\dist\index.js:19:42

  16 },
  17 updateUser: ({ id, ...data }) => p.user.update({ where: { id }, data }),
  18 deleteUser: (id) => p.user.delete({ where: { id } }),
→ 19 linkAccount: (data) => p.account.create(
Unique constraint failed on the fields: (`userId`)
    at RequestHandler.handleRequestError (C:\Users\matt\Documents\GitHub\njs13\tailwindui-pocket\node_modules\@prisma\client\runtime\index.js:35024:13)
    at RequestHandler.handleAndLogRequestError (C:\Users\matt\Documents\GitHub\njs13\tailwindui-pocket\node_modules\@prisma\client\runtime\index.js:34996:12)
    at RequestHandler.request (C:\Users\matt\Documents\GitHub\njs13\tailwindui-pocket\node_modules\@prisma\client\runtime\index.js:34991:12)
    at async PrismaClient._request (C:\Users\matt\Documents\GitHub\njs13\tailwindui-pocket\node_modules\@prisma\client\runtime\index.js:36082:16) {
  name: 'LinkAccountError',
  code: 'P2002'

How to reproduce

create two twitch accounts with same email address

sign in to your prisma twitch provider website with both accounts

only the first account will be created, the second one will be errored

Expected behavior

allow both accounts to be logged in with separate user ids? not sure if it shoudl link them or make new acts

tried allowDangerousEmailAccountLinking: true but did not change anything except bypass the first issue of this: error=OAuthAccountNotLinked

rohailaltaf commented 1 year ago

How is this handled with other providers which allow multiple users with one email? Or is this the first of its kind? If it is indeed the first of its kind might be worth having a discussion how to address it moving forward. Can see a few scenarios:

We could also make the above a configuration setting when defining the provider

Geczy commented 1 year ago

I should mention, email addresses are optional on Twitch. i've had users sign up with an empty email address and oauth would error, so i had to make emails default nullable in the prisma schema, and non unique

this could be accounted for too with this issue?

rohailaltaf commented 1 year ago

Looking at the prisma docs it seems like a User object can have multiple Account objects and this is probably the functionality we want. Looking at the twitch adapter along with the twitch api docs the user ID is the unique identifier as opposed to the email. Hopefully a maintainer of the repo can give more clarity on what happens when a account can have multiple sub-accounts and can proceed from there. Happy to help on the PR side as well (if needed).

Geczy commented 1 year ago

yeah i agree, just wanted to point out that currently prisma assumes emails are unique: https://github.com/nextauthjs/next-auth/blob/main/packages/adapter-prisma/prisma/schema.prisma#L13 so this will error for people wanting to use this in the future

Geczy commented 1 year ago

also keep in mind, even if we have multiple Account objects for 1 User object, how will we track username differences? the Account object does not keep the username (name), this is stored on User (same for image differences)

Geczy commented 1 year ago

for this specific error maybe its my fault for having userId unique constraint on the Account schema. i see the prisma schema does not have unique on userId in Account. ill try without it and see what happens

image
Geczy commented 1 year ago

yeah once removing the unique constraint it's working now to save multiple accounts. but the username / image does not match the new account

balazsorban44 commented 1 year ago

Currently, we assume that emails are the same for all accounts that are connected to a single user. Actually, the author of next-auth assumed that multiple accounts with the same e-mail address might have been a mistake by the user, so the design heavily relies on the fact that e-mails can identify single users:

https://github.com/nextauthjs/next-auth/blob/3539a356010b952fefcad2a02ae3d60e2cba992d/packages/core/src/lib/callback-handler.ts#L161-L179

As such, this is currently expected behavior, so I'll convert this to a feature request for now, so the discussion can go on there.