This commit is contained in:
Manav Rathi
2024-06-10 09:42:12 +05:30
parent d9e6379020
commit f40da137cd
3 changed files with 21 additions and 14 deletions

View File

@@ -116,7 +116,10 @@ const Page = () => {
// Conceptually we can `setStatus("done")` at this point, but we'll
// leave this page anyway, so no need to tickle React.
redirectAfterPasskeyAuthentication(redirectURL, authorizationResponse);
await redirectAfterPasskeyAuthentication(
redirectURL,
authorizationResponse,
);
};
useEffect(() => {

View File

@@ -6,10 +6,10 @@ import { nullToUndefined } from "@/utils/transform";
import {
fromB64URLSafeNoPadding,
toB64URLSafeNoPadding,
toB64URLSafeNoPaddingString,
} from "@ente/shared/crypto/internal/libsodium";
import { apiOrigin } from "@ente/shared/network/api";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import _sodium from "libsodium-wrappers";
import { z } from "zod";
/** Return true if the user's browser supports WebAuthn (Passkeys). */
@@ -511,14 +511,14 @@ const authenticatorAssertionResponse = (credential: Credential) => {
* @param twoFactorAuthorizationResponse The result of
* {@link finishPasskeyAuthentication} returned by the backend.
*/
export const redirectAfterPasskeyAuthentication = (
export const redirectAfterPasskeyAuthentication = async (
redirectURL: URL,
twoFactorAuthorizationResponse: TwoFactorAuthorizationResponse,
) => {
const encodedResponse = _sodium.to_base64(
const encodedResponse = await toB64URLSafeNoPaddingString(
JSON.stringify(twoFactorAuthorizationResponse),
);
// TODO-PK: Shouldn't this be URL encoded?
window.location.href = `${redirectURL}?response=${encodedResponse}`;
redirectURL.searchParams.set("response", encodedResponse)
window.location.href = redirectURL.href;
};

View File

@@ -1,5 +1,6 @@
import { VerticallyCentered } from "@ente/shared/components/Container";
import EnteSpinner from "@ente/shared/components/EnteSpinner";
import { fromB64URLSafeNoPaddingString } from "@ente/shared/crypto/internal/libsodium";
import InMemoryStore, { MS_KEYS } from "@ente/shared/storage/InMemoryStore";
import { LS_KEYS, getData, setData } from "@ente/shared/storage/localStorage";
import { useRouter } from "next/router";
@@ -23,11 +24,11 @@ const Page: React.FC<PageProps> = () => {
const response = searchParams.get("response");
if (!response) return;
saveCredentials(response);
const redirectURL = InMemoryStore.get(MS_KEYS.REDIRECT_URL);
InMemoryStore.delete(MS_KEYS.REDIRECT_URL);
router.push(redirectURL ?? PAGES.CREDENTIALS);
saveCredentials(response).then(() => {
const redirectURL = InMemoryStore.get(MS_KEYS.REDIRECT_URL);
InMemoryStore.delete(MS_KEYS.REDIRECT_URL);
router.push(redirectURL ?? PAGES.CREDENTIALS);
});
}, []);
return (
@@ -47,9 +48,12 @@ export default Page;
* @param response The string that is passed as the response query parameter to
* us (we're the final "finish" page in the passkey flow).
*/
const saveCredentials = (response: string) => {
// Decode response string.
const decodedResponse = JSON.parse(atob(response));
const saveCredentials = async (response: string) => {
// Decode response string (inverse of the steps we perform in
// `redirectAfterPasskeyAuthentication`).
const decodedResponse = JSON.parse(
await fromB64URLSafeNoPaddingString(response),
);
// Only one of `encryptedToken` or `token` will be present depending on the
// account's lifetime: