HuXn-WebDev / Auth.js-v5-Complete-Course

All the source code for my Auth.js v5 Complete Course 🥂
https://www.youtube.com/watch?v=soprdrmpO3M
66 stars 5 forks source link

I am struggling to show the appropriate response message from the 'authorize' function the when the user tries to sign-in. It is not re #2

Open Python-killer14 opened 3 months ago

Python-killer14 commented 3 months ago

I am struggling to show the appropriate response message from the 'authorize' function the when the user tries to sign-in. The message is not being received in my signIn form:

This is part of the signin page that handles submission: "use client"; import React, { useState } from "react"; import Link from "next/link"; import { cn } from "@/lib/utils";

// Zod and form validation import { useForm, SubmitHandler } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { authFormSchema } from "./formValidationSchemas/formValidationSchema";

// Compons import { Input } from "@mui/joy"; import { Button } from "../ui/button";

// Icons import { Eye, EyeOff, Lock, Mail, User } from "lucide-react"; import { SignUpFormTypes } from "@/types/authTypes/authTypes"; import { signIn } from "next-auth/react"; import { z } from "zod";

const AuthForm = ({ isLogin }: { isLogin: boolean }) => { // Form validation setups const { register, handleSubmit, setError, formState: { errors }, } = useForm({ resolver: zodResolver(authFormSchema) });

// States const [passwordType, setPasswordType] = useState("password");

const togglePassType = () => { passwordType === "password" ? setPasswordType("text") : setPasswordType("password"); };

// On submit handler function const onSubmit: SubmitHandler = async ( data: z.infer ) => { if (isLogin) { // Handle sign in const res = await signIn("credentials", { email: data.email, password: data.password, redirect: false, //Prevent redirect });

  if (res?.error) {
    console.log("signin err:", res);
    setError("email", { type: "manual", message: res.error });
    setError("password", { type: "manual", message: res.error });
  } else {
    console.log("signin resp:", res);
  }
} else {
  // Handle sign up
  // console.log("Sign up data:", data);
}

};

return ( <form onSubmit={handleSubmit(onSubmit)} className={cn(isLogin ? "grid" : "grid grid-cols-2 gap-x-2 text-inherit")}

} {...register("email")} /> {errors.email?.message && (

{/* Invalid email, pls try again. */} {errors.email.message}

)}
  {!isLogin && (
    <div className="mb-4">
      <Input
        type="text"
        placeholder="First Name"
        startDecorator={<User strokeWidth={1.4} className="" />}
        className=""
        {...register("firstName")}
      />
      {errors.firstName && (
        <p className="text-xs text-red-600 mt-1">
          {errors.firstName?.message || "Err"}
        </p>
      )}
    </div>
  )}

  {!isLogin && (
    <div className=" mb-4">
      <Input
        type="text"
        placeholder="Last Name"
        startDecorator={<User strokeWidth={1.4} className="" />}
        className=""
        {...register("lastName")}
      />
      {errors.lastName && (
        <p className=" text-xs text-red-600 mt-1">
          {errors.lastName?.message}
        </p>
      )}
    </div>
  )}

  <div className="col-span-2">
    <Input
      type={passwordType}
      placeholder="Password"
      startDecorator={<Lock strokeWidth={1.4} />}
      endDecorator={
        passwordType === "password" ? (
          <Eye onClick={togglePassType} />
        ) : (
          <EyeOff onClick={togglePassType} />
        )
      }
      className="border rounded col-span-2"
      {...register("password")}
    />
    {errors.password && (
      <p className=" text-xs text-red-600 mt-1">
        {errors.password?.message}
      </p>
    )}
  </div>

  {/* Forgot password options */}
  <section className="text-right col-span-2 py-2 ">
    {isLogin && (
      <Link
        href="/forgot-password"
        className=" text-blue-600 text-xs font-medium hover:underline"
      >
        Forgot password
      </Link>
    )}
  </section>

  {/* Submit btn */}
  <Button
    type="submit"
    className={cn(
      "mt-6 w-full col-span-2 bg-rose-red transition-colors duration-100 ease-linear hover:bg-darker-red-rose"
    )}
  >
    {isLogin ? "Sign in" : "Sign up"}
  </Button>
</form>

); };

export default AuthForm;

And here is my auth.ts with authroize -----------------------------------------------

import NextAuth, { CredentialsSignin, User } from "next-auth"; import Credentials from "next-auth/providers/credentials"; import Github from "next-auth/providers/github"; import Google from "next-auth/providers/google"; import connectDB from "@/utils/connectDB"; import userModel from "@/app/models/userModel"; import bcrypt from "bcryptjs";

export const { handlers, signIn, signOut, auth } = NextAuth({ providers: [ Google, Credentials({ name: "Credentials", credentials: { email: { label: "Email", type: "email" }, password: { label: "Password", type: "password" }, },

  authorize: async (credentials) => {
    const email = credentials.email as string | undefined;
    const password = credentials.password as string | undefined;

    if (!email || !password) {
      throw new Error("Please provide both email & password");
    }

    await connectDB();

    const user = await userModel.findOne({ email });

    if (!user) {
      console.log("1. User not found ----");
      throw new Error("Invalid email or password");
    }

    if (!user.password) {
      console.log("2. Invalid email or password ----");
      throw new Error("Invalid email or password");
    }

    // const isMatched = await bcrypt.compare(password, user.password);
    const isMatched = password === user.password;

    if (!isMatched) {
      console.log("3. Password did not matched ----");
      throw new Error("Password did not matched");
    }

    const userData = {
      firstName: user.firstName,
      lastName: user.lastName,
      email: user.email,
      role: user.role,
      id: user._id,
    };

    return userData;
  },
}),

],

pages: { signIn: "/login", },

callbacks: { async session({ session, token }) { if (token && token?.role) { session.user.id = token.id as string; session.user.role = token.role as string; } return session; },

async jwt({ token, user }) {
  if (user) {
    token.role = user.role;
  }
  return token;
},

signIn: async ({ user, account }) => {
  if (account?.provider === "google") {
    try {
      const { email, name, image, id } = user;
      await connectDB();
      const alreadyUser = await userModel.findOne({ email });

      if (!alreadyUser) {
        await userModel.create({ email, name, image, authProviderId: id });
      } else {
        return true;
      }
    } catch (error) {
      throw new Error("Error while creating user");
    }
  }

  if (account?.provider === "credentials") {
    return true;
  } else {
    return false;
  }
},

}, });