diff --git a/backend/controllers/referral.controller.js b/backend/controllers/referral.controller.js index 96c657d..f2bf630 100644 --- a/backend/controllers/referral.controller.js +++ b/backend/controllers/referral.controller.js @@ -394,20 +394,21 @@ async function rejectReferral(req, res, next) { // Get single referral by ID async function getReferralById(req, res, next) { try { - const referral = await JobReferral.findById(req.params.id) - .populate('postedBy', 'name email alumnus_bio type referralPostingSuspended referralPostingSuspendedReason') - .populate('applicants.user', 'name email alumnus_bio'); - + const { referral, access } = await getReferralAccess(req.params.id, req.user.id); + if (!referral) { return res.status(404).json({ message: 'Referral not found' }); } - const currentUser = req.user?.id ? await getCurrentUserSummary(req.user.id) : null; - const isOwner = referral.postedBy?._id?.toString() === req.user?.id; - if (isReferralHidden(referral) && currentUser?.type !== 'admin' && !isOwner) { + if (!access) { + // Do not leak referral existence. return res.status(404).json({ message: 'Referral not found' }); } + // Keep response structure consistent with prior implementation. + await referral.populate('postedBy', 'name email alumnus_bio type referralPostingSuspended referralPostingSuspendedReason'); + await referral.populate('applicants.user', 'name email alumnus_bio'); + res.json(referral); } catch (err) { next(err); @@ -416,14 +417,14 @@ async function getReferralById(req, res, next) { async function getReferralTimeline(req, res, next) { try { - const referral = await JobReferral.findById(req.params.id).select('timeline moderation postedBy'); + const { referral, access } = await getReferralAccess(req.params.id, req.user.id); + if (!referral) { return res.status(404).json({ message: 'Referral not found' }); } - const currentUser = req.user?.id ? await getCurrentUserSummary(req.user.id) : null; - const isOwner = referral.postedBy?.toString() === req.user?.id; - if (isReferralHidden(referral) && currentUser?.type !== 'admin' && !isOwner) { + if (!access) { + // Do not leak referral existence. return res.status(404).json({ message: 'Referral not found' }); } @@ -437,7 +438,9 @@ async function getReferralTimeline(req, res, next) { } } + async function closeReferral(req, res, next) { + try { const { id } = req.params; const currentUser = await getCurrentUserSummary(req.user.id); diff --git a/frontend/src/components/ReferralDetail.jsx b/frontend/src/components/ReferralDetail.jsx index faa2a28..31c74f8 100644 --- a/frontend/src/components/ReferralDetail.jsx +++ b/frontend/src/components/ReferralDetail.jsx @@ -65,14 +65,15 @@ const ReferralDetail = () => { return; } - if (isOwner && applicants.length > 0 && !selectedRecipientId) { - setSelectedRecipientId(getDocId(applicants[0].user)); + if (isOwner) { + if (applicants.length > 0 && !selectedRecipientId) { + setSelectedRecipientId(getDocId(applicants[0].user)); + } + return; } - if (!isOwner) { - setSelectedRecipientId(getDocId(referral.postedBy)); - } - }, [referral, applicants, isOwner, selectedRecipientId]); + setSelectedRecipientId(getDocId(referral.postedBy)); + }, [referral, applicants, isOwner]); const fetchReferral = async () => { try { @@ -487,7 +488,7 @@ const ReferralDetail = () => {