From c2c91002d2c9dbf884a50ee99a7567eb6fe576be Mon Sep 17 00:00:00 2001 From: Agampreet Singh <68941022+agam778@users.noreply.github.com> Date: Fri, 9 Aug 2024 18:24:35 +0530 Subject: [PATCH] Add setting for external link handling Introduced an option for users to open external links in their default browser rather than within the app. Enabled by default, can be configured in menu. #240 --- app/config/menu.js | 14 +++++ app/config/store.js | 1 + app/domains.json | 125 ++++++++++++++++++++++++++++++++++++++++++++ app/main.js | 71 +++++++++++++++++++------ 4 files changed, 194 insertions(+), 17 deletions(-) create mode 100644 app/domains.json diff --git a/app/config/menu.js b/app/config/menu.js index f7045d0..ab2113f 100644 --- a/app/config/menu.js +++ b/app/config/menu.js @@ -454,6 +454,20 @@ const commonPreferencesSubmenu = [ }, checked: getValue("blockadsandtrackers") === "true", }, + { + label: "Open External Links in Default Browser", + type: "checkbox", + click: () => { + setValue("externalLinks", getValue("externalLinks") === "true" ? "false" : "true"); + dialog.showMessageBoxSync({ + type: "info", + title: "External Links in Default Browser", + message: `External links will now open in ${getValue("externalLinks") === "true" ? "your default browser" : "MS-365-Electron"}`, + buttons: ["OK"], + }); + }, + checked: getValue("externalLinks") === "true", + }, { type: "separator" }, { label: "Windows User-Agent String", diff --git a/app/config/store.js b/app/config/store.js index 61dc025..d6be942 100644 --- a/app/config/store.js +++ b/app/config/store.js @@ -33,6 +33,7 @@ getValueOrDefault("windowWidth", 0.71); getValueOrDefault("windowHeight", 0.74); getValueOrDefault("customWindowSize", false); getValueOrDefault("aptabaseTracking", null); +getValueOrDefault("externalLinks", "true"); if (getValue("enterprise-or-normal") === "https://microsoft365.com/?auth=1") { setValue("enterprise-or-normal", "?auth=1"); diff --git a/app/domains.json b/app/domains.json new file mode 100644 index 0000000..64142d4 --- /dev/null +++ b/app/domains.json @@ -0,0 +1,125 @@ +{ + "domains": [ + "*.1drv.ms", + "*.microsoft365.com", + "*.office365.com", + "*.live.com", + "*.office.com", + "*.microsoftonline.com", + "*.onenote.com", + "*.onedrive.com", + "*.outlook.com", + "*.microsoft.com", + "*.cloud.microsoft", + "*.skype.com", + "*.clipchamp.com", + "*.sharepoint.com", + "*.yammer.com", + "*.outlook.cloud.microsoft", + "*.outlook.office.com", + "*.outlook.office365.com", + "*.protection.outlook.com", + "*.mail.protection.outlook.com", + "*.mx.microsoft", + "*.sharepointonline.com", + "*.storage.live.com", + "*.search.production.apac.trafficmanager.net", + "*.search.production.emea.trafficmanager.net", + "*.search.production.us.trafficmanager.net", + "*.wns.windows.com", + "*.admin.onedrive.com", + "*.officeclient.microsoft.com", + "*.g.live.com", + "*.oneclient.sfx.ms", + "*.spoprod-a.akamaihd.net", + "*.svc.ms", + "*.teams.microsoft.com", + "*.lync.com", + "*.keydelivery.mediaservices.windows.net", + "*.streaming.mediaservices.windows.net", + "*.mlccdn.blob.core.windows.net", + "*.aka.ms", + "*.users.storage.live.com", + "*.adl.windows.com", + "*.secure.skypeassets.com", + "*.mlccdnprod.azureedge.net", + "*.skype.com", + "*.compass-ssl.microsoft.com", + "*.officeapps.live.com", + "*.online.office.com", + "*.office.live.com", + "*.office.net", + "*.onenote.com", + "*.cdn.onenote.net", + "*.ajax.aspnetcdn.com", + "*.apis.live.net", + "*.www.onedrive.com", + "*.auth.microsoft.com", + "*.msftidentity.com", + "*.msidentity.com", + "*.account.activedirectory.windowsazure.com", + "*.accounts.accesscontrol.windows.net", + "*.adminwebservice.microsoftonline.com", + "*.api.passwordreset.microsoftonline.com", + "*.autologon.microsoftazuread-sso.com", + "*.becws.microsoftonline.com", + "*.ccs.login.microsoftonline.com", + "*.clientconfig.microsoftonline-p.net", + "*.companymanager.microsoftonline.com", + "*.device.login.microsoftonline.com", + "*.graph.microsoft.com", + "*.graph.windows.net", + "*.login-us.microsoftonline.com", + "*.login.microsoft.com", + "*.login.microsoftonline-p.com", + "*.login.microsoftonline.com", + "*.login.windows.net", + "*.logincert.microsoftonline.com", + "*.loginex.microsoftonline.com", + "*.nexus.microsoftonline-p.com", + "*.passwordreset.microsoftonline.com", + "*.provisioningapi.microsoftonline.com", + "*.hip.live.com", + "*.microsoftonline-p.com", + "*.msauth.net", + "*.msauthimages.net", + "*.msecnd.net", + "*.msftauth.net", + "*.msftauthimages.net", + "*.phonefactor.net", + "*.enterpriseregistration.windows.net", + "*.policykeyservice.dc.ad.msft.net", + "*.sharepointonline.com", + "*.staffhub.ms", + "*.staffhubweb.azureedge.net", + "*.sway.com", + "*.www.sway.com", + "*.eus-www.sway-cdn.com", + "*.eus-www.sway-extensions.com", + "*.wus-www.sway-cdn.com", + "*.wus-www.sway-extensions.com", + "*.microsoftusercontent.com", + "*.azure-apim.net", + "*.flow.microsoft.com", + "*.powerapps.com", + "*.powerautomate.com", + "*.activity.windows.com", + "*.cortana.ai", + "*.admin.microsoft.com", + "*.cdn.odc.officeapps.live.com", + "*.cdn.uci.officeapps.live.com", + "*.cloud.microsoft", + "*.static.microsoft", + "*.usercontent.microsoft", + "*.compliance.microsoft.com", + "*.protection.office.com", + "*.security.microsoft.com", + "*.defender.microsoft.com", + "*.blob.core.windows.net", + "*.firstpartyapps.oaspapps.com", + "*.prod.firstpartyapps.oaspapps.com.akadns.net", + "*.telemetryservice.firstpartyapps.oaspapps.com", + "*.wus-firstpartyapps.oaspapps.com" + ], + "source": "https://learn.microsoft.com/en-us/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide" +} diff --git a/app/main.js b/app/main.js index bb37a03..025455d 100644 --- a/app/main.js +++ b/app/main.js @@ -1,15 +1,15 @@ -import { app, Menu, BrowserWindow, dialog, nativeImage, screen } from "electron"; +import { app, Menu, BrowserWindow, dialog, nativeImage, shell } from "electron"; import { clearActivity, setActivity, loginToRPC } from "./config/rpc.js"; import { initialize, trackEvent } from "@aptabase/electron/main"; import { ElectronBlocker } from "@cliqz/adblocker-electron"; import { setValue, getValue } from "./config/store.js"; +import { dirname, join } from "path"; import { fileURLToPath } from "url"; -import { dirname } from "path"; -import { join } from "path"; import { getScreenWidth, getScreenHeight } from "./config/dimensions.js"; import Windows from "./useragents.json" with { type: "json" }; import checkInternetConnected from "check-internet-connected"; +import domains from "./domains.json" with { type: "json" }; import contextMenu from "electron-context-menu"; import updaterpkg from "electron-updater"; import ElectronDl from "electron-dl"; @@ -141,27 +141,64 @@ app.on("ready", () => { app.on("web-contents-created", (event, contents) => { contents.setWindowOpenHandler(({ url }) => { - if (getValue("websites-in-new-window") === "false") { - if (url.includes("page=Download")) { - return { action: "allow" }; + const urlObject = new URL(url); + const domain = urlObject.hostname; + const protocol = urlObject.protocol; + + if (getValue("externalLinks") === "true") { + if (protocol === "http:" || protocol === "https:") { + const isAllowedDomain = domains.domains.some((allowedDomain) => + new RegExp(`^${allowedDomain.replace("*.", ".*")}$`).test(domain) + ); + + if (isAllowedDomain) { + if (getValue("websites-in-new-window") === "false") { + if (url.includes("page=Download")) return { action: "allow" }; + BrowserWindow.getFocusedWindow().loadURL(url).catch(); + if (getValue("discordrpcstatus") === "true") { + setActivity(`On "${BrowserWindow.getFocusedWindow().webContents.getTitle()}"`); + } + return { action: "deny" }; + } else { + if (getValue("discordrpcstatus") === "true") { + setActivity(`On "${BrowserWindow.getFocusedWindow().webContents.getTitle()}"`); + } + return { + action: "allow", + overrideBrowserWindowOptions: { + width: Math.round(getScreenWidth() * (windowWidth - 0.07)), + height: Math.round(getScreenHeight() * (windowHeight - 0.07)), + }, + }; + } + } else { + shell.openExternal(url); + return { action: "deny" }; + } } else { + shell.openExternal(url); + return { action: "deny" }; + } + } else { + if (getValue("websites-in-new-window") === "false") { + if (url.includes("page=Download")) return { action: "allow" }; BrowserWindow.getFocusedWindow().loadURL(url).catch(); if (getValue("discordrpcstatus") === "true") { setActivity(`On "${BrowserWindow.getFocusedWindow().webContents.getTitle()}"`); } return { action: "deny" }; + } else { + if (getValue("discordrpcstatus") === "true") { + setActivity(`On "${BrowserWindow.getFocusedWindow().webContents.getTitle()}"`); + } + return { + action: "allow", + overrideBrowserWindowOptions: { + width: Math.round(getScreenWidth() * (windowWidth - 0.07)), + height: Math.round(getScreenHeight() * (windowHeight - 0.07)), + }, + }; } - } else { - if (getValue("discordrpcstatus") === "true") { - setActivity(`On "${BrowserWindow.getFocusedWindow().webContents.getTitle()}"`); - } - return { - action: "allow", - overrideBrowserWindowOptions: { - width: Math.round(getScreenWidth() * (windowWidth - 0.07)), - height: Math.round(getScreenHeight() * (windowHeight - 0.07)), - }, - }; } }); contents.on("did-finish-load", () => {