Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Changing email address

19 views
Skip to first unread message

Jeff Schnitzer

unread,
May 29, 2012, 11:34:38 PM5/29/12
to dev-id...@lists.mozilla.org
I'm finally actually really really integrating the new watch api into
Voost. I'm still having trouble figuring out a couple workflows,
totally independent of multi-auth with FB. I suspect they are all
resolvable if I can come up with the answer to this question:

How do I change an email address? If I fire off
navigator.id.request(), I don't see how to distinguish between:

* User is logged in and changing email address
* User logged out and logged in as someone else

I can't just set a localStorage value ("inChangeEmailState") because
there's no guarantee that the next onLogin() call isn't actually a
normal login, right? I can't even guarantee that the same web browser
is being used after the email dance.

My other issue, which we've discussed before, is the "when user logs
in they need to be redirected to their final destination". Storing a
value in localStorage doesn't get around the different-web-browser
problem.

It feels like there needs to be some piece of arbitrary state that
actually goes through the protocol roundtrip - ie, not stashed in
localStorage.

Thanks,
Jeff

Lloyd Hilaiel

unread,
May 30, 2012, 3:38:46 AM5/30/12
to Jeff Schnitzer, dev-id...@lists.mozilla.org
Jeff,

Thanks for digging into this and sharing your implementation experience.
This is *really* valuable vetting of the new API.

I'll respond to your specific challenges below, but I'd love to hear whatever
else you have to say about your overall experience with the new API.

On May 30, 2012, at 6:34 AM, Jeff Schnitzer wrote:

> I'm finally actually really really integrating the new watch api into
> Voost. I'm still having trouble figuring out a couple workflows,
> totally independent of multi-auth with FB. I suspect they are all
> resolvable if I can come up with the answer to this question:
>
> How do I change an email address? If I fire off
> navigator.id.request(), I don't see how to distinguish between:
>
> * User is logged in and changing email address
> * User logged out and logged in as someone else
>
> I can't just set a localStorage value ("inChangeEmailState") because
> there's no guarantee that the next onLogin() call isn't actually a
> normal login, right? I can't even guarantee that the same web browser
> is being used after the email dance.

Given what's spec'd and implemented in the observer api today, the only
sane way I can think of doing this is with an explicit change address
button in a management page somewhere. Clicking upon that button stores
state in the javascript context that goes away if the page is unloaded.

This will fall apart in the case that a user wants to change their email
address to a new address that they have not registered yet with browserid
and happens to unload the page in the process of verifying their email
address.

I wonder how many users would have trouble with that flow?

What we could probably do is contribute some real user testing to this
simplified flow to evaluate it? I can't promise anything, but I can
pitch it to our UX/user research folks. Ping me if you're interested
and we can explore this.

> My other issue, which we've discussed before, is the "when user logs
> in they need to be redirected to their final destination". Storing a
> value in localStorage doesn't get around the different-web-browser
> problem.
>
> It feels like there needs to be some piece of arbitrary state that
> actually goes through the protocol roundtrip - ie, not stashed in
> localStorage.

I think this could be viable as a longer term solution. At a high level,
how would it work? Would there be a payload specified at .request() time
that would make its way into the assertion generated as a result of that
request, and that request only? /me thinks

lloyd

> Thanks,
> Jeff
> _______________________________________________
> dev-identity mailing list
> dev-id...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-identity

Daniel Mills

unread,
May 30, 2012, 4:06:08 AM5/30/12
to Lloyd Hilaiel, Jeff Schnitzer, dev-id...@lists.mozilla.org
On May 30, 2012, at 8:38 AM, Lloyd Hilaiel <ll...@hilaiel.com> wrote:

> Given what's spec'd and implemented in the observer api today, the only
> sane way I can think of doing this is with an explicit change address
> button in a management page somewhere. Clicking upon that button stores
> state in the javascript context that goes away if the page is unloaded.

Thinking beyond what's spec'ed, how about an explicit email change API call and/or event?

Dan

Lloyd Hilaiel

unread,
May 30, 2012, 4:16:46 AM5/30/12
to Daniel Mills, Jeff Schnitzer, dev-id...@lists.mozilla.org
Compare and contrast to RP controlled metadata?

I lean toward the latter if we can safely do it, because "change email" or
"add email to account" or even "confirm email address for web app receipt verification"
are semantics that are defined by and meaningful to the RP.

IOW, there are lots of different reasons an rp might call .request(), I'm not
sure I can enumerate them all, and it seems like the site implementor would
want to know *why* they're getting an assertion in all of these cases.

lloyd

> Dan

Jeff Schnitzer

