Skip to content

Commit

Permalink
Merge pull request #1147 from OneCommunityGlobal/development
Browse files Browse the repository at this point in the history
Backend Release to Main [2.04]
  • Loading branch information
one-community authored Nov 13, 2024
2 parents fda8fc9 + 53c3b50 commit 6d3af9a
Show file tree
Hide file tree
Showing 12 changed files with 523 additions and 314 deletions.
Binary file modified .DS_Store
Binary file not shown.
74 changes: 74 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"babel-plugin-module-resolver": "^5.0.0",
"bcryptjs": "^2.4.3",
"body-parser": "^1.18.3",
"cheerio": "^1.0.0-rc.12",
"cors": "^2.8.4",
"cron": "^1.8.2",
"dotenv": "^5.0.1",
Expand Down
141 changes: 100 additions & 41 deletions src/controllers/emailController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// emailController.js
const nodemailer = require('nodemailer');
// const nodemailer = require('nodemailer');
const jwt = require('jsonwebtoken');
const cheerio = require('cheerio');
const emailSender = require('../utilities/emailSender');
const { hasPermission } = require('../utilities/permissions');
const EmailSubcriptionList = require('../models/emailSubcriptionList');
Expand All @@ -9,6 +10,53 @@ const userProfile = require('../models/userProfile');
const frontEndUrl = process.env.FRONT_END_URL || 'http://localhost:3000';
const jwtSecret = process.env.JWT_SECRET || 'EmailSecret';

const handleContentToOC = (htmlContent) =>
`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
${htmlContent}
</body>
</html>`;

const handleContentToNonOC = (htmlContent, email) =>
`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
${htmlContent}
<p> Thank you for subscribing to our email updates!</p>
<p> If you would like to unsubscribe, please click <a href="${frontEndUrl}/email-unsubscribe?email=${email}">here</a></p>
</body>
</html>`;

function extractImagesAndCreateAttachments(html) {
const $ = cheerio.load(html);
const attachments = [];

$('img').each((i, img) => {
const src = $(img).attr('src');
if (src.startsWith('data:image')) {
const base64Data = src.split(',')[1];
const _cid = `image-${i}`;
attachments.push({
filename: `image-${i}.png`,
content: Buffer.from(base64Data, 'base64'),
cid: _cid,
});
$(img).attr('src', `cid:${_cid}`);
}
});
return {
html: $.html(),
attachments,
};
}

