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

[HOLD for payment 2023-07-20] [$1000] "Incorrect magic code" error if click login in 2FA input page #21147

Closed
1 of 6 tasks
kavimuru opened this issue Jun 20, 2023 · 50 comments
Closed
1 of 6 tasks
Assignees
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor

Comments

@kavimuru
Copy link

kavimuru commented Jun 20, 2023

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Action Performed:

  1. logout if you already logged in
  2. enter email which has 2FA enable
  3. enter magic code and click on sign in button
  4. scroll login page and click on login

Expected Result:

should not show "Incorrect magic code" error

Actual Result:

shows "Incorrect magic code" error

Workaround:

Can the user still use Expensify without this being fixed? Have you informed them of the workaround?

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • Android / native
  • Android / Chrome
  • iOS / native
  • iOS / Safari
  • MacOS / Chrome / Safari
  • MacOS / Desktop

Version Number: 1.3.29-8
Reproducible in staging?: y
Reproducible in production?: y
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos: Any additional supporting documentation

Screen.Recording.2023-06-15.at.11.02.25.AM.mov
Recording.1038.mp4

Expensify/Expensify Issue URL:
Issue reported by: @gadhiyamanan
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1686808469824509

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~010bba1d812d6c5f0f
  • Upwork Job ID: 1673472692971782144
  • Last Price Increase: 2023-07-03
@kavimuru kavimuru added Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels Jun 20, 2023
@melvin-bot
Copy link

melvin-bot bot commented Jun 20, 2023

Triggered auto assignment to @alexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

@melvin-bot
Copy link

melvin-bot bot commented Jun 20, 2023

