Skip to content

fix: a rejected email code cannot be corrected — hold the code input instead of dropping to the factor chooser - #449

Open
dbeattie71 wants to merge 1 commit into
clerk-community:mainfrom
bytefoo:fix/hold-code-input-on-rejected-code
Open

fix: a rejected email code cannot be corrected — hold the code input instead of dropping to the factor chooser#449
dbeattie71 wants to merge 1 commit into
clerk-community:mainfrom
bytefoo:fix/hold-code-input-on-rejected-code

Conversation

@dbeattie71

Copy link
Copy Markdown

Fixes #448.

A mistyped email code cannot be corrected. ClerkSignInPanel._onError resets _strategy to unknown on every error, and showCodeInput is _strategy.requiresCode — so a 422 form_code_incorrect takes the code field off screen and, since signIn.needsFirstFactor is still true, lands the user on the factor chooser. The only way forward from there re-prepares the factor, emailing a fresh code and invalidating the one already in their inbox. They type the code they are looking at, it is now the previous one, and it is rejected in turn. Every retry races the inbox.

Changes

clerk_flutter — hold the panel's position for a rejected code.

if (error.isIncorrectCode == false) {
  _strategy = clerk.Strategy.unknown;
}

Clearing the strategy is right for errors that invalidate the chosen factor. It is wrong for form_code_incorrect, where the verification is still valid and retyping is all that is needed. _password and _code are still cleared in both cases, so the field empties for a fresh attempt.

Nothing else moves: the message still surfaces through ClerkErrorListener, and onResend is already on screen for anyone who does want a new code.

clerk_auth — name the condition rather than matching a string at the call site.

/// Does this represent form_code_incorrect?
bool get containsIncorrectCodeError => _contains('form_code_incorrect');

on ExternalErrorCollection, following the existing containsExternalAccountNotFoundError, surfaced on ClerkError as:

bool get isIncorrectCode => errors?.containsIncorrectCodeError == true;

Tests

Seven new tests in clerk_auth, covering both predicates: the code present alone and among several errors, a different code (verification_expired), an empty collection, and a ClerkError carrying no external errors at all.

dart analyze and flutter analyze clean; 679 clerk_auth tests and 735 clerk_flutter tests pass on this branch.

Relationship to #443

Same form_code_incorrect, different defect. #443 makes a correct code fail by re-preparing on every submission; this makes an incorrect code unrecoverable. This branch is cut from main and is independent of #443 — they can land in either order.

Worth noting the two mask each other: with #443 present, every code fails, so nobody reaches the state where a correct retype would have succeeded. This was found only after applying #443's fix locally.

`ClerkSignInPanel._onError` resets `_strategy` to `unknown` on every error.
`showCodeInput` is `_strategy.requiresCode`, so that takes the code field off
screen and returns the panel to the factor chooser.

For a rejected code that is self-perpetuating. `signIn.needsFirstFactor` is
still true, so the chooser is what the user lands on, and the only way forward
is to pick the factor again — which re-prepares it, emailing a fresh code and
invalidating the one already in their inbox. They then type the code they are
looking at, which is now the previous one, and it is rejected in turn. Every
retry races the inbox, so the loop has no exit.

A rejected code is the one error recoverable where the user is standing: the
verification it was checked against is still valid, so retyping is enough.
Keep the strategy in that case and let the panel hold its position. The error
still surfaces through `ClerkErrorListener`, and `onResend` is already on
screen for anyone who does want a new code. Every other error resets as before.

`form_code_incorrect` is matched through a new
`ExternalErrorCollection.containsIncorrectCodeError`, following
`containsExternalAccountNotFoundError`, and surfaced as
`ClerkError.isIncorrectCode` so the panel reads the intent rather than a
string.

Note this is distinct from clerk-community#443, which reaches the same `form_code_incorrect`
by re-preparing the factor on every submission. That one makes a *correct*
code fail; this one makes an *incorrect* code unrecoverable. Fixing clerk-community#443 does
not fix this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A rejected email code cannot be corrected: ClerkSignInPanel drops to the factor chooser, and retrying re-sends the code

2 participants