I am using next-auth @beta for authentication. Signin and signout working properly. If any error occur like password mismatch or user not found, it is not throwing the error. instead response is getting as {error: 'CredentialsSignin', status: 200, ok: true, url: null}
if email same and password different it is literally logging in even though credential doesn’t match.
// [...nextauth].js
import NextAuth, { AuthError } from "next-auth";
import Google from "next-auth/providers/google";
import Facebook from "next-auth/providers/facebook";
import Credentials from "next-auth/providers/credentials";
import { User } from "@/model/User";
import bcrypt from "bcryptjs";
import { authConfig } from "./auth.config";
import { NextResponse } from "next/server";
export const { handlers, signIn, signOut, auth } = NextAuth({
...authConfig,
providers: [
Google({
profile(profile) {
return { ...profile, role: profile.role ?? "user" };
},
}),
Facebook({
profile(profile) {
return { ...profile, role: profile.role ?? "user" };
},
}),
Credentials({
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Password", type: "password" },
},
authorize: async (credentials) => {
try {
const user = await User(credentials.email);
if (!user || !user.password) {
console.log('No user found');
throw new AuthError("User not found.")
}
const isPasswordCorrect = bcrypt.compare(
credentials.password,
user.password
);
if (!isPasswordCorrect) {
throw new AuthError("Incorrect password");
}
if (user.verified !== 1) {
throw new AuthError("User not verified");
}
return user;
} catch (error) {
console.error('Error in authorization:', error);
// throw error; // Re-throw the error
}
},
}),
],
});
this is auth.js inside src folder
"use client";
import axios from "axios";
import { useGoogleReCaptcha } from "react-google-recaptcha-v3";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Link from "next/link";
import React, { useEffect, useState } from "react";
import { signIn, useSession, getSession } from "next-auth/react";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
import * as Yup from "yup";
import { ErrorMessage, Field, Form, Formik } from "formik";
import { FormGroup, Label } from "reactstrap";
const LoginPage = () => {
const [errorMessage, setErrorMessage] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
const { data: session, status } = useSession();
const router = useRouter();
const [isMounted, setIsMounted] = useState(false);
const [passwordVisible, setPasswordVisible] = useState(false);
const { executeRecaptcha } = useGoogleReCaptcha();
const initialValues = {
email: "",
password: "",
};
const validationSchema = Yup.object().shape({
email: Yup.string().email("Invalid email").required("Required"),
password: Yup.string().min(5, "Too Short!").required("Required"),
});
useEffect(() => {
setIsMounted(true);
}, []);
useEffect(() => {
console.log("session", session);
if (status === "authenticated" && session?.user?.type) {
if (session.user.type === "STUDENT") {
router.push(`/`);
} else if (
session.user.type === "CONSULTANCIES" ||
session.user.type === "SUPER_ADMIN"
) {
if (session.user.is_approved === 1) {
router.push("/admin/dashboard");
}
}
}
}, [session, status, router]);
const handleSubmit = async (values) => {
setIsSubmitting(true);
try {
const signInResponse = await signIn("credentials", {
...values,
redirect: false,
});
console.log("signInResponse", signInResponse);
if (!signInResponse.error) {
toast.success("Login Successful");
// Fetch the updated session
const updatedSession = await getSession();
if (updatedSession && updatedSession.user) {
if (updatedSession.user.type === "STUDENT") {
router.push(`/`);
} else if (
updatedSession.user.type === "CONSULTANCIES" ||
updatedSession.user.type === "SUPER_ADMIN"
) {
if (updatedSession.user.is_approved === 1) {
router.push("/admin/dashboard");
}
}
} else {
throw new Error("Session is not defined");
}
setIsSubmitting(false);
} else {
throw new Error("Login failed");
}
} catch (error) {
if (error instanceof AuthError) {
setErrorMessage(error.message);
} else {
console.error("Login error", error);
}
setIsSubmitting(false);
}
};
const togglePasswordVisibility = () => {
setPasswordVisible(!passwordVisible);
};
if (!isMounted) {
return null;
}
return (
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
className="mt-5"
>
<Form>
<h4 className="text-center">
<b>Login</b>
</h4>
<p className="text-muted lh-large">
Access personalized support and services for your study abroad journey
</p>
{errorMessage && <h1 className="z-1">{errorMessage}</h1>}
<FormGroup>
<Label>Email *</Label>
<Field type="text" id="email" name="email" className="form-control" />
<ErrorMessage name="email" component="div" className="text-danger" />
</FormGroup>
<FormGroup>
<Label>Password *</Label>
<div className="input-group">
<Field
type={passwordVisible ? "text" : "password"}
id="password"
name="password"
className="form-control"
/>
<button
type="button"
className="btn border"
onClick={togglePasswordVisibility}
>
{passwordVisible ? (
<FontAwesomeIcon icon={faEyeSlash} />
) : (
<FontAwesomeIcon icon={faEye} />
)}
</button>
</div>
<ErrorMessage
name="password"
component="div"
className="text-danger"
/>
</FormGroup>
<div className="pt-1 mb-2">
<div className="d-grid gap-2 d-flex justify-content-between mb-2">
<a className="small text-muted" href="/forgot-password">
Forgot password?
</a>
<button
className="btn btn-block login-btn"
type="submit"
disabled={isSubmitting}
>
{isSubmitting ? "Logging in..." : "Login"}
</button>
</div>
<div className="login-social-title">
<h5>Sign in with</h5>
</div>
<div className="d-flex align-items-center justify-content-between gap-2 mt-2">
<button
type="button"
className="btn btn-google"
onClick={() => signIn("google")}
>
Google
</button>
<button
type="button"
className="btn btn-facebook"
onClick={() => signIn("facebook")}
>
Facebook
</button>
</div>
</div>
<p className="my-1 lh-lg">
Don't have an account? <Link href={"/register"}>Register here</Link>
</p>
</Form>
</Formik>
);
};
export default LoginPage;
this is login page. Error is correctly getting is auth.js but not as response in login page.