1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-18219] Normalize blocked domain checks to a common util (#13416)

* normalize blocked domain checks to common util

* do not use currentTabIsOnBlocklist$ in showCurrentTabIsBlockedBanner$ resolution

* update additional vault popup autofill service cases to use isUrlInList

* cleanup and use Utils get hostname instead of tldts directly
This commit is contained in:
Jonathan Prusik
2025-02-21 13:15:02 -05:00
committed by GitHub
parent 0bc7813b1c
commit 2e96405f15
5 changed files with 145 additions and 45 deletions

View File

@@ -1,6 +1,13 @@
import { NeverDomains } from "@bitwarden/common/models/domain/domain-service";
import { CardView } from "../vault/models/view/card.view";
import { normalizeExpiryYearFormat, isCardExpired, parseYearMonthExpiry } from "./utils";
import {
isCardExpired,
isUrlInList,
normalizeExpiryYearFormat,
parseYearMonthExpiry,
} from "./utils";
function getExpiryYearValueFormats(currentCentury: string) {
return [
@@ -281,3 +288,73 @@ describe("parseYearMonthExpiry", () => {
});
});
});
describe("isUrlInList", () => {
let mockUrlList: NeverDomains;
it("returns false if the passed URL list is empty", () => {
const urlIsInList = isUrlInList("", mockUrlList);
expect(urlIsInList).toEqual(false);
});
it("returns true if the URL hostname is on the passed URL list", () => {
mockUrlList = {
["bitwarden.com"]: { bannerIsDismissed: true },
["duckduckgo.com"]: null,
[".lan"]: null,
[".net"]: null,
["localhost"]: null,
["extensions"]: null,
};
const testPages = [
"https://www.bitwarden.com/landing-page?some_query_string_key=1&another_one=1",
" https://duckduckgo.com/pro ", // Note: embedded whitespacing is intentional
"https://network-private-domain.lan/homelabs-dashboard",
"https://jsfiddle.net/",
"https://localhost:8443/#/login",
"chrome://extensions/",
];
for (const pageUrl of testPages) {
const urlIsInList = isUrlInList(pageUrl, mockUrlList);
expect(urlIsInList).toEqual(true);
}
});
it("returns false if no items on the passed URL list are a full match for the page hostname", () => {
const urlIsInList = isUrlInList("https://paypal.com/", {
["some.packed.subdomains.sandbox.paypal.com"]: null,
});
expect(urlIsInList).toEqual(false);
});
it("returns false if the URL hostname is not on the passed URL list", () => {
const testPages = ["https://archive.org/", "bitwarden.com.some.otherdomain.com"];
for (const pageUrl of testPages) {
const urlIsInList = isUrlInList(pageUrl, mockUrlList);
expect(urlIsInList).toEqual(false);
}
});
it("returns false if the passed URL is empty", () => {
const urlIsInList = isUrlInList("", mockUrlList);
expect(urlIsInList).toEqual(false);
});
it("returns false if the passed URL is not a valid URL", () => {
const testPages = ["twasbrillingandtheslithytoves", "/landing-page", undefined];
for (const pageUrl of testPages) {
const urlIsInList = isUrlInList(pageUrl, mockUrlList);
expect(urlIsInList).toEqual(false);
}
});
});

View File

@@ -1,3 +1,6 @@
import { NeverDomains } from "@bitwarden/common/models/domain/domain-service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { CardView } from "../vault/models/view/card.view";
import {
@@ -329,3 +332,29 @@ export function parseYearMonthExpiry(combinedExpiryValue: string): [Year | null,
return [parsedYear, parsedMonth];
}
/**
* Takes a URL string and a NeverDomains object and determines if the passed URL's hostname is in `urlList`
*
* @param {string} url - representation of URL to check
* @param {NeverDomains} urlList - object with hostname key names
*/
export function isUrlInList(url: string = "", urlList: NeverDomains = {}): boolean {
const urlListKeys = urlList && Object.keys(urlList);
if (urlListKeys.length && url?.length) {
let tabHostname;
try {
tabHostname = Utils.getHostname(url);
} catch {
// If the input was invalid, exit early and return false
return false;
}
if (tabHostname) {
return urlListKeys.some((blockedHostname) => tabHostname.endsWith(blockedHostname));
}
}
return false;
}