Skip to content

Commit 6c26eba

Browse files
authored
@W-20224267 Passkey login in checkout (#3585)
* add new usePasskeyLogin hook to be used to initiate passkey login * call usePasskeyLogin from ContactInfo page * ensure merge basket is handled
1 parent 9b304ef commit 6c26eba

File tree

11 files changed

+789
-118
lines changed

11 files changed

+789
-118
lines changed

packages/commerce-sdk-react/src/auth/index.test.ts

Lines changed: 242 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,113 +1305,268 @@ describe('Webauthn', () => {
13051305
} as ShopperLoginTypes.AuthenticatorAssertionResponseJson
13061306
}
13071307

1308-
test('authorizeWebauthnRegistration', async () => {
1309-
const auth = new Auth(config)
1310-
await auth.authorizeWebauthnRegistration({
1311-
user_id: 'test-user-id',
1312-
mode: 'test-mode',
1313-
channel_id: 'test-channel-id'
1314-
})
1315-
1316-
expect((auth as any).client.authorizeWebauthnRegistration).toHaveBeenCalledWith({
1317-
headers: {
1318-
Authorization: ''
1308+
test.each([
1309+
[
1310+
'with all parameters specified',
1311+
{
1312+
user_id: 'user@example.com',
1313+
mode: 'email',
1314+
channel_id: 'custom-channel-id',
1315+
client_id: 'custom-client-id',
1316+
locale: 'en-GB',
1317+
code_challenge: 'test-code-challenge',
1318+
callback_uri: 'https://example.com/callback',
1319+
idp_name: 'customIdp',
1320+
hint: 'custom_hint'
13191321
},
1320-
body: {
1321-
user_id: 'test-user-id',
1322-
mode: 'test-mode',
1323-
channel_id: 'test-channel-id'
1322+
{
1323+
user_id: 'user@example.com',
1324+
mode: 'email',
1325+
channel_id: 'custom-channel-id',
1326+
client_id: 'custom-client-id',
1327+
locale: 'en-GB',
1328+
code_challenge: 'test-code-challenge',
1329+
callback_uri: 'https://example.com/callback',
1330+
idp_name: 'customIdp',
1331+
hint: 'custom_hint'
13241332
}
1325-
})
1326-
})
1333+
],
1334+
[
1335+
'defaults optional parameters when only required parameters are specified',
1336+
{
1337+
user_id: 'user@example.com',
1338+
mode: 'email'
1339+
},
1340+
{
1341+
user_id: 'user@example.com',
1342+
mode: 'email',
1343+
channel_id: config.siteId
1344+
}
1345+
]
1346+
])(
1347+
'authorizeWebauthnRegistration %s',
1348+
async (
1349+
_,
1350+
input: Partial<ShopperLoginTypes.authorizeWebauthnRegistrationBodyType>,
1351+
expectedBody: Partial<ShopperLoginTypes.authorizeWebauthnRegistrationBodyType>
1352+
) => {
1353+
const auth = new Auth(config)
1354+
await auth.authorizeWebauthnRegistration(
1355+
input as ShopperLoginTypes.authorizeWebauthnRegistrationBodyType
1356+
)
13271357

1328-
test('startWebauthnUserRegistration', async () => {
1329-
const auth = new Auth(config)
1330-
await auth.startWebauthnUserRegistration({
1331-
channel_id: 'test-channel-id',
1332-
display_name: 'test-display-name',
1333-
nick_name: 'test-nick-name',
1334-
client_id: 'test-client-id',
1335-
pwd_action_token: 'test-pwd-action-token',
1336-
user_id: 'test-user-id'
1337-
})
1358+
expect((auth as any).client.authorizeWebauthnRegistration).toHaveBeenCalledWith({
1359+
headers: {
1360+
Authorization: ''
1361+
},
1362+
body: expectedBody
1363+
})
1364+
}
1365+
)
13381366

1339-
expect((auth as any).client.startWebauthnUserRegistration).toHaveBeenCalledWith({
1340-
headers: {
1341-
Authorization: ''
1367+
test.each([
1368+
[
1369+
'with all parameters specified',
1370+
{
1371+
user_id: 'user@example.com',
1372+
pwd_action_token: 'test-pwd-action-token',
1373+
channel_id: 'custom-channel-id',
1374+
client_id: 'custom-client-id',
1375+
display_name: 'Test Display Name',
1376+
nick_name: 'Test Nick Name'
13421377
},
1343-
body: {
1344-
display_name: 'test-display-name',
1345-
nick_name: 'test-nick-name',
1346-
client_id: 'test-client-id',
1347-
channel_id: 'test-channel-id',
1378+
{
1379+
user_id: 'user@example.com',
13481380
pwd_action_token: 'test-pwd-action-token',
1349-
user_id: 'test-user-id'
1381+
channel_id: 'custom-channel-id',
1382+
client_id: 'custom-client-id',
1383+
display_name: 'Test Display Name',
1384+
nick_name: 'Test Nick Name'
13501385
}
1351-
})
1352-
})
1386+
],
1387+
[
1388+
'defaults optional parameters when only required parameters are specified',
1389+
{
1390+
user_id: 'user@example.com',
1391+
pwd_action_token: 'test-pwd-action-token'
1392+
},
1393+
{
1394+
user_id: 'user@example.com',
1395+
pwd_action_token: 'test-pwd-action-token',
1396+
channel_id: config.siteId
1397+
}
1398+
]
1399+
])(
1400+
'startWebauthnUserRegistration %s',
1401+
async (
1402+
_,
1403+
input: Partial<ShopperLoginTypes.startWebauthnUserRegistrationBodyType>,
1404+
expectedBody: Partial<ShopperLoginTypes.startWebauthnUserRegistrationBodyType>
1405+
) => {
1406+
const auth = new Auth(config)
1407+
await auth.startWebauthnUserRegistration(
1408+
input as ShopperLoginTypes.startWebauthnUserRegistrationBodyType
1409+
)
13531410

1354-
test('finishWebauthnUserRegistration', async () => {
1355-
const auth = new Auth(config)
1356-
await auth.finishWebauthnUserRegistration({
1357-
client_id: 'test-client-id',
1358-
username: 'test-username',
1359-
credential: PUBLIC_KEY_CREDENTIAL_JSON,
1360-
channel_id: 'test-channel-id',
1361-
pwd_action_token: 'test-pwd-action-token'
1362-
})
1411+
expect((auth as any).client.startWebauthnUserRegistration).toHaveBeenCalledWith({
1412+
headers: {
1413+
Authorization: ''
1414+
},
1415+
body: expectedBody
1416+
})
1417+
}
1418+
)
13631419

1364-
expect((auth as any).client.finishWebauthnUserRegistration).toHaveBeenCalledWith({
1365-
headers: {
1366-
Authorization: ''
1420+
test.each([
1421+
[
1422+
'with all parameters specified',
1423+
{
1424+
username: 'user@example.com',
1425+
credential: PUBLIC_KEY_CREDENTIAL_JSON,
1426+
pwd_action_token: 'test-pwd-action-token',
1427+
channel_id: 'custom-channel-id',
1428+
client_id: 'custom-client-id'
13671429
},
1368-
body: {
1369-
client_id: 'test-client-id',
1370-
username: 'test-username',
1430+
{
1431+
username: 'user@example.com',
1432+
credential: PUBLIC_KEY_CREDENTIAL_JSON,
1433+
pwd_action_token: 'test-pwd-action-token',
1434+
channel_id: 'custom-channel-id',
1435+
client_id: 'custom-client-id'
1436+
}
1437+
],
1438+
[
1439+
'defaults optional parameters when only required parameters are specified',
1440+
{
1441+
username: 'user@example.com',
13711442
credential: PUBLIC_KEY_CREDENTIAL_JSON,
1372-
channel_id: 'test-channel-id',
13731443
pwd_action_token: 'test-pwd-action-token'
1444+
},
1445+
{
1446+
username: 'user@example.com',
1447+
credential: PUBLIC_KEY_CREDENTIAL_JSON,
1448+
pwd_action_token: 'test-pwd-action-token',
1449+
channel_id: config.siteId,
1450+
client_id: config.clientId
13741451
}
1375-
})
1376-
})
1452+
]
1453+
])(
1454+
'finishWebauthnUserRegistration %s',
1455+
async (
1456+
_,
1457+
input: Partial<ShopperLoginTypes.RegistrationFinishRequest>,
1458+
expectedBody: Partial<ShopperLoginTypes.RegistrationFinishRequest>
1459+
) => {
1460+
const auth = new Auth(config)
1461+
await auth.finishWebauthnUserRegistration(
1462+
input as ShopperLoginTypes.RegistrationFinishRequest
1463+
)
13771464

1378-
test('startWebauthnAuthentication', async () => {
1379-
const auth = new Auth(config)
1380-
await auth.startWebauthnAuthentication({
1381-
user_id: 'test-user-id',
1382-
channel_id: 'test-channel-id',
1383-
client_id: 'test-client-id'
1384-
})
1465+
expect((auth as any).client.finishWebauthnUserRegistration).toHaveBeenCalledWith({
1466+
headers: {
1467+
Authorization: ''
1468+
},
1469+
body: expectedBody
1470+
})
1471+
}
1472+
)
13851473

1386-
expect((auth as any).client.startWebauthnAuthentication).toHaveBeenCalledWith({
1387-
headers: {
1388-
Authorization: ''
1474+
test.each([
1475+
[
1476+
'with all parameters specified',
1477+
{
1478+
user_id: 'user@example.com',
1479+
tenant_id: 'tenant-123',
1480+
channel_id: 'custom-channel-id',
1481+
client_id: 'custom-client-id'
13891482
},
1390-
body: {
1391-
user_id: 'test-user-id',
1392-
channel_id: 'test-channel-id',
1393-
client_id: 'test-client-id'
1483+
{
1484+
user_id: 'user@example.com',
1485+
tenant_id: 'tenant-123',
1486+
channel_id: 'custom-channel-id',
1487+
client_id: 'custom-client-id'
13941488
}
1395-
})
1396-
})
1489+
],
1490+
[
1491+
'defaults optional parameters when empty object is provided',
1492+
{},
1493+
{
1494+
channel_id: config.siteId,
1495+
client_id: config.clientId
1496+
}
1497+
]
1498+
])(
1499+
'startWebauthnAuthentication %s',
1500+
async (
1501+
_,
1502+
input: Partial<ShopperLoginTypes.startWebauthnAuthenticationBodyType>,
1503+
expectedBody: Partial<ShopperLoginTypes.startWebauthnAuthenticationBodyType>
1504+
) => {
1505+
const auth = new Auth(config)
1506+
await auth.startWebauthnAuthentication(
1507+
input as ShopperLoginTypes.startWebauthnAuthenticationBodyType
1508+
)
13971509

1398-
test('finishWebauthnAuthentication', async () => {
1399-
const auth = new Auth(config)
1400-
await auth.finishWebauthnAuthentication({
1401-
client_id: 'test-client-id',
1402-
channel_id: 'test-channel-id',
1403-
credential: PUBLIC_KEY_CREDENTIAL_JSON
1404-
})
1510+
expect((auth as any).client.startWebauthnAuthentication).toHaveBeenCalledWith({
1511+
headers: {
1512+
Authorization: ''
1513+
},
1514+
body: expectedBody
1515+
})
1516+
}
1517+
)
14051518

1406-
expect((auth as any).client.finishWebauthnAuthentication).toHaveBeenCalledWith({
1407-
headers: {
1408-
Authorization: ''
1519+
test.each([
1520+
[
1521+
'with all parameters specified',
1522+
{
1523+
user_id: 'user@example.com',
1524+
email: 'user@example.com',
1525+
tenant_id: 'tenant-123',
1526+
usid: 'usid-123',
1527+
channel_id: 'custom-channel-id',
1528+
client_id: 'custom-client-id',
1529+
credential: PUBLIC_KEY_CREDENTIAL_JSON
14091530
},
1410-
body: {
1411-
client_id: 'test-client-id',
1412-
channel_id: 'test-channel-id',
1531+
{
1532+
user_id: 'user@example.com',
1533+
email: 'user@example.com',
1534+
tenant_id: 'tenant-123',
1535+
usid: 'usid-123',
1536+
channel_id: 'custom-channel-id',
1537+
client_id: 'custom-client-id',
14131538
credential: PUBLIC_KEY_CREDENTIAL_JSON
14141539
}
1415-
})
1416-
})
1540+
],
1541+
[
1542+
'defaults optional parameters when only required parameters are specified',
1543+
{
1544+
credential: PUBLIC_KEY_CREDENTIAL_JSON
1545+
},
1546+
{
1547+
channel_id: config.siteId,
1548+
client_id: config.clientId,
1549+
credential: PUBLIC_KEY_CREDENTIAL_JSON
1550+
}
1551+
]
1552+
])(
1553+
'finishWebauthnAuthentication %s',
1554+
async (
1555+
_,
1556+
input: Partial<ShopperLoginTypes.AuthenticateFinishRequest>,
1557+
expectedBody: Partial<ShopperLoginTypes.AuthenticateFinishRequest>
1558+
) => {
1559+
const auth = new Auth(config)
1560+
await auth.finishWebauthnAuthentication(
1561+
input as ShopperLoginTypes.AuthenticateFinishRequest
1562+
)
1563+
1564+
expect((auth as any).client.finishWebauthnAuthentication).toHaveBeenCalledWith({
1565+
headers: {
1566+
Authorization: ''
1567+
},
1568+
body: expectedBody
1569+
})
1570+
}
1571+
)
14171572
})

packages/commerce-sdk-react/src/auth/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,9 +1387,7 @@ class Auth {
13871387
if (authHeader) {
13881388
options.headers.Authorization = authHeader
13891389
}
1390-
// TODO: no code verifier needed with the fix blair has made, delete this when the fix has been merged to production
1391-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1392-
// @ts-ignore
1390+
13931391
const res = await this.client.resetPassword(options)
13941392
return res
13951393
}
@@ -1532,12 +1530,14 @@ class Auth {
15321530
// Required params
15331531
client_id: parameters.client_id || slasClient.clientConfig.parameters.clientId,
15341532
channel_id: parameters.channel_id || slasClient.clientConfig.parameters.siteId,
1535-
user_id: parameters.user_id,
15361533
// Optional params
1534+
...(parameters.user_id && {user_id: parameters.user_id}),
15371535
...(parameters.tenant_id && {tenant_id: parameters.tenant_id})
15381536
}
15391537
}
15401538

1539+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
1540+
// @ts-ignore TODO: user_id is optional, but commerce-sdk-isomorphic expects it to be required. Remove this comment after commerce-sdk-isomorphic is updated.
15411541
return await slasClient.startWebauthnAuthentication(options)
15421542
}
15431543

0 commit comments

Comments
 (0)