From fe6d3b41da6edbf3d421be085e7d496f696e202d Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Wed, 2 Oct 2024 21:20:57 +0530 Subject: [PATCH 1/3] feat(ConnectWalletForm): ask consent for automatic key addition --- src/_locales/en/messages.json | 12 +++++ src/background/services/keyAutoAdd.ts | 9 ++++ src/background/services/openPayments.ts | 21 +++++++- src/popup/components/ConnectWalletForm.tsx | 62 +++++++++++++++++++--- src/popup/pages/Settings.tsx | 3 ++ src/shared/messages.ts | 3 +- tests/e2e/connectAutoKeyTestWallet.spec.ts | 10 +++- 7 files changed, 109 insertions(+), 11 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 979f21a6..5fd0e3b5 100755 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -172,9 +172,21 @@ "connectWallet_error_grantRejected": { "message": "Connect wallet cancelled. You rejected the request." }, + "connectWalletKeyService_text_consent": { + "message": "By agreeing, you provide us consent to automatically access your wallet to securely add a key. Please note, this process does not involve accessing or handling your funds." + }, + "connectWalletKeyService_label_consentAccept": { + "message": "Accept" + }, + "connectWalletKeyService_label_consentDecline": { + "message": "Decline" + }, "connectWalletKeyService_error_notImplemented": { "message": "Automatic key addition is not implemented for given wallet provider yet." }, + "connectWalletKeyService_error_noConsent": { + "message": "You declined consent for automatic key addition." + }, "connectWalletKeyService_error_failed": { "message": "Automatic key addition failed at step “$STEP_ID$” with message “$MESSAGE$”.", "placeholders": { diff --git a/src/background/services/keyAutoAdd.ts b/src/background/services/keyAutoAdd.ts index 2a08df54..2ead6816 100644 --- a/src/background/services/keyAutoAdd.ts +++ b/src/background/services/keyAutoAdd.ts @@ -168,6 +168,15 @@ export class KeyAutoAddService { })); } } + + static supports(walletAddress: WalletAddress): boolean { + try { + void walletAddressToProvider(walletAddress); + return true; + } catch { + return false; + } + } } export function walletAddressToProvider(walletAddress: WalletAddress): { diff --git a/src/background/services/openPayments.ts b/src/background/services/openPayments.ts index 1f7ecec0..d7a23725 100644 --- a/src/background/services/openPayments.ts +++ b/src/background/services/openPayments.ts @@ -340,7 +340,13 @@ export class OpenPaymentsService { this.setConnectState(null); return; } - const { walletAddressUrl, amount, recurring, skipAutoKeyShare } = params; + const { + walletAddressUrl, + amount, + recurring, + autoKeyAdd, + autoKeyAddConsent, + } = params; const walletAddress = await getWalletInformation(walletAddressUrl); const exchangeRates = await getExchangeRates(); @@ -385,8 +391,19 @@ export class OpenPaymentsService { if ( isErrorWithKey(error) && error.key === 'connectWallet_error_invalidClient' && - !skipAutoKeyShare + autoKeyAdd ) { + if (!KeyAutoAddService.supports(walletAddress)) { + this.updateConnectStateError(error); + throw new ErrorWithKey( + 'connectWalletKeyService_error_notImplemented', + ); + } + if (!autoKeyAddConsent) { + this.updateConnectStateError(error); + throw new ErrorWithKey('connectWalletKeyService_error_noConsent'); + } + // add key to wallet and try again try { const tabId = await this.addPublicKeyToWallet(walletAddress); diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx index ece16642..7c75b8b4 100644 --- a/src/popup/components/ConnectWalletForm.tsx +++ b/src/popup/components/ConnectWalletForm.tsx @@ -28,6 +28,7 @@ interface Inputs { walletAddressUrl: string; amount: string; recurring: boolean; + autoKeyAddConsent: boolean; } interface ConnectWalletFormProps { @@ -62,9 +63,14 @@ export const ConnectWalletForm = ({ const [recurring, setRecurring] = React.useState( defaultValues.recurring || false, ); + const [autoKeyShareFailed, setAutoKeyShareFailed] = React.useState( isAutoKeyAddFailed(state), ); + const [showConsent, setShowConsent] = React.useState(false); + const autoKeyAddConsent = React.useRef( + defaultValues.autoKeyAddConsent || false, + ); const resetState = React.useCallback(async () => { await clearConnectState(); @@ -156,12 +162,8 @@ export const ConnectWalletForm = ({ [saveValue, currencySymbol, t], ); - const handleSubmit = async (ev: React.FormEvent) => { - ev.preventDefault(); - if (!walletAddressInfo) { - setErrors((_) => ({ ..._, walletAddressUrl: 'Not fetched yet?!' })); - return; - } + const handleSubmit = async (ev?: React.FormEvent) => { + ev?.preventDefault(); const errWalletAddressUrl = validateWalletAddressUrl(walletAddressUrl); const errAmount = validateAmount(amount, currencySymbol.symbol); @@ -186,7 +188,8 @@ export const ConnectWalletForm = ({ walletAddressUrl: toWalletAddressUrl(walletAddressUrl), amount, recurring, - skipAutoKeyShare, + autoKeyAdd: !skipAutoKeyShare, + autoKeyAddConsent: autoKeyAddConsent.current, }); if (res.success) { onConnect(); @@ -194,6 +197,10 @@ export const ConnectWalletForm = ({ if (isErrorWithKey(res.error)) { const error = res.error; if (error.key.startsWith('connectWalletKeyService_error_')) { + if (error.key === 'connectWalletKeyService_error_noConsent') { + setShowConsent(true); + return; + } setErrors((_) => ({ ..._, keyPair: t(error) })); } else { setErrors((_) => ({ ..._, connect: t(error) })); @@ -223,6 +230,26 @@ export const ConnectWalletForm = ({ } }, [defaultValues.walletAddressUrl, handleWalletAddressUrlChange]); + if (showConsent) { + return ( + { + autoKeyAddConsent.current = true; + // saveValue('autoKeyAddConsent', true); + setShowConsent(false); + handleSubmit(); + }} + onDecline={() => { + setErrors((_) => ({ + ..._, + keyPair: t('connectWalletKeyService_error_noConsent'), + })); + setShowConsent(false); + }} + /> + ); + } + return (
void; + onDecline: () => void; +}> = ({ onAccept, onDecline }) => { + const t = useTranslation(); + return ( + +

{t('connectWalletKeyService_text_consent')}

+ +
+ + +
+
+ ); +}; + const ManualKeyPairNeeded: React.FC<{ error: { message: string; details: string; whyText: string }; hideError?: boolean; diff --git a/src/popup/pages/Settings.tsx b/src/popup/pages/Settings.tsx index 5e10314a..bba0a6ec 100644 --- a/src/popup/pages/Settings.tsx +++ b/src/popup/pages/Settings.tsx @@ -22,6 +22,9 @@ export const Component = () => { amount: localStorage?.getItem('connect.amount') || undefined, walletAddressUrl: localStorage?.getItem('connect.walletAddressUrl') || undefined, + autoKeyAddConsent: + localStorage?.getItem('connect.autoKeyAddConsent') === 'true' || + false, }} saveValue={(key, val) => { localStorage?.setItem(`connect.${key}`, val.toString()); diff --git a/src/shared/messages.ts b/src/shared/messages.ts index fc0e8ccc..a3670e6d 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -93,7 +93,8 @@ export interface ConnectWalletPayload { walletAddressUrl: string; amount: string; recurring: boolean; - skipAutoKeyShare: boolean; + autoKeyAdd: boolean; + autoKeyAddConsent: boolean | null; } export interface AddFundsPayload { diff --git a/tests/e2e/connectAutoKeyTestWallet.spec.ts b/tests/e2e/connectAutoKeyTestWallet.spec.ts index 38e510d9..6b3d7538 100644 --- a/tests/e2e/connectAutoKeyTestWallet.spec.ts +++ b/tests/e2e/connectAutoKeyTestWallet.spec.ts @@ -42,9 +42,17 @@ test('Connect to test wallet with automatic key addition when not logged-in to w await page.close(); }); - page = await test.step('shows login page', async () => { + await test.step('asks for key-add consent', async () => { await connectButton.click(); + await popup.waitForSelector( + `[data-testid="connect-wallet-auto-key-consent"]`, + ); + expect(popup.getByTestId('connect-wallet-auto-key-consent')).toBeVisible(); + await popup.getByRole('button', { name: 'Accept' }).click(); + }); + + page = await test.step('shows login page', async () => { const openedPage = await context.waitForEvent('page', { predicate: (page) => page.url().startsWith(loginPageUrl), timeout: 3 * 1000, From 2dcf9ed053ef652821c91ed5439e4c98fed29e7d Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:38:00 +0530 Subject: [PATCH 2/3] ui fixes --- src/_locales/en/messages.json | 7 ++- src/popup/components/ConnectWalletForm.tsx | 72 +++++++++++----------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 5fd0e3b5..7dd14d10 100755 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -172,8 +172,11 @@ "connectWallet_error_grantRejected": { "message": "Connect wallet cancelled. You rejected the request." }, - "connectWalletKeyService_text_consent": { - "message": "By agreeing, you provide us consent to automatically access your wallet to securely add a key. Please note, this process does not involve accessing or handling your funds." + "connectWalletKeyService_text_consentP1": { + "message": "By agreeing, you provide us consent to automatically access your wallet to securely add a key." + }, + "connectWalletKeyService_text_consentP2": { + "message": "Please note, this process does not involve accessing or handling your funds." }, "connectWalletKeyService_label_consentAccept": { "message": "Accept" diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx index 7c75b8b4..efd5f92c 100644 --- a/src/popup/components/ConnectWalletForm.tsx +++ b/src/popup/components/ConnectWalletForm.tsx @@ -404,13 +404,6 @@ export const ConnectWalletForm = ({ > {t('connectWallet_action_connect')} - - {!errors.keyPair && !autoKeyShareFailed && ( -