Skip to content

Commit

Permalink
Enforce email domain whitelist
Browse files Browse the repository at this point in the history
  • Loading branch information
2JJ1 committed Apr 17, 2023
1 parent b0cc4ef commit b11acdf
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 28 deletions.
23 changes: 10 additions & 13 deletions my_modules/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ module.exports = {
var mailgun = require("mailgun-js")({apiKey: process.env.MAILGUN_APIKEY, domain: process.env.MAILGUN_DOMAIN});

return new Promise( ( resolve, reject ) => {
//Sanitize
if(!this.isEmailCompatible(emaildata.to)) reject("Email not compatible")

//Sends
mailgun.messages().send(emaildata, function (error, body) {
if (error) reject(error);
Expand All @@ -25,18 +22,18 @@ module.exports = {
text: body
};

return this.SendMail(emaildata)
return module.exports.SendMail(emaildata)
},

//Checks if mailgun can send an email to this address
//I'm using a shared ip and it has a bad reputation unforunately.
//Because of the bad reputation, email providers like Outlook and Yahoo block me
isEmailCompatible: (address) => {
isMajorEmailDomain: (emailAddress) => {
const whitelist = ["gmail.com", "aol.com", "outlook.com", "yahoo.com", "icloud.com", "mozilla.com",
"proton.com", "hotmail.com", "zoho.com", "live.com", "comcast.net"]

//Grabs the domain part of an email address. (eg. [email protected] = domain.com)
var ind = address.indexOf("@");
var sliced = address.slice((ind+1),address.length);
//If the domain is blacklisted, its imcompatible(false). Compatible(true) otherwise
var blackList = /outlook.com|yahoo.com/
return !blackList.test(sliced)
var ind = emailAddress.indexOf("@");
var sliced = emailAddress.slice((ind+1),emailAddress.length);

//Checks if the domain is whitelisted
return whitelist.includes(sliced)
}
}
6 changes: 3 additions & 3 deletions routes/api/account/manager/security.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const mongoose = require('mongoose')
const bcrypt = require('bcrypt')

const other = require('../../../../my_modules/other')
const mailgun = require('../../../../my_modules/email')
const email = require('../../../../my_modules/email')
const tfa = require('../../../../my_modules/2fa')
const accountAPI = require('../../../../my_modules/accountapi')

Expand Down Expand Up @@ -58,7 +58,7 @@ router.post('/', async (req, res, next) => {
})

if(!other.ValidateEmail(req.body.email)) throw "Invalid email"
if(!mailgun.isEmailCompatible(req.body.email)) throw "Incompatible email provider. Use another email address such as GMail"
if(!email.isMajorEmailDomain(req.body.email)) "We only allow email addresses from major email providers, such as Gmail."

keyvalues.email = escape(req.body.email)
}
Expand All @@ -79,7 +79,7 @@ router.post('/', async (req, res, next) => {
`${process.env.FORUM_URL}/verify?token=${hash}\n\n` +
`This message was generated by ${process.env.FORUM_URL}.`

await mailgun.SendBasicEmail(keyvalues.email, `${(await ForumSettings.findOne({type: "name"})).value} Email Verification`, emailBody)
await email.SendBasicEmail(keyvalues.email, `${(await ForumSettings.findOne({type: "name"})).value} Email Verification`, emailBody)
.then(async err=>{
if(err) throw err

Expand Down
8 changes: 2 additions & 6 deletions routes/api/account/recovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ router.post('/', async (req, res, next) => {
expireDate.setMinutes(expireDate.getMinutes()+15);

// Sends reset session email
if(!mailgun.isEmailCompatible(accountdata.email)) throw `Sorry, but the email provider tied to that account has recently blocked automated emails from ${forumTitle}. Please contact support for assistance.`
await mailgun.SendMail({
from: `"noreply" ${process.env.MAILGUN_NOREPLY_ADDRESS}`, // sender address
to: accountdata.email, // list of receivers
Expand Down Expand Up @@ -101,9 +100,6 @@ router.post('/', async (req, res, next) => {
`This message was generated by ${process.env.FORUM_URL}`
};

if(!mailgun.isEmailCompatible(emaildata.to))
throw `Sorry, but the email provider tied to that account has recently blocked automated emails from ${forumTitle}. Please contact support for assistance.`

await mailgun.SendMail(emaildata)

response.success = true
Expand Down Expand Up @@ -166,8 +162,8 @@ router.post('/passreset', async (req, res, next) => {

// Send password has reset notice
let forumTitle = (await ForumSettings.findOne({type: "name"})).value
if(mailgun.isEmailCompatible(account.email))
await mailgun.SendMail({

await mailgun.SendMail({
from: `"noreply" ${process.env.MAILGUN_NOREPLY_ADDRESS}`, // sender address
to: account.email, // list of receivers
subject: `${forumTitle} | Password Reset Confirmation`, // Subject line
Expand Down
6 changes: 3 additions & 3 deletions routes/api/account/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const fetch = require('node-fetch')

const other = require('../../../my_modules/other')
const recaptcha = require('../../../my_modules/captcha')
const mailgun = require('../../../my_modules/email')
const email = require('../../../my_modules/email')
const accountAPI = require('../../../my_modules/accountapi')
const pfAPI = require('../../../my_modules/pfapi')

Expand Down Expand Up @@ -59,8 +59,8 @@ router.post('/', async (req, res, next) => {

if('email' in _POST){
if(!other.ValidateEmail(req.body.email)) throw "Invalid email"
if(!mailgun.isEmailCompatible(req.body.email)) throw "Incompatible email provider. Use another email address such as Gmail"
keyvalues.email = escape(req.body.email)
if(!email.isMajorEmailDomain(req.body.email)) throw "We only allow email addresses from major email providers, such as Gmail."

//Uses gravatar for pfp if one exists for their email
let hashedEmail = md5(req.body.email)
Expand Down Expand Up @@ -123,7 +123,7 @@ router.post('/', async (req, res, next) => {
`${process.env.FORUM_URL}/verify?token=${hash}\n\n` +
`This message was generated by ${process.env.FORUM_URL}.`

mailgun.SendBasicEmail(keyvalues.email, `${(await ForumSettings.findOne({type: "title"})).value} | Email Verification`, emailBody)
email.SendBasicEmail(keyvalues.email, `${(await ForumSettings.findOne({type: "title"})).value} | Email Verification`, emailBody)
.catch(err=>{
//Handle the error, but allow account to remain created successfully
console.error(`Issue when sending the email verification at register for @${req.session.uid} ${keyvalues.email}: `, err)
Expand Down
3 changes: 0 additions & 3 deletions routes/api/account/verifyemail.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ router.post('/', async (req, res, next) => {
//Where to send the verification step to
var accData = await accountAPI.fetchAccount(req.session.uid)

//Check if we can email this address
if(!mailgun.isEmailCompatible(accData.email)) throw "We can not send emails to that email provider. Please change your email address!"

// Create email verification session

//Creates verification token
Expand Down

0 comments on commit b11acdf

Please sign in to comment.