const catchAsync = require("../../utils/catchAsync"); const { createToken, verifyToken } = require("../../utils/jwt"); const sendResponse = require("../../utils/sendResponse"); const sendConfirmationEmail = require("../../utils/sendConfirmationEmail"); const sendResetPassEmail = require("../../utils/sendResetPassEmail"); const { registerUser, loginUser, firebaseLogin: firebaseAuth, } = require("./auth.service"); const httpStatus = require("http-status"); const AppError = require("../../errors/AppError"); const supabase = require("../../config/supabaseClient"); const bcrypt = require("bcrypt"); const { client_url } = require("../../config"); const register = catchAsync(async (req, res) => { const user = await registerUser(req.body); const verificationToken = createToken( { email: user.email, userId: user.id }, "24h" ); await sendConfirmationEmail(user.email, verificationToken); sendResponse(res, { success: true, message: "Registration successful. Please check your email for verification.", data: { id: user.id, name: user.name, email: user.email }, statusCode: httpStatus.CREATED, }); }); const login = catchAsync(async (req, res) => { const result = await loginUser(req.body); sendResponse(res, { success: true, message: "Login successful", data: result, statusCode: httpStatus.OK, }); }); const firebaseLogin = catchAsync(async (req, res) => { const result = await firebaseAuth(req.body); sendResponse(res, { success: true, message: "Login successful", data: result, statusCode: httpStatus.OK, }); }); const verifyEmail = catchAsync(async (req, res) => { const { token } = req.query; if (!token) { throw new AppError(httpStatus.BAD_REQUEST, "Verification token required"); } const decoded = verifyToken(token); const { error } = await supabase .from("users") .update({ is_verified: true }) .eq("email", decoded.email) .eq("id", decoded.userId); if (error) { throw new AppError(httpStatus.BAD_REQUEST, "Verification failed"); } sendResponse(res, { success: true, message: "Email verified successfully", data: null, statusCode: httpStatus.OK, }); }); const resendVerification = catchAsync(async (req, res) => { const { email } = req.body; const { data: user, error } = await supabase .from("users") .select("*") .eq("email", email) .single(); if (error || !user) { throw new AppError(httpStatus.NOT_FOUND, "User not found"); } if (user.is_verified) { throw new AppError(httpStatus.BAD_REQUEST, "User already verified"); } const verificationToken = createToken( { email: user.email, userId: user.id }, "24h" ); await sendConfirmationEmail(user.email, verificationToken); sendResponse(res, { success: true, message: "Verification email sent", data: null, statusCode: httpStatus.OK, }); }); const forgotPassword = catchAsync(async (req, res) => { const { email } = req.body; const { data: user } = await supabase .from("users") .select("*") .eq("email", email) .single(); if (!user) { sendResponse(res, { success: true, message: "If email exists, reset link has been sent", data: null, statusCode: httpStatus.OK, }); return; } const resetToken = createToken({ email, userId: user.id }, "15m"); const resetLink = `${client_url}/reset-password?token=${resetToken}`; await sendResetPassEmail(email, resetLink); sendResponse(res, { success: true, message: "Password reset email sent", data: null, statusCode: httpStatus.OK, }); }); const resetPassword = catchAsync(async (req, res) => { const { newPassword, token } = req.body; const decoded = verifyToken(token); const hashedPassword = await bcrypt.hash(newPassword, 10); const { error } = await supabase .from("users") .update({ password_hash: hashedPassword }) .eq("email", decoded.email) .eq("id", decoded.userId); if (error) { throw new AppError(httpStatus.BAD_REQUEST, "Password reset failed"); } sendResponse(res, { success: true, message: "Password reset successful", data: null, statusCode: httpStatus.OK, }); }); const getProfile = catchAsync(async (req, res) => { const { data: user, error } = await supabase .from("users") .select( "id, name, email, phone, role, is_verified, profile_picture, created_at" ) .eq("id", req.user.userId) .single(); if (error) { throw new AppError(httpStatus.NOT_FOUND, "User not found"); } sendResponse(res, { success: true, message: "Profile retrieved successfully", data: user, statusCode: httpStatus.OK, }); }); const AuthController = { register, login, firebaseLogin, verfiyEmail: verifyEmail, resendVerification, forgotPassword, resetPassword, getProfile, }; module.exports = AuthController;