From 5f8ddd076a3b5a7ef440f0f96d43b01421098cda Mon Sep 17 00:00:00 2001 From: Rob Knight Date: Thu, 26 Sep 2024 18:29:35 +0100 Subject: [PATCH] Remove Chrome storage access request --- .../screens/LoginScreens/LoginScreen.tsx | 194 +++--------------- 1 file changed, 25 insertions(+), 169 deletions(-) diff --git a/apps/passport-client/components/screens/LoginScreens/LoginScreen.tsx b/apps/passport-client/components/screens/LoginScreens/LoginScreen.tsx index 2f34338e87..7f83c79c06 100644 --- a/apps/passport-client/components/screens/LoginScreens/LoginScreen.tsx +++ b/apps/passport-client/components/screens/LoginScreens/LoginScreen.tsx @@ -1,8 +1,4 @@ -import { - requestDownloadAndDecryptStorage, - requestLogToServer -} from "@pcd/passport-interface"; -import { TextButton } from "@pcd/passport-ui"; +import { requestLogToServer } from "@pcd/passport-interface"; import { validateEmail } from "@pcd/util"; import { ChangeEvent, @@ -11,7 +7,6 @@ import { useEffect, useState } from "react"; -import { UAParser } from "ua-parser-js"; import { appConfig } from "../../../src/appConfig"; import { useDispatch, @@ -30,7 +25,6 @@ import { setPendingViewFrogCryptoRequest, setPendingViewSubscriptionsRequest } from "../../../src/sessionStorage"; -import { useSelector } from "../../../src/subscribe"; import { BigInput, Button, @@ -44,23 +38,12 @@ import { RippleLoader } from "../../core/RippleLoader"; import { AppContainer } from "../../shared/AppContainer"; import { InlineError } from "../../shared/InlineError"; -enum StorageAccessStatus { - None, // Default status - CanRequest, // Suitable browser, show the option to request - Requesting, // Request dialog visible - Granted, // Access granted - NoLocalStorage, // Access granted but no relevant storage values found - Denied // Access denied -} - export function LoginScreen(): JSX.Element { const dispatch = useDispatch(); const state = useStateContext().getState(); const [error, setError] = useState(); const query = useQuery(); const redirectedFromAction = query?.get("redirectedFromAction") === "true"; - const connectedZapp = useSelector((state) => state.connectedZapp); - const zappOrigin = useSelector((state) => state.zappOrigin); const pendingGetWithoutProvingRequest = query?.get( pendingRequestKeys.getWithoutProving @@ -152,104 +135,6 @@ export function LoginScreen(): JSX.Element { [dispatch, email] ); - const [storageAccessStatus, setStorageAccessStatus] = useState( - StorageAccessStatus.None - ); - - /** - * Assuming we're in Chrome and an iframe, and we've successfully loaded an - * encryption key from local storage, try to use it to log in. - */ - const tryToLogin = useCallback( - async (encryptionKey: string) => { - // Try to download and decrypt the storage - const storageRequest = await requestDownloadAndDecryptStorage( - appConfig.zupassServer, - encryptionKey - ); - if (storageRequest.success) { - // Success, log in - dispatch({ - type: "load-after-login", - storage: storageRequest.value, - encryptionKey - }); - } else { - // Something unexpected went wrong - setError( - "Unable to log in automatically, please enter your email to log in" - ); - setStorageAccessStatus(StorageAccessStatus.Denied); - } - }, - [dispatch] - ); - - /** - * This will only be called if we're in an iframe and Chrome. - */ - const requestStorageAndLogIn = useCallback(async () => { - try { - setStorageAccessStatus(StorageAccessStatus.Requesting); - // @ts-expect-error Chrome-only API - const handle: { localStorage: Storage } = - // @ts-expect-error Chrome-only API - await document.requestStorageAccess({ localStorage: true }); - - setStorageAccessStatus(StorageAccessStatus.Granted); - // Access granted, try reading the local storage - const encryptionKey = handle.localStorage.getItem("encryption_key"); - if (encryptionKey) { - await tryToLogin(encryptionKey); - } else { - setStorageAccessStatus(StorageAccessStatus.NoLocalStorage); - } - } catch (_e) { - // If the user rejected the storage access request, set an error message. - // The finally block will return the user to the regular login flow. - setError( - "Unable to log in automatically, please enter your email to log in" - ); - setStorageAccessStatus(StorageAccessStatus.Denied); - } - }, [tryToLogin]); - - useEffect(() => { - (async (): Promise => { - // Are we in an iframe? If so, we might be able to skip requesting the - // user's email and password by retrieving their encryption key from the - // first-party local storage. Currently this only works on Chrome 125+. - const parser = new UAParser(); - const browserName = parser.getBrowser().name; - const browserVersion = parser.getBrowser().version; - const isChrome125OrAbove = - browserName === "Chrome" && - browserVersion && - parseInt(browserVersion) >= 125; - - if (window.parent !== window && isChrome125OrAbove) { - // Do we already have access? - const hasAccess = await document.hasStorageAccess(); - if (!hasAccess) { - // No access, try requesting it interactively - // Setting this state will trigger the UI to show the "Connect to - // Zupass" button. To request storage access, the user must click - // the button and approve the dialog. - // Storage access requests must occur in response to a user action, - // so we can't request it automatically here and must wait for the - // user to click the button. - setStorageAccessStatus(StorageAccessStatus.CanRequest); - } else { - // Access is allowed in principle, now we can request storage - // Show a spinner: - setStorageAccessStatus(StorageAccessStatus.Requesting); - // Try to read from storage and log in - requestStorageAndLogIn(); - } - } - })(); - }, [dispatch, requestStorageAndLogIn, tryToLogin]); - useEffect(() => { // Redirect to home if already logged in if (self) { @@ -290,61 +175,32 @@ export function LoginScreen(): JSX.Element { )} - {storageAccessStatus === StorageAccessStatus.CanRequest && ( - - - Do you want to allow {connectedZapp?.name} ({zappOrigin}) to - connect to Zupass? - - {" "} - - setStorageAccessStatus(StorageAccessStatus.Denied)} - > - Log in manually - - - )} - - {(storageAccessStatus === StorageAccessStatus.Requesting || - storageAccessStatus === StorageAccessStatus.Granted) && ( - + {!state.loggingOut && ( + <> - - + +
+ ) => + setEmail(e.target.value) + } + /> + + + + +
+ + )} - - {(storageAccessStatus === StorageAccessStatus.None || - storageAccessStatus === StorageAccessStatus.Denied || - storageAccessStatus === StorageAccessStatus.NoLocalStorage) && - !state.loggingOut && ( - <> - - -
- ) => - setEmail(e.target.value) - } - /> - - - - -
- - - )} ); }