Coder Social home page Coder Social logo

Comments (17)

bibaswan7 avatar bibaswan7 commented on June 29, 2024 8

I am not sure if its done intentionally but I went through the next-auth code and figured out that, even though CredentialsSignin error is being thrown, it is then passed to CallbackRouteError, which is why we are getting CallbackRouteError.
catch (e) { if (e instanceof AuthError) throw e; const error = new CallbackRouteError(e, { provider: provider.id }); logger.debug("callback route error details", { method, query, body }); throw error; }

here as you can see, catch recieves CredentialsSignin error. Since it is an instance of Error and not of AuthError, it skips the conditional, then rest is pretty much self explanatory.

In order to solve this issue, if its an CredentialsSignin error, then instead of checking error.type === 'CredentialsSignin', what you can do is
error.cause.err.code === 'credentials'

from next-auth.

shunkica avatar shunkica commented on June 29, 2024 4

For me, just returning null from authorize() throws the CallbackRouteError

from next-auth.

danbeo95 avatar danbeo95 commented on June 29, 2024 3

The same issue with 5.0.0-beta.19

from next-auth.

jessethomson avatar jessethomson commented on June 29, 2024 2

Experiencing the same issue as others: If I return null from authorize, it throws this error.

This issue only started happening after upgrading to the latest beta. I went from 5.0.0-beta.4 to 5.0.0-beta.19 so I'm not sure which version in between those specifically causes this issue.

from next-auth.

ondery avatar ondery commented on June 29, 2024 1

@ondery what error are you getting? mind sharing the code snippets?

@bibaswan7 error.cause.err.code === 'credentials' will give true in case of database connection problems too unfortunately.

from next-auth.

Ali-Raza764 avatar Ali-Raza764 commented on June 29, 2024 1

I think I have a fix of just signing in and handling an error if the password is incorrect. Instead of using signIn() function from the @/auth.js file we can do somthing like this in the signinForm:

import { signIn } from "next-auth/react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
import Providers from "../components/Providers";

