Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
ef2c877
feat: add account created toast and register passkey modal
hajinsuha1 Nov 5, 2025
38a634a
feat: rename and refactor passkey registration components
hajinsuha1 Nov 5, 2025
82aad01
feat: add hardcoded config for local passkey registration testing
hajinsuha1 Nov 6, 2025
318856f
feat: implement passkey registration with email verification
hajinsuha1 Nov 7, 2025
39cb5c8
feat: centralize passkey registration prompt to account page
hajinsuha1 Nov 7, 2025
ad550f7
refactor: standardize session storage handling for new accounts
hajinsuha1 Nov 7, 2025
df2cdc0
@W-20223950 - Add config for passkey login (#3497)
yunakim714 Dec 8, 2025
51f587a
display create passkey prompt upon showing account page
hajinsuha1 Jan 2, 2026
ee8bc68
Merge remote-tracking branch 'origin/develop' into feature/webauthn-l…
yunakim714 Jan 7, 2026
56a40fb
Merge remote-tracking branch 'origin/W-19604275-webauthn-spike' into …
jeremy-jung1 Jan 7, 2026
ce6ea32
@W-20328381 - Add Webauthn Register/Authenticate APIs to `commerce-sd…
yunakim714 Jan 12, 2026
6598ee3
Merge remote-tracking branch 'origin/feature/webauthn-login' into W-2…
jeremy-jung1 Jan 15, 2026
678cf40
Implement passkey login hook and call it when the contact-info compon…
hajinsuha1 Jan 19, 2026
0043eaf
Add finishWebauthnAuthentication to usePasskeyLogin hook and enhance …
hajinsuha1 Jan 19, 2026
b6ea2d4
add unit tests and rename to loginWithPasskey
hajinsuha1 Jan 20, 2026
dfbd5bb
rename startPasskeyLogin to loginWithPasskey in contact-info
hajinsuha1 Jan 20, 2026
22df1c1
@W-20474693 - [WebauthN] Passkey Registration (#3571)
yunakim714 Jan 20, 2026
74d3679
Merge branch 'feature/webauthn-login' into W-20224267-passkey-login-i…
hajinsuha1 Jan 20, 2026
aff8cd5
use toJSON to encode credential and fallback to manual encoded on error
hajinsuha1 Jan 21, 2026
ba1f2d0
Update ESLint configuration to use latest ECMAScript version and adju…
hajinsuha1 Jan 21, 2026
4be0858
add unit test for fallback to manual encoding
hajinsuha1 Jan 21, 2026
baeeeb5
remove window.PublicKeyCredential call now that eslint version has be…
hajinsuha1 Jan 21, 2026
5d0a567
Merge remote-tracking branch 'origin/feature/webauthn-login' into W-2…
jeremy-jung1 Jan 22, 2026
8513ed3
ensure errors are displayed when loginWithPasskey fails
hajinsuha1 Jan 22, 2026
03887c1
update eslint and remove es2025
hajinsuha1 Jan 22, 2026
8130e6e
increase bundle size
hajinsuha1 Jan 23, 2026
2cee2cf
Update ESLint configuration to support ECMAScript 2024
hajinsuha1 Jan 23, 2026
5ed8117
revert eslint changes and use /* global PublicKeyCredential */
hajinsuha1 Jan 23, 2026
17fa736
update unit tests
hajinsuha1 Jan 23, 2026
d9c5324
revert unnecessary changes to bundle size and eslint
hajinsuha1 Jan 23, 2026
d2c4c05
Handle NotAllowedError in usePasskeyLogin hook and add corresponding …
hajinsuha1 Jan 23, 2026
1870877
Just some initial commit
jeremy-jung1 Jan 24, 2026
7203494
Merge remote-tracking branch 'origin/W-20224267-passkey-login-in-chec…
jeremy-jung1 Jan 24, 2026
c52520f
Refactor contact info handling to handle merge basket when the custom…
hajinsuha1 Jan 26, 2026
1b88a0e
Test commit
hajinsuha1 Jan 26, 2026
02cc12b
Revert "Test commit"
hajinsuha1 Jan 26, 2026
c2cbe12
Enhance usePasskeyLogin hook to include usid and update corresponding…
hajinsuha1 Jan 26, 2026
7c599ea
Update contact info component to merge basket after successful login …
hajinsuha1 Jan 26, 2026
0176e46
Update bundle size limits in package.json for main.js and vendor.js
hajinsuha1 Jan 26, 2026
051f1a0
Refactor Webauthn unit tests to use specific types for input and expe…
hajinsuha1 Jan 26, 2026
5a59bac
Update contact info component to ensure basket is merged after passke…
hajinsuha1 Jan 26, 2026
c76aaaa
more changes
jeremy-jung1 Jan 26, 2026
8b62155
Merge remote-tracking branch 'origin/W-20224267-passkey-login-in-chec…
jeremy-jung1 Jan 27, 2026
447bd05
Update index.jsx
jeremy-jung1 Jan 27, 2026
d9b517e
Update useAuthHelper.ts
jeremy-jung1 Jan 27, 2026
d6eb18b
remove registration
jeremy-jung1 Jan 27, 2026
54d95fc
Update contact info component to call handleMergeBasket after passkey…
hajinsuha1 Jan 27, 2026
2c8c8dc
Refactor usage of PublicKeyCredential in authentication hooks and log…
hajinsuha1 Jan 27, 2026
68da030
lint
hajinsuha1 Jan 27, 2026
9b304ef
@W-20224082 - [Webauthn] Create passkey in browser and register in SL…
yunakim714 Jan 27, 2026
c394c40
Merge branch 'feature/webauthn-login' into W-20224267-passkey-login-i…
hajinsuha1 Jan 27, 2026
a6ef6bf
changes
jeremy-jung1 Jan 28, 2026
3c43ddc
remove translations
jeremy-jung1 Jan 28, 2026
b73f130
Merge remote-tracking branch 'origin/feature/webauthn-login' into W-2…
jeremy-jung1 Jan 28, 2026
ca42fa8
updates
jeremy-jung1 Jan 28, 2026
e36f2db
More updates
jeremy-jung1 Jan 28, 2026
3cfda69
Updates
jeremy-jung1 Jan 28, 2026
e8f952d
tests
jeremy-jung1 Jan 28, 2026
8043eb5
Merge remote-tracking branch 'origin/W-20224267-passkey-login-in-chec…
jeremy-jung1 Jan 28, 2026
ca4f4e4
changes
jeremy-jung1 Jan 28, 2026
4a6adf0
update
jeremy-jung1 Jan 28, 2026
789d93a
Update en-XA.json
jeremy-jung1 Jan 28, 2026
f5d234b
tests
jeremy-jung1 Jan 28, 2026
d78e21e
Merge branch 'develop' into feature/webauthn-login
jeremy-jung1 Jan 28, 2026
6c26eba
@W-20224267 Passkey login in checkout (#3585)
hajinsuha1 Jan 29, 2026
7cfb97f
Address some feedback
jeremy-jung1 Jan 29, 2026
d915b2c
Update tests
jeremy-jung1 Jan 29, 2026
1776ebb
Merge branch 'feature/webauthn-login' into W-20224220-passkey-in-auth…
jeremy-jung1 Jan 30, 2026
4786611
Merge branch 'feature/webauthn-login' into W-20224220-passkey-in-auth…
jeremy-jung1 Jan 30, 2026
2961538
Fix brace
jeremy-jung1 Jan 30, 2026
cc2264e
Merge branch 'feature/webauthn-login' of github.com:SalesforceCommerc…
jeremy-jung1 Jan 30, 2026
8ba060c
Merge branch 'feature/webauthn-login' into W-20224220-passkey-in-auth…
jeremy-jung1 Jan 30, 2026
40bd7c6
fix merge
jeremy-jung1 Jan 31, 2026
8d46da1
Merge branch 'feature/webauthn-login' into W-20224220-passkey-in-auth…
jeremy-jung1 Feb 1, 2026
338f103
Update commerce-sdk-isomorphic dependency to version 5.0.0 preview an…
hajinsuha1 Feb 2, 2026
0eb14be
Merge pull request #3611 from SalesforceCommerceCloud/W-20224220-pass…
jeremy-jung1 Feb 2, 2026
a62b56b
Merge remote-tracking branch 'origin/develop' into feature/webauthn-l…
hajinsuha1 Feb 2, 2026
0d3683a
Merge branch 'develop' into feature/webauthn-login
hajinsuha1 Feb 4, 2026
a635542
update package-lock.json to use commerce-sdk-isomorphic 5.0.0-unstabl…
hajinsuha1 Feb 4, 2026
e293a52
@W-20224360 Passkey login E2E tests (#3636)
hajinsuha1 Feb 11, 2026
7098a83
Merge branch 'develop' into feature/webauthn-login
hajinsuha1 Feb 12, 2026
8075704
Merge branch 'develop' into feature/webauthn-login
hajinsuha1 Feb 17, 2026
1ae954b
Update package-lock.json to reflect latest dependency changes
hajinsuha1 Feb 19, 2026
cdd7745
fix package-lock.json unwanted changes
hajinsuha1 Feb 20, 2026
1939e36
Merge branch 'develop' into feature/webauthn-login
hajinsuha1 Feb 20, 2026
50f2629
@W-21056536 Error handling Passkey Registration and Login (#3672)
hajinsuha1 Feb 23, 2026
e9050d7
@W-21253277 Passkey login cancelled after user logs in or navigates a…
hajinsuha1 Feb 26, 2026
e7706b5
Merge branch 'develop' into feature/webauthn-login
hajinsuha1 Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions e2e/scripts/pageHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
const {expect} = require('@playwright/test')
const config = require('../config')
const {getCreditCardExpiry, runAccessibilityTest} = require('../scripts/utils.js')
const crypto = require('crypto')
/**
* Note: As a best practice, we should await the network call and assert on the network response rather than waiting for pageLoadState()
* to avoid race conditions from lock in pageLoadState being released before network call resolves.
Expand Down Expand Up @@ -791,3 +792,85 @@ export const selectStoreFromPLP = async ({page}) => {
await page.getByRole('button', {name: 'Close'}).click()
}
}

/**
* Validates that a passkey login request is made to the /webAuthn/authenticate/finish endpoint.
* We can't register an actual passkey in the E2E environment because registration requires a token verification.
* Instead,we add a mock credential to the virtual authenticator to bypass the registration flow and verify the
* request to the /webAuthn/authenticate/finish endpoint.
*
* @param {Object} options.page - Playwright page object representing a browser tab/window
*/
export const validatePasskeyLogin = async ({page}) => {
// Start a CDP session to interact with WebAuthn
const client = await page.context().newCDPSession(page)
await client.send('WebAuthn.enable')
// Create a virtual authenticator to simulate a hardware authenticator for testing
const {authenticatorId} = await client.send('WebAuthn.addVirtualAuthenticator', {
options: {
protocol: 'ctap2',
transport: 'internal',
hasResidentKey: true,
hasUserVerification: true,
isUserVerified: true,
// Enabling automaticPresenceSimulation automatically completes the device's passkey prompt without user interaction
automaticPresenceSimulation: true
}
})

// Preload mock credential into the virtual authenticator
const rpId = new URL(config.EXTRA_FEATURES_E2E_RETAIL_APP_HOME).hostname
// Generate a valid EC key pair for WebAuthn (ES256/P-256)
const {privateKey} = crypto.generateKeyPairSync('ec', {namedCurve: 'P-256'})
const privateKeyBase64 = privateKey.export({format: 'der', type: 'pkcs8'}).toString('base64')

console.log('privateKeyBase64', privateKeyBase64)
const credentialIdBuffer = Buffer.from('mock-credential-id-' + Date.now())
const credentialIdBase64 = credentialIdBuffer.toString('base64') // For mock credential
const credentialId = credentialIdBuffer.toString('base64url') // For verifying the request
await client.send('WebAuthn.addCredential', {
authenticatorId,
credential: {
credentialId: credentialIdBase64,
isResidentCredential: true,
rpId,
privateKey: privateKeyBase64,
userHandle: Buffer.from('test-user-handle').toString('base64'),
signCount: 0,
transports: ['internal']
}
})

let interceptedRequest = null

// Intercept the WebAuthn authenticate/finish endpoint to verify the request
await page.route(
'**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/webauthn/authenticate/finish',
(route) => {
interceptedRequest = route.request()
route.continue()
}
)

await page.goto(config.EXTRA_FEATURES_E2E_RETAIL_APP_HOME + '/login')

// Wait for the WebAuthn authenticate/finish request
await page.waitForResponse(
'**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/webauthn/authenticate/finish'
)

// Verify the /webAuthn/authenticate/finish request
expect(interceptedRequest).toBeTruthy()
expect(interceptedRequest.method()).toBe('POST')
const postData = interceptedRequest.postData()
expect(postData).toBeTruthy()
const requestBody = JSON.parse(postData)
expect(requestBody).toBeTruthy()

// Verify the request body structure matches expected format
expect(requestBody.client_id).toBeTruthy()
expect(requestBody.channel_id).toBe(config.EXTRA_FEATURES_E2E_RETAIL_APP_HOME_SITE)
expect(requestBody.credential.id).toBe(credentialId)
expect(requestBody.credential.clientExtensionResults).toBeTruthy()
expect(requestBody.credential.response).toBeTruthy()
}
Loading
Loading