diff --git a/src/auth-service/config/global/email-templates.js b/src/auth-service/config/global/email-templates.js
index 68346fdef9..3b2f54b004 100644
--- a/src/auth-service/config/global/email-templates.js
+++ b/src/auth-service/config/global/email-templates.js
@@ -1,6 +1,8 @@
const mongoose = require("mongoose");
const ObjectId = mongoose.Types.ObjectId;
+const baseUrl = process.env.PLATFORM_STAGING_BASE_URL || process.env.PLATFORM_PRODUCTION_BASE_URL;
+
const emailTemplates = {
EMAIL_GREETINGS: function (name) {
return `
@@ -23,7 +25,8 @@ const emailTemplates = {
`;
},
- EMAIL_FOOTER_TEMPLATE: function (email) {
+ EMAIL_FOOTER_TEMPLATE: function (email, product, type, paramString) {
+ const unSubsciptionUrl = `${baseUrl}/api/v2/users/unsubscribe/${product}/${type}?${paramString}`;
return `
@@ -56,8 +59,9 @@ const emailTemplates = {
.
If you'd rather not receive this kind of email, you can
- unsubscribe
+
or
@@ -76,11 +80,11 @@ const emailTemplates = {
`;
},
- EMAIL_BODY: function (email, content, name) {
- const footerTemplate = this.EMAIL_FOOTER_TEMPLATE(email);
+ EMAIL_BODY: function (email, content, name, product, type, paramString) {
+ const footerTemplate = this.EMAIL_FOOTER_TEMPLATE(email, product, type, paramString);
const headerTemplate = this.EMAIL_HEADER_TEMPLATE();
let greetings = this.EMAIL_GREETINGS(name);
- if (!name) {
+ if (!name || name === "") {
greetings = ``;
}
return `
diff --git a/src/auth-service/models/User.js b/src/auth-service/models/User.js
index 0e9285d94d..1d4d145fba 100644
--- a/src/auth-service/models/User.js
+++ b/src/auth-service/models/User.js
@@ -195,11 +195,17 @@ const UserSchema = new Schema(
category: {
type: String,
},
- notifications: {
- email: { type: Boolean, default: false },
- push: { type: Boolean, default: false },
- text: { type: Boolean, default: false },
- phone: { type: Boolean, default: false },
+ mobile_notifications: {
+ email: { type: Boolean, default: true },
+ push: { type: Boolean, default: true },
+ text: { type: Boolean, default: true },
+ phone: { type: Boolean, default: true },
+ },
+ analytics_notifications: {
+ email: { type: Boolean, default: true },
+ push: { type: Boolean, default: true },
+ text: { type: Boolean, default: true },
+ phone: { type: Boolean, default: true },
},
profilePicture: {
type: String,
diff --git a/src/auth-service/routes/v2/users.js b/src/auth-service/routes/v2/users.js
index 744c9cce11..45fe018345 100644
--- a/src/auth-service/routes/v2/users.js
+++ b/src/auth-service/routes/v2/users.js
@@ -1041,8 +1041,8 @@ router.get(
);
/*********************************** user notifications **********************/
-router.post(
- "/subscribe/:type",
+router.get(
+ "/subscribe/:product/:type",
oneOf([
[
query("tenant")
@@ -1054,40 +1054,49 @@ router.post(
.toLowerCase()
.isIn(["airqo"])
.withMessage("the tenant value is not among the expected ones"),
+ query("email")
+ .optional()
+ .notEmpty()
+ .withMessage("the email must not be empty if provided")
+ .bail()
+ .isEmail()
+ .withMessage("this is not a valid email address")
+ .trim(),
+ query("mongo_user_id")
+ .optional()
+ .notEmpty()
+ .withMessage("the mongo_user_id must not be empty if provided")
+ .bail()
+ .trim()
+ .isMongoId()
+ .withMessage("the mongo_user_id must be an object ID")
+ .bail()
+ .customSanitizer((value) => {
+ return ObjectId(value);
+ }),
+ query("firebase_user_id")
+ .optional()
+ .notEmpty()
+ .withMessage("the firebase_uid must not be empty if provided")
+ .bail()
+ .trim(),
],
]),
- oneOf([
- body("email")
- .exists()
- .withMessage(
- "the user identifier is missing in request, consider using the email"
- )
- .bail()
- .notEmpty()
- .withMessage("the email must not be empty if provided")
- .bail()
- .isEmail()
- .withMessage("this is not a valid email address")
- .trim(),
- body("user_id")
- .exists()
- .withMessage(
- "the user identifier is missing in request, consider using the user_id"
- )
- .bail()
- .notEmpty()
- .withMessage("the user_id must not be empty if provided")
- .bail()
- .trim()
- .isMongoId()
- .withMessage("the user_id must be an object ID")
- .bail()
- .customSanitizer((value) => {
- return ObjectId(value);
- }),
- ]),
oneOf([
[
+ param("product")
+ .exists()
+ .withMessage("the product must be provided")
+ .bail()
+ .notEmpty()
+ .withMessage("the product should not be empty if provided")
+ .bail()
+ .trim()
+ .toLowerCase()
+ .isIn(["analytics", "mobile", "website"])
+ .withMessage(
+ "the product value is not among the expected ones: analytics, mobile and website"
+ ),
param("type")
.exists()
.withMessage("the type must be provided")
@@ -1105,8 +1114,8 @@ router.post(
]),
createUserController.subscribeToNotifications
);
-router.post(
- "/unsubscribe/:type",
+router.get(
+ "/unsubscribe/:product/:type",
oneOf([
[
query("tenant")
@@ -1118,40 +1127,49 @@ router.post(
.toLowerCase()
.isIn(["airqo"])
.withMessage("the tenant value is not among the expected ones"),
+ query("email")
+ .optional()
+ .notEmpty()
+ .withMessage("the email must not be empty if provided")
+ .bail()
+ .isEmail()
+ .withMessage("this is not a valid email address")
+ .trim(),
+ query("mongo_user_id")
+ .optional()
+ .notEmpty()
+ .withMessage("the mongo_user_id must not be empty if provided")
+ .bail()
+ .trim()
+ .isMongoId()
+ .withMessage("the mongo_user_id must be an object ID")
+ .bail()
+ .customSanitizer((value) => {
+ return ObjectId(value);
+ }),
+ query("firebase_user_id")
+ .optional()
+ .notEmpty()
+ .withMessage("the firebase_uid must not be empty if provided")
+ .bail()
+ .trim(),
],
]),
- oneOf([
- body("email")
- .exists()
- .withMessage(
- "the user identifier is missing in request, consider using the email"
- )
- .bail()
- .notEmpty()
- .withMessage("the email must not be empty if provided")
- .bail()
- .isEmail()
- .withMessage("this is not a valid email address")
- .trim(),
- body("user_id")
- .exists()
- .withMessage(
- "the user identifier is missing in request, consider using the user_id"
- )
- .bail()
- .notEmpty()
- .withMessage("the user_id must not be empty if provided")
- .bail()
- .trim()
- .isMongoId()
- .withMessage("the user_id must be an object ID")
- .bail()
- .customSanitizer((value) => {
- return ObjectId(value);
- }),
- ]),
oneOf([
[
+ param("product")
+ .exists()
+ .withMessage("the product must be provided")
+ .bail()
+ .notEmpty()
+ .withMessage("the product should not be empty if provided")
+ .bail()
+ .trim()
+ .toLowerCase()
+ .isIn(["analytics", "mobile", "website"])
+ .withMessage(
+ "the product value is not among the expected ones: analytics, mobile and website"
+ ),
param("type")
.exists()
.withMessage("the type must be provided")
diff --git a/src/auth-service/utils/create-candidate.js b/src/auth-service/utils/create-candidate.js
index 81ec922cc7..7c7a9370ed 100644
--- a/src/auth-service/utils/create-candidate.js
+++ b/src/auth-service/utils/create-candidate.js
@@ -86,12 +86,14 @@ const createCandidate = {
if (responseFromCreateCandidate.success === true) {
const createdCandidate = await responseFromCreateCandidate.data;
+ const user_id = createdCandidate._id;
const responseFromSendEmail = await mailer.candidate(
{
firstName,
lastName,
email,
tenant,
+ user_id
},
next
);
diff --git a/src/auth-service/utils/create-inquiry.js b/src/auth-service/utils/create-inquiry.js
index 45bf71430a..eb655d432b 100644
--- a/src/auth-service/utils/create-inquiry.js
+++ b/src/auth-service/utils/create-inquiry.js
@@ -1,6 +1,8 @@
+const UserModel = require("@models/User");
const InquiryModel = require("@models/Inquiry");
const { logObject } = require("@utils/log");
const mailer = require("@utils/mailer");
+const CreateUserUtil = require("@utils/create-user");
const httpStatus = require("http-status");
const constants = require("@config/constants");
const generatFilter = require("@utils/generate-filter");
@@ -32,6 +34,8 @@ const inquiry = {
);
if (responseFromCreateInquiry.success === true) {
+ const responseFromListUser = await CreateUserUtil.list(request, next);
+ const user_id = responseFromListUser.data[0]._id;
const createdInquiry = await responseFromCreateInquiry.data;
const responseFromSendEmail = await mailer.inquiry(
{
@@ -40,6 +44,7 @@ const inquiry = {
category,
message,
tenant,
+ user_id
},
next
);
diff --git a/src/auth-service/utils/create-request.js b/src/auth-service/utils/create-request.js
index 522105ad4b..4aee4ee34c 100644
--- a/src/auth-service/utils/create-request.js
+++ b/src/auth-service/utils/create-request.js
@@ -86,6 +86,7 @@ const createAccessRequest = {
email: user.email,
tenant,
entity_title: group.grp_title,
+ user_id: user._id,
},
next
);
@@ -486,6 +487,7 @@ const createAccessRequest = {
email: user.email,
tenant,
entity_title: network.net_name,
+ user_id: user._id,
},
next
);
diff --git a/src/auth-service/utils/create-user.js b/src/auth-service/utils/create-user.js
index 1c3d24f03a..33f496c4a0 100644
--- a/src/auth-service/utils/create-user.js
+++ b/src/auth-service/utils/create-user.js
@@ -1779,12 +1779,21 @@ const createUserModule = {
},
next
);
+
if (responseFromModifyUser.success === true) {
+ const responseFromListUser = await UserModel(tenant).list(
+ {
+ filter,
+ },
+ next
+ );
+ const user_id = responseFromListUser.data[0]._id;
const responseFromSendEmail = await mailer.forgot(
{
email: filter.email,
token,
tenant,
+ user_id,
},
next
);
@@ -2259,54 +2268,145 @@ const createUserModule = {
}
},
subscribeToNotifications: async (request, next) => {
+
try {
- let { email, type, tenant, user_id } = {
- ...request.body,
+ let { product, email, type, tenant, mongo_user_id, firebase_user_id } = {
...request.query,
...request.params,
};
- if (!isEmpty(user_id)) {
- const user = await UserModel(tenant)
- .findOne({ _id: user_id })
- .select("email")
- .lean();
- if (isEmpty(user)) {
- return {
- success: false,
- message: "Bad Request Error",
- status: httpStatus.BAD_REQUEST,
- errors: { message: `Provided user_id ${user_id} does not exist` },
- };
- }
- logObject("the email", user.email);
- email = user.email;
- }
- const updatedSubscription = await SubscriptionModel(
- tenant
- ).findOneAndUpdate(
- { email },
- { $set: { [`notifications.${type}`]: true } },
- { new: true, upsert: true }
- );
+ switch (product) {
+ case "mobile":
+
+ const userRef = db.collection(constants.FIREBASE_COLLECTION_USERS).doc(firebase_user_id);
+ const userDoc = await userRef.get();
+ let firebase_result, mongo_result;
+ let updateField = {};
+
+ switch (type) {
+ case "email":
+ updateField.email = true;
+ break;
+ case "push":
+ updateField.push = true;
+ break;
+ default:
+ updateField.email = true;
+ break;
+ }
- if (updatedSubscription) {
- return {
- success: true,
- message: `Successfully Subscribed to ${type} notifications`,
- status: httpStatus.OK,
- };
- } else {
- return {
- success: false,
- message: `Internal Server Error`,
- status: httpStatus.INTERNAL_SERVER_ERROR,
- errors: {
- message: `Failed to subscribe users to ${type} notifications`,
- },
- };
+ if (userDoc.exists) {
+ const existingData = userDoc.data();
+ const updatedIsSubscribed = {
+ ...existingData.isSubscribedtoNotifs,
+ ...updateField
+ };
+ result = await userRef.update({
+ isSubscribedtoNotifs: updatedIsSubscribed
+ });
+ }
+
+ firebase_result = result.writeTime ? true : false;
+
+ if (!isEmpty(userDoc.data().analyticsMongoID)) {
+ const user = await UserModel(tenant)
+ .findOne({ _id: mongo_user_id })
+ .select("email")
+ .lean();
+ if (isEmpty(user)) {
+ return {
+ success: false,
+ message: "Bad Request Error",
+ status: httpStatus.BAD_REQUEST,
+ errors: { message: `Provided mongo_user_id ${mongo_user_id} does not exist` },
+ };
+ }
+ logObject("the email", user.email);
+ email = user.email;
+
+
+ const updatedSubscription = await SubscriptionModel(
+ tenant
+ ).findOneAndUpdate(
+ { email },
+ { $set: { [`mobile_notifications.${type}`]: true } },
+ { new: true, upsert: true }
+ );
+
+ mongo_result = updatedSubscription ? true : false;
+ }
+ if (firebase_result || mongo_result) {
+ return {
+ success: true,
+ message: `Successfully Subscribed to ${type} notifications`,
+ status: httpStatus.OK,
+ };
+ } else {
+ return {
+ success: false,
+ message: `Internal Server Error`,
+ status: httpStatus.INTERNAL_SERVER_ERROR,
+ errors: {
+ message: `Failed to subscribe users to ${type} notifications`,
+ },
+ };
+ }
+
+ break;
+
+ case "analytics":
+ if (isEmpty(mongo_user_id)) {
+ return {
+ success: false,
+ message: `Please provide the mongo_user_id`,
+ status: httpStatus.BAD_REQUEST,
+ };
+ }
+ const user = await UserModel(tenant)
+ .findOne({ _id: mongo_user_id })
+ .select("email")
+ .lean();
+ if (isEmpty(user)) {
+ return {
+ success: false,
+ message: "Bad Request Error",
+ status: httpStatus.BAD_REQUEST,
+ errors: { message: `Provided mongo_user_id ${mongo_user_id} does not exist` },
+ };
+ }
+ logObject("the email", user.email);
+ email = user.email;
+
+
+ const updatedSubscription = await SubscriptionModel(
+ tenant
+ ).findOneAndUpdate(
+ { email },
+ { $set: { [`analytics_notifications.${type}`]: true } },
+ { new: true, upsert: true }
+ );
+
+ if (updatedSubscription) {
+ return {
+ success: true,
+ message: `Successfully Subscribed to ${type} notifications`,
+ status: httpStatus.OK,
+ };
+ } else {
+ return {
+ success: false,
+ message: `Internal Server Error`,
+ status: httpStatus.INTERNAL_SERVER_ERROR,
+ errors: {
+ message: `Failed to subscribe users to ${type} notifications`,
+ },
+ };
+ }
+ break;
}
+
+
} catch (error) {
logger.error(`🐛🐛 Internal Server Error ${error.message}`);
next(
@@ -2321,50 +2421,162 @@ const createUserModule = {
},
unSubscribeFromNotifications: async (request, next) => {
try {
- let { email, type, tenant, user_id } = {
- ...request.body,
+ let { product, email, type, tenant, mongo_user_id, firebase_user_id } = {
...request.query,
...request.params,
};
- if (!isEmpty(user_id)) {
- const user = await UserModel(tenant)
- .findOne({ _id: user_id })
- .select("email")
- .lean();
- if (isEmpty(user)) {
- return {
- success: false,
- message: "Bad Request Error",
- status: httpStatus.BAD_REQUEST,
- errors: { message: `Provided user_id ${user_id} does not exist` },
- };
- }
- email = user.email;
- }
- const updatedSubscription = await SubscriptionModel(
- tenant
- ).findOneAndUpdate(
- { email },
- { $set: { [`notifications.${type}`]: false } },
- { new: true, upsert: true }
- );
+ let result;
+
+ switch (product) {
+ case "mobile":
+ const userRef = db.collection(constants.FIREBASE_COLLECTION_USERS).doc(firebase_user_id);
+ const userDoc = await userRef.get();
+ let firebase_result, mongo_result;
+ let updateField = {};
+
+ switch (type) {
+ case "email":
+ updateField.email = false;
+ break;
+ case "push":
+ updateField.push = false;
+ break;
+ default:
+ updateField.email = false;
+ break;
+ }
- if (updatedSubscription) {
- return {
- success: true,
- message: `Successfully UnSubscribed user from ${type} notifications`,
- status: httpStatus.OK,
- };
- } else {
- return {
- success: false,
- message: `Internal Server Error`,
- status: httpStatus.INTERNAL_SERVER_ERROR,
- errors: {
- message: `Failed to UnSubscribe the user from ${type} notifications`,
- },
- };
+ if (userDoc.exists) {
+ const existingData = userDoc.data();
+ const updatedIsSubscribed = {
+ ...existingData.isSubscribedtoNotifs,
+ ...updateField
+ };
+ result = await userRef.update({
+ isSubscribedtoNotifs: updatedIsSubscribed
+ });
+ }
+
+ firebase_result = result.writeTime ? true : false;
+
+ if (!isEmpty(userDoc.data().analyticsMongoID)) {
+ const user = await UserModel(tenant)
+ .findOne({ _id: mongo_user_id })
+ .select("email")
+ .lean();
+ if (isEmpty(user)) {
+ return {
+ success: false,
+ message: "Bad Request Error",
+ status: httpStatus.BAD_REQUEST,
+ errors: { message: `Provided mongo_user_id ${mongo_user_id} does not exist` },
+ };
+ }
+ email = user.email;
+
+ const updatedSubscription = await SubscriptionModel(
+ tenant
+ ).findOneAndUpdate(
+ { email },
+ { $set: { [`mobile_notifications.${type}`]: false } },
+ { new: true, upsert: true }
+ );
+
+ mongo_result = updatedSubscription ? true : false;
+ }
+ if (firebase_result || mongo_result) {
+ let userEmail = email || userDoc.data().emailAddress;
+
+ if (userEmail) {
+ let name = userDoc.data().firstName;
+ if (name == null) {
+ name = "";
+ }
+
+ let queryParams = {};
+
+ if (firebase_user_id) {
+ queryParams.firebase_user_id = firebase_user_id;
+ }
+
+ if (userEmail) {
+ queryParams.email = userEmail;
+ }
+
+ if (mongo_user_id) {
+ queryParams.mongo_user_id = mongo_user_id;
+ }
+
+ const paramString = Object.keys(queryParams)
+ .map(key => `${key}=${queryParams[key]}`)
+ .join('&');
+ await mailer.sendUnsubscriptionEmail({ product, type, userEmail, name, paramString }, next);
+ }
+ return {
+ success: true,
+ message: `Successfully Unsubscribed from ${type} notifications`,
+ status: httpStatus.OK,
+ };
+ } else {
+ return {
+ success: false,
+ message: `Internal Server Error`,
+ status: httpStatus.INTERNAL_SERVER_ERROR,
+ errors: {
+ message: `Failed to unsubscribe users from ${type} notifications`,
+ },
+ };
+ }
+ break;
+
+ case "analytics":
+ if (isEmpty(mongo_user_id)) {
+ return {
+ success: false,
+ message: `Please provide the mongo_user_id`,
+ status: httpStatus.BAD_REQUEST,
+ };
+ }
+ const user = await UserModel(tenant)
+ .findOne({ _id: mongo_user_id })
+ .select("email")
+ .lean();
+ if (isEmpty(user)) {
+ return {
+ success: false,
+ message: "Bad Request Error",
+ status: httpStatus.BAD_REQUEST,
+ errors: { message: `Provided mongo_user_id ${mongo_user_id} does not exist` },
+ };
+ }
+ email = user.email;
+
+ const updatedSubscription = await SubscriptionModel(
+ tenant
+ ).findOneAndUpdate(
+ { email },
+ { $set: { [`analytics_notifications.${type}`]: false } },
+ { new: true, upsert: true }
+ );
+
+ if (updatedSubscription) {
+ return {
+ success: true,
+ message: `Successfully Unsubscribed from ${type} notifications`,
+ status: httpStatus.OK,
+ };
+ } else {
+ return {
+ success: false,
+ message: `Internal Server Error`,
+ status: httpStatus.INTERNAL_SERVER_ERROR,
+ errors: {
+ message: `Failed to unsubscribe users from ${type} notifications`,
+ },
+ };
+ }
+ break;
}
} catch (error) {
logger.error(`🐛🐛 Internal Server Error ${error.message}`);
diff --git a/src/auth-service/utils/email.msgs.js b/src/auth-service/utils/email.msgs.js
index 38db6b948e..0a9b8db28c 100644
--- a/src/auth-service/utils/email.msgs.js
+++ b/src/auth-service/utils/email.msgs.js
@@ -13,7 +13,7 @@ module.exports = {
resend: "Confirmation email resent, maybe check your spam?",
couldNotFind: "Could not find you!",
alreadyConfirmed: "Your email was already confirmed",
- recovery_email: (token, tenant, email) => {
+ recovery_email: (token, tenant, email, user_id) => {
const content = `
@@ -29,9 +29,9 @@ module.exports = {
|
`;
- return constants.EMAIL_BODY(email, content);
+ return constants.EMAIL_BODY(email, content, "", "analytics", "email", `email=${email}&mongo_user_id=${user_id}`);
},
- joinRequest: (firstName, lastName, email) => {
+ joinRequest: (firstName, lastName, email, user_id) => {
const name = firstName + " " + lastName;
const content = `
|
`;
- return constants.EMAIL_BODY(email, content, name);
+ return constants.EMAIL_BODY(email, content, name, "analytics", "email", `email=${email}&mongo_user_id=${user_id}`);
},
- joinEntityRequest: (email, entity_title) => {
+ joinEntityRequest: (email, entity_title, user_id) => {
const name = "";
const content = `
|
`;
- return constants.EMAIL_BODY(email, content, name);
+ return constants.EMAIL_BODY(email, content, name, "analytics", "email", `email=${email}&mongo_user_id=${user_id}`);
},
- inquiry: (fullName, email, category) => {
+ inquiry: (fullName, email, category, user_id) => {
let content;
switch (category) {
case "policy":
@@ -147,7 +147,7 @@ module.exports = {
`;
break;
}
- return constants.EMAIL_BODY(email, content, fullName);
+ return constants.EMAIL_BODY(email, content, fullName, "analytics", "email", `email=${email}&mongo_user_id=${user_id}`);
},
welcome_kcca: (firstName, lastName, password, email) => {
@@ -434,4 +434,33 @@ module.exports = {
`;
return constants.EMAIL_BODY(recepientEmail, content);
},
+
+ emailNotificationUnsubscibe: (product, type, email, name, paramString) => {
+
+ const subsciptionUrl = `${constants.PLATFORM_BASE_URL}/api/v2/users/subscribe/${product}/${type}?${paramString}`;
+ const content = `
+
+ We're sorry to see you go, but we've successfully unsubscribed you from our email notifications. You will no longer receive updates and notifications from your favorite locations.
+
+
+ You will no longer receive updates and notifications from your favorite locations. If you ever change your mind and want to rejoin us, feel free to subscribe again at any time.
+
+
+
+
+
+
+ If you have any questions or require further assistance, please feel free to reach out to our support team.
+ Thank you for being a part of the AirQo community. We hope to see you back in the future!
+
+ |
+
`;
+ return constants.EMAIL_BODY(email, content, name, product, type, paramString);
+ },
};
diff --git a/src/auth-service/utils/mailer.js b/src/auth-service/utils/mailer.js
index 00394017cd..c414005951 100644
--- a/src/auth-service/utils/mailer.js
+++ b/src/auth-service/utils/mailer.js
@@ -51,7 +51,7 @@ let attachments = [
const mailer = {
candidate: async (
- { firstName, lastName, email, tenant = "airqo" } = {},
+ { firstName, lastName, email, tenant = "airqo", user_id } = {},
next
) => {
try {
@@ -94,7 +94,7 @@ const mailer = {
},
to: `${email}`,
subject: "AirQo Analytics JOIN request",
- html: msgs.joinRequest(firstName, lastName, email),
+ html: msgs.joinRequest(firstName, lastName, email, user_id),
bcc,
attachments: attachments,
};
@@ -132,7 +132,7 @@ const mailer = {
}
},
request: async (
- { email, targetId, tenant = "airqo", entity_title = "" } = {},
+ { email, targetId, tenant = "airqo", entity_title = "", user_id } = {},
next
) => {
try {
@@ -178,7 +178,7 @@ const mailer = {
subject: `AirQo Analytics Request to Access ${processString(
entity_title
)} Team`,
- html: msgs.joinEntityRequest(email, entity_title),
+ html: msgs.joinEntityRequest(email, entity_title, user_id),
bcc,
attachments: attachments,
};
@@ -321,7 +321,7 @@ const mailer = {
}
},
inquiry: async (
- { fullName, email, category, message, tenant = "airqo" } = {},
+ { fullName, email, category, message, tenant = "airqo", user_id } = {},
next
) => {
try {
@@ -379,8 +379,8 @@ const mailer = {
address: constants.EMAIL,
},
subject: `Welcome to AirQo`,
- html: msgs.inquiry(fullName, email, category),
- bcc: subscribedBccEmails,
+ html: msgs.inquiry(fullName, email, category, user_id),
+ // bcc: subscribedBccEmails,
attachments,
};
@@ -947,7 +947,7 @@ const mailer = {
);
}
},
- forgot: async ({ email, token, tenant = "airqo" } = {}, next) => {
+ forgot: async ({ email, token, tenant = "airqo", user_id } = {}, next) => {
try {
const checkResult = await SubscriptionModel(
tenant
@@ -963,7 +963,7 @@ const mailer = {
},
to: email,
subject: `Link To Reset Password`,
- html: msgs.recovery_email(token, tenant, email),
+ html: msgs.recovery_email(token, tenant, email, user_id),
attachments: attachments,
};
let response = transporter.sendMail(mailOptions);
@@ -1415,6 +1415,69 @@ const mailer = {
);
}
},
+
+ sendUnsubscriptionEmail: async (
+ { product, type, userEmail, name, paramString } = {},
+ next
+ ) => {
+ try {
+
+ const mailOptions = {
+ from: {
+ name: "AirQo Data Team",
+ address: process.env.MAIL_USER,
+ },
+ to: `${userEmail}`,
+ subject: "We're Sad to See You Go - Unsubscription Confirmation!",
+ html: `${msgs.emailNotificationUnsubscibe(product, type, userEmail, name, paramString)}`,
+ attachments: attachments,
+ };
+
+
+ if (userEmail === "automated-tests@airqo.net") {
+ return {
+ success: true,
+ message: "email successfully sent",
+ data: [],
+ status: httpStatus.OK,
+ };
+ }
+
+ const response = await transporter.sendMail(mailOptions);
+
+ const data = response;
+ if (isEmpty(data.rejected) && !isEmpty(data.accepted)) {
+ return {
+ success: true,
+ message: "email successfully sent",
+ data,
+ status: httpStatus.OK,
+ };
+ } else {
+ next(
+ new HttpError(
+ "Internal Server Error",
+ httpStatus.INTERNAL_SERVER_ERROR,
+ {
+ message: "email not sent",
+ emailResults: data,
+ }
+ )
+ );
+ }
+ } catch (error) {
+ logger.error(`🐛🐛 Internal Server Error ${error.message}`);
+ next(
+ new HttpError(
+ "Internal Server Error",
+ httpStatus.INTERNAL_SERVER_ERROR,
+ { message: error.message }
+ )
+ );
+ }
+ },
+
+
newMobileAppUser: async (
{ email, message, subject, tenant = "airqo" } = {},
next