NextAuth /verify-request double-triggering, invalidating token

Hello, I'm experiencing some issues with the EmailProvider from NextAuth. Unable to find any answers online I thought I'd take my question here, if someone has had any similar issues. So for some context, I am running MongoDB /w Prisma and this is is model for the VerificationToken (however I doubt the issue lies here)
model VerificationToken {
id String @id @default(auto()) @map("_id") @db.ObjectId
identifier String
token String @unique
expires DateTime

@@unique([identifier, token])
}
model VerificationToken {
id String @id @default(auto()) @map("_id") @db.ObjectId
identifier String
token String @unique
expires DateTime

@@unique([identifier, token])
}
my auth.ts like so:
export const authOptions: NextAuthOptions = {
callbacks: {
signIn: async (user) => {
const { name, image, id } = user.user;
if (!name || !image)
await prisma.user.update({
where: { id },
data: {
name: !name ? "User" : undefined,
image: !image
? "/assets/imgs/default-avatar.png"
: undefined,
},
});

return true;
},
session: ({ session, user }) => ({
...session,
user: {
...session.user,
id: user.id,
tag: user.tag,
lastTagReset: user.lastTagReset,
role: user.role,
},
}),
},
adapter: PrismaAdapter(prisma),
providers: [
...
EmailProvider({
server: env.EMAIL_SERVER,
from: env.EMAIL_FROM,
}),
...
],
cookies: {
pkceCodeVerifier: {
name: "next-auth.pkce.code_verifier",
options: {
httpOnly: true,
sameSite: "none",
path: "/",
secure: true,
},
},
},
};
export const authOptions: NextAuthOptions = {
callbacks: {
signIn: async (user) => {
const { name, image, id } = user.user;
if (!name || !image)
await prisma.user.update({
where: { id },
data: {
name: !name ? "User" : undefined,
image: !image
? "/assets/imgs/default-avatar.png"
: undefined,
},
});

return true;
},
session: ({ session, user }) => ({
...session,
user: {
...session.user,
id: user.id,
tag: user.tag,
lastTagReset: user.lastTagReset,
role: user.role,
},
}),
},
adapter: PrismaAdapter(prisma),
providers: [
...
EmailProvider({
server: env.EMAIL_SERVER,
from: env.EMAIL_FROM,
}),
...
],
cookies: {
pkceCodeVerifier: {
name: "next-auth.pkce.code_verifier",
options: {
httpOnly: true,
sameSite: "none",
path: "/",
secure: true,
},
},
},
};
I have placed a quick console.log in the NextAuth src, just to possibly get some more information, to which I discovered that it seems to double trigger
useVerificationToken {
identifier: '...',
token: 'b8df22aa3d0ff9f1321805437ea807d6199d833e3ec4b0cba278d79ee0404793'
}
useVerificationToken {
identifier: '...',
token: 'b8df22aa3d0ff9f1321805437ea807d6199d833e3ec4b0cba278d79ee0404793'
}
useVerificationToken {
identifier: '...',
token: 'b8df22aa3d0ff9f1321805437ea807d6199d833e3ec4b0cba278d79ee0404793'
}
useVerificationToken {
identifier: '...',
token: 'b8df22aa3d0ff9f1321805437ea807d6199d833e3ec4b0cba278d79ee0404793'
}
I am also able to see the actual session in the DB, which then gets REMOVED but still gives errors that it was "unable to find the record"
prisma:error
Invalid `prisma.verificationToken.delete()` invocation:


An operation failed because it depends on one or more records that were required but not found. Record to delete does not exist.
{"name":"PrismaClientKnownRequestError","code":"P2025","clientVersion":"5.3.1","meta":{"cause":"Record to delete does not exist."}}
prisma:error
Invalid `prisma.verificationToken.delete()` invocation:


An operation failed because it depends on one or more records that were required but not found. Record to delete does not exist.
{"name":"PrismaClientKnownRequestError","code":"P2025","clientVersion":"5.3.1","meta":{"cause":"Record to delete does not exist."}}
ANY help is appreciated, I've been banging my head over this for hours now and I don't understand why it's acting like this
Solution:
After coming back to this a few days later, I have found the problem, opening the dumb link through Outlook (because the standard Windows Mail app was not enough) it seems to trigger the endpoint on it's own somehow, invalidating the URL and then when I finally had the window open, the link was now already used. So TL;DR: Probably use Gmail or the standard windows Mail app until it gets discontinued. If you use outlook, copy the link and paste it in the browser yourself...
Jump to solution
2 Replies
Snow
Snow14mo ago
Additional console output:
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, }, }, ])
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, identifier: 1, token: 1, expires: 1, }, }, ])
prisma:query db.VerificationToken.deleteMany({ _id: { $in: [ ObjectId("652188cb5cf49952dc051faf"), ], }, })
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, }, }, ])
prisma:query db.VerificationToken.deleteMany({ _id: { $in: [ ObjectId("652188cb5cf49952dc051faf"), ], }, })
prisma:query db.User.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $eq: [ "$email", { $literal: "...", }, ], }, { $ne: [ "$email", "$$REMOVE", ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, name: 1, tag: 1, lastTagReset: 1, bio: 1, email: 1, emailVerified: 1, password: 1, banner: 1, image: 1, role: 1, verified: 1, likedPosts: 1, followerIds: 1, followingIds: 1, }, }, ])
prisma:query db.Session.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $eq: [ "$sessionToken", { $literal: "d1aedcd2-7a9d-4ba9-abea-f4bfad5f0ec2", }, ], }, { $ne: [ "$sessionToken", "$$REMOVE", ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, sessionToken: 1, userId: 1, expires: 1, }, }, ])
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, identifier: 1, token: 1, expires: 1, }, }, ])
prisma:query db.User.aggregate([ { $match: { $expr: { $and: [ { $in: [ "$_id", [ { $literal: ObjectId("6387a6701ea31d5d5394e144"), }, ], ], }, { $ne: [ "$_id", "$$REMOVE", ], }, ], }, }, }, { $project: { _id: 1, name: 1, tag: 1, lastTagReset: 1, bio: 1, email: 1, emailVerified: 1, password: 1, banner: 1, image: 1, role: 1, verified: 1, likedPosts: 1, followerIds: 1, followingIds: 1, }, }, ])
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, }, }, ])
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, identifier: 1, token: 1, expires: 1, }, }, ])
prisma:query db.VerificationToken.deleteMany({ _id: { $in: [ ObjectId("652188cb5cf49952dc051faf"), ], }, })
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, }, }, ])
prisma:query db.VerificationToken.deleteMany({ _id: { $in: [ ObjectId("652188cb5cf49952dc051faf"), ], }, })
prisma:query db.User.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $eq: [ "$email", { $literal: "...", }, ], }, { $ne: [ "$email", "$$REMOVE", ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, name: 1, tag: 1, lastTagReset: 1, bio: 1, email: 1, emailVerified: 1, password: 1, banner: 1, image: 1, role: 1, verified: 1, likedPosts: 1, followerIds: 1, followingIds: 1, }, }, ])
prisma:query db.Session.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $eq: [ "$sessionToken", { $literal: "d1aedcd2-7a9d-4ba9-abea-f4bfad5f0ec2", }, ], }, { $ne: [ "$sessionToken", "$$REMOVE", ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, sessionToken: 1, userId: 1, expires: 1, }, }, ])
prisma:query db.VerificationToken.aggregate([ { $match: { $expr: { $and: [ { $and: [ { $and: [ { $and: [ { $eq: [ "$identifier", { $literal: "...", }, ], }, { $ne: [ "$identifier", "$$REMOVE", ], }, ], }, { $and: [ { $eq: [ "$token", { $literal: "55edb37ad4c3604d500feb4abf5a1c3231b9f4f2efa2f95f9feb880aae5fc80e", }, ], }, { $ne: [ "$token", "$$REMOVE", ], }, ], }, ], }, ], }, { }, ], }, }, }, { $project: { _id: 1, identifier: 1, token: 1, expires: 1, }, }, ])
prisma:query db.User.aggregate([ { $match: { $expr: { $and: [ { $in: [ "$_id", [ { $literal: ObjectId("6387a6701ea31d5d5394e144"), }, ], ], }, { $ne: [ "$_id", "$$REMOVE", ], }, ], }, }, }, { $project: { _id: 1, name: 1, tag: 1, lastTagReset: 1, bio: 1, email: 1, emailVerified: 1, password: 1, banner: 1, image: 1, role: 1, verified: 1, likedPosts: 1, followerIds: 1, followingIds: 1, }, }, ])
Solution
Snow
Snow13mo ago
After coming back to this a few days later, I have found the problem, opening the dumb link through Outlook (because the standard Windows Mail app was not enough) it seems to trigger the endpoint on it's own somehow, invalidating the URL and then when I finally had the window open, the link was now already used. So TL;DR: Probably use Gmail or the standard windows Mail app until it gets discontinued. If you use outlook, copy the link and paste it in the browser yourself
Want results from more Discord servers?
Add your server