Repository: manusa/electronim
Pull request #323 (2023-09-02 07:32:08)

🐛 shell.openExternal only invoked for http(s) / ftp(s) protocols

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=manusa_electronim&pullRequest=323)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=manusa_electronim&pullRequest=323&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=manusa_electronim&pullRequest=323&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=manusa_electronim&pullRequest=323&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=manusa_electronim&pullRequest=323&resolved=false&types=CODE_SMELL)

[![100.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/100-16px.png '100.0%')](https://sonarcloud.io/component_measures?id=manusa_electronim&pullRequest=323&metric=new_coverage&view=list) [100.0% Coverage](https://sonarcloud.io/component_measures?id=manusa_electronim&pullRequest=323&metric=new_coverage&view=list)  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=manusa_electronim&pullRequest=323&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=manusa_electronim&pullRequest=323&metric=new_duplicated_lines_density&view=list)

![warning](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/message_warning-16px.png 'warning') The version of Java (11.0.3) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17.
Read more [here](https://docs.sonarcloud.io/appendices/scanner-environment/)




Patch:
diff --git a/src/tab-manager/redirect.js b/src/tab-manager/redirect.js
index 60ab02f..5a2389b 100644
--- a/src/tab-manager/redirect.js
+++ b/src/tab-manager/redirect.js
@@ -58,11 +58,18 @@ const shouldOpenInExternalBrowser = (browserView, url) => {
   return ret;
 };
 
+const openExternal = urlString => {
+  if (!['http:', 'https:', 'ftp:', 'ftps:'].includes(new URL(urlString).protocol)) {
+    return;
+  }
+  shell.openExternal(urlString).then(() => {});
+};
+
 const handleRedirect = browserView => (e, urlString) => {
   const url = new URL(urlString);
   if (shouldOpenInExternalBrowser(browserView, url)) {
     e.preventDefault();
-    shell.openExternal(urlString);
+    openExternal(urlString);
   }
 };
 
@@ -70,7 +77,7 @@ const windowOpenHandler = browserView => ({url}) => {
   if (!shouldOpenInExternalBrowser(browserView, new URL(url))) {
     return {action: 'allow'};
   }
-  shell.openExternal(url);
+  openExternal(url);
   return {action: 'deny'};
 };
 


Test patch:
diff --git a/src/__tests__/electron.js b/src/__tests__/electron.js
index d4a2c91..9170aa0 100644
--- a/src/__tests__/electron.js
+++ b/src/__tests__/electron.js
@@ -133,7 +133,7 @@ const mockElectronInstance = ({...overriddenProps} = {}) => {
       defaultSession: sessionInstance
     },
     shell: {
-      openExternal: jest.fn()
+      openExternal: jest.fn(async () => {})
     },
     ...overriddenProps
   };
diff --git a/src/tab-manager/__tests__/redirect.test.js b/src/tab-manager/__tests__/redirect.test.js
index fa71175..3298a83 100644
--- a/src/tab-manager/__tests__/redirect.test.js
+++ b/src/tab-manager/__tests__/redirect.test.js
@@ -248,6 +248,17 @@ describe('Tab Manager Redirect module test suite', () => {
         expect(require('electron').shell.openExternal).toHaveBeenCalledWith('https://example.com/site-page');
       });
     });
+    describe('different origin, not handled, and invalid protocol', () => {
+      beforeEach(() => {
+        redirect.handleRedirect(mockBrowserView)(event, 'smb://example.com/share');
+      });
+      test('should prevent default', () => {
+        expect(event.preventDefault).toHaveBeenCalled();
+      });
+      test('should not open window in external browser', () => {
+        expect(require('electron').shell.openExternal).not.toHaveBeenCalledWith('smb://example.com/share');
+      });
+    });
   });
   describe('windowOpenHandler', () => {
     test('same origin, opens window in Electron popup', () => {