/** * Copyright (c) 2026 Niolla * All rights reserved. * * This source code is proprietary and confidential. * Unauthorized copying, modification, distribution, or use * of this file, via any medium, is strictly prohibited. */ // app/controllers/profile.controller.js const db = require("../models"); const Profile = db.Profile; const Upload = db.Upload; const User = db.User; const { generateTodoId } = require("../utils/idGen.util"); const { getSignedFileUrl } = require("../utils/s3Upload.utill"); const { generateResetToken, resetPassword, } = require("../utils/passwordReset.utill"); const { sendMail } = require("../utils/mail.util"); const { logActivity } = require("../services/activity.service"); const { hashPassword, checkPassword } = require("../utils/hashPassword.util"); const { log } = require("../utils/consoleLog.utill"); // Get Profile avatar by user ID exports.getProfileAvatar = async (req, res) => { try { const userId = req.params.userId || req.user.id; const profile = await Profile.findOne({ where: { user_id: userId } }); if (!profile) { return res.status(404).json({ error: "Profile not found" }); } const uploadRecord = await Upload.findByPk(profile.profilePicture_id); if (!uploadRecord || uploadRecord.status !== "AVAILABLE" || (uploadRecord.visibility !== "PUBLIC" && uploadRecord.owner_id !== userId)) return res.status(404).json({ success: false, message: "Profile image not found" }); const fileUrl = await getSignedFileUrl(uploadRecord.file_path); res.json({ success: true, data: { userId: profile.user_id, profilePictureUrl: fileUrl, }, }); } catch (error) { console.error("Error fetching profile:", error); res.status(500).json({ success: false, message: "Internal server error", error: error.message, }); } }; // Get profile background image by user ID exports.getProfileBackgroundImage = async (req, res) => { try { const userId = req.params.userId || req.user.id; const profile = await Profile.findOne({ where: { user_id: userId } }); if (!profile) { return res .status(404) .json({ success: false, message: "Profile not found" }); } const uploadRecord = await Upload.findByPk(profile.backgroundImage_id); if (!uploadRecord || uploadRecord.status !== "AVAILABLE" || (uploadRecord.visibility !== "PUBLIC" && uploadRecord.owner_id !== userId)) return res.status(404).json({ success: false, message: "Profile background not found" }); const fileUrl = await getSignedFileUrl(uploadRecord.file_path); res.json({ success: true, data: { userId: profile.user_id, backgroundImageUrl: fileUrl, }, }); } catch (error) { console.error("Error fetching profile background image:", error); res.status(500).json({ success: false, message: "Internal server error", error: error.message, }); } }; // Request password reset token exports.requestPasswordReset = async (req, res) => { try { const { email } = req.body; const user = await User.findOne({ where: { email }, }); if (user) { const token = await generateResetToken(user.id); const resetLink = `${process.env.FRONTEND_URL}/reset-password?token=${token}&email=${encodeURIComponent(email)}`; await sendMail({ to: user.email, subject: "Password Reset", templateName: "passwordReset", templateVars: { firstName: user.firstName, resetLink, expiryTime: process.env.PASSWORD_RESET_EXPIRY_TIME || "10 minutes", }, }); const activityUser = { id: 1, firstName: "System", }; await logActivity({ user: activityUser, description: "Requested password reset for email: " + email, type: "PASSWORD_RESET_REQUEST", module: "Authentication", }); } return res.json({ success: true, message: "If an account exists with this email address, a password reset email has been sent.", }); } catch (error) { console.error(error); return res.status(500).json({ success: false, message: "Internal server error", }); } }; // Reset password using token exports.resetPassword = async (req, res) => { try { const { email, token, newPassword } = req.body; // Validate email const user = await User.findOne({ where: { email }, }); if (!user) { return res.status(400).json({ success: false, message: "Invalid email address.", }); } await resetPassword(user.id, token, newPassword); return res.json({ success: true, message: "Password reset successfully.", }); } catch (error) { return res.status(400).json({ success: false, message: error.message || "Invalid or expired token.", }); } }; // Change Password exports.changePassword = async (req, res) => { try { const { currentPassword, newPassword } = req.body; const user = req.user; log(`User:`, user); const foundUser = await User.findOne({ where: { id: user.id } }); if (!foundUser) { return res.status(404).json({ success: false, message: "User not found.", }); } const isMatch = await checkPassword(currentPassword, foundUser.password); if (!isMatch) { return res.status(400).json({ success: false, message: "Current password is incorrect.", }); } foundUser.password = await hashPassword(newPassword); await foundUser.save(); await logActivity({ user: req.user, description: "Changed password", type: "PASSWORD_CHANGE", module: "Authentication", }); return res.json({ success: true, message: "Password changed successfully.", }); } catch (error) { return res.status(400).json({ success: false, message: error.message || "Failed to change password.", }); } };