unread,
May 30, 2012, 4:36:30 AM5/30/12
to Lloyd Hilaiel, dev-id...@lists.mozilla.org
On Wed, May 30, 2012 at 12:38 AM, Lloyd Hilaiel <ll...@hilaiel.com> wrote:
>
> Given what's spec'd and implemented in the observer api today, the only
> sane way I can think of doing this is with an explicit change address
> button in a management page somewhere.  Clicking upon that button stores
> state in the javascript context that goes away if the page is unloaded.
>
> This will fall apart in the case that a user wants to change their email
> address to a new address that they have not registered yet with browserid
> and happens to unload the page in the process of verifying their email
> address.
>
> I wonder how many users would have trouble with that flow?

While it works well enough for the case when a user already has the
new email associated, it seems likely that users will frequently
change to a new email address which is not associated. Furthermore,
this situation seems rather catastrophic because when onLogin() is
called with the new email address, the server will interpret this as a
fresh login - creating a new account (!) with that email address. Now
we have a merge problem.

> What we could probably do is contribute some real user testing to this
> simplified flow to evaluate it?  I can't promise anything, but I can
> pitch it to our UX/user research folks.  Ping me if you're interested
> and we can explore this.

Unless I'm missing something, the risk of onLogin() being
misinterpreted as an account creation rather than a changeEmail fairly
well precludes this strategy.

> I think this could be viable as a longer term solution.  At a high level,
> how would it work?  Would there be a payload specified at .request() time
> that would make its way into the assertion generated as a result of that
> request, and that request only?  /me thinks

This is what I imagine... somehow the request() payload makes it into
the onLogin() method as a parameter. It would be handier to have it
available client-side at onLogin() instead of having to extract it
from the assertion server-side.

Jeff

Jeff Schnitzer

unread,
May 30, 2012, 4:42:49 AM5/30/12
to Lloyd Hilaiel, Daniel Mills, dev-id...@lists.mozilla.org
+1

I would much rather have control over this myself, especially since
there are all sorts of business-level complications to changing email
address (collisions and merges, for example). A simple payload
mechanism also provides me with an easy answer to the "where do I
redirect the user when they complete sign-in" question. I simply
include a little payload that my app interprets as "redirect to the
register for event XYZ page".

Jeff

Lloyd Hilaiel

unread,
May 30, 2012, 4:57:40 AM5/30/12
to Jeff Schnitzer, dev-id...@lists.mozilla.org

On May 30, 2012, at 11:36 AM, Jeff Schnitzer wrote:

> On Wed, May 30, 2012 at 12:38 AM, Lloyd Hilaiel <ll...@hilaiel.com> wrote:
>>
>> Given what's spec'd and implemented in the observer api today, the only
>> sane way I can think of doing this is with an explicit change address
>> button in a management page somewhere. Clicking upon that button stores
>> state in the javascript context that goes away if the page is unloaded.
>>
>> This will fall apart in the case that a user wants to change their email
>> address to a new address that they have not registered yet with browserid
>> and happens to unload the page in the process of verifying their email
>> address.
>>
>> I wonder how many users would have trouble with that flow?
>
> While it works well enough for the case when a user already has the
> new email associated, it seems likely that users will frequently
> change to a new email address which is not associated. Furthermore,
> this situation seems rather catastrophic because when onLogin() is
> called with the new email address, the server will interpret this as a
> fresh login - creating a new account (!) with that email address. Now
> we have a merge problem.

Yeah, a bunch of account merging UI would be lame, I agree pre-empting
that would be good.

I agree that RP controlled metadata at .request() time looks like the
promising and robust solution.

But staying in the confines of what's possible right now to attempt to
uncover a short term solution: If you feel like users will frequently
forget what email they used to log in, and this will
be a non-fringe case (20% of the time?), then perhaps it would be worth an
extra user confirmation before new account creation?

"You haven't logged in here before, Welcome to Voost! We are awesome and
you will like it here!

(Confused? Already have an account? <link>just log in with a different email</link>)

<button>Start Voosting!</button>"

Then at the time the user clicks "just log in with a different email" and goes
through this flow, you have *two* assertions. So you could add this new email
to their account as an alternate way to log in, if that felt like the right thing
to do and you felt this is in accordance with their desires. Maybe this could be
nice? In context setup of backup email addresses? Paving cowpaths? You *are*
correlating user's email addresses, but they *are* sharing these email addresses
with you, with the intention of using your site. It seems fair and good to me with
a little careful ui.

FWIW, upon last check there was 1.6 emails per user in our database. so the common
case for people is one or two emails. So I'd *guess* this isn't an extremely
prevalent case, but I defer to your intuition and data here. (and as persona becomes
more popular, that number could change).