const sendEmail = async (req, res) => {
const canSendEmail = await hasPermission(req.body.requestor, 'sendEmails');
if (!canSendEmail) {
Expand All @@ -17,10 +65,27 @@ const sendEmail = async (req, res) => {
}
try {
const { to, subject, html } = req.body;
// Validate required fields
if (!subject || !html || !to) {
const missingFields = [];
if (!subject) missingFields.push('Subject');
if (!html) missingFields.push('HTML content');
if (!to) missingFields.push('Recipient email');
console.log('missingFields', missingFields);
return res
.status(400)
.send(`${missingFields.join(' and ')} ${missingFields.length > 1 ? 'are' : 'is'} required`);
}

// Extract images and create attachments
const { html: processedHtml, attachments } = extractImagesAndCreateAttachments(html);

// Log recipient for debugging
console.log('Recipient:', to);

console.log('to', to);
// Send email
emailSender(to, subject, handleContentToOC(processedHtml), attachments);

emailSender(to, subject, html);
return res.status(200).send('Email sent successfully');
} catch (error) {
console.error('Error sending email:', error);
Expand All @@ -36,46 +101,44 @@ const sendEmailToAll = async (req, res) => {
}
try {
const { subject, html } = req.body;
if (!subject || !html) {
return res.status(400).send('Subject and HTML content are required');
}

const { html: processedHtml, attachments } = extractImagesAndCreateAttachments(html);

const users = await userProfile.find({
firstName: 'Haoji',
firstName: '',
email: { $ne: null },
isActive: true,
emailSubscriptions: true,
});
let to = '';
const emailContent = ` <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
if (users.length === 0) {
return res.status(404).send('No users found');
}

const recipientEmails = users.map((user) => user.email);
console.log('# sendEmailToAll to', recipientEmails.join(','));
if (recipientEmails.length === 0) {
throw new Error('No recipients defined');
}

<body>
${html}
</body>
</html>`;
users.forEach((user) => {
to += `${user.email},`;
});
emailSender(to, subject, emailContent);
const emailList = await EmailSubcriptionList.find({ email: { $ne: null } });
emailList.forEach((emailObject) => {
const { email } = emailObject;
const emailContent = ` <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
const emailContentToOCmembers = handleContentToOC(processedHtml);
await Promise.all(
recipientEmails.map((email) =>
emailSender(email, subject, emailContentToOCmembers, attachments),
),
);

const emailSubscribers = await EmailSubcriptionList.find({ email: { $exists: true, $ne: '' } });
console.log('# sendEmailToAll emailSubscribers', emailSubscribers.length);
await Promise.all(
emailSubscribers.map(({ email }) => {
const emailContentToNonOCmembers = handleContentToNonOC(processedHtml, email);
return emailSender(email, subject, emailContentToNonOCmembers, attachments);
}),
);

<body>
${html}
<p> Thank you for subscribing to our email updates!</p>
<p> If you would like to unsubscribe, please click <a href="${frontEndUrl}/email-unsubscribe?email=${email}">here</a></p>
</body>
</html>`;
emailSender(email, subject, emailContent);
});
return res.status(200).send('Email sent successfully');
} catch (error) {
console.error('Error sending email:', error);
Expand Down Expand Up @@ -113,13 +176,9 @@ const addNonHgnEmailSubscription = async (req, res) => {
}
const payload = { email };

const token = jwt.sign(
payload,
jwtSecret,
{
expiresIn: 360,
},
);
const token = jwt.sign(payload, jwtSecret, {
expiresIn: 360,
});
const emailContent = ` <!DOCTYPE html>
<html>
<head>
Expand Down
48 changes: 46 additions & 2 deletions src/controllers/teamController.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,12 @@ const teamcontroller = function (Team) {
},
},
])
.then((result) => res.status(200).send(result))
.then((result) => {
res.status(200).send(result)
})
.catch((error) => {
Logger.logException(error, null, `TeamId: ${teamId} Request:${req.body}`);
res.status(500).send(error);
return res.status(500).send(error);
});
};
const updateTeamVisibility = async (req, res) => {
Expand Down Expand Up @@ -310,6 +312,47 @@ const teamcontroller = function (Team) {
});
};

const getAllTeamMembers = async function (req,res) {
try{
const teamIds = req.body;
const cacheKey='teamMembersCache'
if(cache.hasCache(cacheKey)){
let data=cache.getCache('teamMembersCache')
return res.status(200).send(data);
}
if (!Array.isArray(teamIds) || teamIds.length === 0 || !teamIds.every(team => mongoose.Types.ObjectId.isValid(team._id))) {
return res.status(400).send({ error: 'Invalid request: teamIds must be a non-empty array of valid ObjectId strings.' });
}
let data = await Team.aggregate([
{
$match: { _id: { $in: teamIds.map(team => mongoose.Types.ObjectId(team._id)) } }
},
{ $unwind: '$members' },
{
$lookup: {
from: 'userProfiles',
localField: 'members.userId',
foreignField: '_id',
as: 'userProfile',
},
},
{ $unwind: { path: '$userProfile', preserveNullAndEmptyArrays: true } },
{
$group: {
_id: '$_id', // Group by team ID
teamName: { $first: '$teamName' }, // Use $first to keep the team name
createdDatetime: { $first: '$createdDatetime' },
members: { $push: '$members' }, // Rebuild the members array
},
},
])
cache.setCache(cacheKey,data)
res.status(200).send(data);
}catch(error){
console.log(error)
res.status(500).send({'message':"Fetching team members failed"});
}
}
return {
getAllTeams,
getAllTeamCode,
Expand All @@ -320,6 +363,7 @@ const teamcontroller = function (Team) {
assignTeamToUsers,
getTeamMembership,
updateTeamVisibility,
getAllTeamMembers
};
};

Expand Down
Loading

0 comments on commit 6d3af9a

Please sign in to comment.