@W-20224220 Passkey login in auth modal and login page#3611
@W-20224220 Passkey login in auth modal and login page#3611jeremy-jung1 merged 64 commits intofeature/webauthn-loginfrom
Conversation
- Created CreatePasskeyModal component for registering new passkeys with custom nicknames - Added useAccountCreatedToast hook to show success toast with passkey promotion after account creation - Integrated passkey registration flow into auth modal, checkout confirmation, and registration pages - Implemented initial WebAuthn registration API call to /oauth2/webauthn/register/authorize - Added UI elements for passkey nickname input and registration button - Update
- Renamed CreatePasskeyModal component to PasskeyRegistrationModal for clearer naming - Renamed useAccountCreatedToast hook to usePasskeyRegistration to better reflect its purpose - Refactored modal state management to pass props directly instead of wrapping in component - Updated imports and references across auth, registration and checkout confirmation pages - Simplified modal state object returned from usePasskeyRegistration hook - Updated component
- Added two-step passkey registration flow with email verification code - Implemented WebAuthn credential creation using browser's native API - Added base64url encoding/decoding utilities for WebAuthn binary data handling - Created verification code input with auto-submit on 8 digits - Added resend code functionality for verification step - Added state management to handle registration steps and form data - Updated modal UI to show different
- Moved PasskeyRegistrationModal from auth/registration/checkout pages to account page for consistent user experience - Added session storage flag 'newAccountCreated' to track when to show passkey registration prompt - Simplified registration flow by removing duplicate passkey modal instances - Updated auth flows to defer passkey registration until user reaches account page - Removed unused passkey imports from auth-modal, registration,
- Replaced direct sessionStorage calls with utility functions (setSessionJSONItem, getSessionJSONItem, clearSessionJSONItem) - Consolidated new account flag handling across auth modal, registration, checkout, and account pages - Added temporary login trigger for passkey registration testing - Updated all components to use consistent storage approach for newAccountCreated flag
…W-20224220-passkey-in-auth-modal
…0224220-passkey-in-auth-modal
…error handling - Integrated finishWebauthnAuthentication to complete the passkey login flow. - Improved error handling and logging for authentication processes. - Added helper functions for base64url encoding/decoding to facilitate credential processing.
…st environment settings
…0224220-passkey-in-auth-modal
…kout' into W-20224220-passkey-in-auth-modal
…er changes to isRegistered in a useEffect
| // Try WebAuthn first if enabled | ||
| if (isWebAuthnEnabled) { | ||
| console.log('WebAuthn enabled, trying to login with WebAuthn') | ||
| try { | ||
| await loginWithPasskey() | ||
| // If successful, close modal and navigate | ||
| onClose() | ||
| navigate('/account') | ||
| return | ||
| } catch (error) { | ||
| // Show error and stop - don't fall back to passwordless | ||
| form.setError('global', { | ||
| type: 'manual', | ||
| message: formatMessage(API_ERROR_MESSAGE) | ||
| }) | ||
| return | ||
| } | ||
| } |
There was a problem hiding this comment.
@jeremy-jung1 I believe we agreed upon just having passkey be prompted automatically and not have it triggered via the button: https://salesforce.quip.com/3BbOAa3HFWrt#temp:C:CFGd921a1317f96456e88a1ba965
Also the latest best practices for passkey seem to be prompt automatically or triggering via autofill
| const email = data.email | ||
| // Try WebAuthn first if enabled | ||
| if (isWebAuthnEnabled) { | ||
| console.log('WebAuthn enabled, trying to login with WebAuthn') |
There was a problem hiding this comment.
should we remove this log?
| }, [isRegistered, redirectPath]) | ||
|
|
||
| useEffect(() => { | ||
| if (isWebAuthnEnabled) { |
There was a problem hiding this comment.
the loginWithPasskey hook actually already checks if passkey is enabled so we don't need to check before we call it
| loginWithPasskey().catch((error) => { | ||
| // Silently fail passkey login, user can still use other methods | ||
| console.log('Passkey login failed:', error) | ||
| }) |
There was a problem hiding this comment.
this is okay for now as we'll address error messages as part of:
https://gus.lightning.force.com/lightning/r/ADM_Work__c/a07EE00002TfC8TYAV/view
Can we link the gus ticket so it doesn't get lost :)
| loginWithPasskey().catch((error) => { | |
| // Silently fail passkey login, user can still use other methods | |
| console.log('Passkey login failed:', error) | |
| }) | |
| loginWithPasskey().catch((error) => { | |
| // TODO W-21056536: Add error message handling | |
| }) |
| loginWithPasskey() | ||
| } catch (error) { | ||
| // Silently fail | ||
| } |
There was a problem hiding this comment.
similar to above
| } | |
| } catch (error) { | |
| // TODO W-21056536: Add error message handling |
| onClose, | ||
| isPasswordlessEnabled: !!passwordless?.enabled, | ||
| isSocialEnabled: !!social?.enabled, | ||
| isWebAuthnEnabled: !!passkey?.enabled, |
There was a problem hiding this comment.
technically we don't need to pass isWebAuthnEnabled as loginWithPasskey handles the feature flag check
| jest.mock('@salesforce/commerce-sdk-react', () => { | ||
| const actual = jest.requireActual('@salesforce/commerce-sdk-react') | ||
| return { | ||
| ...actual, | ||
| useAuthHelper: (helperType) => { | ||
| if (helperType === actual.AuthHelpers.StartWebauthnAuthentication) { | ||
| return {mutateAsync: mockStartWebauthnAuthentication} | ||
| } | ||
| if (helperType === actual.AuthHelpers.FinishWebauthnAuthentication) { | ||
| return {mutateAsync: mockFinishWebauthnAuthentication} | ||
| } | ||
| // Return actual for other helper types | ||
| return actual.useAuthHelper(helperType) | ||
| } | ||
| } | ||
| }) |
There was a problem hiding this comment.
one feedback i got in the feature/email-otp branch was to use msw for mocking the actual network call instead of mocking the commerce-sdk-react hook to be consistent with the other calls in this file.
…-modal Signed-off-by: jeremy-jung1 <140001271+jeremy-jung1@users.noreply.github.com>
Adding passkey login to the login modal and login page
Description
Types of Changes
Changes
How to Test-Drive This PR
Checklists
General
Accessibility Compliance
You must check off all items in one of the follow two lists:
or...
Localization