From ef86b18850f6265144b07b375ace88c2e788e197 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:15:26 +0530 Subject: [PATCH] feat(ConnectWalletForm): ask consent for automatic key addition don't save consent; ask each time nit: define component like rest of components move copy into _locales style improvements --- src/_locales/en/messages.json | 12 +++++ src/background/services/keyAutoAdd.ts | 9 ++++ src/background/services/openPayments.ts | 16 +++++- src/popup/components/ConnectWalletForm.tsx | 58 ++++++++++++++++++++-- src/popup/pages/Settings.tsx | 3 ++ src/shared/messages.ts | 3 +- 6 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 979f21a6..8011b5cc 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_conceptAccept": { + "message": "Accept" + }, + "connectWalletKeyService_label_conceptDecline": { + "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 afc46391..a2b383e8 100644 --- a/src/background/services/keyAutoAdd.ts +++ b/src/background/services/keyAutoAdd.ts @@ -150,6 +150,15 @@ export class KeyAutoAddService { const state = status ? { status } : null; this.storage.setPopupTransientState('connect', () => state); } + + 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 84220c41..c920992a 100644 --- a/src/background/services/openPayments.ts +++ b/src/background/services/openPayments.ts @@ -336,7 +336,8 @@ export class OpenPaymentsService { walletAddressUrl, amount, recurring, - skipAutoKeyShare, + autoKeyAdd, + autoKeyAddConsent, }: ConnectWalletPayload) { const walletAddress = await getWalletInformation(walletAddressUrl); const exchangeRates = await getExchangeRates(); @@ -380,8 +381,19 @@ export class OpenPaymentsService { } catch (error) { if ( error.message === this.t('connectWallet_error_invalidClient') && - !skipAutoKeyShare + autoKeyAdd ) { + if (!KeyAutoAddService.supports(walletAddress)) { + this.setConnectState('error'); + throw new ErrorWithKey( + 'connectWalletKeyService_error_notImplemented', + ); + } + if (!autoKeyAddConsent) { + this.setConnectState('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 65f82858..0d40ade8 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 { @@ -60,7 +61,12 @@ export const ConnectWalletForm = ({ const [recurring, setRecurring] = React.useState( defaultValues.recurring || false, ); + const [autoKeyShareFailed, setAutoKeyShareFailed] = React.useState(false); + const [showConsent, setShowConsent] = React.useState(false); + const autoKeyAddConsent = React.useRef( + defaultValues.autoKeyAddConsent || false, + ); const [walletAddressInfo, setWalletAddressInfo] = React.useState(null); @@ -136,8 +142,8 @@ export const ConnectWalletForm = ({ [saveValue, currencySymbol, t], ); - const handleSubmit = async (ev: React.FormEvent) => { - ev.preventDefault(); + const handleSubmit = async (ev?: React.FormEvent) => { + ev?.preventDefault(); if (!walletAddressInfo) { setErrors((_) => ({ ..._, walletAddressUrl: 'Not fetched yet?!' })); return; @@ -166,7 +172,8 @@ export const ConnectWalletForm = ({ walletAddressUrl: toWalletAddressUrl(walletAddressUrl), amount, recurring, - skipAutoKeyShare, + autoKeyAdd: !skipAutoKeyShare, + autoKeyAddConsent: autoKeyAddConsent.current, }); if (res.success) { onConnect(); @@ -174,6 +181,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) })); @@ -203,6 +214,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 34cff522..f33f1864 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 89176c0c..858aca3a 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 {