const SignInForm = () => {
  const [loading, setLoading] = useState(false);
  const router = useRouter();
  const [error, setError] = useState("");

  const handleSubmit = async (e) => {
    e.preventDefault();
    const email = e.target.email.value;
    const password = e.target.password.value;

    try {
      setLoading(true);
      setError("");
      const res = await signIn("credentials", {
        redirect: false,
        email,
        password,
      });

      //* The res here has no credentials data only error:true or error:null so we can manage the state based on that
      //* Next auth does not send the data due to security reasons
      if (res.error === null) {
        router.push("/protected");
      }
      if (res.error) {
        setError("Check Your Email Or Password");
      }
    } catch (error) {
      console.error(error.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="shadow bg-gray-400 p-4 rounded-md m-2 min-w-[20rem]">
      <form onSubmit={handleSubmit} className="flex flex-col gap-4">
        <input
          type="text"
          name="email"
          placeholder="Email"
          className="border-b-2 border-gray-400 focus:border-red-500 outline-none  p-2 transition disabled:border-none disabled:bg-gray-400"
          required
          disabled={loading}
        />
        <input
          type="password"
          name="password"
          placeholder="Password"
          className="border-b-2 border-gray-400 focus:border-red-500 outline-none  p-2 transition disabled:border-none disabled:bg-gray-400"
          required
          disabled={loading}
        />
        <p className="text-red-500">{error}</p>
        <button
          type="submit"
          className="p-2 px-4 bg-gray-800 rounded-md text-white disabled:border-none disabled:bg-gray-600"
          disabled={loading}
        >
          Submit
        </button>
      </form>
      <div className="my-2 w-full text-center"> Or</div>
      <div className="w-full">
        <Providers />
      </div>
      <Link href="/auth/signup">SignUp</Link>
    </div>
  );
};

export default SignInForm;

If the signIn() functions throws an error Then it means that The credentials are invalid...
And If you are storing your user credentials in a database you can handle that authentication from the auth.js file using a server action:

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",
        };

        const res = await oauthSignIn(payload);
        user.id = res.data._id.toString();
        user.isVerified = res.data.isVerified;
        user.image = res.data.avatar;

        return user;
      }
      // Default to allow sign-in
      return user;
    },
    async jwt({ trigger, token, user }) {
      // Add user information to the token during sign-in
      if (trigger === "update") {
        token.isVerified = session.user.isVerified;
      }
      if (user) {
        console.log(user);
        const id = user._id?.toString() || user.id;
        token.id = id;
        token.email = user.email;
        token.name = user.name;
        token.isVerified = user.isVerified;
        token.picture = user.avatar || user.image;
      }
      return token;
    },
    async session({ session, token }) {
      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;
    },
  },
});```
I think this pretty much works for now. If you want to see detailed implementation for this you can checkout this [repo](https://github.com/Ali-Raza764/next-auth-tookit)

from next-auth.

yukinoyuu avatar yukinoyuu commented on June 29, 2024 1

Yeah @Ali-Raza764 That's exactly what I do currently, but I just want a bit more fine grain control over the error, and it is supposed to work, but just doesn't. For example, what if my API endpoint became unreachable and just timed out.. It would still say to check the credentials on the client side, even if they are correct. That would lead the user to try a bunch of times and then try to reset the password, which is not something I would want. Instead I want to distinguish whether it's because of the credentials (user does not exist on the token in the Callback). I think this could just be fixed with the typing, as @bibaswan7 said.

The issue for the broken types is #11155.

The types are broken in #11050

Screenshot 2024-06-14 at 11 31 09 AM

from next-auth.

bibaswan7 avatar bibaswan7 commented on June 29, 2024

i am facing the exact same issue

from next-auth.

nprdservice3 avatar nprdservice3 commented on June 29, 2024

I am not sure if its done intentionally but I went through the next-auth code and figured out that, even though CredentialsSignin error is being thrown, it is then passed to CallbackRouteError, which is why we are getting CallbackRouteError. catch (e) { if (e instanceof AuthError) throw e; const error = new CallbackRouteError(e, { provider: provider.id }); logger.debug("callback route error details", { method, query, body }); throw error; }

here as you can see, catch recieves CredentialsSignin error. Since it is an instance of Error and not of AuthError, it skips the conditional, then rest is pretty much self explanatory.

In order to solve this issue, if its an CredentialsSignin error, then instead of checking error.type === 'CredentialsSignin', what you can do is error.cause.err.code === 'credentials'

thanks it worked

from next-auth.

ondery avatar ondery commented on June 29, 2024

I am not sure if its done intentionally but I went through the next-auth code and figured out that, even though CredentialsSignin error is being thrown, it is then passed to CallbackRouteError, which is why we are getting CallbackRouteError. catch (e) { if (e instanceof AuthError) throw e; const error = new CallbackRouteError(e, { provider: provider.id }); logger.debug("callback route error details", { method, query, body }); throw error; }

here as you can see, catch recieves CredentialsSignin error. Since it is an instance of Error and not of AuthError, it skips the conditional, then rest is pretty much self explanatory.

In order to solve this issue, if its an CredentialsSignin error, then instead of checking error.type === 'CredentialsSignin', what you can do is error.cause.err.code === 'credentials'

When done this way, it will give the same error again if there is a connection problem with the database.

from next-auth.

bibaswan7 avatar bibaswan7 commented on June 29, 2024

@ondery what error are you getting? mind sharing the code snippets?

from next-auth.

azizali avatar azizali commented on June 29, 2024

same issue for me.

Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!

from next-auth.

yukinoyuu avatar yukinoyuu commented on June 29, 2024

@bibaswan7 I came to the same conclusion, but since I'm using typescript, it screams at me saying that property of code does not exist on type Error. Does anyone know a way to do typing properly with this weird wrapping, as well as @ondery mentioned, a way to disambiguate this error further?

I looked into the typing issue a bit more and found commit d089923 , where the typing of CredentialsSignin is changed from extending SignInError to extending Error. This further ambiguities the typing on the error. I found the issue for it in #11155

from next-auth.

Ali-Raza764 avatar Ali-Raza764 commented on June 29, 2024

Ok I do understand that. So we can wait until the new release makes a fix ?

from next-auth.

riky-on-devcra avatar riky-on-devcra commented on June 29, 2024

any updates?

Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!

from next-auth.

sambecker avatar sambecker commented on June 29, 2024

In case it's helpful, can confirm that Credentials-based error handling broke for me when switching to from beta.18 to beta.19.

Errors previously classified CredentialsSignin became classified CallbackRouteError.

from next-auth.

Ali-Raza764 avatar Ali-Raza764 commented on June 29, 2024

What if we can customize the authorize() function to return custom errors like this #9871
And here #9099

from next-auth.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.