>> I think this could be viable as a longer term solution. At a high level,
>> how would it work? Would there be a payload specified at .request() time
>> that would make its way into the assertion generated as a result of that
>> request, and that request only? /me thinks
>
> This is what I imagine... somehow the request() payload makes it into
> the onLogin() method as a parameter. It would be handier to have it
> available client-side at onLogin() instead of having to extract it
> from the assertion server-side.

That makes sense. +1. I'm curious to hear what others think. Pending a little
fist pumping and some thought, we can turn this into an issue. If we don't
get feedback in this thread, we can break it out into a separate, more focused email
thread.

lloyd

Lloyd Hilaiel

unread,
May 30, 2012, 5:07:43 AM5/30/12
to Jeff Schnitzer, Daniel Mills, dev-id...@lists.mozilla.org
On May 30, 2012, at 11:42 AM, Jeff Schnitzer wrote:

> I would much rather have control over this myself, especially since
> there are all sorts of business-level complications to changing email
> address (collisions and merges, for example). A simple payload
> mechanism also provides me with an easy answer to the "where do I
> redirect the user when they complete sign-in" question. I simply
> include a little payload that my app interprets as "redirect to the
> register for event XYZ page".

To argue against myself, and maybe overtype: one key benefit of enumerating
the cases (maybe why dan suggested this?) is that we can optimize the user facing
language inside the dialog for popular cases "Add a new address to your account at
Voost" or "Change your login email for Voost".

But as we identify the common cases actually used in practice, we can
optimize the most common ones as needed. There's sufficient cost for this kind
of optimization (requiredEmail has really slowed us down) that I'd
like to be lazy about it and wait till we're *really* confident that
we've identified what specific cases developers want. (and the two
features are not mutually exclusive).

lloyd

Jeff Schnitzer

unread,
May 30, 2012, 12:01:59 PM5/30/12
to Lloyd Hilaiel, dev-id...@lists.mozilla.org
I have to admit this doesn't excite me; it creates a lot of worrisome
edge cases.

After sleeping on it, I have an alternative solution that will work
for now: Remove browserid from the change email process and handle it
all myself. I'll send my own "please confirm" email, and when the
user clicks the link, I will execute the change and log the user out.
The user will need to re-log-in with the new email address, which is
annoying, but since this is a pretty rare process I think we can live
with it.

Also: This is a better solution for FB-authed users as well. Making
FB users go through browserid to change email address (as I currently
do) is confusing.

For the redirect-on-login issue, I'll just store temporary state in
localStorage. It's not elegant and it doesn't cover a few edge cases
like wrong-browser-after-email-dance, but it will work 99.9% of the
time. And the failure case is not a disaster.

So for the moment, I'm not blocked.

Jeff

Jeff Schnitzer

unread,
May 30, 2012, 12:09:43 PM5/30/12
to Lloyd Hilaiel, Daniel Mills, dev-id...@lists.mozilla.org
On Wed, May 30, 2012 at 2:07 AM, Lloyd Hilaiel <ll...@hilaiel.com> wrote:
>
> To argue against myself, and maybe overtype: one key benefit of enumerating
> the cases (maybe why dan suggested this?) is that we can optimize the user facing
> language inside the dialog for popular cases "Add a new address to your account at
> Voost" or "Change your login email for Voost".

Perhaps the RP can include some arbitrary text? It might open up
phishing attacks though.

> But as we identify the common cases actually used in practice, we can
> optimize the most common ones as needed.  There's sufficient cost for this kind
> of optimization (requiredEmail has really slowed us down) that I'd
> like to be lazy about it and wait till we're *really* confident that
> we've identified what specific cases developers want.  (and the two
> features are not mutually exclusive).

I haven't looked in too much detail at the protocol, but is it
possible to leave this payload out of the encryption routine? Since
it's both client-defined and client-interpreted, there's no security
issue. Validation of the payload must be handled by the RP
server-side; for example, the "change my email" payload will need to
include the signed id of the account which will receive the new email
when the login is successfully processed.

Jeff

Francois Marier

unread,
May 30, 2012, 7:08:00 PM5/30/12
to
On 31/05/12 04:01, Jeff Schnitzer wrote:
> After sleeping on it, I have an alternative solution that will work
> for now: Remove browserid from the change email process and handle it
> all myself. I'll send my own "please confirm" email, and when the
> user clicks the link, I will execute the change and log the user out.
> The user will need to re-log-in with the new email address, which is
> annoying, but since this is a pretty rare process I think we can live
> with it.

I wonder whether this would be a good place to use requiredEmail? It
could potentially replace your own "click this link" verification email:

