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

RFC: How to handle email updates #57

Closed
kiwicopple opened this issue Feb 15, 2021 · 4 comments
Closed

RFC: How to handle email updates #57

kiwicopple opened this issue Feb 15, 2021 · 4 comments
Assignees

Comments

@kiwicopple
Copy link
Member

RFC

We need to figure a clean strategy for handling email updates

When a user signs up, GoTrue returns a user

{
  "app_metadata": Object {
    "provider": "email",
  },
  "aud": Any<String>,
  "confirmed_at": Any<String>,
  "created_at": Any<String>,
  "email": user@email.com,         // user email
  "id": Any<String>,
  "last_sign_in_at": Any<String>,
  "role": "",
  "updated_at": Any<String>,
  "user_metadata": Object {},
}

then if they update their email using PUT /user, a completely new field is added

{
  "app_metadata": Object {
    "provider": "email",
  },
  "aud": Any<String>,
  "confirmed_at": Any<String>,
  "created_at": Any<String>,
  "email": user@email.com,         // original email
  "new_email": "updated@email.com",            // updated email
  "email_change_sent_at": "2021-02-15T07:41:15.8564305Z", // new field
  "id": Any<String>,
  "last_sign_in_at": Any<String>,
  "role": "",
  "updated_at": Any<String>,
  "user_metadata": Object {},
}

If we update again, the original email stays, but the new_email field is updated.

{
  "app_metadata": Object {
    "provider": "email",
  },
  "aud": Any<String>,
  "confirmed_at": Any<String>,
  "created_at": Any<String>,
  "email": user@email.com,         // original email
  "new_email": "updated_again@email.com",            // updated email - changed
  "email_change_sent_at": "2021-02-15T07:41:15.8699128Z",
  "id": Any<String>,
  "last_sign_in_at": Any<String>,
  "role": "",
  "updated_at": Any<String>,
  "user_metadata": Object {},
}

I'm sure there is a reason why it was done this way in GoTrue, but I can't figure out why.

Should we standardise the object in this library so that it always returns the current email?

  async function getUser(
    jwt: string
  ): Promise<{ user: User | null; data: User | null; error: Error | null }> {
    try {
      const data: any = await get(`${this.url}/user`, { headers: this._createRequestHeaders(jwt) })
      let user = data 
      if (data.new_email) user.email = data.new_email
      return { user, data, error: null }
    } catch (error) {
      return { user: null, data: null, error }
    }
  }
@kiwicopple
Copy link
Member Author

PR here: #58

@m0ast
Copy link

m0ast commented May 3, 2021

Hello, maybe this isn't an issue anymore but after looking around I've found that gotrue reset new_email to '' only after confirmation, which is then omitted on serialization.
Also maybe this is expected behavior as unconfirmed email doesn't seem to enable sign-in?

@markwcollins
Copy link

Hi all! I don't suppose there is any progress on this one? I noticed there were a few conflicts on the PR #58 which was from a while back. Ideally, I've love to be able to update the user's email directly without using the new_email field which I think requires the user to validate before it gets added as the user's actual email. Thanks!

@kangmingtay
Copy link
Member

Hey everyone, updating a user's email requires at least a single confirmation from the user. The typical flow is as follows:

  1. User logs in
  2. User updates email via PUT /user
  3. Gotrue sends a confirm email change link to the new_email
  4. User clicks on confirm email change link by logging into the new_email address provided

The new_email field indicates the email that the user wants to update to. Maybe we should consider renaming it if it seems confusing.

Ideally, I've love to be able to update the user's email directly without using the new_email field which I think requires the user to validate before it gets added as the user's actual email.

@markwcollins user validation is a necessary security feature for email updates. A malicious user can potentially call the email update endpoint, change the user's email to theirs and perform a password reset action which sends a password reset link to the update email address.

Closing this for now but feel free to reopen it if i've misunderstood the issue.

This issue was closed.
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

No branches or pull requests

5 participants