auth-js
auth-js copied to clipboard
verifyOTP response causes session to not be persisted, auto-refresh not to be triggered, & user to not be set correctly
Bug report
Describe the bug
When you verify an OTP, the session is not persisted to localStorage, auto-refresh is not started, and the user is undefined.
I believe this is because the return payload of verifyMobileOPT is:
{
"access_token": "...",
"expires_in": ...,
"refresh_token": "...",
"token_type": "bearer"
}
Note that this is does not include expires_at and user.
If we then look at the definition of _saveSession we can see why:
private _saveSession(session: Session) {
this.currentSession = session
this.currentUser = session.user
const expiresAt = session.expires_at
if (expiresAt) {
const timeNow = Math.round(Date.now() / 1000)
const expiresIn = expiresAt - timeNow
const refreshDurationBeforeExpires = expiresIn > 60 ? 60 : 0.5
this._startAutoRefreshToken((expiresIn - refreshDurationBeforeExpires) * 1000)
}
// Do we need any extra check before persist session
// access_token or user ?
if (this.persistSession && session.expires_at) {
this._persistSession(this.currentSession)
}
}
A couple things here:
- Because
session.useris nullcurrentUseris set to be null - Without
expires_atthe auto-refresh system is never started - Without
expires_at, the session is not persisted
To Reproduce
- Sign in via OTP
- See that the response does not include
expires_atanduseris undefined - Refresh the page
- Session is not persisted/recovered
Expected behavior
I expect the session signing in via verifyOTP to work the same as signing in via magic link & password
Screenshots
System information
- OS: MacOS
- Version of supabase-js: 1.21.0
- Version of Node.js: 14.15.5
Additional context
I was able to work around this by
- Verifying the OTP
- Fetch the
userviaapi.getUser - Calculate
expires_atfrom current_time &expires_in - Create a new session based on the return of
verifyOTPand steps 2 & 3 - Manually call both
_saveSession(newSession)and_notifyAllSubscribers('SIGNED_IN')
This is not ideal as it relies on calling "private" functions, but it gets everything to work
I was able to work around this by
- Verifying the OTP
- Fetch the
userviaapi.getUser- Calculate
expires_atfrom current_time &expires_in- Create a new session based on the return of
verifyOTPand steps 2 & 3- Manually call both
_saveSession(newSession)and_notifyAllSubscribers('SIGNED_IN')This is not ideal as it relies on calling "private" functions, but it gets everything to work
@jaredramirez thanks for providing these steps! Worked for me as well.
I'm guessing this issue is also related to https://github.com/supabase/gotrue/issues/141
Hey @jaredramirez and @dshukertjr, this issue should have been fixed sometime ago already! See here
Feel free to reopen this if it's still a problem!