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/7] 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 (
+ );
+};
+
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/7] 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 && (
-
- )}
);
@@ -422,18 +415,42 @@ const AutoKeyAddConsent: React.FC<{
}> = ({ onAccept, onDecline }) => {
const t = useTranslation();
return (
-
+
+
+
{t('connectWalletKeyService_text_consentP2')}
+
{t('connectWalletKeyService_text_consentP3')}
+
+
+
+
+
+
+
);
};
From abcf0b846ec8c2be42963644c08d4b809c2ada1c Mon Sep 17 00:00:00 2001
From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com>
Date: Fri, 4 Oct 2024 17:41:19 +0530
Subject: [PATCH 4/7] address feedback
---
src/background/services/keyAutoAdd.ts | 2 +-
src/popup/components/ConnectWalletForm.tsx | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/background/services/keyAutoAdd.ts b/src/background/services/keyAutoAdd.ts
index 2ead6816..662209f6 100644
--- a/src/background/services/keyAutoAdd.ts
+++ b/src/background/services/keyAutoAdd.ts
@@ -171,7 +171,7 @@ export class KeyAutoAddService {
static supports(walletAddress: WalletAddress): boolean {
try {
- void walletAddressToProvider(walletAddress);
+ walletAddressToProvider(walletAddress);
return true;
} catch {
return false;
diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx
index ff655dd9..ec0876ca 100644
--- a/src/popup/components/ConnectWalletForm.tsx
+++ b/src/popup/components/ConnectWalletForm.tsx
@@ -201,9 +201,9 @@ export const ConnectWalletForm = ({
setShowConsent(true);
return;
}
- setErrors((_) => ({ ..._, keyPair: t(error) }));
+ setErrors((prev) => ({ ...prev, keyPair: t(error) }));
} else {
- setErrors((_) => ({ ..._, connect: t(error) }));
+ setErrors((prev) => ({ ...prev, connect: t(error) }));
}
} else {
throw new Error(res.message);
@@ -240,8 +240,8 @@ export const ConnectWalletForm = ({
handleSubmit();
}}
onDecline={() => {
- setErrors((_) => ({
- ..._,
+ setErrors((prev) => ({
+ ...prev,
keyPair: t('connectWalletKeyService_error_noConsent'),
}));
setShowConsent(false);
From fb62a2d49b42de561854a2215e6d207075dd9172 Mon Sep 17 00:00:00 2001
From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com>
Date: Fri, 4 Oct 2024 17:46:41 +0530
Subject: [PATCH 5/7] nit
---
src/popup/components/ConnectWalletForm.tsx | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx
index 51364459..0f3a566f 100644
--- a/src/popup/components/ConnectWalletForm.tsx
+++ b/src/popup/components/ConnectWalletForm.tsx
@@ -245,12 +245,8 @@ export const ConnectWalletForm = ({
handleSubmit();
}}
onDecline={() => {
- setErrors((prev) => ({
- ...prev,
- keyPair: toErrorInfo(
- errorWithKey('connectWalletKeyService_error_noConsent'),
- ),
- }));
+ const error = errorWithKey('connectWalletKeyService_error_noConsent');
+ setErrors((prev) => ({ ...prev, keyPair: toErrorInfo(error) }));
setShowConsent(false);
}}
/>
From 08f0c1f70b16c83ca05561bd1274d90ece3be947 Mon Sep 17 00:00:00 2001
From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com>
Date: Fri, 4 Oct 2024 18:17:14 +0530
Subject: [PATCH 6/7] allow retry on consent decline
---
src/popup/components/ConnectWalletForm.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx
index 54fe040e..26694dba 100644
--- a/src/popup/components/ConnectWalletForm.tsx
+++ b/src/popup/components/ConnectWalletForm.tsx
@@ -523,6 +523,7 @@ function isAutoKeyAddFailed(state: PopupTransientState['connect']) {
function canRetryAutoKeyAdd(err?: ErrorInfo['info']) {
if (!err) return false;
return (
+ err.key === 'connectWalletKeyService_error_noConsent' ||
err.cause?.key === 'connectWalletKeyService_error_timeoutLogin' ||
err.cause?.key === 'connectWalletKeyService_error_accountNotFound'
);
From f46718a118c31a25b115132aa24e35853e6ae7d0 Mon Sep 17 00:00:00 2001
From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com>
Date: Fri, 4 Oct 2024 18:19:55 +0530
Subject: [PATCH 7/7] nit
---
src/popup/pages/Settings.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/popup/pages/Settings.tsx b/src/popup/pages/Settings.tsx
index bba0a6ec..1c129d58 100644
--- a/src/popup/pages/Settings.tsx
+++ b/src/popup/pages/Settings.tsx
@@ -23,8 +23,7 @@ export const Component = () => {
walletAddressUrl:
localStorage?.getItem('connect.walletAddressUrl') || undefined,
autoKeyAddConsent:
- localStorage?.getItem('connect.autoKeyAddConsent') === 'true' ||
- false,
+ localStorage?.getItem('connect.autoKeyAddConsent') === 'true',
}}
saveValue={(key, val) => {
localStorage?.setItem(`connect.${key}`, val.toString());