diff --git a/src/app/common/hooks/auth/use-magic-recovery-code.ts b/src/app/common/hooks/auth/use-magic-recovery-code.ts deleted file mode 100644 index 744202a6..00000000 --- a/src/app/common/hooks/auth/use-magic-recovery-code.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; -import toast from 'react-hot-toast'; -import { useNavigate, useSearchParams } from 'react-router-dom'; - -import { decrypt } from '@stacks/wallet-sdk'; - -import { RouteUrls } from '@shared/route-urls'; - -import { useFinishAuthRequest } from '@app/common/authentication/use-finish-auth-request'; -import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state'; -import { useLoading } from '@app/common/hooks/use-loading'; -import { delay } from '@app/common/utils'; -import { useAppDispatch } from '@app/store'; -import { inMemoryKeyActions } from '@app/store/in-memory-key/in-memory-key.actions'; - -function pullMagicRecoveryCodeFromParams(urlSearchParams: URLSearchParams) { - return urlSearchParams.get('magicRecoveryCode'); -} - -async function simulateShortDelayToAvoidImmediateNavigation() { - await delay(850); -} - -export function useMagicRecoveryCode() { - const { isLoading, setIsLoading, setIsIdle } = useLoading('useMagicRecoveryCode'); - const [urlSearchParams] = useSearchParams(); - - const finishSignIn = useFinishAuthRequest(); - const [error, setPasswordError] = useState(''); - const { decodedAuthRequest } = useOnboardingState(); - const navigate = useNavigate(); - - const dispatch = useAppDispatch(); - - const handleNavigate = useCallback(() => { - if (decodedAuthRequest) { - setTimeout(() => { - void finishSignIn(0); - }, 1000); - } else { - navigate(RouteUrls.SetPassword); - } - }, [navigate, decodedAuthRequest, finishSignIn]); - - const decryptMagicRecoveryCode = useCallback( - async (password: string) => { - const magicRecoveryCode = pullMagicRecoveryCodeFromParams(urlSearchParams); - if (!magicRecoveryCode) throw Error('No magic recovery seed'); - setIsLoading(); - try { - const codeBuffer = Buffer.from(magicRecoveryCode, 'base64'); - const secretKey = await decrypt(codeBuffer, password); - toast.success('Password correct'); - await simulateShortDelayToAvoidImmediateNavigation(); - dispatch(inMemoryKeyActions.saveUsersSecretKeyToBeRestored(secretKey)); - handleNavigate(); - } catch (error) { - setPasswordError(`Incorrect password, try again.`); - setIsIdle(); - } - }, - [urlSearchParams, setIsLoading, dispatch, handleNavigate, setIsIdle] - ); - - useEffect(() => { - if (pullMagicRecoveryCodeFromParams(urlSearchParams)) return; - navigate(RouteUrls.SignIn); - }, [navigate, urlSearchParams]); - - useEffect(() => { - setIsIdle(); - return () => setIsIdle(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return { - error, - isLoading, - decryptMagicRecoveryCode, - }; -} diff --git a/src/app/common/utils.ts b/src/app/common/utils.ts index 69315d32..2d6f844c 100644 --- a/src/app/common/utils.ts +++ b/src/app/common/utils.ts @@ -47,25 +47,6 @@ export function extractPhraseFromPasteEvent(event: ClipboardEvent) { return extractPhraseFromString(pasted); } -export function validateAndCleanRecoveryInput(value: string) { - const cleaned = value.trim(); - // Base64 encoded encrypted phrase - let cleanedEncrypted = cleaned.replace(/\s/gm, ''); - const isPossibleRecoveryKey = /^[a-zA-Z0-9\+\/]+=?$/.test(cleanedEncrypted); - - if (isPossibleRecoveryKey && cleanedEncrypted.slice(-1) !== '=') { - // Append possibly missing equals sign padding - cleanedEncrypted = `${cleanedEncrypted}=`; - } - if (cleanedEncrypted.length >= 108) { - return { - isValid: true, - value: cleanedEncrypted, - }; - } - return { isValid: false, value }; -} - interface MakeTxExplorerLinkArgs { blockchain: Blockchains; mode: BitcoinNetworkModes; diff --git a/src/app/pages/onboarding/magic-recovery-code/magic-recovery-code.tsx b/src/app/pages/onboarding/magic-recovery-code/magic-recovery-code.tsx deleted file mode 100644 index 33ebab08..00000000 --- a/src/app/pages/onboarding/magic-recovery-code/magic-recovery-code.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { memo } from 'react'; -import { useNavigate } from 'react-router-dom'; - -import { Button, Flex, Input, Stack, StackProps, Text } from '@stacks/ui'; -import { WalletPageSelectors } from '@tests-legacy/page-objects/wallet.selectors'; -import { Form, Formik } from 'formik'; - -import { RouteUrls } from '@shared/route-urls'; - -import { useMagicRecoveryCode } from '@app/common/hooks/auth/use-magic-recovery-code'; -import { useRouteHeader } from '@app/common/hooks/use-route-header'; -import { CenteredPageContainer } from '@app/components/centered-page-container'; -import { ErrorLabel } from '@app/components/error-label'; -import { Header } from '@app/components/header'; -import { Caption } from '@app/components/typography'; - -const MagicRecoveryCodeForm: React.FC = memo(props => { - const navigate = useNavigate(); - const { decryptMagicRecoveryCode, error, isLoading } = useMagicRecoveryCode(); - - return ( - decryptMagicRecoveryCode(values.password)} - > - {form => ( -
- - - - {error && ( - - - {error} - - - )} - - - - - - -
- )} -
- ); -}); - -export const MagicRecoveryCode: React.FC = memo(() => { - const navigate = useNavigate(); - - useRouteHeader( -
navigate(RouteUrls.SignIn)} hideActions /> - ); - - return ( - - - You entered a Magic Recovery Code. Enter the password you set when you first created your - Blockstack ID. - - - - ); -}); diff --git a/src/app/pages/onboarding/sign-in/hooks/use-sign-in.ts b/src/app/pages/onboarding/sign-in/hooks/use-sign-in.ts index f70cab6c..6c77056d 100644 --- a/src/app/pages/onboarding/sign-in/hooks/use-sign-in.ts +++ b/src/app/pages/onboarding/sign-in/hooks/use-sign-in.ts @@ -1,5 +1,4 @@ import { useCallback, useEffect, useRef, useState } from 'react'; -import toast from 'react-hot-toast'; import { useNavigate } from 'react-router-dom'; import { validateMnemonic } from 'bip39'; @@ -8,11 +7,7 @@ import { RouteUrls } from '@shared/route-urls'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; import { useLoading } from '@app/common/hooks/use-loading'; -import { - delay, - extractPhraseFromPasteEvent, - validateAndCleanRecoveryInput, -} from '@app/common/utils'; +import { delay, extractPhraseFromPasteEvent } from '@app/common/utils'; import { useAppDispatch } from '@app/store'; import { inMemoryKeyActions } from '@app/store/in-memory-key/in-memory-key.actions'; import { onboardingActions } from '@app/store/onboarding/onboarding.actions'; @@ -56,24 +51,6 @@ export function useSignIn() { handleSetError('Entering your Secret Key is required.'); } - // recovery key? - if (parsedKeyInput.split(' ').length <= 1) { - const result = validateAndCleanRecoveryInput(parsedKeyInput); - if (result.isValid) { - toast.success('Magic recovery code detected'); - await simulateShortDelayToAvoidImmediateNavigation(); - dispatch(onboardingActions.hideSuggestedFirstSteps(true)); - navigate({ - pathname: RouteUrls.MagicRecoveryCode, - search: `?magicRecoveryCode=${parsedKeyInput}`, - }); - return; - } else { - // single word and not a valid recovery key - handleSetError(); - } - } - if (!validateMnemonic(parsedKeyInput)) { handleSetError(); return; diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index 752d4e91..828d5448 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -30,7 +30,6 @@ import { ChooseAccount } from '@app/pages/choose-account/choose-account'; import { FundPage } from '@app/pages/fund/fund'; import { Home } from '@app/pages/home/home'; import { BackUpSecretKeyPage } from '@app/pages/onboarding/back-up-secret-key/back-up-secret-key'; -import { MagicRecoveryCode } from '@app/pages/onboarding/magic-recovery-code/magic-recovery-code'; import { SignIn } from '@app/pages/onboarding/sign-in/sign-in'; import { WelcomePage } from '@app/pages/onboarding/welcome/welcome'; import { PsbtRequest } from '@app/pages/psbt-request/psbt-request'; @@ -190,7 +189,6 @@ function useAppRoutes() { } /> - } /> { await wallet.waitForEnterPasswordInput(); }); - it('should be able to login from Magic Recovery Code', async () => { - await wallet.clickDenyAnalytics(); - await wallet.clickSignIn(); - await wallet.enterSecretKey(MAGIC_RECOVERY_KEY); - await wallet.waitForMagicRecoveryMessage(); - const magicRecoveryElement = await wallet.page.$$(wallet.$magicRecoveryMessage); - const magicRecoveryMessage = await magicRecoveryElement[0].innerText(); - expect(magicRecoveryMessage).toEqual( - 'You entered a Magic Recovery Code. Enter the password you set when you first created your Blockstack ID.' - ); - await wallet.decryptRecoveryCode(MAGIC_RECOVERY_PASSWORD); - await wallet.enterNewPassword('lksjdflksjlfkjsdlfjsldf'); - await wallet.waitForHomePage(); - const homePageVisible = await wallet.page.isVisible(wallet.$homePageContainer); - expect(homePageVisible).toBeTruthy(); - }); - it('should show onboarding steps for a new wallet with only one account', async () => { await wallet.clickDenyAnalytics(); await wallet.clickSignUp(); diff --git a/tests-legacy/mocks/index.ts b/tests-legacy/mocks/index.ts index 2778541a..f8a23242 100644 --- a/tests-legacy/mocks/index.ts +++ b/tests-legacy/mocks/index.ts @@ -64,10 +64,3 @@ export const STX_TRANSFER_DECODED = { export const SECRET_KEY_2 = 'derive plug aerobic cook until crucial school fine cushion panda ready crew photo typical nuclear ride steel indicate cupboard potato ignore bamboo script galaxy'; - -export const MAGIC_RECOVERY_KEY = - 'KDR6O8gKXGmstxj4d2oQqCi806M/Cmrbiatc6g7MkQQLVreRA95IoPtvrI3N230jTTGb2XWT5joRFKPfY/2YlmRz1brxoaDJCNS4z18Iw5Y='; - -export const MAGIC_RECOVERY_PASSWORD = 'test202020'; - -// export const APINetworkRecipientAddress = 'SPJ2XRD8PNGVAMX9GFJSP00A7Y0H9Z5WE39NE5XP';