Skip to content

Commit 80d9dd1

Browse files
committed
Refactor and improve comments
1 parent 31c65ec commit 80d9dd1

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

src/frontend/src/lib/utils/findWebAuthnFlows.ts

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@ type Parameters = {
1818
relatedOrigins: string[];
1919
};
2020

21+
// The devices are expected to be ordered by recently used already
22+
// Move devices registered on the new flow origins to the end using toSorted (preserving relative order within groups)
23+
const newFlowOrigins = canisterConfig.new_flow_origins[0] ?? [];
24+
const isInNewFlow = (credentialData: CredentialData): boolean => {
25+
const origin = credentialData.origin ?? II_LEGACY_ORIGIN;
26+
return newFlowOrigins.some((o) => isSameOrigin(o, origin));
27+
};
28+
const sortNewFlowOriginsToEnd = (
29+
a: CredentialData,
30+
b: CredentialData,
31+
): number => {
32+
const aIn = isInNewFlow(a);
33+
const bIn = isInNewFlow(b);
34+
// Keep the order if both are in the new flow or both are not
35+
if (aIn === bIn) return 0;
36+
// Move the one that is in the new flow to the end
37+
return aIn ? 1 : -1;
38+
};
39+
2140
/**
2241
* Function that returns the ordered steps to try to perform the webauthn authentication.
2342
*
@@ -27,7 +46,13 @@ type Parameters = {
2746
*
2847
* Logic:
2948
* - To calculate the RP IDs, we look for all RP IDs within the devices
30-
* - At the moment, we only use non-iframe if the RP ID matches the current origin. to avoid bad UX, if the RP ID doesn't match the current origin, the iframe will be used.
49+
* - We sort the devices to move the devices registered on the new flow origins to the end
50+
* - The rest of the order we keep as is because it's the order by last used (recently used first) returned by the backend
51+
* We do this because during the upgrade flow a new passkey is created and it will be used to authenticate in 1.0. This was initially considered a feature, not a bug.
52+
* But users don't know where passkeys are stored.
53+
* Therefore, the passkey that they use to authenticate in 1.0 is not in the same place where they upgraded.
54+
* Which triggers a new UX for the user that confuses them because they were used to a different UX.
55+
* - We only use non-iframe if the RP ID matches the current origin. to avoid bad UX, if the RP ID doesn't match the current origin, the iframe will be used.
3156
*
3257
* @param {Parameters} params - The parameters to find the webauthn steps.
3358
* @returns {WebAuthnFlow[]} The ordered steps to try to perform the webauthn authentication.
@@ -42,27 +67,10 @@ export const findWebAuthnFlows = ({
4267
(relatedOrigin) => new URL(relatedOrigin).hostname,
4368
);
4469

45-
// The devices are expected to be ordered by recently used already
46-
// Move devices registered on the new flow origins to the end using toSorted (preserving relative order within groups)
47-
const newFlowOrigins = canisterConfig.new_flow_origins[0] ?? [];
48-
const isInNewFlow = (credentialData: CredentialData): boolean => {
49-
const origin = credentialData.origin ?? II_LEGACY_ORIGIN;
50-
return newFlowOrigins.some((o) => isSameOrigin(o, origin));
51-
};
52-
const sortNewFlowOriginsToEnd = (
53-
a: CredentialData,
54-
b: CredentialData,
55-
): number => {
56-
const aIn = isInNewFlow(a);
57-
const bIn = isInNewFlow(b);
58-
// Keep the order if both are in the new flow or both are not
59-
if (aIn === bIn) return 0;
60-
// Move the one that is in the new flow to the end
61-
return aIn ? 1 : -1;
62-
};
63-
64-
const orderedDeviceRpIds: (string | undefined)[] = [...devices]
65-
.sort(sortNewFlowOriginsToEnd)
70+
// Sort devices in place
71+
devices.sort(sortNewFlowOriginsToEnd);
72+
// Create steps from `devices`, currently that's one step per RP ID
73+
const steps: WebAuthnFlow[] = devices
6674
// Device origin to RP ID (hostname)
6775
.map((device: CredentialData) =>
6876
device.origin === currentOrigin ||
@@ -81,13 +89,11 @@ export const findWebAuthnFlows = ({
8189
return rpIds;
8290
}
8391
return [...rpIds, rpId];
84-
}, []);
85-
86-
// Create steps from `deviceRpIds`, currently that's one step per RP ID
87-
const steps: WebAuthnFlow[] = orderedDeviceRpIds.map((rpId) => ({
88-
rpId,
89-
useIframe: nonNullish(rpId) && rpId !== currentRpId,
90-
}));
92+
}, [])
93+
.map((rpId) => ({
94+
rpId,
95+
useIframe: nonNullish(rpId) && rpId !== currentRpId,
96+
}));
9197

9298
// If there are no steps, add a default step.
9399
if (steps.length === 0) {

0 commit comments

Comments
 (0)