authjs-nuxt icon indicating copy to clipboard operation
authjs-nuxt copied to clipboard

can singin with Email Provider by link in email when open in new tab

Open mttzzz opened this issue 10 months ago • 2 comments

Environment

Reproduction

I use simple [...].ts

import EmailProvider from '@auth/core/providers/nodemailer'
import type { AuthConfig } from '@auth/core/types'
import { NuxtAuthHandler } from '#auth'
import prisma from '~/server/prisma/client'
import { CustomPrismaAdapter } from '~/server/prisma/custom-prisma-adapter'

const runtimeConfig = useRuntimeConfig()

// Refer to Auth.js docs for more details
export const authOptions: AuthConfig = {
  debug: true,
  basePath: '/api/auth',
  secret: runtimeConfig.authJs.secret,
  adapter: CustomPrismaAdapter(prisma),
  session: {
    strategy: 'database',
  },
  providers: [
    EmailProvider({
      server: {
        service: 'yandex',
        auth: {
          user: runtimeConfig.nodemailer.user,
          pass: runtimeConfig.nodemailer.password,
        },
      },
      from: runtimeConfig.nodemailer.from,
    }),
  ],
}

export default NuxtAuthHandler(authOptions, runtimeConfig)

When i go to http://localhost:3000/api/auth/signin and enter email i reveive email with link. If i copy this link and paste in the same browser tab -- everithing work. im authnethicated, but if i just clink on link and browser open new tab with this link. i receive

Unable to sign in
The sign in link is no longer valid.

It may have been used already or it may have expired.

and error in console

 ERROR  [auth][error] Verification: Read more at https://errors.authjs.dev#verification


 ERROR      at Module.callback (file:///C:/Users/kiril/projects/chatgpt.pushka.biz/node_modules/.pnpm/@[email protected][email protected]/node_modules/@auth/core/lib/actions/callback/index.js:134:23)      
    at async AuthInternal (file:///C:/Users/kiril/projects/chatgpt.pushka.biz/node_modules/.pnpm/@[email protected][email protected]/node_modules/@auth/core/lib/index.js:27:24)
    at async Auth (file:///C:/Users/kiril/projects/chatgpt.pushka.biz/node_modules/.pnpm/@[email protected][email protected]/node_modules/@auth/core/index.js:109:34)
    at Object.handler (C:\Users\kiril\projects\chatgpt.pushka.biz\node_modules\.pnpm\@[email protected]_@[email protected][email protected]\node_modules\@hebilicious\authjs-nuxt\dist\runtime\lib\server.mjs:23:22)
    at async file:///C:/Users/kiril/projects/chatgpt.pushka.biz/node_modules/.pnpm/[email protected]/node_modules/h3/dist/index.mjs:1962:19
    at async Object.callAsync (file:///C:/Users/kiril/projects/chatgpt.pushka.biz/node_modules/.pnpm/[email protected]/node_modules/unctx/dist/index.mjs:72:16)
    at async Server.toNodeHandle (file:///C:/Users/kiril/projects/chatgpt.pushka.biz/node_modules/.pnpm/[email protected]/node_modules/h3/dist/index.mjs:2249:7)

Describe the bug

Im litteraly mad. Please help! :)

Additional context

No response

Logs

No response

mttzzz avatar Apr 06 '24 17:04 mttzzz

Some email clients send a HEAD request to the link when the user clicks it in the body. This leads to the link being actually wasted in that validation. Then, when the client sends the real request to the server, the link is no longer valid.

You can catch this HEAD request if you create a [...].head.ts (next to your [...].ts) to simply reply a 200 and make email client happy without wasting the link.

export default defineEventHandler(async (event) => { setResponseStatus(event, 200) })

Hope this works

josedgm avatar Apr 10 '24 19:04 josedgm

Some email clients send a HEAD request to the link when the user clicks it in the body. This leads to the link being actually wasted in that validation. Then, when the client sends the real request to the server, the link is no longer valid.

You can catch this HEAD request if you create a [...].head.ts (next to your [...].ts) to simply reply a 200 and make email client happy without wasting the link.

export default defineEventHandler(async (event) => { setResponseStatus(event, 200) })

Hope this works

@josedgm thx for help. But this dont work with Outlook. I can fix this with fake path and redirect

export default defineEventHandler((event) => {
  const params: Record<string, string> = getQuery(event)
  const queryString = new URLSearchParams(params).toString()
  const redirectUrl = `/api/auth/callback/email?${queryString}`
  return sendRedirect(event, redirectUrl)
})

mttzzz avatar Apr 19 '24 07:04 mttzzz