Bug0 Triage Checklist (Main S/O)

  • This "bug" occurs on a supported platform (ensure Platforms in OP are ✅)
  • This bug is not a duplicate report (check E/App issues and #expensify-bugs)
    • If it is, comment with a link to the original report, close the issue and add any novel details to the original issue instead
  • This bug is reproducible using the reproduction steps in the OP. S/O
    • If the reproduction steps are clear and you're unable to reproduce the bug, check with the reporter and QA first, then close the issue.
    • If the reproduction steps aren't clear and you determine the correct steps, please update the OP.
  • This issue is filled out as thoroughly and clearly as possible
    • Pay special attention to the title, results, platforms where the bug occurs, and if the bug happens on staging/production.
  • I have reviewed and subscribed to the linked Slack conversation to ensure Slack/Github stay in sync

@hungvu193
Copy link
Contributor

hungvu193 commented Jun 21, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

"Incorrect magic code" error if click login in 2FA input page

What is the root cause of that problem?

When user clicked Login button, we cleared session and credentials. But inside BaseValidateCodeForm we didn't clear the validateCode. So when account is being clear, the condition to render 2Factor MagicCodeInput is failed, it will render MagicCodeInput for validate code, and because validateCode isn't cleared, it will trigger onFullFill again which caused this issue.

{props.account.requiresTwoFactorAuth ? (
<View style={[styles.mv3]}>
<MagicCodeInput
autoComplete={props.autoComplete}
ref={input2FARef}
label={props.translate('common.twoFactorCode')}
name="twoFactorAuthCode"
value={twoFactorAuthCode}
onChangeText={(text) => onTextInput(text, 'twoFactorAuthCode')}
onFulfill={validateAndSubmitForm}
maxLength={CONST.TFA_CODE_LENGTH}
errorText={formError.twoFactorAuthCode ? props.translate(formError.twoFactorAuthCode) : ''}
hasError={hasError}
autoFocus
/>
</View>
) : (
<View style={[styles.mv3]}>
<MagicCodeInput
autoComplete={props.autoComplete}
ref={inputValidateCodeRef}
label={props.translate('common.magicCode')}
name="validateCode"
value={validateCode}
onChangeText={(text) => onTextInput(text, 'validateCode')}
onFulfill={validateAndSubmitForm}
errorText={formError.validateCode ? props.translate(formError.validateCode) : ''}
hasError={hasError}
autoFocus
/>
<View>

What changes do you think we should make in order to solve the problem?

Inside validateAndSubmitForm of BaseValidateCodeForm, we should check if we already validate the validate code and we didn't have 2Factor fullfill code yet, we shouldn't do anything.

        const accountID = lodashGet(props.credentials, 'accountID');
        if (accountID) {
            Session.signInWithValidateCode(accountID, validateCode, props.preferredLocale, twoFactorAuthCode);
        } else {
            if (props.credentials.validateCode && twoFactorAuthCode.length !== CONST.TFA_CODE_LENGTH) {
                return;
            }
            Session.signIn('', validateCode, twoFactorAuthCode, props.preferredLocale);
        }

What alternative solutions did you explore? (Optional)

N/A

@tienifr
Copy link
Contributor

tienifr commented Jun 21, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

"Incorrect magic code" error if click login in 2FA input page

What is the root cause of that problem?

When users press login we execute navigateHome function

onPress: () => navigateHome(scrollPageToTop),

then we will clear account and credential data

function clearSignInData() {
Onyx.multiSet({
[ONYXKEYS.ACCOUNT]: null,
[ONYXKEYS.CREDENTIALS]: {},
});
}

Unfortunately, the BaseValidateCodeForm is still appear, and at that time props.account.requiresTwoFactorAuth change to false => MagicCodeInput for validateCode is mounted again => onFulfill is executed again

<View style={[styles.mv3]}>
<MagicCodeInput
autoComplete={props.autoComplete}
ref={inputValidateCodeRef}
label={props.translate('common.magicCode')}
name="validateCode"
value={validateCode}
onChangeText={(text) => onTextInput(text, 'validateCode')}
onFulfill={validateAndSubmitForm}

=> We call API signIn again with the old code => the error is shown

What changes do you think we should make in order to solve the problem?

If we just check props.credentials.validateCode && !twoFactorAuthCode as proposal above, and users type several numbers (1->5 numbers) on 2FA input, the condition will be false => We'll call signIn again

In

const validateAndSubmitForm = useCallback(() => {

we should check if the props.account is empty then early return. And update the dependencies if needed

    const validateAndSubmitForm = useCallback(() => {
        if(_.isEmpty(props.account)){ // this line means the account is cleared
            return;
        }
...

@hungvu193
Copy link
Contributor

If we just check props.credentials.validateCode && !twoFactorAuthCode as proposal above, and users type several numbers (1->5 numbers) on 2FA input, the condition will be false => We'll call signIn again

Oh thank you, I've updated, it should be

            if (props.credentials.validateCode && twoFactorAuthCode.length !== CONST.TFA_CODE_LENGTH) {
                return;
            }

@bernhardoj
Copy link
Contributor

bernhardoj commented Jun 21, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

A sign-in request is unexpectedly fired when pressing the Login button in the Footer while in 2fa form.

What is the root cause of that problem?

On the Sign In page, it will show the 2FA form only if showValidateCodeForm is true.

{showValidateCodeForm ? <ValidateCodeForm isVisible={showValidateCodeForm} /> : <PasswordForm isVisible={showPasswordForm} />}

// Show the new magic code / validate code form if
// - A login has been entered or a validateCode has been cached from sign in link
// - AND the login isn't an unvalidated secondary login
// - AND the user is on the 'passwordless' beta
const showValidateCodeForm =
Boolean(this.props.credentials.login || this.props.credentials.validateCode) && !showUnlinkLoginForm && Permissions.canUsePasswordlessLogins(this.props.betas);

One of the requirements to show the form is the credentials from Onyx should contain either login or validateCode property. This means, when the credentials is cleared, the form will be hidden.

When we press Login in Footer, it will clear both ACCOUNT and CREDENTIALS onyx

function clearSignInData() {
Onyx.multiSet({
[ONYXKEYS.ACCOUNT]: null,
[ONYXKEYS.CREDENTIALS]: {},
});
}

The problem is when we are clearing both ACCOUNT and CREDENTIALS Onyx, it will notify the update to the subscriber (component) one by one. In our case, SignInPage will first rerender with an empty (null) ACCOUNT. Empty ACCOUNT won't affect the value of showValidateCodeForm, it will stay true. This makes the BaseValidateCodeForm a chance to rerender with an empty (null) ACCOUNT.

BaseValidateCodeForm is the component for rendering 2FA/magic code form.

{props.account.requiresTwoFactorAuth ? (
<View style={[styles.mv3]}>
<MagicCodeInput
autoComplete={props.autoComplete}
ref={input2FARef}
label={props.translate('common.twoFactorCode')}
name="twoFactorAuthCode"
value={twoFactorAuthCode}
onChangeText={(text) => onTextInput(text, 'twoFactorAuthCode')}
onFulfill={validateAndSubmitForm}
maxLength={CONST.TFA_CODE_LENGTH}
errorText={formError.twoFactorAuthCode ? props.translate(formError.twoFactorAuthCode) : ''}
hasError={hasError}
autoFocus
/>
</View>
) : (
<View style={[styles.mv3]}>
<MagicCodeInput
autoComplete={props.autoComplete}
ref={inputValidateCodeRef}
label={props.translate('common.magicCode')}
name="validateCode"
value={validateCode}
onChangeText={(text) => onTextInput(text, 'validateCode')}
onFulfill={validateAndSubmitForm}
errorText={formError.validateCode ? props.translate(formError.validateCode) : ''}
hasError={hasError}
autoFocus
/>
<View>
<PressableWithFeedback
style={[styles.mt2, resendButtonStyle]}
onPress={resendValidateCode}
underlayColor={themeColors.componentBG}
disabled={props.network.isOffline}
hoverDimmingValue={1}
pressDimmingValue={0.2}
accessibilityRole="button"
accessibilityLabel={props.translate('validateCodeForm.magicCodeNotReceived')}
>
<Text style={[styles.link]}>{props.translate('validateCodeForm.magicCodeNotReceived')}</Text>
</PressableWithFeedback>
{linkSent && !hasError && !_.isEmpty(props.account.message) && (
<DotIndicatorMessage
type="success"
style={[styles.mt2]}
messages={{0: props.translate(props.account.message)}}
/>
)}
</View>
</View>
)}

As the ACCOUNT Onyx is cleared, props.account.requiresTwoFactorAuth condition becomes false and now it will rerender with magic code instead. When magic code input is mounted, it will trigger the onFulfill props because validateCode state is never cleared.

const validateAndSubmit = () => {
const numbers = decomposeString(props.value, props.maxLength);
if (!props.shouldSubmitOnComplete || _.filter(numbers, (n) => ValidationUtils.isNumeric(n)).length !== props.maxLength || props.network.isOffline) {
return;
}
// Blurs the input and removes focus from the last input and, if it should submit
// on complete, it will call the onFulfill callback.
blurMagicCodeInput();
props.onFulfill(props.value);
};
useOnNetworkReconnect(validateAndSubmit);
useEffect(() => {
validateAndSubmit();
// We have not added the editIndex as the dependency because we don't want to run this logic after focusing on an input to edit it after the user has completed the code.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.value, props.shouldSubmitOnComplete, props.onFulfill]);

onFulfill will trigger the sign in request with the used magic code which then returns an error from the server.

Finally, SignInPage will rerender with an empty CREDENTIALS which hides the form.

image

What changes do you think we should make in order to solve the problem?

What we want to achieve is, as soon as the user press Login in the Footer, we want to immediately hide the validate code form. As validate code form depends on both ACCOUNT and CREDENTIALS, we should show the form only if both exist and hide if one of them is cleared.

ACCOUNT and CREDENTIALS onyx will always have data when we are signing in (CREDENTIALS onyx is set from the API response).

const optimisticData = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.ACCOUNT,
value: {
...CONST.DEFAULT_ACCOUNT_DATA,
isLoading: true,
message: null,
loadingForm: CONST.FORMS.LOGIN_FORM,
},
},
];

And as explained on the root cause, both are cleared when pressing the Login button in the Footer (it's also being cleared if we press Go back, see img below).
image

Currently, showValidateCodeForm only depends on CREDENTIALS, so what we need to do is to add a new condition to check if ACCOUNT onyx is not empty, then we show the validate code form.

Add && !_.isEmpty(this.props.account) to showValidateCodeForm.

What alternative solutions did you explore? (Optional)

Clears CREDENTIALS first by switching up the position of ACCOUNT and CREDENTIALS.

function clearSignInData() {
Onyx.multiSet({
[ONYXKEYS.ACCOUNT]: null,
[ONYXKEYS.CREDENTIALS]: {},
});
}

@alexpensify
Copy link
Contributor

This is on my test list

@alexpensify
Copy link
Contributor

I'm catching up from my half day, I'll review soon.

@melvin-bot melvin-bot bot added the Overdue label Jun 26, 2023
@alexpensify
Copy link
Contributor

There is a similar GH here: #19712. I'm going to test in Staging to confirm if this one is not fixed by the GH I mentioned.

@melvin-bot melvin-bot bot removed the Overdue label Jun 26, 2023
@alexpensify alexpensify added the External Added to denote the issue can be worked on by a contributor label Jun 26, 2023
@melvin-bot melvin-bot bot changed the title "Incorrect magic code" error if click login in 2FA input page [$1000] "Incorrect magic code" error if click login in 2FA input page Jun 26, 2023
@melvin-bot
Copy link

melvin-bot bot commented Jun 26, 2023

Job added to Upwork: https://www.upwork.com/jobs/~010bba1d812d6c5f0f

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Jun 26, 2023
@melvin-bot
Copy link

melvin-bot bot commented Jun 26, 2023

Current assignee @alexpensify is eligible for the External assigner, not assigning anyone new.

@melvin-bot
Copy link

melvin-bot bot commented Jun 26, 2023

Triggered auto assignment to Contributor-plus team member for initial proposal review - @sobitneupane (External)

@alexpensify
Copy link
Contributor

The GH above is a different bug but even if it looks similar. I've confirmed that clicking click on Log In button at the button of the page does return this error:

image

@alexpensify
Copy link
Contributor

@sobitneupane - Out the gate, we have some proposals here. Can you review if any will resolve the issue from this GH? Thank you!

@alexpensify
Copy link
Contributor

@sobitneupane - have you been able to review the proposals yet? Thank you for the update!

@sobitneupane
Copy link
Contributor

@bernhardoj I kind of like your proposal of handling the issue from SignInPage. But we cannot make use of this.props.account.validated because I think this.props.account.validated is not true for accounts singing in for the first time.

@bernhardoj
Copy link
Contributor

@sobitneupane You're right. I didn't think of that case. I updated my proposal to check if the ACCOUNT Onyx is empty or not instead. But with this change, I think I would prefer clearing the CREDENTIALS first solution.

@alexpensify alexpensify added Bug Something is broken. Auto assigns a BugZero manager. and removed Bug Something is broken. Auto assigns a BugZero manager. labels Jun 29, 2023
@melvin-bot
Copy link

melvin-bot bot commented Jun 29, 2023

Triggered auto assignment to @slafortune (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

@alexpensify
Copy link
Contributor

Alright, removing the other 🐛 team member. I'm back online and see that this is our current state:

Prepare for automation!

@alexpensify
Copy link
Contributor

Still waiting on automation here

@melvin-bot melvin-bot bot added Weekly KSv2 Awaiting Payment Auto-added when associated PR is deployed to production and removed Daily KSv2 labels Jul 13, 2023
@melvin-bot melvin-bot bot changed the title [$1000] "Incorrect magic code" error if click login in 2FA input page [HOLD for payment 2023-07-20] [$1000] "Incorrect magic code" error if click login in 2FA input page Jul 13, 2023
@melvin-bot melvin-bot bot removed the Reviewing Has a PR in review label Jul 13, 2023
@melvin-bot
Copy link

melvin-bot bot commented Jul 13, 2023

Reviewing label has been removed, please complete the "BugZero Checklist".

@melvin-bot
Copy link

melvin-bot bot commented Jul 13, 2023

The solution for this issue has been 🚀 deployed to production 🚀 in version 1.3.39-11 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

If no regressions arise, payment will be issued on 2023-07-20. 🎊

After the hold period is over and BZ checklist items are completed, please complete any of the applicable payments for this issue, and check them off once done.

  • External issue reporter
  • Contributor that fixed the issue
  • Contributor+ that helped on the issue and/or PR

As a reminder, here are the bonuses/penalties that should be applied for any External issue:

  • Merged PR within 3 business days of assignment - 50% bonus
  • Merged PR more than 9 business days after assignment - 50% penalty

@melvin-bot
Copy link

melvin-bot bot commented Jul 13, 2023

BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:

  • [@sobitneupane] The PR that introduced the bug has been identified. Link to the PR:
  • [@sobitneupane] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:
  • [@sobitneupane] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:
  • [@sobitneupane] Determine if we should create a regression test for this bug.
  • [@sobitneupane] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
  • [@alexpensify] Link the GH issue for creating/updating the regression test once above steps have been agreed upon:

@melvin-bot melvin-bot bot added Daily KSv2 and removed Weekly KSv2 labels Jul 19, 2023
@alexpensify
Copy link
Contributor

@gadhiyamanan and @bernhardoj - I've prepared your payments in Upwork. Please accept and I can complete the next steps.

@sobitneupane please complete the checklist and request payment.


Thank you!

@gadhiyamanan
Copy link
Contributor

@alexpensify offer accepted, thanks!

@alexpensify
Copy link
Contributor

@gadhiyamanan and @bernhardoj - I've completed your payment in Upwork.

@alexpensify
Copy link
Contributor

@sobitneupane please complete the checklist and then I can close out this GH. Thank you!

@bernhardoj
Copy link
Contributor

Thanks!

@alexpensify
Copy link
Contributor

alexpensify commented Jul 21, 2023

@anmurali - we are on hold for C+ payment and will give the 🟢 as soon as the checklist has been completed.

@alexpensify
Copy link
Contributor

@sobitneupane when you get a chance, please complete the checklist so we can close this one out. Thank you!

@sobitneupane
Copy link
Contributor

sobitneupane commented Jul 24, 2023

BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:

  • [@sobitneupane] The PR that introduced the bug has been identified. Link to the PR:

#13655

  • [@sobitneupane] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:

#13655 (comment)

  • [@sobitneupane] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:

This is an edge case. I don't think this could have been caught in PR reivew.

  • [@sobitneupane] Determine if we should create a regression test for this bug.

yes.

  • [@sobitneupane] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.

#21147 (comment)

@sobitneupane
Copy link
Contributor

Regression Test Proposal

  1. Sign out if you are signed in
  2. Enter your email and press Continue
  3. Enter the magic code from the email
  4. Verify you are brought to the authenticator input page
  5. Scroll to the bottom of the Footer
  6. Press Login
  7. Verify you are scrolled to the top and brought to the login input page
  8. Verify there is no error shown below the login input

Do we agree 👍 or 👎

@sobitneupane
Copy link
Contributor

Payment Requested on newDot.

@alexpensify
Copy link
Contributor

@sobitneupane, thank you! @jasperhuangg can you please review the checklist and give a 👍🏼 ? Thanks

@alexpensify
Copy link
Contributor

Here is the payment summary:

Upwork Job:
https://www.upwork.com/jobs/~010bba1d812d6c5f0f

*If applicable, the bonuses will be applied on the final payment

Extra Notes regarding payment: N/A

@alexpensify
Copy link
Contributor

@JmillsExpensify - the payment summary has been added here. It's ready for payment-- thank you!

@JmillsExpensify
Copy link

Reviewed details for @sobitneupane. This is accurate based on summary from Business Reviewer and approved for payment in NewDot.

@melvin-bot melvin-bot bot added the Overdue label Jul 31, 2023
@alexpensify
Copy link
Contributor

Closing - no update here, so I'm going to close this out. I closed the job in Upwork too.

@melvin-bot melvin-bot bot removed the Overdue label Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor
Projects
None yet
Development

No branches or pull requests

10 participants