Skip to content

Commit 6a77e4b

Browse files
authored
fix: prevent Duplicate Block Explorer Entries and Ensure Proper Input Validation (#11995)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** When editing a network and attempting to add a new block explorer URL, the 'Add Block Explorer URL +' button allows users to add a duplicate entry even if no input is provided. This results in duplicate block explorer URLs being added to the list. The expected behavior is that the 'Add Block Explorer URL' button should remain disabled until valid input is provided, and existing URLs should not be re-added. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Related issues** Fixes: #11990 ## **Manual testing steps** 1. Go to network add form 2. go to add block explorer url 3. The 'Add Block Explorer URL' button should be disabled until a valid URL is inputted into the field. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/05f72bf8-8046-40a4-a941-51f39cfc9a09 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
1 parent def6f50 commit 6a77e4b

File tree

2 files changed

+494
-9
lines changed

2 files changed

+494
-9
lines changed

app/components/Views/Settings/NetworksSettings/NetworkSettings/index.js

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ export class NetworkSettings extends PureComponent {
447447
blockExplorerUrls: [],
448448
selectedRpcEndpointIndex: 0,
449449
blockExplorerUrl: undefined,
450+
blockExplorerUrlForm: undefined,
450451
nickname: undefined,
451452
chainId: undefined,
452453
ticker: undefined,
@@ -714,7 +715,11 @@ export class NetworkSettings extends PureComponent {
714715
// in an error message in the form.
715716
if (!formChainId.startsWith('0x')) {
716717
try {
717-
endpointChainId = new BigNumber(endpointChainId, 16).toString(10);
718+
const endpointChainIdNumber = new BigNumber(endpointChainId, 16);
719+
if (endpointChainIdNumber.isNaN()) {
720+
throw new Error('Invalid endpointChainId');
721+
}
722+
endpointChainId = endpointChainIdNumber.toString(10);
718723
} catch (err) {
719724
Logger.error(err, {
720725
endpointChainId,
@@ -1288,10 +1293,21 @@ export class NetworkSettings extends PureComponent {
12881293
};
12891294

12901295
onBlockExplorerItemAdd = async (url) => {
1296+
// If URL is empty or undefined, return early
12911297
if (!url) {
12921298
return;
12931299
}
12941300

1301+
// Check if the URL already exists in blockExplorerUrls
1302+
const { blockExplorerUrls } = this.state;
1303+
const urlExists = blockExplorerUrls.includes(url);
1304+
1305+
if (urlExists) {
1306+
// If the URL already exists, return early
1307+
return;
1308+
}
1309+
1310+
// If the URL doesn't exist, proceed with adding it
12951311
await this.setState((prevState) => ({
12961312
blockExplorerUrls: [...prevState.blockExplorerUrls, url],
12971313
}));
@@ -1351,6 +1367,7 @@ export class NetworkSettings extends PureComponent {
13511367
onBlockExplorerUrlChange = async (url) => {
13521368
const { addMode } = this.state;
13531369
await this.setState({
1370+
blockExplorerUrlForm: url,
13541371
blockExplorerUrl: url,
13551372
});
13561373

@@ -1486,7 +1503,10 @@ export class NetworkSettings extends PureComponent {
14861503
};
14871504

14881505
closeAddBlockExplorerRpcForm = () => {
1489-
this.setState({ showAddBlockExplorerForm: { isVisible: false } });
1506+
this.setState({
1507+
showAddBlockExplorerForm: { isVisible: false },
1508+
blockExplorerUrlForm: undefined,
1509+
});
14901510
};
14911511

14921512
closeRpcModal = () => {
@@ -1603,6 +1623,7 @@ export class NetworkSettings extends PureComponent {
16031623
rpcUrlForm,
16041624
rpcNameForm,
16051625
rpcName,
1626+
blockExplorerUrlForm,
16061627
} = this.state;
16071628
const { route, networkConfigurations } = this.props;
16081629
const isCustomMainnet = route.params?.isCustomMainnet;
@@ -2204,6 +2225,7 @@ export class NetworkSettings extends PureComponent {
22042225
ref={this.inputBlockExplorerURL}
22052226
style={inputStyle}
22062227
autoCapitalize={'none'}
2228+
value={blockExplorerUrlForm}
22072229
autoCorrect={false}
22082230
onChangeText={this.onBlockExplorerUrlChange}
22092231
placeholder={strings(
@@ -2214,23 +2236,28 @@ export class NetworkSettings extends PureComponent {
22142236
onSubmitEditing={this.toggleNetworkDetailsModal}
22152237
keyboardAppearance={themeAppearance}
22162238
/>
2217-
{blockExplorerUrl && !isUrl(blockExplorerUrl) && (
2218-
<View>
2239+
{blockExplorerUrl &&
2240+
(!isUrl(blockExplorerUrl) ||
2241+
blockExplorerUrls.includes(blockExplorerUrlForm)) && (
22192242
<Text style={styles.warningText}>
22202243
{strings('app_settings.invalid_block_explorer_url')}
22212244
</Text>
2222-
</View>
2223-
)}
2245+
)}
2246+
22242247
<View style={styles.addRpcNameButton}>
22252248
<ButtonPrimary
22262249
label={strings('app_settings.add_block_explorer_url')}
22272250
size={ButtonSize.Lg}
22282251
onPress={() => {
2229-
this.onBlockExplorerItemAdd(blockExplorerUrl);
2252+
this.onBlockExplorerItemAdd(blockExplorerUrlForm);
22302253
}}
22312254
width={ButtonWidthTypes.Full}
22322255
labelTextVariant={TextVariant.DisplayMD}
2233-
isDisabled={!blockExplorerUrl || !isUrl(blockExplorerUrl)}
2256+
isDisabled={
2257+
!blockExplorerUrl ||
2258+
!blockExplorerUrlForm ||
2259+
!isUrl(blockExplorerUrl)
2260+
}
22342261
/>
22352262
</View>
22362263
</SafeAreaView>

0 commit comments

Comments
 (0)