Handle qp

This commit is contained in:
Manav Rathi
2025-07-03 08:40:50 +05:30
parent aec3ec718b
commit 802a3edf9b
3 changed files with 27 additions and 21 deletions

View File

@@ -1,9 +1,10 @@
import {
getData,
setData,
saveKeyAttributes,
setLSUser,
} from "ente-accounts/services/accounts-db";
import { unstashRedirect } from "ente-accounts/services/redirect";
import { TwoFactorAuthorizationResponse } from "ente-accounts/services/user";
import { LoadingIndicator } from "ente-base/components/loaders";
import { fromB64URLSafeNoPadding } from "ente-base/crypto";
import log from "ente-base/log";
@@ -57,6 +58,8 @@ const saveQueryCredentialsAndNavigateTo = async (
) => {
// This function's implementation is on the same lines as that of the
// `saveCredentialsAndNavigateTo` function in passkey utilities.
//
// See: [Note: Ending the passkey flow]
const inflightPasskeySessionID = nullToUndefined(
sessionStorage.getItem("inflightPasskeySessionID"),
@@ -78,28 +81,19 @@ const saveQueryCredentialsAndNavigateTo = async (
// Decode response string (inverse of the steps we perform in
// `passkeyAuthenticationSuccessRedirectURL`).
const decodedResponse = JSON.parse(
new TextDecoder().decode(await fromB64URLSafeNoPadding(response)),
const decodedResponse = TwoFactorAuthorizationResponse.parse(
JSON.parse(
new TextDecoder().decode(await fromB64URLSafeNoPadding(response)),
),
);
// Only one of `encryptedToken` or `token` will be present depending on the
// account's lifetime:
//
// - The plaintext "token" will be passed during fresh signups, where we
// don't yet have keys to encrypt it, the account itself is being created
// as we go through this flow.
//
// TODO: Conceptually this cannot happen. During a _real_ fresh signup
// we'll never enter the passkey verification flow. Remove this code after
// making sure that it doesn't get triggered in cases where an existing
// user goes through the new user flow.
//
// - The encrypted `encryptedToken` will be present otherwise (i.e. if the
// user is signing into an existing account).
const { keyAttributes, encryptedToken, token, id } = decodedResponse;
const { id, keyAttributes, encryptedToken } = decodedResponse;
// TODO: See: [Note: empty token?]
const token = undefined;
await setLSUser({ ...getData("user"), token, encryptedToken, id });
setData("keyAttributes", keyAttributes);
saveKeyAttributes(keyAttributes);
return unstashRedirect() ?? "/credentials";
};

View File

@@ -49,6 +49,8 @@ const Page: React.FC = () => {
await setLSUser({
...getData("user"),
id,
// TODO: [Note: empty token?]
//
// The original code was parsing an token which is never going
// to be present in the response, so effectively was always
// setting token to undefined. So this works, but is it needed?

View File

@@ -243,8 +243,18 @@ export const checkPasskeyVerificationStatus = async (
export const saveCredentialsAndNavigateTo = async (
response: TwoFactorAuthorizationResponse,
) => {
// The implementation is similar to the `saveQueryCredentialsAndNavigateTo`
// function on the "/passkeys/finish" page.
// [Note: Ending the passkey flow]
//
// The implementation of this function is similar to that of the
// `saveQueryCredentialsAndNavigateTo` on the "/passkeys/finish" page.
//
// This one, `saveCredentialsAndNavigateTo`, is used when the user presses
// the check verification status button on the page that triggered the
// passkey flow (when they're using the desktop app).
//
// The other one, `saveQueryCredentialsAndNavigateTo`, is used when the user
// goes through the passkey flow in the browser itself (when they are using
// the web app).
const { id, encryptedToken, keyAttributes } = response;