nextauthjs / next-auth

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

refetchInterval does not send "update" trigger #11037

Open sandervspl opened 5 months ago

sandervspl commented 5 months ago

Environment

  System:
    OS: macOS 14.3
    CPU: (12) arm64 Apple M2 Pro
    Memory: 2.55 GB / 32.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 18.18.0 - ~/.nvm/versions/node/v18.18.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.18.0/bin/yarn
    npm: 10.3.0 - ~/.nvm/versions/node/v18.18.0/bin/npm
    pnpm: 8.7.6 - ~/.nvm/versions/node/v18.18.0/bin/pnpm
    bun: 1.1.8 - ~/.nvm/versions/node/v18.18.0/bin/bun
  Browsers:
    Chrome: 125.0.6422.78
    Safari: 17.3

Reproduction URL

https://github.com/sandervspl/next-auth-refetchinterval

Describe the issue

I might be misunderstanding the point of refetchInterval, but currently it does not pass a value to the "trigger" prop in the JWT callback. The update() function DOES have a "update" value on trigger in the JWT callback.

When I read the docs (https://next-auth.js.org/getting-started/client#refetch-interval) there is a link to an "alternative" option that uses the update() function to achieve the same thing. So my understanding is that refetchInterval should also fire with an "update" trigger, just like the update() function does.

How to reproduce

  1. Clone the repo
  2. npm install
  3. npm run dev
  4. go to http://localhost:3000/
  5. Login with any username
  6. Check the terminal for logs to see that the jwt callback is fired without a trigger (should be "update")

Expected behavior

I expect the JWT callback trigger to have a value of update when I read the docs.

Ali-Raza764 commented 5 months ago

I have been facing a same issue. After email is verified I want to update the session because it holds the isEmail verified property. The v5 docs allow you to use the unstable_update method but it does not seem to work. Here is how I am using it. `import { auth, unstable_update } from "@/auth"; // Correctly import unstable_update import User from "@/utils/db/models/user.model"; import { NextResponse } from "next/server"; import dbConnect from "@/utils/db/dbConnect";

export async function GET(request) { const { searchParams } = new URL(request.url); const token = searchParams.get("token"); console.log("token", token);

const session = await auth();
if (!session) {
  return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}

await dbConnect();

const userId = session.user.id;
const user = await User.findById(userId);

if (!user) {
  return NextResponse.json({ message: "User not found" }, { status: 404 });
}

const currentTime = new Date().getTime();

if (
  token === user.verificationToken &&
  currentTime < user.verificationTokenExpiry
) {
  user.isVerified = true;
  await user.save();

  // Update the session and token with the new isVerified status
  await unstable_update({
    user: {
      ...session.user,
      isVerified: true
    }
  });

  // console.log("Route Session", session);

  return NextResponse.json({ message: "Verification successful" });
}

return NextResponse.json(
  { message: "Verification failed" },
  { status: 400 }
);}`
Ali-Raza764 commented 5 months ago

import NextAuth from "next-auth"; import GitHub from "next-auth/providers/github"; import Google from "next-auth/providers/google"; import CredentialsProvider from "next-auth/providers/credentials"; import { SignInWithEmailAndPassword, oauthSignIn, } from "@/actions/user/user.actions";

const providers = [ Google, GitHub, CredentialsProvider({ name: "Credentials", credentials: { email: { label: "Email", type: "email" }, password: { label: "Password", type: "password" }, }, async authorize(credentials) { const user = await SignInWithEmailAndPassword(credentials); // User verification logic if (user.status === 400) { return null; } return user.data; }, }), ];

export const providerMap = providers.map((provider) => { if (typeof provider === "function") { const providerData = provider(); return { id: providerData.id, name: providerData.name }; } else { return { id: provider.id, name: provider.name }; } });

export const { handlers, auth, signIn, signOut, unstable_update } = NextAuth({ providers, pages: { signIn: "/auth/sign-in", }, callbacks: { async signIn({ user, account }) { if (account.provider === "google" || account.provider === "github") { const { name, email, image } = user; const payload = { name, email, avatar: image, authType: "Oauth", };

    await oauthSignIn(payload);

    return true;
  }
  // Default to allow sign-in
  return true;
},
async jwt({ token, user }) {
  // Add user information to the token during sign-in
  if (user) {
    token.id = user._id.toString();
    token.email = user.email;
    token.name = user.name;
    token.isVerified = user.isVerified;
    token.picture = user.avatar;
  }
  return token;
},
async session({ session, token }) {
  // Add custom properties to the session object
  session.user.id = token.id;
  session.user.email = token.email;
  session.user.name = token.name;
  session.user.image = token.picture;
  session.user.isVerified = token.isVerified;
  return session;
},

}, });