client.updateUser email flow, how do i pass the 2nd token?
Current "update email address" flow:
(see attached image for visual)
1. User clicks on "update email address"
1.1. UI calls
supabase.auth.reauthenticate()
because "Secure email address" option is toggled on, which requires a nonce when calling updateUser
with email
param.
1.2. UI moves to next step.
2. User enters nonce/otp/code received to their current email address.
3. User enters new email address.
3.1. UI calls supabase.auth.updateUser({ email: newEmail, nonce: nonce })
3.2. UI moves to next step.
4. User enters nonce/otp/code received to their new email address.
Issue:
I already called updateUser
, so how do I pass both codes to updateUser
to actually update the email address?
29 Replies
idk if the issues are related, but i receive 2 exact same emails (so a total of 3); 1 to the current email address and 1 the new email address. Is this expected?

Yes two emails are expected if you have secure email change turned on.
but
updateUser
accepts only 1 token which is the nonce. So, which token do i need to pass to updateUser
?
https://supabase.com/docs/reference/javascript/auth-updateuserAre the tokens not the same?
nope, i receive 2 different tokens
So you pass the token for the you are updating. It only requires one per email
-
reauthenticate()
(https://supabase.com/docs/reference/javascript/auth-reauthentication) sends 1 token to current email address
- updateUser()
(https://supabase.com/docs/reference/javascript/auth-updateuser) sends 2 different tokens, 1 to current email address and 1 to new email address
so i have 3 emails, and 3 different tokens
--
but i have "Secure email change" turned on, surely i need to enter one of the tokens somewhere else?According to the docs the
nonce
is only use if the password is being updated.ah, thank you
so, i still have 2 different tokens. But updateUser only accepts 1?
If you are doing an email change you shouldn't be calling
.reauthenticate
.I believe you need to call verifyOtp method with type: email_change
Here is the reference doc https://supabase.com/docs/reference/javascript/auth-reauthentication
JavaScript: Send a password reauthentication nonce | Supabase Docs
Supabase API reference for JavaScript: Send a password reauthentication nonce
i understand reauthentication and nonce, thank you
Yes this is correct. It's not a
nonce
it's a otp
in this case.
I dislike the term nonce
so much, because it has a different meaning here in the UK.i am from the UK and I agree...
so, back to the issue:
1. the UI calls
updateUser
to generate 2 tokens
2. ...
what should the ui call?
because const { data, error } = await supabase.auth.verifyOtp({ token_hash: tokenHash, type: 'email'})
accepts only 1 tokenIt should then call
.verifyOtp
as @inder highlighted above.but
verifyOtp
accepts 1 otp, and i got 2Yes correct, each email would enter the
token
.
I think you are thinking of the flow from a one email client perspective.so the UI calls
verifyOtp
twice?
1. current email address + its token
2. new email address + its tokenAn email is sent to
harry@example.com
and one is sent to the new email of dave@example.com
. Harry has to click on the link to go and verify his email along with the token that was sent to him in your app. Dave also has to click on the link and go and verify his email along with the token that was sent to him in your app. Your app only needs one verify
screen that accepts an email
and otp
. Your app only has the code for .verifyOtp
once.but surely harry's and dave's UI have to call
verifyOtp
once individually? So that's 2 calls in totalDon't worry about the calls, worry about the amount of times you need it in your app because this is where you seem to be getting the confusion from in regards to it requiring two
otp
's at the same time. They are never needed at the same time.okay so harry entered his new email address, and clicked on next
-
harryA@email.com
received otp
A
- harryB@email.com
received otp
B
from my understanding,
- step 2: Enter OTP in your current email. Clicks "verify". UI calls.verifyOtp({ email: currentEmail, token: tokenInCurrentEmail })
- step 3: Enter OTP in your new email. Clicks "verify". UI calls.verifyOtp({ email: newEmail, token: tokenInNewEmail })
Before we contine, is this a web app or a mobile app? I'm trying to understand the flow you are going for because it seems you never leave the app and it transitions through screens like a step by step flow.
web app or a mobile app?web
seems you never leave the app and it transitions through screens like a step by step flow.correct
This is correct.
perfect, thank you boss. I will implement it now, and come back if i can't make it work
There might be a slight flaw in this flow but I'll wait for you to return with your results.
The flaw would be that
.verifyOtp
logs you in as the user which could potentially break the flow but it might just work.