Pass as a query param instead
Mobile prefers it this way
This commit is contained in:
@@ -566,8 +566,9 @@ export const passkeyAuthenticationSuccessRedirectURL = async (
|
||||
twoFactorAuthorizationResponse: TwoFactorAuthorizationResponse,
|
||||
) => {
|
||||
const encodedResponse = await toB64URLSafeNoPaddingString(
|
||||
JSON.stringify({ ...twoFactorAuthorizationResponse, passkeySessionID }),
|
||||
JSON.stringify(twoFactorAuthorizationResponse),
|
||||
);
|
||||
redirectURL.searchParams.set("passkeySessionID", passkeySessionID);
|
||||
redirectURL.searchParams.set("response", encodedResponse);
|
||||
return redirectURL;
|
||||
};
|
||||
|
||||
@@ -23,12 +23,15 @@ const Page: React.FC<PageProps> = () => {
|
||||
useEffect(() => {
|
||||
// Extract response from query params
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const passkeySessionID = searchParams.get("passkeySessionID");
|
||||
const response = searchParams.get("response");
|
||||
if (!response) return;
|
||||
if (!passkeySessionID || !response) return;
|
||||
|
||||
saveCredentialsAndNavigateTo(response).then((slug: string) => {
|
||||
router.push(slug);
|
||||
});
|
||||
saveCredentialsAndNavigateTo(passkeySessionID, response).then(
|
||||
(slug: string) => {
|
||||
router.push(slug);
|
||||
},
|
||||
);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -45,12 +48,36 @@ export default Page;
|
||||
* and save them to local storage for use by subsequent steps (or normal
|
||||
* functioning) of the app.
|
||||
*
|
||||
* @param response The string that is passed as the response query parameter to
|
||||
* @param passkeySessionID The string that is passed as the "passkeySessionID"
|
||||
* query parameter to us.
|
||||
*
|
||||
* @param response The string that is passed as the "response" query parameter to
|
||||
* us (we're the final "finish" page in the passkey flow).
|
||||
*
|
||||
* @returns the slug that we should navigate to now.
|
||||
*/
|
||||
const saveCredentialsAndNavigateTo = async (response: string) => {
|
||||
const saveCredentialsAndNavigateTo = async (
|
||||
passkeySessionID: string,
|
||||
response: string,
|
||||
) => {
|
||||
const inflightPasskeySessionID = nullToUndefined(
|
||||
sessionStorage.getItem("inflightPasskeySessionID"),
|
||||
);
|
||||
if (
|
||||
!inflightPasskeySessionID ||
|
||||
passkeySessionID != inflightPasskeySessionID
|
||||
) {
|
||||
// This is not the princess we were looking for. However, we have
|
||||
// already entered this castle. Redirect back to home without changing
|
||||
// any state, hopefully this will get the user back to where they were.
|
||||
log.info(
|
||||
`Ignoring redirect for unexpected passkeySessionID ${passkeySessionID}`,
|
||||
);
|
||||
return "/";
|
||||
}
|
||||
|
||||
sessionStorage.removeItem("inflightPasskeySessionID");
|
||||
|
||||
// Decode response string (inverse of the steps we perform in
|
||||
// `passkeyAuthenticationSuccessRedirectURL`).
|
||||
const decodedResponse = JSON.parse(
|
||||
@@ -66,27 +93,7 @@ const saveCredentialsAndNavigateTo = async (response: string) => {
|
||||
//
|
||||
// - The encrypted `encryptedToken` will be present otherwise (i.e. if the
|
||||
// user is signing into an existing account).
|
||||
const { passkeySessionID, keyAttributes, encryptedToken, token, id } =
|
||||
decodedResponse;
|
||||
|
||||
const inflightPasskeySessionID = nullToUndefined(
|
||||
sessionStorage.getItem("inflightPasskeySessionID"),
|
||||
);
|
||||
if (
|
||||
!passkeySessionID ||
|
||||
!inflightPasskeySessionID ||
|
||||
passkeySessionID != inflightPasskeySessionID
|
||||
) {
|
||||
// This is not the princess we were looking for. However, we have
|
||||
// already entered this castle. Redirect back to home without changing
|
||||
// any state, hopefully this will get the user back to where they were.
|
||||
log.info(
|
||||
`Ignoring redirect for unexpected passkeySessionID ${passkeySessionID}`,
|
||||
);
|
||||
return "/";
|
||||
}
|
||||
|
||||
sessionStorage.removeItem("inflightPasskeySessionID");
|
||||
const { keyAttributes, encryptedToken, token, id } = decodedResponse;
|
||||
|
||||
setData(LS_KEYS.USER, {
|
||||
...getData(LS_KEYS.USER),
|
||||
|
||||
Reference in New Issue
Block a user