-
Notifications
You must be signed in to change notification settings - Fork 897
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
MFA TOTP resolveSignIn fails with "user._updateTokensIfNecessary is not a function" error #8647
Comments
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight. |
I wasn't able to reproduce this using the same code. Can you log the value of
I know this is a code snippet so you've probably already accounted for this elsewhere, but are you doing an |
@hsubox76 Thank you for your response. Let me provide more context about the actual flow - the reauthentication is triggered when trying to unenroll TOTP MFA, which results in a CREDENTIAL_TOO_OLD_LOGIN_AGAIN error. Here's the more complete code snippet that might be relevant to this issue: async function unenroll() {
const user = getCurrentUser()
const mfaInfo = multiFactor(user).enrolledFactors.find(
(factor) => factor.factorId === FactorId.TOTP,
)
if (!mfaInfo) {
throw new Error('TOTP is not enrolled')
}
try {
await multiFactor(user).unenroll(mfaInfo)
} catch (error) {
const firebaseError = error as FirebaseError
if (firebaseError.code === AuthErrorCodes.CREDENTIAL_TOO_OLD_LOGIN_AGAIN) {
await reauthenticate(user)
}
}
}
async function reauthenticate(user: User) {
try {
await reauthenticateWithPopup(user, new GoogleAuthProvider())
} catch (error) {
const fbError = error as FirebaseError
if (fbError.code === AuthErrorCodes.MFA_REQUIRED) {
const mfaResolver = getMultiFactorResolver(auth, fbError)
const totpInfo = mfaResolver.hints.find(
(info) => info.factorId === FactorId.TOTP,
)
if (!totpInfo) {
throw new Error('TOTP is not enrolled')
}
// user inputs otp
const multiFactorAssertion = TotpMultiFactorGenerator.assertionForSignIn(
totpInfo.uid,
otp,
)
// fails with the error
await mfaResolver.resolveSignIn(multiFactorAssertion)
}
}
}
// when user wants to unenroll TOTP MFA
unenroll()
Regarding this question, yes, we are using onAuthStateChanged() to ensure currentUser is properly populated. As for the user logging points you requested, I'll gather that information and update this thread shortly. By the way, I found that using signInWithPopup instead of reauthenticateWithPopup works without the error and successfully completes the reauthentication. Here's the working code for reference: async function reauthenticate(user: User) {
try {
// await reauthenticateWithPopup(user, new GoogleAuthProvider())
await signInWithPopup(getAuth(app), new GoogleAuthProvider())
} catch (error) {
// ... |
Operating System
macOS Ventura 13.6.6
Environment (if applicable)
Node.js v20.1.0 Chrome 128
Firebase SDK Version
v9.22.0 (still reproducible in the latest version v11.0.2)
Firebase SDK Product(s)
Auth
Project Tooling
Next.js app with React and Jest for testing. Built using TypeScript.
Detailed Problem Description
When attempting to reauthenticate a user with MFA (TOTP) enabled, the following error occurs:
What I was trying to achieve:
What actually happened:
mfaResolver.resolveSignIn()
with TOTP assertion, it fails with an internal errorError message:
This appears to be an internal Firebase Auth SDK issue where the user object is missing an expected method during the MFA resolution process.
Steps and code to reproduce issue
The text was updated successfully, but these errors were encountered: