Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email copy of message to user #98

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open

Conversation

randylubin
Copy link
Contributor

This branch enables users to send a copy of their message to themselves.

It adds a checkbox on the Compose page and uses the AWS SES API to send the message.

The AWS keys need to be added to Config. The EFF email address needs to be added to eff-aws-ses.js

I would strongly advise a code review as my knowledge of the backend is rusty and I did some cargo-cult coding based on how we implemented the ‘subscribe to EFF mailing list’ feature (we should check to make sure that feature still works).

I haven't added any tests, though I'm not sure I needed tests for the sections I worked on. I would also like a quick check to see if the error handling is correct.

Thanks!

I naively copied over everything from the EFF email list subscription
and did some manual find / replace. Still a ways to go
created the models, paths, etc

I think all that remains is implementing the actual email API (though
there are probably bugs to work out)
var request = apiHelpers.getModelData(req.body, models.EmailCopyRequest);

var params = {
'contact_params': {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's unquote these keys, for consistency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


effAWSSES.emailUserCopyOfMessage(params, req.app.locals.CONFIG, function(err) {
if (err) {
res.status(400).json(resHelpers.makeError(err));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This copies a pattern from another area in the app, but I think it's problematic. We should bail out of the function here by returning. res.json sends the response, so the subsequent call below will cause problems in the err case as it tries to send a response when headers/body have already been sent here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok - I just cut out the response – anything else here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should send back the 400/json response and also return from the function. So like

  if (err) {
    return res.status(400).json(resHelpers.makeError(err));
  }

I opened another PR #99 to address this in the rest of the app.


var emailUserCopyOfMessage = function(params, config, cb) {

awsConfig = config.get('CREDENTIALS.AWS');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change this to var awsConfig = ... to clarify the scope?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

var to = [params.contact_params.email];

// this must relate to a verified SES account
var from = '[email protected]'; //TODO change to EFF email verified with AWS SES
Copy link
Contributor

@wioux wioux Feb 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add a key to the config for the from address.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you mention in your PR body the email address is supposed to be pulled from eff-aws-ses.js?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's currently set to be hard coded in eff-aws-ses.js somewhat like the Civi CRM has an endpoint hard coded. I don't have any preference one way or another.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do want to put it in the Config, I'll defer to you all as the best place to put it. Doesn't neatly fit under Credentials or API

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I misunderstood here (this is eff-aws-ses.js). But yeah, let's put it in the config so we don't have to modify a tracked file. I agree it doesn't exactly fit but we could do API -> AWS_SES_EMAIL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

}

, function(err, data) {
if(err) throw err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semi-colon.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@wioux
Copy link
Contributor

wioux commented Feb 9, 2017

Thanks @randylubin! I've added notes on some things I think should be addressed before we merge (email config and error handling).

@randylubin
Copy link
Contributor Author

Thanks @wioux – I'll try to get to these tonight or this weekend

@mfb
Copy link
Contributor

mfb commented Feb 9, 2017

Does this do bounce handling? for https://act.eff.org we have an endpoint to receive bounce notifications from AWS and add to list of bad email addresses - see https://github.com/EFForg/action-center-platform/blob/master/app/controllers/bounce_controller.rb

I'm not sure of the details for how we handle bouncing addresses - I would guess they need to be stored for some period of time N rather than permanently, after which we could attempt delivery again.

@randylubin
Copy link
Contributor Author

@mfb Right now there isn't any endpoint for bounce handling; I think we'd need to use AWS SNS service.

These aren't critical emails and they're only sent once, whereas the Action Center might send multiple emails. It might be fine to ignore bounces in this case.

Another option would be use the shared list with the Action Center bounce list. Depending on how things are configured, that list might start getting the bounces from D.io with the current setup.

@mfb
Copy link
Contributor

mfb commented Feb 10, 2017

The problem is that AWS will shut us off if we send emails to a bouncing address at too high a rate, to protect sending reputation. This happens when someone is pentesting or otherwise attacking a site. That's why Mailgun is easier to setup than SES - they automatically ignore delivery attempts to bouncing addresses.

@randylubin
Copy link
Contributor Author

Ah, makes sense. The best solution might be to have just one EFF SES service that handles requests from all other EFF projects.

It seems we have a few options, let me know which makes sense.

  • I'm happy to recode it for Mailgun if EFF has an endpoint
  • I'm can have the server check a shared bounce list if you have an endpoint for me to hit
  • I can look into setting up SNS + an expiring email list in Redis. We already have an IP throttling set up that I can reference. This is a bigger project and I may need some help.

@mfb
Copy link
Contributor

mfb commented Feb 10, 2017

The redis bounce list sounds fine (as long as it has good uptime, because we'd need it to last longer than the IP throttling). AWS doesn't disclose what is the maximum bounce rate: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/e-faq-bn.html A shared bounce list sounds neat but overly complex because we have to figure out more APIs for apps to talk to each other.

We haven't starting lining up another email delivery provider but it's doable.

@randylubin
Copy link
Contributor Author

A possible quick solution: how about a captcha? That should mitigate the risks of pentesting / attack, right?

@sinak
Copy link
Owner

sinak commented Feb 13, 2017

I think we should stick with the Redis. A captcha would work, but some users already need to fill in one or more captchas, so adding in another seems like a bit much.

@randylubin If the redis piece is a heavy lift on your end @l12s or @wioux might be able to help.

@randylubin
Copy link
Contributor Author

I've started exploring the work around email bounces and it's a lot for me to bite off. I haven't done any work with Redis or Amazon SNS endpoints, though I'm sure I can learn. It might make sense to pair with someone in EFF who has access to the AWS console so we can get the notifications settings right.

I'm heading out on vacation for a week and can try to dive into this when I return (around Feb 25th).

Otherwise, this feature is ready to launch. We could also just launch now and disable the feature if our bounce rate is too high but that might be too high risk.

@sinak
Copy link
Owner

sinak commented Apr 13, 2017

@wioux Would be awesome to get this feature live, as it's the single thing we get the most requests for. Any chance you have bandwidth to rake over getting the email bounces issue sorted?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants