From e6cd82171079c46aad8ffa38fa50d6d38deabde2 Mon Sep 17 00:00:00 2001 From: Mark Hendrickson Date: Tue, 23 Apr 2024 18:10:43 +0200 Subject: [PATCH] feat: disable request diagnostics on install --- .../common/hooks/analytics/use-analytics.ts | 7 +- .../features/container/utils/route-helpers.ts | 2 +- .../allow-diagnostics-layout.tsx | 78 ------------------- .../allow-diagnostics/allow-diagnostics.tsx | 45 ----------- src/app/pages/onboarding/welcome/welcome.tsx | 3 - src/app/routes/app-routes.tsx | 2 - src/app/store/settings/settings.selectors.ts | 18 ----- src/app/store/settings/settings.slice.ts | 6 -- .../containers/dialog/dialog.stories.tsx | 6 +- .../components/containers/dialog/dialog.tsx | 2 +- src/background/background.ts | 3 +- src/shared/route-urls.ts | 1 - src/shared/utils/analytics.ts | 9 --- tests/page-object-models/onboarding.page.ts | 10 +-- tests/selectors/onboarding.selectors.ts | 2 - tests/specs/settings/settings.spec.ts | 2 +- .../store-migrations/store-migrations.spec.ts | 2 +- 17 files changed, 13 insertions(+), 185 deletions(-) delete mode 100644 src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx delete mode 100644 src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx diff --git a/src/app/common/hooks/analytics/use-analytics.ts b/src/app/common/hooks/analytics/use-analytics.ts index 88b2213fb29..558d79eb5ce 100644 --- a/src/app/common/hooks/analytics/use-analytics.ts +++ b/src/app/common/hooks/analytics/use-analytics.ts @@ -14,7 +14,6 @@ import { analytics, initAnalytics } from '@shared/utils/analytics'; import { flow, origin } from '@app/common/initial-search-params'; import { useWalletType } from '@app/common/use-wallet-type'; import { useCurrentNetworkState } from '@app/store/networks/networks.hooks'; -import { useHasUserExplicitlyDeclinedAnalytics } from '@app/store/settings/settings.selectors'; const IGNORED_PATH_REGEXPS = [/^\/$/]; @@ -27,12 +26,10 @@ function isHiroApiUrl(url: string) { } export function useInitalizeAnalytics() { - const hasUserDeclinedAnalytics = useHasUserExplicitlyDeclinedAnalytics(); - useEffect(() => { - if (hasUserDeclinedAnalytics || !SEGMENT_WRITE_KEY || IS_TEST_ENV) return; + if (!SEGMENT_WRITE_KEY || IS_TEST_ENV) return; initAnalytics(); - }, [hasUserDeclinedAnalytics]); + }, []); } export function useAnalytics() { diff --git a/src/app/features/container/utils/route-helpers.ts b/src/app/features/container/utils/route-helpers.ts index 868bea018dd..7e7f66f31fa 100644 --- a/src/app/features/container/utils/route-helpers.ts +++ b/src/app/features/container/utils/route-helpers.ts @@ -12,7 +12,7 @@ function isHomePage(pathname: RouteUrls) { } export function isLandingPage(pathname: RouteUrls) { - return pathname === RouteUrls.RequestDiagnostics || pathname.match(RouteUrls.Onboarding); // need to match get-started/ledger + return pathname.match(RouteUrls.Onboarding); // need to match get-started/ledger } function isOnboardingPage(pathname: RouteUrls) { diff --git a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx b/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx deleted file mode 100644 index ce7e6ddf6a4..00000000000 --- a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics-layout.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors'; -import { Box, Flex, Stack, styled } from 'leather-styles/jsx'; - -import { Button } from '@app/ui/components/button/button'; -import { Dialog } from '@app/ui/components/containers/dialog/dialog'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { Flag } from '@app/ui/components/flag/flag'; -import { CheckmarkIcon } from '@app/ui/icons/'; -import { LogomarkIcon } from '@app/ui/icons/logomark-icon'; - -interface ReasonToAllowDiagnosticsProps { - text: string; -} -function ReasonToAllowDiagnostics({ text }: ReasonToAllowDiagnosticsProps) { - return ( - }> - {text} - - ); -} - -interface AllowDiagnosticsLayoutProps { - onUserAllowDiagnostics(): void; - onUserDenyDiagnostics(): void; -} -export function AllowDiagnosticsLayout({ - onUserAllowDiagnostics, - onUserDenyDiagnostics, -}: AllowDiagnosticsLayoutProps) { - // this dialog cannot close without a footer action has no header - return ( - null} - footer={ -
- - - - -
- } - > - - - - - - - Help us improve - - Leather would like to gather deidentified service usage data to help improve the - experience of the wallet. - - - - - - - - -
- ); -} diff --git a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx b/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx deleted file mode 100644 index 4d1dd6e5263..00000000000 --- a/src/app/pages/onboarding/allow-diagnostics/allow-diagnostics.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { useCallback, useEffect } from 'react'; -import { useDispatch } from 'react-redux'; -import { useLocation, useNavigate } from 'react-router-dom'; - -import { RouteUrls } from '@shared/route-urls'; - -import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; -import { settingsActions } from '@app/store/settings/settings.actions'; - -import { AllowDiagnosticsLayout } from './allow-diagnostics-layout'; - -export function AllowDiagnosticsModal() { - const navigate = useNavigate(); - const dispatch = useDispatch(); - const analytics = useAnalytics(); - const { pathname } = useLocation(); - - useEffect(() => void analytics.page('view', `${pathname}`), [analytics, pathname]); - - const setDiagnosticsPermissionsAndGoToOnboarding = useCallback( - (areDiagnosticsAllowed: boolean) => { - dispatch(settingsActions.setHasAllowedAnalytics(areDiagnosticsAllowed)); - - navigate(RouteUrls.Onboarding); - }, - [navigate, dispatch] - ); - - return ( - { - void analytics.track('respond_diagnostics_consent', { - areDiagnosticsAllowed: false, - }); - setDiagnosticsPermissionsAndGoToOnboarding(false); - }} - onUserAllowDiagnostics={() => { - void analytics.track('respond_diagnostics_consent', { - areDiagnosticsAllowed: true, - }); - setDiagnosticsPermissionsAndGoToOnboarding(true); - }} - /> - ); -} diff --git a/src/app/pages/onboarding/welcome/welcome.tsx b/src/app/pages/onboarding/welcome/welcome.tsx index ae3a1d54166..b9431d15d6d 100644 --- a/src/app/pages/onboarding/welcome/welcome.tsx +++ b/src/app/pages/onboarding/welcome/welcome.tsx @@ -9,11 +9,9 @@ import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state' import { useKeyActions } from '@app/common/hooks/use-key-actions'; import { doesBrowserSupportWebUsbApi, isPopupMode, whenPageMode } from '@app/common/utils'; import { openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab'; -import { useHasUserRespondedToAnalyticsConsent } from '@app/store/settings/settings.selectors'; import { WelcomeLayout } from '@app/ui/pages/welcome.layout'; export function WelcomePage() { - const hasResponded = useHasUserRespondedToAnalyticsConsent(); const navigate = useNavigate(); const { decodedAuthRequest } = useOnboardingState(); const analytics = useAnalytics(); @@ -39,7 +37,6 @@ export function WelcomePage() { }, [keyActions, analytics, decodedAuthRequest, navigate]); useEffect(() => { - if (!hasResponded) navigate(RouteUrls.RequestDiagnostics); return () => setIsGeneratingWallet(false); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index efb89d692c2..564cba2a437 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -33,7 +33,6 @@ import { ChooseAccount } from '@app/pages/choose-account/choose-account'; import { ChooseCryptoAssetToFund } from '@app/pages/fund/choose-asset-to-fund/choose-asset-to-fund'; import { FundPage } from '@app/pages/fund/fund'; import { Home } from '@app/pages/home/home'; -import { AllowDiagnosticsModal } from '@app/pages/onboarding/allow-diagnostics/allow-diagnostics'; import { BackUpSecretKeyPage } from '@app/pages/onboarding/back-up-secret-key/back-up-secret-key'; import { SignIn } from '@app/pages/onboarding/sign-in/sign-in'; import { WelcomePage } from '@app/pages/onboarding/welcome/welcome'; @@ -129,7 +128,6 @@ function useAppRoutes() { } > - } /> } /> } /> diff --git a/src/app/store/settings/settings.selectors.ts b/src/app/store/settings/settings.selectors.ts index 4103be10dda..dbb64f30d64 100644 --- a/src/app/store/settings/settings.selectors.ts +++ b/src/app/store/settings/settings.selectors.ts @@ -12,24 +12,6 @@ export function useUserSelectedTheme() { return useSelector(selectUserSelectedTheme); } -const selectHasUserExplicitlyDeclinedAnalytics = createSelector( - selectSettings, - state => state.hasAllowedAnalytics === false -); - -export function useHasUserExplicitlyDeclinedAnalytics() { - return useSelector(selectHasUserExplicitlyDeclinedAnalytics); -} - -const selectHasUserRespondedToAnalyticsConsent = createSelector( - selectSettings, - state => state.hasAllowedAnalytics !== null -); - -export function useHasUserRespondedToAnalyticsConsent() { - return useSelector(selectHasUserRespondedToAnalyticsConsent); -} - const selectDismissedMessageIds = createSelector( selectSettings, state => state.dismissedMessages ?? [] diff --git a/src/app/store/settings/settings.slice.ts b/src/app/store/settings/settings.slice.ts index 36105a6b890..edce40b7e0c 100644 --- a/src/app/store/settings/settings.slice.ts +++ b/src/app/store/settings/settings.slice.ts @@ -2,16 +2,13 @@ import { PayloadAction, createSlice } from '@reduxjs/toolkit'; import { UserSelectedTheme } from '@app/common/theme-provider'; -type HasAcceptedAnalytics = null | boolean; interface InitialState { userSelectedTheme: UserSelectedTheme; - hasAllowedAnalytics: HasAcceptedAnalytics; dismissedMessages: string[]; } const initialState: InitialState = { userSelectedTheme: 'system', - hasAllowedAnalytics: null, dismissedMessages: [], }; @@ -22,9 +19,6 @@ export const settingsSlice = createSlice({ setUserSelectedTheme(state, action: PayloadAction) { state.userSelectedTheme = action.payload; }, - setHasAllowedAnalytics(state, action: PayloadAction) { - state.hasAllowedAnalytics = action.payload; - }, messageDismissed(state, action: PayloadAction) { if (!Array.isArray(state.dismissedMessages)) state.dismissedMessages = []; state.dismissedMessages = [...state.dismissedMessages, action.payload]; diff --git a/src/app/ui/components/containers/dialog/dialog.stories.tsx b/src/app/ui/components/containers/dialog/dialog.stories.tsx index dbbb86e3770..fc746780938 100644 --- a/src/app/ui/components/containers/dialog/dialog.stories.tsx +++ b/src/app/ui/components/containers/dialog/dialog.stories.tsx @@ -18,7 +18,11 @@ export function Dialog() { return ( <> - setIsShowing(false)}> + Some Header} + isShowing={isShowing} + onClose={() => setIsShowing(false)} + >

Some Dialog

diff --git a/src/app/ui/components/containers/dialog/dialog.tsx b/src/app/ui/components/containers/dialog/dialog.tsx index be96b35cc7f..84ec243ac56 100644 --- a/src/app/ui/components/containers/dialog/dialog.tsx +++ b/src/app/ui/components/containers/dialog/dialog.tsx @@ -14,7 +14,7 @@ export interface DialogProps { interface RadixDialogProps extends DialogProps { children: ReactNode; footer?: ReactNode; - header?: ReactElement>; + header: ReactElement>; onGoBack?(): void; wrapChildren?: boolean; } diff --git a/src/background/background.ts b/src/background/background.ts index d2a78af40bd..81e9d6ec221 100755 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -3,7 +3,6 @@ // https://developer.chrome.com/docs/extensions/mv3/architecture-overview/#background_script import { logger } from '@shared/logger'; import { CONTENT_SCRIPT_PORT, type LegacyMessageFromContentScript } from '@shared/message-types'; -import { RouteUrls } from '@shared/route-urls'; import { WalletRequests } from '@shared/rpc/rpc-methods'; import { warnUsersAboutDevToolsDangers } from '@shared/utils/dev-tools-warning-log'; @@ -21,7 +20,7 @@ warnUsersAboutDevToolsDangers(); chrome.runtime.onInstalled.addListener(async details => { if (details.reason === 'install' && process.env.WALLET_ENVIRONMENT !== 'testing') { await chrome.tabs.create({ - url: chrome.runtime.getURL(`index.html#${RouteUrls.RequestDiagnostics}`), + url: chrome.runtime.getURL(`index.html`), }); } }); diff --git a/src/shared/route-urls.ts b/src/shared/route-urls.ts index d9bffa73381..92141e0e63f 100644 --- a/src/shared/route-urls.ts +++ b/src/shared/route-urls.ts @@ -1,6 +1,5 @@ export enum RouteUrls { // Onboarding routes - RequestDiagnostics = '/get-started/request-diagnostics', Onboarding = '/get-started', BackUpSecretKey = '/back-up-secret-key', SetPassword = '/set-password', diff --git a/src/shared/utils/analytics.ts b/src/shared/utils/analytics.ts index 8f074d38806..ecaec8413fa 100644 --- a/src/shared/utils/analytics.ts +++ b/src/shared/utils/analytics.ts @@ -12,7 +12,6 @@ import { base58 } from '@scure/base'; import { AnalyticsBrowser } from '@segment/analytics-next'; import * as Sentry from '@sentry/react'; import { token } from 'leather-styles/tokens'; -import { getStoredState } from 'redux-persist'; import { IS_TEST_ENV, @@ -20,9 +19,6 @@ import { SENTRY_DSN, WALLET_ENVIRONMENT, } from '@shared/environment'; -import { persistConfig } from '@shared/storage/redux-pesist'; - -import type { RootState } from '@app/store'; export const analytics = new AnalyticsBrowser(); @@ -110,11 +106,6 @@ export function initSentry() { environment: WALLET_ENVIRONMENT, autoSessionTracking: false, async beforeSend(event) { - const state = (await getStoredState(persistConfig)) as RootState; - const hasAllowedAnalytics = state.settings.hasAllowedAnalytics; - - if (!hasAllowedAnalytics) return null; - delete event.user?.ip_address; delete event.extra?.ip_address; diff --git a/tests/page-object-models/onboarding.page.ts b/tests/page-object-models/onboarding.page.ts index e1d17fd4010..ee4b7012748 100644 --- a/tests/page-object-models/onboarding.page.ts +++ b/tests/page-object-models/onboarding.page.ts @@ -40,7 +40,6 @@ export const testSoftwareAccountDefaultWalletState = { }, settings: { userSelectedTheme: 'system', - hasAllowedAnalytics: false, dismissedMessages: [], }, _persist: { version: 2, rehydrated: true }, @@ -225,18 +224,13 @@ export function makeLedgerTestAccountWalletState(keysToInclude: SupportedBlockch 'Explore apps': 0, }, }, - settings: { dismissedMessages: [], hasAllowedAnalytics: false, userSelectedTheme: 'system' }, + settings: { dismissedMessages: [], userSelectedTheme: 'system' }, }; } export class OnboardingPage { constructor(readonly page: Page) {} - async denyAnalytics() { - await this.page.getByTestId(OnboardingSelectors.DenyAnalyticsBtn).click(); - await this.page.waitForURL('**' + RouteUrls.Onboarding); - } - async setPassword() { await this.page.waitForURL('**' + RouteUrls.SetPassword); await this.page.getByTestId(OnboardingSelectors.NewPasswordInput).fill(TEST_PASSWORD); @@ -245,14 +239,12 @@ export class OnboardingPage { } async signUpNewUser() { - await this.denyAnalytics(); await this.page.getByTestId(OnboardingSelectors.SignUpBtn).click(); await this.page.waitForURL('**' + RouteUrls.BackUpSecretKey); await this.page.getByTestId(OnboardingSelectors.BackUpSecretKeyBtn).click(); await this.setPassword(); } async initiateSignIn() { - await this.denyAnalytics(); await this.page.getByTestId(OnboardingSelectors.SignInLink).click(); } diff --git a/tests/selectors/onboarding.selectors.ts b/tests/selectors/onboarding.selectors.ts index fa4e8cb66f7..c644c4b4b3b 100644 --- a/tests/selectors/onboarding.selectors.ts +++ b/tests/selectors/onboarding.selectors.ts @@ -1,7 +1,5 @@ export enum OnboardingSelectors { - AllowAnalyticsBtn = 'allow-analytics-btn', BackUpSecretKeyBtn = 'back-up-secret-key-btn', - DenyAnalyticsBtn = 'deny-analytics-btn', LogoRouteToHome = 'logo-route-to-home', NewPasswordInput = 'set-or-enter-password-input', NoAssetsFundAccountLink = 'no-assets-fund-account-link', diff --git a/tests/specs/settings/settings.spec.ts b/tests/specs/settings/settings.spec.ts index 1ed4296a0c0..5afe444075b 100644 --- a/tests/specs/settings/settings.spec.ts +++ b/tests/specs/settings/settings.spec.ts @@ -25,7 +25,7 @@ test.describe('Settings menu', () => { test('that menu item can perform sign out', async ({ homePage, onboardingPage }) => { await homePage.signOut(); - const button = onboardingPage.page.getByTestId(OnboardingSelectors.DenyAnalyticsBtn); + const button = onboardingPage.page.getByTestId(OnboardingSelectors.SignUpBtn); test.expect(button).toBeTruthy(); }); diff --git a/tests/specs/store-migrations/store-migrations.spec.ts b/tests/specs/store-migrations/store-migrations.spec.ts index a159bec5787..1295e1944b6 100644 --- a/tests/specs/store-migrations/store-migrations.spec.ts +++ b/tests/specs/store-migrations/store-migrations.spec.ts @@ -10,7 +10,7 @@ test.describe('Store migrations', () => { test.describe('Migration 0 --> 2', () => { const previousSerializedState = - '{"analytics":"{\\"hasStxDeposits\\":{\\"1\\":true,\\"2147483648\\":true}}","chains":"{\\"stx\\":{\\"default\\":{\\"highestAccountIndex\\":16,\\"currentAccountIndex\\":0}}}","keys":"{\\"ids\\":[\\"default\\"],\\"entities\\":{\\"default\\":{\\"type\\":\\"software\\",\\"id\\":\\"default\\",\\"salt\\":\\"c4cccf33166051f7704cd877a2f03f93\\",\\"encryptedSecretKey\\":\\"b7f516798e7160eca15c50b62e588698937f8ecf3930efc42baa690ddc0c7a51b74e3e4b129859274ed272652bc47651c6b6effbddf4d72a3eb9d2ea657b64a833c9bdccb562e45d94f0cc1366154072f12d35290566a99a6f952cd234ca9259\\"}}}","networks":"{\\"ids\\":[],\\"entities\\":{},\\"currentNetworkId\\":\\"mainnet\\"}","onboarding":"{\\"hideSteps\\":true,\\"stepsStatus\\":{\\"Back up secret key\\":1,\\"Add some funds\\":0,\\"Explore apps\\":0,\\"Buy an NFT\\":0}}","settings":"{\\"userSelectedTheme\\":\\"system\\",\\"hasAllowedAnalytics\\":false,\\"dismissedMessages\\":[]}","_persist":"{\\"version\\":1,\\"rehydrated\\":true}"}'; + '{"analytics":"{\\"hasStxDeposits\\":{\\"1\\":true,\\"2147483648\\":true}}","chains":"{\\"stx\\":{\\"default\\":{\\"highestAccountIndex\\":16,\\"currentAccountIndex\\":0}}}","keys":"{\\"ids\\":[\\"default\\"],\\"entities\\":{\\"default\\":{\\"type\\":\\"software\\",\\"id\\":\\"default\\",\\"salt\\":\\"c4cccf33166051f7704cd877a2f03f93\\",\\"encryptedSecretKey\\":\\"b7f516798e7160eca15c50b62e588698937f8ecf3930efc42baa690ddc0c7a51b74e3e4b129859274ed272652bc47651c6b6effbddf4d72a3eb9d2ea657b64a833c9bdccb562e45d94f0cc1366154072f12d35290566a99a6f952cd234ca9259\\"}}}","networks":"{\\"ids\\":[],\\"entities\\":{},\\"currentNetworkId\\":\\"mainnet\\"}","onboarding":"{\\"hideSteps\\":true,\\"stepsStatus\\":{\\"Back up secret key\\":1,\\"Add some funds\\":0,\\"Explore apps\\":0,\\"Buy an NFT\\":0}}","settings":"{\\"userSelectedTheme\\":\\"system\\",\\"dismissedMessages\\":[]}","_persist":"{\\"version\\":1,\\"rehydrated\\":true}"}'; test('that the app detects old store format', async ({ extensionId, globalPage }) => { const { page } = globalPage;