Skip to content

Render MFA alternatives on external action waiting screen#5

Merged
masnwilliams merged 1 commit into
mainfrom
mason/external-action-mfa-options
May 12, 2026
Merged

Render MFA alternatives on external action waiting screen#5
masnwilliams merged 1 commit into
mainfrom
mason/external-action-mfa-options

Conversation

@masnwilliams
Copy link
Copy Markdown
Contributor

@masnwilliams masnwilliams commented May 12, 2026

Summary

  • The backend sends mfa_options (e.g. "Try another way") alongside AWAITING_EXTERNAL_ACTION events, but ExternalActionWaiting was only receiving the message prop — dropping MFA alternatives on the floor.
  • Wires mfaOptions and submitMFA through to ExternalActionWaiting so users can switch to an alternative verification method (TOTP, SMS, etc.) instead of being stuck waiting for a push notification that may not arrive.
  • Reuses the same Button/slot/icon pattern from UnifiedAuthForm's MFA option rendering.

Test plan

  • Check the demo app's "awaiting_external_action" state shows the "Try another way" button
  • Trigger a real external action flow (e.g. Google OAuth with push MFA) and verify the alternative appears
  • Clicking the alternative submits the MFA selection and transitions to the next state

Made with Cursor


Note

Medium Risk
Adds interactive MFA-selection controls to the external-action waiting step and wires them to submitMFA, which could affect authentication flow transitions if option handling is incorrect.

Overview
External-action waiting now surfaces alternate MFA methods. KernelManagedAuth passes backend mfa_options into ExternalActionWaiting and hooks selection to submitMFA (with loading/disable state).

ExternalActionWaiting is extended to render a list of secondary buttons for provided MFA options, including per-MFAType icons and slot keys for customization; styles add layout for the alternatives section. The demo state picker adds an awaiting_external_action_multi scenario and updates the existing external-action state to display these options.

Reviewed by Cursor Bugbot for commit f38988a. Bugbot is set up for automated code reviews on this repo. Configure here.

@firetiger-agent
Copy link
Copy Markdown

Firetiger deploy monitoring skipped

This PR didn't match the auto-monitor filter configured on your GitHub connection:

Any PR that changes the kernel API. Monitor changes to API endpoints (packages/api/cmd/api/) and Temporal workflows (packages/api/lib/temporal) in the kernel repo

Reason: This PR modifies frontend UI components for MFA rendering and does not change kernel API endpoints or Temporal workflows.

To monitor this PR anyway, reply with @firetiger monitor this.

The backend sends mfa_options (e.g. "Try another way") alongside
external action events, but ExternalActionWaiting was only receiving
the message prop. Wire through mfaOptions and submitMFA so users can
switch to an alternative verification method instead of being stuck
waiting for a push notification.

Co-authored-by: Cursor <[email protected]>
@masnwilliams masnwilliams force-pushed the mason/external-action-mfa-options branch from 2b30ce0 to f38988a Compare May 12, 2026 01:11
@masnwilliams masnwilliams requested a review from dcruzeneil2 May 12, 2026 01:11
@masnwilliams masnwilliams merged commit a11f9ae into main May 12, 2026
2 checks passed
@masnwilliams masnwilliams removed the request for review from dcruzeneil2 May 12, 2026 01:13
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f38988a. Configure here.

<ExternalActionWaiting
message={state?.external_action_message ?? undefined}
mfaOptions={state?.mfa_options ?? []}
onMFASelect={submitMFA}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MFA submit error recovery navigates to wrong screen

Medium Severity

When submitMFA is called from the ExternalActionWaiting screen and the API call fails, the submit helper's catch block unconditionally falls back to "awaiting_input" UI state. This causes users on the external-action-waiting screen to be unexpectedly redirected to the input form (which may have no relevant fields) instead of returning to the external action screen. Polling will eventually correct the state, but there's a visible flash of the wrong screen.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f38988a. Configure here.

default:
return <KeyIcon />;
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated getMFAIcon function across two components

Low Severity

The getMFAIcon function in ExternalActionWaiting.tsx is an exact copy of the one in UnifiedAuthForm.tsx. This duplication means any future change to icon mappings (e.g. adding a passkey case) needs to be applied in two places, risking inconsistency.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f38988a. Configure here.

</div>
</div>
</Button>
))}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MFA options missing "switch-last" sort from UnifiedAuthForm

Low Severity

UnifiedAuthForm explicitly sorts MFA options so that "switch" types ("Try another way") always render last, with a code comment explaining this intentional design. ExternalActionWaiting renders mfaOptions in the order received from the backend without this sort. If the backend sends the "switch" option before more specific methods like TOTP or SMS, the generic fallback will appear above them, contradicting the established UX pattern.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f38988a. Configure here.

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.

1 participant