Skip to content

Commit

Permalink
Merge pull request #756 from OneCommunityGlobal/Haoji-no-HGN-member-e…
Browse files Browse the repository at this point in the history
…mail-subscriptions

Haoji no hgn member email subscriptions
  • Loading branch information
Haoj1 authored Mar 9, 2024
2 parents 3f7b27f + 0290ede commit 3633ba2
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 9 deletions.
Binary file modified .DS_Store
Binary file not shown.
188 changes: 188 additions & 0 deletions src/controllers/emailController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// emailController.js
const nodemailer = require('nodemailer');
const jwt = require('jsonwebtoken');
const emailSender = require('../utilities/emailSender');
const EmailSubcriptionList = require('../models/emailSubcriptionList');
const userProfile = require('../models/userProfile');

const frontEndUrl = process.env.FRONT_END_URL || 'http://localhost:3000';
const jwtSecret = process.env.JWT_SECRET || 'EmailSecret';

const sendEmail = async (req, res) => {
try {
const { to, subject, html } = req.body;

console.log('to', to);

emailSender(to, subject, html);
return res.status(200).send('Email sent successfully');
} catch (error) {
console.error('Error sending email:', error);
return res.status(500).send('Error sending email');
}
};

const sendEmailToAll = async (req, res) => {
try {
const { subject, html } = req.body;
const users = await userProfile.find({
firstName: 'Haoji',
email: { $ne: null },
isActive: true,
emailSubscriptions: true,
});
let to = '';
const emailContent = ` <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<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>
<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);
return res.status(500).send('Error sending email');
}
};

const updateEmailSubscriptions = async (req, res) => {
try {
const { emailSubscriptions } = req.body;
const { email } = req.body.requestor;
const user = await userProfile.findOneAndUpdate(
{ email },
{ emailSubscriptions },
{ new: true },
);
return res.status(200).send(user);
} catch (error) {
console.error('Error updating email subscriptions:', error);
return res.status(500).send('Error updating email subscriptions');
}
};

const addNonHgnEmailSubscription = async (req, res) => {
try {
const { email } = req.body;
if (!email) {
return res.status(400).send('Email is required');
}
const emailList = await EmailSubcriptionList.find({
email: { $eq: email },
});
if (emailList.length > 0) {
return res.status(400).send('Email already exists');
}
const payload = { email };

const token = jwt.sign(
payload,
jwtSecret,
{
expiresIn: 360,
},
);
const emailContent = ` <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>Thank you for subscribing to our email updates!</p>
<p><a href="${frontEndUrl}/email-subscribe?token=${token}">Click here to confirm your email</a></p>
</body>
`;
// console.log('email', email);
emailSender(email, 'HGN Email Subscription', emailContent);
return res.status(200).send('Email subsribed successfully');
} catch (error) {
console.error('Error updating email subscriptions:', error);
res.status(500).send('Error updating email subscriptions');
}
};

const confirmNonHgnEmailSubscription = async (req, res) => {
try {
const { token } = req.body;
if (!token) {
return res.status(400).send('Invalid token');
}
let payload = {};
try {
payload = jwt.verify(token, jwtSecret);
} catch (err) {
// console.log(err);
return res.status(401).json({ errors: [{ msg: 'Token is not valid' }] });
}
const { email } = payload;
if (!email) {
return res.status(400).send('Invalid token');
}
try {
const newEmailList = new EmailSubcriptionList({ email });
await newEmailList.save();
} catch (error) {
if (error.code === 11000) {
return res.status(200).send('Email already exists');
}
}
// console.log('email', email);
return res.status(200).send('Email subsribed successfully');
} catch (error) {
console.error('Error updating email subscriptions:', error);
return res.status(500).send('Error updating email subscriptions');
}
};

const removeNonHgnEmailSubscription = async (req, res) => {
try {
const { email } = req.body;
if (!email) {
return res.status(400).send('Email is required');
}
await EmailSubcriptionList.findOneAndDelete({
email: { $eq: email },
});
// console.log('delete', email);
return res.status(200).send('Email unsubsribed successfully');
} catch (error) {
console.error('Error updating email subscriptions:', error);
return res.status(500).send('Error updating email subscriptions');
}
};

module.exports = {
sendEmail,
sendEmailToAll,
updateEmailSubscriptions,
addNonHgnEmailSubscription,
removeNonHgnEmailSubscription,
confirmNonHgnEmailSubscription,
};
14 changes: 5 additions & 9 deletions src/controllers/userProfileController.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ const userProfileController = function (UserProfile) {

if (userByEmail) {
res.status(400).send({
error:
'That email address is already in use. Please choose another email address.',
error: 'That email address is already in use. Please choose another email address.',
type: 'email',
});
return;
Expand Down Expand Up @@ -191,8 +190,7 @@ const userProfileController = function (UserProfile) {

if (userByPhoneNumber) {
res.status(400).send({
error:
'That phone number is already in use. Please choose another number.',
error: 'That phone number is already in use. Please choose another number.',
type: 'phoneNumber',
});
return;
Expand All @@ -206,8 +204,7 @@ const userProfileController = function (UserProfile) {

if (userDuplicateName && !req.body.allowsDuplicateName) {
res.status(400).send({
error:
'That name is already in use. Please confirm if you want to use this name.',
error: 'That name is already in use. Please confirm if you want to use this name.',
type: 'name',
});
return;
Expand Down Expand Up @@ -409,9 +406,7 @@ const userProfileController = function (UserProfile) {

// If their last update was made today, remove that
const lasti = record.weeklycommittedHoursHistory.length - 1;
const lastChangeDate = moment(
record.weeklycommittedHoursHistory[lasti].dateChanged,
);
const lastChangeDate = moment(record.weeklycommittedHoursHistory[lasti].dateChanged);
const now = moment();

if (lastChangeDate.isSame(now, 'day')) {
Expand Down Expand Up @@ -641,6 +636,7 @@ const userProfileController = function (UserProfile) {
{ firstName: name.split(' ')[0], lastName: name.split(' ')[1] },
'_id, profilePic, badgeCollection',
)

.then((results) => {
res.status(200).send(results);
})
Expand Down
15 changes: 15 additions & 0 deletions src/helpers/userHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ const userHelper = function () {
};

const validateProfilePic = function (profilePic) {

// if it is a url
if (typeof profilePic !== "string") {
return {
result: false,
errors: "Invalid image"
};
}
if (profilePic.startsWith('http') || profilePic.startsWith('https')) {
return {
result: true,
errors: "Valid image"
};
}

const picParts = profilePic.split(",");
let result = true;
const errors = [];
Expand Down
14 changes: 14 additions & 0 deletions src/models/emailSubcriptionList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable quotes */
const mongoose = require("mongoose");

const { Schema } = mongoose;

const emailSubscriptionSchema = new Schema({
email: { type: String, required: true, unique: true },
emailSubscriptions: {
type: Boolean,
default: true,
},
});

module.exports = mongoose.model("emailSubscriptions", emailSubscriptionSchema, "emailSubscriptions");
4 changes: 4 additions & 0 deletions src/models/userProfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const userProfileSchema = new Schema({
],
},
copiedAiPrompt: { type: Date, default: Date.now() },
emailSubscriptions: {
type: Boolean,
default: false,
},
weeklycommittedHours: { type: Number, default: 10 },
weeklycommittedHoursHistory: [
{
Expand Down
30 changes: 30 additions & 0 deletions src/routes/emailRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const express = require('express');
const {
sendEmail,
sendEmailToAll,
updateEmailSubscriptions,
addNonHgnEmailSubscription,
removeNonHgnEmailSubscription,
confirmNonHgnEmailSubscription,
} = require('../controllers/emailController');

const routes = function () {
const emailRouter = express.Router();

emailRouter.route('/send-emails')
.post(sendEmail);
emailRouter.route('/broadcast-emails')
.post(sendEmailToAll);

emailRouter.route('/update-email-subscriptions')
.post(updateEmailSubscriptions);
emailRouter.route('/add-non-hgn-email-subscription')
.post(addNonHgnEmailSubscription);
emailRouter.route('/confirm-non-hgn-email-subscription')
.post(confirmNonHgnEmailSubscription);
emailRouter.route('/remove-non-hgn-email-subscription')
.post(removeNonHgnEmailSubscription);
return emailRouter;
};

module.exports = routes;
4 changes: 4 additions & 0 deletions src/startup/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ module.exports = function (app) {
next();
return;
}
if (req.originalUrl === '/api/add-non-hgn-email-subscription' || req.originalUrl === '/api/confirm-non-hgn-email-subscription' || req.originalUrl === '/api/remove-non-hgn-email-subscription' && req.method === 'POST') {
next();
return;
}
if (!req.header('Authorization')) {
res.status(401).send({ 'error:': 'Unauthorized request' });
return;
Expand Down
2 changes: 2 additions & 0 deletions src/startup/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const ownerMessageRouter = require('../routes/ownerMessageRouter')(
ownerMessage,
);

const emailRouter = require('../routes/emailRouter')();
const reasonRouter = require('../routes/reasonRouter')(reason, userProfile);
const mouseoverTextRouter = require('../routes/mouseoverTextRouter')(
mouseoverText,
Expand Down Expand Up @@ -157,6 +158,7 @@ module.exports = function (app) {
app.use('/api', informationRouter);
app.use('/api', mouseoverTextRouter);
app.use('/api', permissionChangeLogRouter);
app.use('/api', emailRouter);
app.use('/api', isEmailExistsRouter);
app.use('/api', mapLocationRouter);
app.use('/api', warningRouter);
Expand Down

0 comments on commit 3633ba2

Please sign in to comment.