amati/src/modules/auth/services/signIn.ts
2024-02-28 18:36:01 +07:00

55 lines
1.9 KiB
TypeScript

import "server-only";
import SignInFormData from "../types/SignInFormData";
import db from "@/core/db";
import AuthError from "../error/AuthError";
import comparePassword from "../utils/comparePassword";
import { createJwtToken } from "../utils/createJwtToken";
/**
* Authenticates a user with email and password credentials.
*
* This function looks up the user in the database by email. If the user exists and the password matches
* the hashed password in the database, a JWT token is created and returned. If any step of this process fails,
* an `AuthError` with a specific error code and message is thrown.
*
* @param rawCredential - Contains the email and password provided by the user.
* @returns An object containing a JWT token if authentication is successful.
* @throws {AuthError} - Throws an `AuthError` with an appropriate error code and message for various failure scenarios.
*/
export default async function signIn(rawCredential: SignInFormData) {
const user = await db.user.findUnique({
where: { email: rawCredential.email },
});
if (!user)
throw new AuthError({
errorCode: "EMAIL_NOT_FOUND",
message: "Email or Password does not match",
});
//TODO: Add handle for empty password hash
// Ensure there is a password hash to compare against.
if (!user.passwordHash)
throw new AuthError({
errorCode: "EMPTY_USER_HASH",
message: "Something wrong. Please contact your administrator",
});
// Compare the provided password with the stored hash.
const isMatch = await comparePassword(
rawCredential.password,
user.passwordHash
);
// Create a JWT token upon successful authentication.
if (!isMatch)
throw new AuthError({
errorCode: "INVALID_CREDENTIALS",
message: "Email or Password does not match",
});
const token = createJwtToken({ id: user.id });
return { token, user: { name: user.name, email: user.email, profilePhotoUrl: user.photoProfile} };
}