Next.js Discord

Discord Forum

Server action for signIn function

Unanswered
TK2 posted this in #help-forum
Open in Discord
TK2OP
I was finally able to get more meaningful error message returned when credentials are incorrect during sign in. I'm just wondering if this could be simplified any further or if I'm missing something
authenticate server action
'use server'
 
import { signIn } from '@/auth'
import { AuthError } from 'next-auth';

export async function authenticate(email: string, password: string, values: Object) {
  try {
    console.log("values inside authenticate()", email, password)
    await signIn("credentials", {
      email: email,
      password: password,
      redirect: false
    })
  } catch (error) {
    if (error instanceof AuthError) {
      switch (error.type) {
        case 'CredentialsSignin':
          return 'Invalid credentials.';
        default:
          return 'Something went wrong.';
      }
    }
    throw error;
  }
}

And here is where I'm calling the function in my login page
  const handleServerSignIn = async (
    values: z.infer<typeof signInSchema>,
    e,
  ) => {
    e.preventDefault();
    try {
      console.log("values in handleServerSignIn", values);
      const data = await authenticate(values.email, values.password);
      console.log("data", data);
      if (data) {
        toast({
          title: "Error",
          description: data,
          variant: "destructive",
        });
      } else {
        router.refresh();
        router.push("/dashboard/admin");
      }
    } catch (error) {
      console.log("error catch handleServerSignIn()", error);
    }
  };

6 Replies

TK2OP
For reference my auth.config I have extending CredentialsSignIn and throwing error strings but have no successfully been able to return those errors to client after failed signin
class InvalidEmailError extends CredentialsSignin {
  code = "Email is not associated with any existing user."
}

class InvalidPasswordError extends CredentialsSignin {
  code = "Password does not match our records."
}

class InvalidLoginError extends CredentialsSignin {
  code = "Invalid credentials."
}
 
export default { 
  providers: 
  [
    GitHub, 
    Google,
    CredentialsProvider({
      id: "credentials",
      name: "Credentials",
      credentials: {
        email: {
          label: "Email",
            type: "text",
            placeholder: "example@gmail.com"
        },
        password: {
          label: "password",
          type: "password",
          placeholder: "************"
        },
      },
      authorize: async (credentials) => {
        try {
          console.log("Credentials inside authorize function", credentials);
          const { email, password } = await signInSchema.parseAsync(credentials);
          console.log("parseAsync credentials ", email, password)
  
          const user = await prisma.user.findUnique({
            where: { email: email.toLowerCase() },
          })

          console.log("user look up", user);
  
          // throw error that email is not found
          if (!user) {
            throw new InvalidEmailError();
          };
  
          // compare passwords and throw password doesn't match records error
          if (!bcryptjs.compareSync(password, user.password)) {
            throw new InvalidPasswordError();
          }
  
          const { password: _, ...rest } = user;


          return user;
  
        } catch(error) {
          console.log("error inside catch block authorize()")
          throw new InvalidLoginError();
        }
      }
    }),
  ],
 } satisfies NextAuthConfig
TK2OP
hmm
You can’t throw in a server action. Just return a object with an error message in it
{error:error.message}
You can’t throw specific data from a server action this is an intended function as it stops leakage of server side secrets
There’s also a nice doc on throwing in server actions someone from the discord made but I gotta find it later I’m mobile