Skip to content

Send email on crate owner invitation #1360

Closed
@carols10cents

Description

@carols10cents

If there's an email address for the person being invited (which we don't require yet)

It'd be awesome if the email included a one-click link to accept the invitation without logging in (so with a token like the email verification works now)

Related:

Instructions

Invitations get created in the krate.owner_add method.

Currently, if you add someone as an owner multiple times, it just updates the one existing invitation record. We don't want to send multiple emails in this situation, as this would be an easy vector for spamming someone.

You can tell whether a row was inserted or not when you say on conflict do update by adding a returning method call to request that the query returns some of the data, getting the result with the get_result method, and calling the optional method to tell diesel it's ok if it doesn't get a result. If the query did nothing (because that record already existed), nothing will be returned and this diesel statement will result in a None value. Here's an example where we do this:

So after creating an invitation, and only if that invitation record was created (rather than only updated because it already existed), send the invited user an email.

Get the email address by first getting the User (owner here is an Owner::User, change the underscore in that match pattern to a variable name to be able to use the inner User that Owner::User holds)

Get the email address for that User NOT through the email field; that's left over from before we verified email addresses. Instead, use the verified_email method. If the user doesn't have a verified email address, don't send the email.

Send the email by calling a new function you'll need to create in src/email.rs. The new function should swallow all errors like send_user_confirm_email does by using let _ =, but should call send_email like try_send_user_confirm_email does. I think we only need one function in the case of sending owner invitation emails, rather than the two functions we have for verifying your email address, because we always want creating the invitation to succeed even if we can't send an email about it.

I would merge a PR that sends an email that always has the same content; something along the lines of "You've been invited to become the owner of a crate! Please visit https://crates.io/me/pending-invites to accept or reject this invitation."

The enhancements I could see making to that email would be:

  • Including the name of the crate you're being invited to own
  • Adding the username of the person who sent the invite
  • Adding a URL with a randomly-generated token (that we'd need to store in a new column on the invitations table) so that you could click on that link to accept the invitation (this would need to be a new URL and controller action added)

but I would rather have a PR with the basic implementation of this feature than no PR.

We don't have a great way to write tests that check emails are sent :-/ You should be able to test this out locally; the emails will be "sent" to a file in /tmp/.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions