Skip to content

Commit

Permalink
FXVPN-190: Set proxy settings to domains, not subdomains (#83)
Browse files Browse the repository at this point in the history
This PR changes `Utils.getFormattedHostname` to `Utils.getDomainName`.
Instead of returning a formatted hostname, the function now takes in a
url and returns the domain name. The net net of this change is that we
now set proxy settings at the domain level instead of the subdomain
level.

- FXVPN-190, FXVPN-183
  • Loading branch information
lesleyjanenorton authored Nov 27, 2024
1 parent 6575329 commit 036a47d
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/background/requestHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export class RequestHandler extends Component {

for (let urlString of [documentUrl, url]) {
if (urlString) {
const parsedHostname = Utils.getFormattedHostname(urlString);
const parsedHostname = Utils.getTopLevelDomain(urlString);
const proxyInfo = self.proxyMap.get(parsedHostname);
if (proxyInfo) {
return proxyInfo;
Expand Down
2 changes: 1 addition & 1 deletion src/background/tabHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class TabHandler extends Component {
return browser.pageAction.hide(currentTab.id);
}

this.currentHostname = await Utils.getFormattedHostname(currentTab.url);
this.currentHostname = await Utils.getTopLevelDomain(currentTab.url);
this.currentContext = this.siteContexts.get(this.currentHostname);

if (this.currentContext && this.currentContext.excluded) {
Expand Down
2 changes: 1 addition & 1 deletion src/background/tabReloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class TabReloader extends Component {
if (hostname === "") {
return false;
}
const tabURL = Utils.getFormattedHostname(tab.url);
const tabURL = Utils.getTopLevelDomain(tab.url);
return tabURL === hostname;
};
}
Expand Down
47 changes: 32 additions & 15 deletions src/shared/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,42 +29,59 @@ export const Utils = {

/**
* Formats and retrieves the hostname from a given URL.
* @param {string} url - The URL to format.
* @returns {string} - The formatted hostname. Is empty if not valid for extension context.
* @param {string} url - URL to format.
* @returns {string} - URL sans prefixes.
*/
getFormattedHostname(url) {
stripPrefixesFromUrl(url) {
// Handle sites being viewed in reader mode
// TODO... other prefixes(?)
const readerPrefix = "about:reader?url=";
if (url.startsWith(readerPrefix)) {
const encodedUrl = url.slice(readerPrefix.length);
url = decodeURIComponent(encodedUrl);
return decodeURIComponent(encodedUrl);
}
const getHostname = (aUrl) => {
try {
const urlObj = new URL(aUrl);
return urlObj.hostname;
} catch (e) {
return null;
return url;
},

/**
* Formats and retrieves the domain from a given URL.
* @param {string} url - URL from which to retrieve the domain name.
* @returns {string} - The domain name, or the url if a valid (within the context of the extension) domain name is not derived.
*/
getTopLevelDomain(url) {
url = this.stripPrefixesFromUrl(url);

try {
// Create a URL object from the input URL
let parsedUrl = new URL(url);

// Split the hostname to remove any subdomains or prefixes
let domainParts = parsedUrl.hostname.split(".");

// If the domain has more than two parts, remove subdomains (e.g., "reader.example.com" becomes "example.com")
if (domainParts.length > 2) {
return domainParts.slice(-2).join(".");
}
};
let hostname = getHostname(url);

// Use the entire URL if hostname is not valid (like about:debugging)
if (!hostname || hostname === "") {
// If it's already just a domain name, return it
return parsedUrl.hostname ? parsedUrl.hostname : url;
} catch (error) {
// Handle invalid URLs
return url;
}
return hostname;
},

isValidForProxySetting: (url) => {
url = Utils.stripPrefixesFromUrl(url);

try {
const urlObj = new URL(url);
return urlObj.protocol === "https:" || urlObj.protocol === "http:";
} catch (error) {
return false;
}
},

nameFor: (countryCode = "", cityCode = "", serverList = []) => {
return Utils.getCity(countryCode, cityCode, serverList)?.name;
},
Expand Down
8 changes: 6 additions & 2 deletions src/ui/browserAction/popupPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export class BrowserActionPopup extends LitElement {
this.hasSiteContext = false;
return;
}
const hostname = Utils.getFormattedHostname(tab.url);
const hostname = Utils.getTopLevelDomain(tab.url);
this.pageURL = hostname;
if (this._siteContexts.has(this.pageURL)) {
this._siteContext = proxyHandler.siteContexts.value.get(this.pageURL);
Expand Down Expand Up @@ -219,7 +219,7 @@ export class BrowserActionPopup extends LitElement {
return html`
<p class="text-secondary">
${parts.at(0)}
<span class="bold">${origin}</span>
<span class="origin bold">${origin}</span>
${parts.at(-1)}
</p>
`;
Expand Down Expand Up @@ -450,6 +450,10 @@ export class BrowserActionPopup extends LitElement {
padding-block: 8px 16px !important;
}
.origin.bold {
word-break: break-word;
max-width: 260px;
}
h3 {
margin-block: calc(var(--padding-default) / 2) 0px;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui/pageAction/pageAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class PageActionPopup extends LitElement {
if (!Utils.isValidForProxySetting(tab.url)) {
return;
}
const hostname = Utils.getFormattedHostname(tab.url);
const hostname = Utils.getTopLevelDomain(tab.url);
this.pageURL = hostname;
if (proxyHandler.siteContexts.value.has(this.pageURL)) {
this._siteContext = proxyHandler.siteContexts.value.get(this.pageURL);
Expand Down
8 changes: 4 additions & 4 deletions tests/jest/background/utils.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ describe("Utils", () => {
mockSet.mockClear();
});

describe("getFormattedHostName", () => {
describe("getTopLevelDomain", () => {
test("Returns a formatted hostname when given a url", () => {
const result = Utils.getFormattedHostname("www.mozilla.org");
const result = Utils.getTopLevelDomain("www.mozilla.org");
expect(result).toBe("www.mozilla.org");
});
test("Removes reader prefixes from the url", () => {
const result = Utils.getFormattedHostname(
const result = Utils.getTopLevelDomain(
"about:reader?url=https://firefox.com"
);
expect(result).toBe("firefox.com");
});
test("Returns the string if the string is not a valid url", () => {
const result = Utils.getFormattedHostname("about:debugging");
const result = Utils.getTopLevelDomain("about:debugging");
expect(result).toBe("about:debugging");
});
});
Expand Down

0 comments on commit 036a47d

Please sign in to comment.