1- your site asks the user for the new email they want to switch to
2- browserid window pops up with requiredEmail set to that email
3- (user may need to confirm email through BrowserID)
4- your site gets an assertion
5- you change the email internally, log the user out, log them in again

I'm just thinking out loud here, I'm not sure what the user flow would
look exactly. But it does seem to be me that for users who already use
BrowserID (i.e. I wouldn't do that for FB users), then there might be an
opportunity to avoid the confirmation email. After all, that's what the
original protocol (Verified Email) was all about.

The above looks quite similar to the steps you'd take if you did it all
yourself:

1- your site asks the user for the new email they want to switch to
2- you fire off an email to the user
3- user clicks on confirmation link
4- your site gets a ping at that random confirmation URL
5- you change the email internally, log the user out, log them in again

Anyways, just a thought.

Cheers,
Francois

Francois Marier

unread,
May 30, 2012, 7:13:36 PM5/30/12
to
On 31/05/12 04:09, Jeff Schnitzer wrote:
> On Wed, May 30, 2012 at 2:07 AM, Lloyd Hilaiel <ll...@hilaiel.com> wrote:
>> To argue against myself, and maybe overtype: one key benefit of enumerating
>> the cases (maybe why dan suggested this?) is that we can optimize the user facing
>> language inside the dialog for popular cases "Add a new address to your account at
>> Voost" or "Change your login email for Voost".
>
> Perhaps the RP can include some arbitrary text? It might open up
> phishing attacks though.

I remember discussing with Ben and another RP the possibility to let the
RP send the BrowserID confirmation email. BrowserID would give the RP
the right confirmation link and then the RP would send whatever "welcome
email" it wants telling the user to click on the link.

Ben had a security mechanism in mind to ensure that the user gave
consent to receiving an email from the RP, but I can't remember the
exact details of it.

Cheers,
Francois

Jeff Schnitzer

unread,
May 30, 2012, 7:25:20 PM5/30/12
to Francois Marier, dev-id...@lists.mozilla.org
Seems to me this does not work around the basic problem: I'm going to
get an onLogin() callback at some point, and how do I know that this
callback means "associate email with existing account" instead of
"create a new account"? Any scheme that involves local storage breaks
in a variety of edge cases (eg wrong browser) and effectively corrupts
the database.

With my own verification email, I can encode the full information
"associate b...@example.com with user id 123" and when that link is
clicked on, I can update my database appropriately. Getting the user
logged in as b...@example.com is a separate annoying step, but at least
at this point the database is correct.

Jeff

On Wed, May 30, 2012 at 4:08 PM, Francois Marier <fran...@mozilla.com> wrote:
>
> I wonder whether this would be a good place to use requiredEmail? It
> could potentially replace your own "click this link" verification email:
>
> 1- your site asks the user for the new email they want to switch to
> 2- browserid window pops up with requiredEmail set to that email
> 3- (user may need to confirm email through BrowserID)
> 4- your site gets an assertion
> 5- you change the email internally, log the user out, log them in again
>
> I'm just thinking out loud here, I'm not sure what the user flow would
> look exactly. But it does seem to be me that for users who already use
> BrowserID (i.e. I wouldn't do that for FB users), then there might be an
> opportunity to avoid the confirmation email. After all, that's what the
> original protocol (Verified Email) was all about.
>
> The above looks quite similar to the steps you'd take if you did it all
> yourself:
>
> 1- your site asks the user for the new email they want to switch to
> 2- you fire off an email to the user
> 3- user clicks on confirmation link
> 4- your site gets a ping at that random confirmation URL
> 5- you change the email internally, log the user out, log them in again
>
> Anyways, just a thought.
>
> Cheers,
> Francois

Dan Callahan

unread,
May 31, 2012, 9:41:22 AM5/31/12
to
On 5/30/12 6:25 PM, Jeff Schnitzer wrote:
> Seems to me this does not work around the basic problem: I'm going to
> get an onLogin() callback at some point, and how do I know that this
> callback means "associate email with existing account" instead of
> "create a new account"? Any scheme that involves local storage breaks
> in a variety of edge cases (eg wrong browser) and effectively corrupts
> the database.

Thinking out loud, but could you just add a new column to your user
table for "pending address" and populate that without doing any
particular validation beyond it formatting?

Then, when a user logs in, you can check the "pending address" column
for the address in the assertion, and if it matches, move the data into
the "address" column and log the user in.

There are other corner case issues here (what to do when they log back
in with their old address, what if the pending address isn't unique,
messaging to the user), but that might work in theory, while saving you
from doing your own email validation.

Still, the fact that we're discussing this at all means that we have a
problem with the usability of our API...

-Callahad
0 new messages