mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 05:43:41 +00:00
[deps] Platform: Update @types/chrome to v0.1.0 (#15697)
* [deps] Platform: Update @types/chrome to v0.1.0 * Fix typing * Fix other build errors * Fix strict compile * Update pkg and fix remaining type errors --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel García <dani-garcia@users.noreply.github.com>
This commit is contained in:
@@ -19,7 +19,7 @@ export type LoginSecurityTaskInfo = {
|
|||||||
|
|
||||||
export type WebsiteOriginsWithFields = Map<chrome.tabs.Tab["id"], Set<string>>;
|
export type WebsiteOriginsWithFields = Map<chrome.tabs.Tab["id"], Set<string>>;
|
||||||
|
|
||||||
export type ActiveFormSubmissionRequests = Set<chrome.webRequest.ResourceRequest["requestId"]>;
|
export type ActiveFormSubmissionRequests = Set<chrome.webRequest.WebRequestDetails["requestId"]>;
|
||||||
|
|
||||||
export type ModifyLoginCipherFormData = {
|
export type ModifyLoginCipherFormData = {
|
||||||
uri: string;
|
uri: string;
|
||||||
|
|||||||
@@ -110,11 +110,11 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("when the AutomaticAppLogIn policy is valid and active", () => {
|
describe("when the AutomaticAppLogIn policy is valid and active", () => {
|
||||||
let webRequestDetails: chrome.webRequest.WebRequestBodyDetails;
|
let webRequestDetails: chrome.webRequest.WebRequestDetails;
|
||||||
|
|
||||||
describe("starting the auto-submit login workflow", () => {
|
describe("starting the auto-submit login workflow", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
webRequestDetails = mock<chrome.webRequest.WebRequestBodyDetails>({
|
webRequestDetails = mock<chrome.webRequest.WebRequestDetails>({
|
||||||
initiator: validIpdUrl1,
|
initiator: validIpdUrl1,
|
||||||
url: validAutoSubmitUrl,
|
url: validAutoSubmitUrl,
|
||||||
type: "main_frame",
|
type: "main_frame",
|
||||||
@@ -196,7 +196,7 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
|
|
||||||
describe("cancelling an active auto-submit login workflow", () => {
|
describe("cancelling an active auto-submit login workflow", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
webRequestDetails = mock<chrome.webRequest.WebRequestBodyDetails>({
|
webRequestDetails = mock<chrome.webRequest.WebRequestDetails>({
|
||||||
initiator: validIpdUrl1,
|
initiator: validIpdUrl1,
|
||||||
url: validAutoSubmitUrl,
|
url: validAutoSubmitUrl,
|
||||||
type: "main_frame",
|
type: "main_frame",
|
||||||
@@ -280,7 +280,7 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("requests that occur within a sub-frame", () => {
|
describe("requests that occur within a sub-frame", () => {
|
||||||
const webRequestDetails = mock<chrome.webRequest.WebRequestBodyDetails>({
|
const webRequestDetails = mock<chrome.webRequest.WebRequestDetails>({
|
||||||
url: validAutoSubmitUrl,
|
url: validAutoSubmitUrl,
|
||||||
frameId: 1,
|
frameId: 1,
|
||||||
});
|
});
|
||||||
@@ -324,7 +324,7 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
it("updates the most recent idp host when a tab is activated", async () => {
|
it("updates the most recent idp host when a tab is activated", async () => {
|
||||||
jest.spyOn(BrowserApi, "getTab").mockResolvedValue(newTab);
|
jest.spyOn(BrowserApi, "getTab").mockResolvedValue(newTab);
|
||||||
|
|
||||||
triggerTabOnActivatedEvent(mock<chrome.tabs.TabActiveInfo>({ tabId: newTabId }));
|
triggerTabOnActivatedEvent(mock<chrome.tabs.OnActivatedInfo>({ tabId: newTabId }));
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
expect(autoSubmitLoginBackground["mostRecentIdpHost"]).toStrictEqual({
|
expect(autoSubmitLoginBackground["mostRecentIdpHost"]).toStrictEqual({
|
||||||
@@ -336,7 +336,7 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
it("updates the most recent id host when a tab is updated", () => {
|
it("updates the most recent id host when a tab is updated", () => {
|
||||||
triggerTabOnUpdatedEvent(
|
triggerTabOnUpdatedEvent(
|
||||||
newTabId,
|
newTabId,
|
||||||
mock<chrome.tabs.TabChangeInfo>({ url: validIpdUrl1 }),
|
mock<chrome.tabs.OnUpdatedInfo>({ url: validIpdUrl1 }),
|
||||||
newTab,
|
newTab,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -389,7 +389,7 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
tabId: newTabId,
|
tabId: newTabId,
|
||||||
};
|
};
|
||||||
|
|
||||||
triggerTabOnRemovedEvent(newTabId, mock<chrome.tabs.TabRemoveInfo>());
|
triggerTabOnRemovedEvent(newTabId, mock<chrome.tabs.OnRemovedInfo>());
|
||||||
|
|
||||||
expect(autoSubmitLoginBackground["currentAutoSubmitHostData"]).toStrictEqual({});
|
expect(autoSubmitLoginBackground["currentAutoSubmitHostData"]).toStrictEqual({});
|
||||||
});
|
});
|
||||||
@@ -403,14 +403,14 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
tabId: tabId,
|
tabId: tabId,
|
||||||
};
|
};
|
||||||
triggerWebRequestOnBeforeRedirectEvent(
|
triggerWebRequestOnBeforeRedirectEvent(
|
||||||
mock<chrome.webRequest.WebRedirectionResponseDetails>({
|
mock<chrome.webRequest.OnBeforeRedirectDetails>({
|
||||||
url: validIpdUrl1,
|
url: validIpdUrl1,
|
||||||
redirectUrl: validIpdUrl2,
|
redirectUrl: validIpdUrl2,
|
||||||
frameId: 0,
|
frameId: 0,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
triggerWebRequestOnBeforeRedirectEvent(
|
triggerWebRequestOnBeforeRedirectEvent(
|
||||||
mock<chrome.webRequest.WebRedirectionResponseDetails>({
|
mock<chrome.webRequest.OnBeforeRedirectDetails>({
|
||||||
url: validIpdUrl2,
|
url: validIpdUrl2,
|
||||||
redirectUrl: validAutoSubmitUrl,
|
redirectUrl: validAutoSubmitUrl,
|
||||||
frameId: 0,
|
frameId: 0,
|
||||||
@@ -418,7 +418,7 @@ describe("AutoSubmitLoginBackground", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
triggerWebRequestOnBeforeRequestEvent(
|
triggerWebRequestOnBeforeRequestEvent(
|
||||||
mock<chrome.webRequest.WebRequestBodyDetails>({
|
mock<chrome.webRequest.WebRequestDetails>({
|
||||||
tabId: tabId,
|
tabId: tabId,
|
||||||
url: `https://${validAutoSubmitHost}`,
|
url: `https://${validAutoSubmitHost}`,
|
||||||
initiator: null,
|
initiator: null,
|
||||||
|
|||||||
@@ -161,7 +161,9 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
*
|
*
|
||||||
* @param details - The details of the request.
|
* @param details - The details of the request.
|
||||||
*/
|
*/
|
||||||
private handleOnBeforeRequest = (details: chrome.webRequest.WebRequestBodyDetails) => {
|
private handleOnBeforeRequest = (
|
||||||
|
details: chrome.webRequest.OnBeforeRequestDetails,
|
||||||
|
): undefined => {
|
||||||
const requestInitiator = this.getRequestInitiator(details);
|
const requestInitiator = this.getRequestInitiator(details);
|
||||||
const isValidInitiator = this.isValidInitiator(requestInitiator);
|
const isValidInitiator = this.isValidInitiator(requestInitiator);
|
||||||
|
|
||||||
@@ -191,7 +193,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
* @param isValidInitiator - A flag indicating if the initiator of the request is valid.
|
* @param isValidInitiator - A flag indicating if the initiator of the request is valid.
|
||||||
*/
|
*/
|
||||||
private postRequestEncounteredAfterSubmission = (
|
private postRequestEncounteredAfterSubmission = (
|
||||||
details: chrome.webRequest.WebRequestBodyDetails,
|
details: chrome.webRequest.OnBeforeRequestDetails,
|
||||||
isValidInitiator: boolean,
|
isValidInitiator: boolean,
|
||||||
) => {
|
) => {
|
||||||
return details.method === "POST" && this.validAutoSubmitHosts.size > 0 && isValidInitiator;
|
return details.method === "POST" && this.validAutoSubmitHosts.size > 0 && isValidInitiator;
|
||||||
@@ -205,7 +207,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
* @param isValidInitiator - A flag indicating if the initiator of the request is valid.
|
* @param isValidInitiator - A flag indicating if the initiator of the request is valid.
|
||||||
*/
|
*/
|
||||||
private requestRedirectsToInvalidHost = (
|
private requestRedirectsToInvalidHost = (
|
||||||
details: chrome.webRequest.WebRequestBodyDetails,
|
details: chrome.webRequest.OnBeforeRequestDetails,
|
||||||
isValidInitiator: boolean,
|
isValidInitiator: boolean,
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
@@ -221,7 +223,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
*
|
*
|
||||||
* @param details - The details of the request.
|
* @param details - The details of the request.
|
||||||
*/
|
*/
|
||||||
private setupAutoSubmitFlow = (details: chrome.webRequest.WebRequestBodyDetails) => {
|
private setupAutoSubmitFlow = (details: chrome.webRequest.OnBeforeRequestDetails) => {
|
||||||
if (this.isRequestInMainFrame(details)) {
|
if (this.isRequestInMainFrame(details)) {
|
||||||
this.currentAutoSubmitHostData = {
|
this.currentAutoSubmitHostData = {
|
||||||
url: details.url,
|
url: details.url,
|
||||||
@@ -288,7 +290,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
* @param details - The details of the request.
|
* @param details - The details of the request.
|
||||||
*/
|
*/
|
||||||
private handleWebRequestOnBeforeRedirect = (
|
private handleWebRequestOnBeforeRedirect = (
|
||||||
details: chrome.webRequest.WebRedirectionResponseDetails,
|
details: chrome.webRequest.OnBeforeRedirectDetails,
|
||||||
) => {
|
) => {
|
||||||
if (this.isRequestInMainFrame(details) && this.urlContainsAutoSubmitHash(details.redirectUrl)) {
|
if (this.isRequestInMainFrame(details) && this.urlContainsAutoSubmitHash(details.redirectUrl)) {
|
||||||
this.validAutoSubmitHosts.add(this.getUrlHost(details.redirectUrl));
|
this.validAutoSubmitHosts.add(this.getUrlHost(details.redirectUrl));
|
||||||
@@ -354,7 +356,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
*/
|
*/
|
||||||
private disableAutoSubmitFlow = async (
|
private disableAutoSubmitFlow = async (
|
||||||
requestInitiator: string,
|
requestInitiator: string,
|
||||||
details: chrome.webRequest.WebRequestBodyDetails,
|
details: chrome.webRequest.OnBeforeRequestDetails,
|
||||||
) => {
|
) => {
|
||||||
if (this.isValidAutoSubmitHost(requestInitiator)) {
|
if (this.isValidAutoSubmitHost(requestInitiator)) {
|
||||||
this.removeUrlFromAutoSubmitHosts(requestInitiator);
|
this.removeUrlFromAutoSubmitHosts(requestInitiator);
|
||||||
@@ -390,7 +392,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
* @param initiator - The initiator of the request.
|
* @param initiator - The initiator of the request.
|
||||||
*/
|
*/
|
||||||
private shouldRouteTriggerAutoSubmit = (
|
private shouldRouteTriggerAutoSubmit = (
|
||||||
details: chrome.webRequest.ResourceRequest,
|
details: chrome.webRequest.OnBeforeRequestDetails,
|
||||||
initiator: string,
|
initiator: string,
|
||||||
) => {
|
) => {
|
||||||
if (this.isRequestInMainFrame(details)) {
|
if (this.isRequestInMainFrame(details)) {
|
||||||
@@ -449,7 +451,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
*
|
*
|
||||||
* @param details - The details of the request.
|
* @param details - The details of the request.
|
||||||
*/
|
*/
|
||||||
private getRequestInitiator = (details: chrome.webRequest.ResourceRequest) => {
|
private getRequestInitiator = (details: chrome.webRequest.OnBeforeRequestDetails) => {
|
||||||
if (!this.isSafariBrowser) {
|
if (!this.isSafariBrowser) {
|
||||||
return details.initiator || (details as browser.webRequest._OnBeforeRequestDetails).originUrl;
|
return details.initiator || (details as browser.webRequest._OnBeforeRequestDetails).originUrl;
|
||||||
}
|
}
|
||||||
@@ -470,7 +472,12 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
*
|
*
|
||||||
* @param details - The details of the request.
|
* @param details - The details of the request.
|
||||||
*/
|
*/
|
||||||
private isRequestInMainFrame = (details: chrome.webRequest.ResourceRequest) => {
|
private isRequestInMainFrame = (
|
||||||
|
details: SetPartial<
|
||||||
|
chrome.webRequest.WebRequestDetails,
|
||||||
|
"documentId" | "documentLifecycle" | "frameType"
|
||||||
|
>,
|
||||||
|
) => {
|
||||||
if (this.isSafariBrowser) {
|
if (this.isSafariBrowser) {
|
||||||
return details.frameId === 0;
|
return details.frameId === 0;
|
||||||
}
|
}
|
||||||
@@ -545,7 +552,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
*
|
*
|
||||||
* @param activeInfo - The active tab information.
|
* @param activeInfo - The active tab information.
|
||||||
*/
|
*/
|
||||||
private handleSafariTabOnActivated = async (activeInfo: chrome.tabs.TabActiveInfo) => {
|
private handleSafariTabOnActivated = async (activeInfo: chrome.tabs.OnActivatedInfo) => {
|
||||||
if (activeInfo.tabId < 0) {
|
if (activeInfo.tabId < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -562,7 +569,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
|
|||||||
* @param tabId - The tab ID associated with the URL.
|
* @param tabId - The tab ID associated with the URL.
|
||||||
* @param changeInfo - The change information of the tab.
|
* @param changeInfo - The change information of the tab.
|
||||||
*/
|
*/
|
||||||
private handleSafariTabOnUpdated = (tabId: number, changeInfo: chrome.tabs.TabChangeInfo) => {
|
private handleSafariTabOnUpdated = (tabId: number, changeInfo: chrome.tabs.OnUpdatedInfo) => {
|
||||||
if (changeInfo) {
|
if (changeInfo) {
|
||||||
this.setMostRecentIdpHost(changeInfo.url, tabId);
|
this.setMostRecentIdpHost(changeInfo.url, tabId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
|
|
||||||
it("ignores requests that are not part of an active form submission", async () => {
|
it("ignores requests that are not part of an active form submission", async () => {
|
||||||
triggerWebRequestOnCompletedEvent(
|
triggerWebRequestOnCompletedEvent(
|
||||||
mock<chrome.webRequest.WebResponseDetails>({
|
mock<chrome.webRequest.OnCompletedDetails>({
|
||||||
url: sender.url,
|
url: sender.url,
|
||||||
tabId: sender.tab.id,
|
tabId: sender.tab.id,
|
||||||
requestId: "123345",
|
requestId: "123345",
|
||||||
@@ -409,7 +409,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
triggerWebRequestOnCompletedEvent(
|
triggerWebRequestOnCompletedEvent(
|
||||||
mock<chrome.webRequest.WebResponseDetails>({
|
mock<chrome.webRequest.OnCompletedDetails>({
|
||||||
url: sender.url,
|
url: sender.url,
|
||||||
tabId: sender.tab.id,
|
tabId: sender.tab.id,
|
||||||
requestId,
|
requestId,
|
||||||
@@ -438,7 +438,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
triggerWebRequestOnCompletedEvent(
|
triggerWebRequestOnCompletedEvent(
|
||||||
mock<chrome.webRequest.WebResponseDetails>({
|
mock<chrome.webRequest.OnCompletedDetails>({
|
||||||
url: sender.url,
|
url: sender.url,
|
||||||
tabId: sender.tab.id,
|
tabId: sender.tab.id,
|
||||||
statusCode: 404,
|
statusCode: 404,
|
||||||
@@ -492,7 +492,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
triggerWebRequestOnCompletedEvent(
|
triggerWebRequestOnCompletedEvent(
|
||||||
mock<chrome.webRequest.WebResponseDetails>({
|
mock<chrome.webRequest.OnCompletedDetails>({
|
||||||
url: sender.url,
|
url: sender.url,
|
||||||
tabId: sender.tab.id,
|
tabId: sender.tab.id,
|
||||||
requestId,
|
requestId,
|
||||||
@@ -541,7 +541,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
triggerWebRequestOnCompletedEvent(
|
triggerWebRequestOnCompletedEvent(
|
||||||
mock<chrome.webRequest.WebResponseDetails>({
|
mock<chrome.webRequest.OnCompletedDetails>({
|
||||||
url: sender.url,
|
url: sender.url,
|
||||||
tabId: sender.tab.id,
|
tabId: sender.tab.id,
|
||||||
requestId,
|
requestId,
|
||||||
@@ -643,7 +643,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("clears all associated data with a removed tab", () => {
|
it("clears all associated data with a removed tab", () => {
|
||||||
triggerTabOnRemovedEvent(sender.tab.id, mock<chrome.tabs.TabRemoveInfo>());
|
triggerTabOnRemovedEvent(sender.tab.id, mock<chrome.tabs.OnRemovedInfo>());
|
||||||
|
|
||||||
expect(overlayNotificationsBackground["websiteOriginsWithFields"].size).toBe(0);
|
expect(overlayNotificationsBackground["websiteOriginsWithFields"].size).toBe(0);
|
||||||
});
|
});
|
||||||
@@ -652,7 +652,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
it("skips clearing the website origins if the changeInfo does not contain a `loading` status", () => {
|
it("skips clearing the website origins if the changeInfo does not contain a `loading` status", () => {
|
||||||
triggerTabOnUpdatedEvent(
|
triggerTabOnUpdatedEvent(
|
||||||
sender.tab.id,
|
sender.tab.id,
|
||||||
mock<chrome.tabs.TabChangeInfo>({ status: "complete" }),
|
mock<chrome.tabs.OnUpdatedInfo>({ status: "complete" }),
|
||||||
mock<chrome.tabs.Tab>({ status: "complete" }),
|
mock<chrome.tabs.Tab>({ status: "complete" }),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -662,7 +662,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
it("skips clearing the website origins if the changeInfo does not contain a url", () => {
|
it("skips clearing the website origins if the changeInfo does not contain a url", () => {
|
||||||
triggerTabOnUpdatedEvent(
|
triggerTabOnUpdatedEvent(
|
||||||
sender.tab.id,
|
sender.tab.id,
|
||||||
mock<chrome.tabs.TabChangeInfo>({ status: "loading", url: "" }),
|
mock<chrome.tabs.OnUpdatedInfo>({ status: "loading", url: "" }),
|
||||||
mock<chrome.tabs.Tab>({ status: "loading" }),
|
mock<chrome.tabs.Tab>({ status: "loading" }),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -672,7 +672,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
it("skips clearing the website origins if the tab does not contain known website origins", () => {
|
it("skips clearing the website origins if the tab does not contain known website origins", () => {
|
||||||
triggerTabOnUpdatedEvent(
|
triggerTabOnUpdatedEvent(
|
||||||
199,
|
199,
|
||||||
mock<chrome.tabs.TabChangeInfo>({ status: "loading", url: "https://example.com" }),
|
mock<chrome.tabs.OnUpdatedInfo>({ status: "loading", url: "https://example.com" }),
|
||||||
mock<chrome.tabs.Tab>({ status: "loading", id: 199 }),
|
mock<chrome.tabs.Tab>({ status: "loading", id: 199 }),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -682,7 +682,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
it("skips clearing the website origins if the changeInfo's url is present as part of the know website origin match patterns", () => {
|
it("skips clearing the website origins if the changeInfo's url is present as part of the know website origin match patterns", () => {
|
||||||
triggerTabOnUpdatedEvent(
|
triggerTabOnUpdatedEvent(
|
||||||
sender.tab.id,
|
sender.tab.id,
|
||||||
mock<chrome.tabs.TabChangeInfo>({
|
mock<chrome.tabs.OnUpdatedInfo>({
|
||||||
status: "loading",
|
status: "loading",
|
||||||
url: "https://subdomain.example.com",
|
url: "https://subdomain.example.com",
|
||||||
}),
|
}),
|
||||||
@@ -695,7 +695,7 @@ describe("OverlayNotificationsBackground", () => {
|
|||||||
it("clears all associated data with a tab that is entering a `loading` state", () => {
|
it("clears all associated data with a tab that is entering a `loading` state", () => {
|
||||||
triggerTabOnUpdatedEvent(
|
triggerTabOnUpdatedEvent(
|
||||||
sender.tab.id,
|
sender.tab.id,
|
||||||
mock<chrome.tabs.TabChangeInfo>({ status: "loading" }),
|
mock<chrome.tabs.OnUpdatedInfo>({ status: "loading" }),
|
||||||
mock<chrome.tabs.Tab>({ status: "loading" }),
|
mock<chrome.tabs.Tab>({ status: "loading" }),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -228,7 +228,9 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
*
|
*
|
||||||
* @param details - The details of the web request
|
* @param details - The details of the web request
|
||||||
*/
|
*/
|
||||||
private handleOnBeforeRequestEvent = (details: chrome.webRequest.WebRequestDetails) => {
|
private handleOnBeforeRequestEvent = (
|
||||||
|
details: chrome.webRequest.OnBeforeRequestDetails,
|
||||||
|
): undefined => {
|
||||||
if (this.isPostSubmissionFormRedirection(details)) {
|
if (this.isPostSubmissionFormRedirection(details)) {
|
||||||
this.setupNotificationInitTrigger(
|
this.setupNotificationInitTrigger(
|
||||||
details.tabId,
|
details.tabId,
|
||||||
@@ -275,7 +277,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
*
|
*
|
||||||
* @param details - The details of the web request
|
* @param details - The details of the web request
|
||||||
*/
|
*/
|
||||||
private isPostSubmissionFormRedirection = (details: chrome.webRequest.WebRequestDetails) => {
|
private isPostSubmissionFormRedirection = (details: chrome.webRequest.OnBeforeRequestDetails) => {
|
||||||
return (
|
return (
|
||||||
details.method?.toUpperCase() === "GET" &&
|
details.method?.toUpperCase() === "GET" &&
|
||||||
this.activeFormSubmissionRequests.has(details.requestId) &&
|
this.activeFormSubmissionRequests.has(details.requestId) &&
|
||||||
@@ -289,7 +291,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
*
|
*
|
||||||
* @param details - The details of the web request
|
* @param details - The details of the web request
|
||||||
*/
|
*/
|
||||||
private isValidFormSubmissionRequest = (details: chrome.webRequest.WebRequestDetails) => {
|
private isValidFormSubmissionRequest = (details: chrome.webRequest.OnBeforeRequestDetails) => {
|
||||||
return (
|
return (
|
||||||
!this.requestHostIsInvalid(details) &&
|
!this.requestHostIsInvalid(details) &&
|
||||||
this.formSubmissionRequestMethods.has(details.method?.toUpperCase())
|
this.formSubmissionRequestMethods.has(details.method?.toUpperCase())
|
||||||
@@ -325,7 +327,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
*
|
*
|
||||||
* @param details - The details of the web response
|
* @param details - The details of the web response
|
||||||
*/
|
*/
|
||||||
private handleOnCompletedRequestEvent = async (details: chrome.webRequest.WebResponseDetails) => {
|
private handleOnCompletedRequestEvent = async (details: chrome.webRequest.OnCompletedDetails) => {
|
||||||
if (
|
if (
|
||||||
this.requestHostIsInvalid(details) ||
|
this.requestHostIsInvalid(details) ||
|
||||||
!this.activeFormSubmissionRequests.has(details.requestId)
|
!this.activeFormSubmissionRequests.has(details.requestId)
|
||||||
@@ -382,8 +384,8 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
* @param modifyLoginData - The modified login form data
|
* @param modifyLoginData - The modified login form data
|
||||||
*/
|
*/
|
||||||
private delayNotificationInitUntilTabIsComplete = async (
|
private delayNotificationInitUntilTabIsComplete = async (
|
||||||
tabId: chrome.webRequest.ResourceRequest["tabId"],
|
tabId: chrome.webRequest.WebRequestDetails["tabId"],
|
||||||
requestId: chrome.webRequest.ResourceRequest["requestId"],
|
requestId: chrome.webRequest.WebRequestDetails["requestId"],
|
||||||
modifyLoginData: ModifyLoginCipherFormData,
|
modifyLoginData: ModifyLoginCipherFormData,
|
||||||
) => {
|
) => {
|
||||||
const handleWebNavigationOnCompleted = async () => {
|
const handleWebNavigationOnCompleted = async () => {
|
||||||
@@ -403,7 +405,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
* @param tab - The tab details
|
* @param tab - The tab details
|
||||||
*/
|
*/
|
||||||
private processNotifications = async (
|
private processNotifications = async (
|
||||||
requestId: chrome.webRequest.ResourceRequest["requestId"],
|
requestId: chrome.webRequest.WebRequestDetails["requestId"],
|
||||||
modifyLoginData: ModifyLoginCipherFormData,
|
modifyLoginData: ModifyLoginCipherFormData,
|
||||||
tab: chrome.tabs.Tab,
|
tab: chrome.tabs.Tab,
|
||||||
config: { skippable: NotificationType[] } = { skippable: [] },
|
config: { skippable: NotificationType[] } = { skippable: [] },
|
||||||
@@ -477,7 +479,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
* @param tab - The tab details
|
* @param tab - The tab details
|
||||||
*/
|
*/
|
||||||
private clearCompletedWebRequest = (
|
private clearCompletedWebRequest = (
|
||||||
requestId: chrome.webRequest.ResourceRequest["requestId"],
|
requestId: chrome.webRequest.WebRequestDetails["requestId"],
|
||||||
tabId: chrome.tabs.Tab["id"],
|
tabId: chrome.tabs.Tab["id"],
|
||||||
) => {
|
) => {
|
||||||
this.activeFormSubmissionRequests.delete(requestId);
|
this.activeFormSubmissionRequests.delete(requestId);
|
||||||
@@ -492,7 +494,12 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
*
|
*
|
||||||
* @param details - The details of the web request
|
* @param details - The details of the web request
|
||||||
*/
|
*/
|
||||||
private requestHostIsInvalid = (details: chrome.webRequest.ResourceRequest) => {
|
private requestHostIsInvalid = (
|
||||||
|
details: SetPartial<
|
||||||
|
chrome.webRequest.WebRequestDetails,
|
||||||
|
"documentId" | "documentLifecycle" | "frameType"
|
||||||
|
>,
|
||||||
|
) => {
|
||||||
return !details.url?.startsWith("http") || details.tabId < 0;
|
return !details.url?.startsWith("http") || details.tabId < 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -553,7 +560,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
|
|||||||
* @param tabId - The id of the tab that was updated
|
* @param tabId - The id of the tab that was updated
|
||||||
* @param changeInfo - The change info of the tab
|
* @param changeInfo - The change info of the tab
|
||||||
*/
|
*/
|
||||||
private handleTabUpdated = (tabId: number, changeInfo: chrome.tabs.TabChangeInfo) => {
|
private handleTabUpdated = (tabId: number, changeInfo: chrome.tabs.OnUpdatedInfo) => {
|
||||||
if (changeInfo.status !== "loading" || !changeInfo.url) {
|
if (changeInfo.status !== "loading" || !changeInfo.url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3371,7 +3371,7 @@ describe("OverlayBackground", () => {
|
|||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
triggerWebRequestOnCompletedEvent(
|
triggerWebRequestOnCompletedEvent(
|
||||||
mock<chrome.webRequest.WebResponseCacheDetails>({
|
mock<chrome.webRequest.OnCompletedDetails>({
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -3391,7 +3391,7 @@ describe("OverlayBackground", () => {
|
|||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
triggerWebRequestOnCompletedEvent(
|
triggerWebRequestOnCompletedEvent(
|
||||||
mock<chrome.webRequest.WebResponseCacheDetails>({
|
mock<chrome.webRequest.OnCompletedDetails>({
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1238,7 +1238,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
* @param details - The web request details
|
* @param details - The web request details
|
||||||
*/
|
*/
|
||||||
private handlePasskeyAuthenticationOnCompleted = (
|
private handlePasskeyAuthenticationOnCompleted = (
|
||||||
details: chrome.webRequest.WebResponseCacheDetails,
|
details: chrome.webRequest.OnCompletedDetails,
|
||||||
) => {
|
) => {
|
||||||
chrome.webRequest.onCompleted.removeListener(this.handlePasskeyAuthenticationOnCompleted);
|
chrome.webRequest.onCompleted.removeListener(this.handlePasskeyAuthenticationOnCompleted);
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export default class TabsBackground {
|
|||||||
*/
|
*/
|
||||||
private handleTabOnUpdated = async (
|
private handleTabOnUpdated = async (
|
||||||
tabId: number,
|
tabId: number,
|
||||||
changeInfo: chrome.tabs.TabChangeInfo,
|
changeInfo: chrome.tabs.OnUpdatedInfo,
|
||||||
tab: chrome.tabs.Tab,
|
tab: chrome.tabs.Tab,
|
||||||
) => {
|
) => {
|
||||||
if (this.focusedWindowId > 0 && tab.windowId !== this.focusedWindowId) {
|
if (this.focusedWindowId > 0 && tab.windowId !== this.focusedWindowId) {
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ export default class WebRequestBackground {
|
|||||||
|
|
||||||
startListening() {
|
startListening() {
|
||||||
this.webRequest.onAuthRequired.addListener(
|
this.webRequest.onAuthRequired.addListener(
|
||||||
async (details, callback) => {
|
(async (
|
||||||
|
details: chrome.webRequest.OnAuthRequiredDetails,
|
||||||
|
callback: (response: chrome.webRequest.BlockingResponse) => void,
|
||||||
|
) => {
|
||||||
if (!details.url || this.pendingAuthRequests.has(details.requestId)) {
|
if (!details.url || this.pendingAuthRequests.has(details.requestId)) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(null);
|
callback(null);
|
||||||
@@ -42,7 +45,7 @@ export default class WebRequestBackground {
|
|||||||
} else {
|
} else {
|
||||||
await this.resolveAuthCredentials(details.url, callback, callback);
|
await this.resolveAuthCredentials(details.url, callback, callback);
|
||||||
}
|
}
|
||||||
},
|
}) as any,
|
||||||
{ urls: ["http://*/*", "https://*/*"] },
|
{ urls: ["http://*/*", "https://*/*"] },
|
||||||
[this.isFirefox ? "blocking" : "asyncBlocking"],
|
[this.isFirefox ? "blocking" : "asyncBlocking"],
|
||||||
);
|
);
|
||||||
@@ -50,16 +53,17 @@ export default class WebRequestBackground {
|
|||||||
this.webRequest.onCompleted.addListener((details) => this.completeAuthRequest(details), {
|
this.webRequest.onCompleted.addListener((details) => this.completeAuthRequest(details), {
|
||||||
urls: ["http://*/*"],
|
urls: ["http://*/*"],
|
||||||
});
|
});
|
||||||
this.webRequest.onErrorOccurred.addListener(
|
this.webRequest.onErrorOccurred.addListener((details) => this.completeAuthRequest(details), {
|
||||||
(details: any) => this.completeAuthRequest(details),
|
urls: ["http://*/*"],
|
||||||
{
|
});
|
||||||
urls: ["http://*/*"],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line
|
private async resolveAuthCredentials(
|
||||||
private async resolveAuthCredentials(domain: string, success: Function, error: Function) {
|
domain: string,
|
||||||
|
success: (response: chrome.webRequest.BlockingResponse) => void,
|
||||||
|
// eslint-disable-next-line
|
||||||
|
error: Function,
|
||||||
|
) {
|
||||||
const activeUserId = await firstValueFrom(
|
const activeUserId = await firstValueFrom(
|
||||||
this.accountService.activeAccount$.pipe(getOptionalUserId),
|
this.accountService.activeAccount$.pipe(getOptionalUserId),
|
||||||
);
|
);
|
||||||
@@ -97,7 +101,7 @@ export default class WebRequestBackground {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private completeAuthRequest(details: chrome.webRequest.WebResponseCacheDetails) {
|
private completeAuthRequest(details: chrome.webRequest.WebRequestDetails) {
|
||||||
this.pendingAuthRequests.delete(details.requestId);
|
this.pendingAuthRequests.delete(details.requestId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,7 +218,10 @@ export class Fido2Background implements Fido2BackgroundInterface {
|
|||||||
tabId: tab.id,
|
tabId: tab.id,
|
||||||
injectDetails: { frame: "all_frames", ...this.sharedInjectionDetails },
|
injectDetails: { frame: "all_frames", ...this.sharedInjectionDetails },
|
||||||
mv2Details: { file: await this.getFido2PageScriptAppendFileName() },
|
mv2Details: { file: await this.getFido2PageScriptAppendFileName() },
|
||||||
mv3Details: { file: Fido2ContentScript.PageScript, world: "MAIN" },
|
mv3Details: {
|
||||||
|
file: Fido2ContentScript.PageScript,
|
||||||
|
world: chrome.scripting.ExecutionWorld.MAIN,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
void this.scriptInjectorService.inject({
|
void this.scriptInjectorService.inject({
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ describe("Fido2 Content Script", () => {
|
|||||||
data: mock<InsecureCreateCredentialParams>(),
|
data: mock<InsecureCreateCredentialParams>(),
|
||||||
});
|
});
|
||||||
const mockResult = { credentialId: "mock" } as CreateCredentialResult;
|
const mockResult = { credentialId: "mock" } as CreateCredentialResult;
|
||||||
jest.spyOn(chrome.runtime, "sendMessage").mockResolvedValue(mockResult);
|
(jest.spyOn(chrome.runtime, "sendMessage") as jest.Mock).mockResolvedValue(mockResult);
|
||||||
|
|
||||||
// FIXME: Remove when updating file. Eslint update
|
// FIXME: Remove when updating file. Eslint update
|
||||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||||
@@ -167,7 +167,9 @@ describe("Fido2 Content Script", () => {
|
|||||||
data: mock<InsecureCreateCredentialParams>(),
|
data: mock<InsecureCreateCredentialParams>(),
|
||||||
});
|
});
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
jest.spyOn(chrome.runtime, "sendMessage").mockResolvedValue({ error: errorMessage });
|
(jest.spyOn(chrome.runtime, "sendMessage") as jest.Mock).mockResolvedValue({
|
||||||
|
error: errorMessage,
|
||||||
|
});
|
||||||
|
|
||||||
// FIXME: Remove when updating file. Eslint update
|
// FIXME: Remove when updating file. Eslint update
|
||||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function triggerWindowOnFocusedChangedEvent(windowId: number) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function triggerTabOnActivatedEvent(activeInfo: chrome.tabs.TabActiveInfo) {
|
export function triggerTabOnActivatedEvent(activeInfo: chrome.tabs.OnActivatedInfo) {
|
||||||
(chrome.tabs.onActivated.addListener as unknown as jest.SpyInstance).mock.calls.forEach(
|
(chrome.tabs.onActivated.addListener as unknown as jest.SpyInstance).mock.calls.forEach(
|
||||||
(call) => {
|
(call) => {
|
||||||
const callback = call[0];
|
const callback = call[0];
|
||||||
@@ -98,7 +98,7 @@ export function triggerTabOnReplacedEvent(addedTabId: number, removedTabId: numb
|
|||||||
|
|
||||||
export function triggerTabOnUpdatedEvent(
|
export function triggerTabOnUpdatedEvent(
|
||||||
tabId: number,
|
tabId: number,
|
||||||
changeInfo: chrome.tabs.TabChangeInfo,
|
changeInfo: chrome.tabs.OnUpdatedInfo,
|
||||||
tab: chrome.tabs.Tab,
|
tab: chrome.tabs.Tab,
|
||||||
) {
|
) {
|
||||||
(chrome.tabs.onUpdated.addListener as unknown as jest.SpyInstance).mock.calls.forEach((call) => {
|
(chrome.tabs.onUpdated.addListener as unknown as jest.SpyInstance).mock.calls.forEach((call) => {
|
||||||
@@ -107,7 +107,7 @@ export function triggerTabOnUpdatedEvent(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function triggerTabOnRemovedEvent(tabId: number, removeInfo: chrome.tabs.TabRemoveInfo) {
|
export function triggerTabOnRemovedEvent(tabId: number, removeInfo: chrome.tabs.OnRemovedInfo) {
|
||||||
(chrome.tabs.onRemoved.addListener as unknown as jest.SpyInstance).mock.calls.forEach((call) => {
|
(chrome.tabs.onRemoved.addListener as unknown as jest.SpyInstance).mock.calls.forEach((call) => {
|
||||||
const callback = call[0];
|
const callback = call[0];
|
||||||
callback(tabId, removeInfo);
|
callback(tabId, removeInfo);
|
||||||
@@ -165,7 +165,7 @@ export function triggerWebRequestOnBeforeRedirectEvent(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function triggerWebRequestOnCompletedEvent(details: chrome.webRequest.WebResponseDetails) {
|
export function triggerWebRequestOnCompletedEvent(details: chrome.webRequest.OnCompletedDetails) {
|
||||||
(chrome.webRequest.onCompleted.addListener as unknown as jest.SpyInstance).mock.calls.forEach(
|
(chrome.webRequest.onCompleted.addListener as unknown as jest.SpyInstance).mock.calls.forEach(
|
||||||
(call) => {
|
(call) => {
|
||||||
const callback = call[0];
|
const callback = call[0];
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default class IdleBackground {
|
|||||||
|
|
||||||
if (this.idle.onStateChanged) {
|
if (this.idle.onStateChanged) {
|
||||||
this.idle.onStateChanged.addListener(
|
this.idle.onStateChanged.addListener(
|
||||||
async (newState: chrome.idle.IdleState | browser.idle.IdleState) => {
|
async (newState: `${chrome.idle.IdleState}` | browser.idle.IdleState) => {
|
||||||
if (newState === "locked") {
|
if (newState === "locked") {
|
||||||
// Need to check if any of the current users have their timeout set to `onLocked`
|
// Need to check if any of the current users have their timeout set to `onLocked`
|
||||||
const allUsers = await firstValueFrom(this.accountService.accounts$);
|
const allUsers = await firstValueFrom(this.accountService.accounts$);
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ export class PhishingDetectionService {
|
|||||||
*/
|
*/
|
||||||
private static async _processNavigation(
|
private static async _processNavigation(
|
||||||
tabId: number,
|
tabId: number,
|
||||||
changeInfo: chrome.tabs.TabChangeInfo,
|
changeInfo: chrome.tabs.OnUpdatedInfo,
|
||||||
tab: chrome.tabs.Tab,
|
tab: chrome.tabs.Tab,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (changeInfo.status !== "complete" || !tab.url) {
|
if (changeInfo.status !== "complete" || !tab.url) {
|
||||||
@@ -253,7 +253,7 @@ export class PhishingDetectionService {
|
|||||||
|
|
||||||
private static _handleNavigationEvent(
|
private static _handleNavigationEvent(
|
||||||
tabId: number,
|
tabId: number,
|
||||||
changeInfo: chrome.tabs.TabChangeInfo,
|
changeInfo: chrome.tabs.OnUpdatedInfo,
|
||||||
tab: chrome.tabs.Tab,
|
tab: chrome.tabs.Tab,
|
||||||
): boolean {
|
): boolean {
|
||||||
this._navigationEventsSubject.next({ tabId, changeInfo, tab });
|
this._navigationEventsSubject.next({ tabId, changeInfo, tab });
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ export type CaughtPhishingDomain = {
|
|||||||
|
|
||||||
export type PhishingDetectionNavigationEvent = {
|
export type PhishingDetectionNavigationEvent = {
|
||||||
tabId: number;
|
tabId: number;
|
||||||
changeInfo: chrome.tabs.TabChangeInfo;
|
changeInfo: chrome.tabs.OnUpdatedInfo;
|
||||||
tab: chrome.tabs.Tab;
|
tab: chrome.tabs.Tab;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -141,8 +141,24 @@ function buildRegisterContentScriptsPolyfill() {
|
|||||||
return [possibleArray];
|
return [possibleArray];
|
||||||
}
|
}
|
||||||
|
|
||||||
function arrayOrUndefined(value?: number) {
|
function createTarget(
|
||||||
return value === undefined ? undefined : [value];
|
tabId: number,
|
||||||
|
frameId: number | undefined,
|
||||||
|
allFrames: boolean,
|
||||||
|
): chrome.scripting.InjectionTarget {
|
||||||
|
if (frameId === undefined) {
|
||||||
|
return {
|
||||||
|
tabId,
|
||||||
|
frameIds: undefined,
|
||||||
|
allFrames: allFrames,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
tabId,
|
||||||
|
frameIds: [frameId],
|
||||||
|
allFrames: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function insertCSS(
|
async function insertCSS(
|
||||||
@@ -170,15 +186,17 @@ function buildRegisterContentScriptsPolyfill() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gotScripting) {
|
if (gotScripting) {
|
||||||
return chrome.scripting.insertCSS({
|
if ("file" in content) {
|
||||||
target: {
|
return chrome.scripting.insertCSS({
|
||||||
tabId,
|
target: createTarget(tabId, frameId, allFrames),
|
||||||
frameIds: arrayOrUndefined(frameId),
|
files: [content.file],
|
||||||
allFrames: frameId === undefined ? allFrames : undefined,
|
});
|
||||||
},
|
} else {
|
||||||
files: "file" in content ? [content.file] : undefined,
|
return chrome.scripting.insertCSS({
|
||||||
css: "code" in content ? content.code : undefined,
|
target: createTarget(tabId, frameId, allFrames),
|
||||||
});
|
css: content.code,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return chromeProxy.tabs.insertCSS(tabId, {
|
return chromeProxy.tabs.insertCSS(tabId, {
|
||||||
@@ -226,11 +244,7 @@ function buildRegisterContentScriptsPolyfill() {
|
|||||||
if (gotScripting) {
|
if (gotScripting) {
|
||||||
assertNoCode(normalizedFiles);
|
assertNoCode(normalizedFiles);
|
||||||
const injection = chrome.scripting.executeScript({
|
const injection = chrome.scripting.executeScript({
|
||||||
target: {
|
target: createTarget(tabId, frameId, allFrames),
|
||||||
tabId,
|
|
||||||
frameIds: arrayOrUndefined(frameId),
|
|
||||||
allFrames: frameId === undefined ? allFrames : undefined,
|
|
||||||
},
|
|
||||||
files: normalizedFiles.map(({ file }: { file: string }) => file),
|
files: normalizedFiles.map(({ file }: { file: string }) => file),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -397,7 +411,7 @@ function buildRegisterContentScriptsPolyfill() {
|
|||||||
};
|
};
|
||||||
const tabListener = async (
|
const tabListener = async (
|
||||||
tabId: number,
|
tabId: number,
|
||||||
{ status }: chrome.tabs.TabChangeInfo,
|
{ status }: chrome.tabs.OnUpdatedInfo,
|
||||||
{ url }: chrome.tabs.Tab,
|
{ url }: chrome.tabs.Tab,
|
||||||
) => {
|
) => {
|
||||||
if (status === "loading" && url) {
|
if (status === "loading" && url) {
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ describe("BrowserApi", () => {
|
|||||||
describe("executeScriptInTab", () => {
|
describe("executeScriptInTab", () => {
|
||||||
it("calls to the extension api to execute a script within the give tabId", async () => {
|
it("calls to the extension api to execute a script within the give tabId", async () => {
|
||||||
const tabId = 1;
|
const tabId = 1;
|
||||||
const injectDetails = mock<chrome.tabs.InjectDetails>();
|
const injectDetails = mock<chrome.extensionTypes.InjectDetails>();
|
||||||
jest.spyOn(BrowserApi, "manifestVersion", "get").mockReturnValue(2);
|
jest.spyOn(BrowserApi, "manifestVersion", "get").mockReturnValue(2);
|
||||||
(chrome.tabs.executeScript as jest.Mock).mockImplementation(
|
(chrome.tabs.executeScript as jest.Mock).mockImplementation(
|
||||||
(tabId, injectDetails, callback) => callback(executeScriptResult),
|
(tabId, injectDetails, callback) => callback(executeScriptResult),
|
||||||
@@ -393,7 +393,7 @@ describe("BrowserApi", () => {
|
|||||||
|
|
||||||
it("calls the manifest v3 scripting API if the extension manifest is for v3", async () => {
|
it("calls the manifest v3 scripting API if the extension manifest is for v3", async () => {
|
||||||
const tabId = 1;
|
const tabId = 1;
|
||||||
const injectDetails = mock<chrome.tabs.InjectDetails>({
|
const injectDetails = mock<chrome.extensionTypes.InjectDetails>({
|
||||||
file: "file.js",
|
file: "file.js",
|
||||||
allFrames: true,
|
allFrames: true,
|
||||||
runAt: "document_start",
|
runAt: "document_start",
|
||||||
@@ -419,7 +419,7 @@ describe("BrowserApi", () => {
|
|||||||
it("injects the script into a specified frameId when the extension is built for manifest v3", async () => {
|
it("injects the script into a specified frameId when the extension is built for manifest v3", async () => {
|
||||||
const tabId = 1;
|
const tabId = 1;
|
||||||
const frameId = 2;
|
const frameId = 2;
|
||||||
const injectDetails = mock<chrome.tabs.InjectDetails>({
|
const injectDetails = mock<chrome.extensionTypes.InjectDetails>({
|
||||||
file: "file.js",
|
file: "file.js",
|
||||||
allFrames: true,
|
allFrames: true,
|
||||||
runAt: "document_start",
|
runAt: "document_start",
|
||||||
@@ -443,7 +443,7 @@ describe("BrowserApi", () => {
|
|||||||
|
|
||||||
it("injects the script into the MAIN world context when injecting a script for manifest v3", async () => {
|
it("injects the script into the MAIN world context when injecting a script for manifest v3", async () => {
|
||||||
const tabId = 1;
|
const tabId = 1;
|
||||||
const injectDetails = mock<chrome.tabs.InjectDetails>({
|
const injectDetails = mock<chrome.extensionTypes.InjectDetails>({
|
||||||
file: null,
|
file: null,
|
||||||
allFrames: true,
|
allFrames: true,
|
||||||
runAt: "document_start",
|
runAt: "document_start",
|
||||||
|
|||||||
@@ -685,29 +685,27 @@ export class BrowserApi {
|
|||||||
*/
|
*/
|
||||||
static executeScriptInTab(
|
static executeScriptInTab(
|
||||||
tabId: number,
|
tabId: number,
|
||||||
details: chrome.tabs.InjectDetails,
|
details: chrome.extensionTypes.InjectDetails,
|
||||||
scriptingApiDetails?: {
|
scriptingApiDetails?: {
|
||||||
world: chrome.scripting.ExecutionWorld;
|
world: chrome.scripting.ExecutionWorld;
|
||||||
},
|
},
|
||||||
): Promise<unknown> {
|
): Promise<unknown> {
|
||||||
if (BrowserApi.isManifestVersion(3)) {
|
if (BrowserApi.isManifestVersion(3)) {
|
||||||
const target: chrome.scripting.InjectionTarget = {
|
let target: chrome.scripting.InjectionTarget;
|
||||||
tabId,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof details.frameId === "number") {
|
if (typeof details.frameId === "number") {
|
||||||
target.frameIds = [details.frameId];
|
target = { tabId, frameIds: [details.frameId] };
|
||||||
}
|
} else if (details.allFrames) {
|
||||||
|
target = { tabId, allFrames: true };
|
||||||
if (!target.frameIds?.length && details.allFrames) {
|
} else {
|
||||||
target.allFrames = details.allFrames;
|
target = { tabId };
|
||||||
}
|
}
|
||||||
|
|
||||||
return chrome.scripting.executeScript({
|
return chrome.scripting.executeScript({
|
||||||
target,
|
target,
|
||||||
files: details.file ? [details.file] : null,
|
files: details.file ? [details.file] : null,
|
||||||
injectImmediately: details.runAt === "document_start",
|
injectImmediately: details.runAt === "document_start",
|
||||||
world: scriptingApiDetails?.world || "ISOLATED",
|
world: scriptingApiDetails?.world || chrome.scripting.ExecutionWorld.ISOLATED,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ describe("ChromeStorageApiService", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
chrome.runtime.lastError = undefined;
|
(chrome.runtime.lastError as any) = undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses `objToStore` to prepare a value for set", async () => {
|
it("uses `objToStore` to prepare a value for set", async () => {
|
||||||
@@ -80,7 +80,7 @@ describe("ChromeStorageApiService", () => {
|
|||||||
|
|
||||||
it("translates chrome.runtime.lastError to promise rejection", async () => {
|
it("translates chrome.runtime.lastError to promise rejection", async () => {
|
||||||
setMock.mockImplementation((data, callback) => {
|
setMock.mockImplementation((data, callback) => {
|
||||||
chrome.runtime.lastError = new Error("Test Error");
|
(chrome.runtime.lastError as any) = new Error("Test Error");
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ describe("ChromeStorageApiService", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
chrome.runtime.lastError = undefined;
|
(chrome.runtime.lastError as any) = undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns a stored value when it is serialized", async () => {
|
it("returns a stored value when it is serialized", async () => {
|
||||||
@@ -132,9 +132,9 @@ describe("ChromeStorageApiService", () => {
|
|||||||
|
|
||||||
it("translates chrome.runtime.lastError to promise rejection", async () => {
|
it("translates chrome.runtime.lastError to promise rejection", async () => {
|
||||||
getMock.mockImplementation((key, callback) => {
|
getMock.mockImplementation((key, callback) => {
|
||||||
chrome.runtime.lastError = new Error("Test Error");
|
(chrome.runtime.lastError as any) = new Error("Test Error");
|
||||||
callback();
|
callback();
|
||||||
chrome.runtime.lastError = undefined;
|
(chrome.runtime.lastError as any) = undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(async () => await service.get("test")).rejects.toThrow("Test Error");
|
await expect(async () => await service.get("test")).rejects.toThrow("Test Error");
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ describe("ScriptInjectorService", () => {
|
|||||||
const mv2SpecificFile = "content/autofill-init-mv2.js";
|
const mv2SpecificFile = "content/autofill-init-mv2.js";
|
||||||
const mv2Details = { file: mv2SpecificFile };
|
const mv2Details = { file: mv2SpecificFile };
|
||||||
const mv3SpecificFile = "content/autofill-init-mv3.js";
|
const mv3SpecificFile = "content/autofill-init-mv3.js";
|
||||||
const mv3Details: Mv3ScriptInjectionDetails = { file: mv3SpecificFile, world: "MAIN" };
|
const mv3Details: Mv3ScriptInjectionDetails = {
|
||||||
|
file: mv3SpecificFile,
|
||||||
|
world: chrome.scripting.ExecutionWorld.MAIN,
|
||||||
|
};
|
||||||
const sharedInjectDetails: CommonScriptInjectionDetails = {
|
const sharedInjectDetails: CommonScriptInjectionDetails = {
|
||||||
runAt: "document_start",
|
runAt: "document_start",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export class BrowserScriptInjectorService extends ScriptInjectorService {
|
|||||||
if (BrowserApi.isManifestVersion(3)) {
|
if (BrowserApi.isManifestVersion(3)) {
|
||||||
try {
|
try {
|
||||||
await BrowserApi.executeScriptInTab(tabId, injectionDetails, {
|
await BrowserApi.executeScriptInTab(tabId, injectionDetails, {
|
||||||
world: mv3Details?.world ?? "ISOLATED",
|
world: mv3Details?.world ?? chrome.scripting.ExecutionWorld.ISOLATED,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Swallow errors for host permissions, since this is believed to be a Manifest V3 Chrome bug
|
// Swallow errors for host permissions, since this is believed to be a Manifest V3 Chrome bug
|
||||||
@@ -112,9 +112,9 @@ export class BrowserScriptInjectorService extends ScriptInjectorService {
|
|||||||
private buildInjectionDetails(
|
private buildInjectionDetails(
|
||||||
injectDetails: CommonScriptInjectionDetails,
|
injectDetails: CommonScriptInjectionDetails,
|
||||||
file: string,
|
file: string,
|
||||||
): chrome.tabs.InjectDetails {
|
): chrome.extensionTypes.InjectDetails {
|
||||||
const { frame, runAt } = injectDetails;
|
const { frame, runAt } = injectDetails;
|
||||||
const injectionDetails: chrome.tabs.InjectDetails = { file };
|
const injectionDetails: chrome.extensionTypes.InjectDetails = { file };
|
||||||
|
|
||||||
if (runAt) {
|
if (runAt) {
|
||||||
injectionDetails.runAt = runAt;
|
injectionDetails.runAt = runAt;
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ describe("Browser Utils Service", () => {
|
|||||||
|
|
||||||
it("returns false if special error is sent", async () => {
|
it("returns false if special error is sent", async () => {
|
||||||
chrome.runtime.sendMessage = jest.fn().mockImplementation((message, callback) => {
|
chrome.runtime.sendMessage = jest.fn().mockImplementation((message, callback) => {
|
||||||
chrome.runtime.lastError = new Error(
|
(chrome.runtime.lastError as any) = new Error(
|
||||||
"Could not establish connection. Receiving end does not exist.",
|
"Could not establish connection. Receiving end does not exist.",
|
||||||
);
|
);
|
||||||
callback(undefined);
|
callback(undefined);
|
||||||
@@ -177,7 +177,7 @@ describe("Browser Utils Service", () => {
|
|||||||
|
|
||||||
expect(isViewOpen).toBe(false);
|
expect(isViewOpen).toBe(false);
|
||||||
|
|
||||||
chrome.runtime.lastError = null;
|
(chrome.runtime.lastError as any) = null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export class BrowserSystemNotificationService implements SystemNotificationsServ
|
|||||||
return new Promise<string>((resolve) => {
|
return new Promise<string>((resolve) => {
|
||||||
const deviceType: DeviceType = this.platformUtilsService.getDevice();
|
const deviceType: DeviceType = this.platformUtilsService.getDevice();
|
||||||
|
|
||||||
const options: chrome.notifications.NotificationOptions<true> = {
|
const options: chrome.notifications.NotificationCreateOptions = {
|
||||||
iconUrl: chrome.runtime.getURL("images/icon128.png"),
|
iconUrl: chrome.runtime.getURL("images/icon128.png"),
|
||||||
message: createInfo.body,
|
message: createInfo.body,
|
||||||
type: "basic",
|
type: "basic",
|
||||||
@@ -70,6 +70,7 @@ export class BrowserSystemNotificationService implements SystemNotificationsServ
|
|||||||
}
|
}
|
||||||
|
|
||||||
async clear(clearInfo: SystemNotificationClearInfo): Promise<undefined> {
|
async clear(clearInfo: SystemNotificationClearInfo): Promise<undefined> {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
chrome.notifications.clear(clearInfo.id);
|
chrome.notifications.clear(clearInfo.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ const scripting = {
|
|||||||
executeScript: jest.fn(),
|
executeScript: jest.fn(),
|
||||||
registerContentScripts: jest.fn(),
|
registerContentScripts: jest.fn(),
|
||||||
unregisterContentScripts: jest.fn(),
|
unregisterContentScripts: jest.fn(),
|
||||||
|
ExecutionWorld: { ISOLATED: "ISOLATED", MAIN: "MAIN" },
|
||||||
};
|
};
|
||||||
|
|
||||||
const windows = {
|
const windows = {
|
||||||
|
|||||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -97,7 +97,7 @@
|
|||||||
"@storybook/test-runner": "0.22.0",
|
"@storybook/test-runner": "0.22.0",
|
||||||
"@storybook/theming": "8.6.12",
|
"@storybook/theming": "8.6.12",
|
||||||
"@storybook/web-components-webpack5": "8.6.12",
|
"@storybook/web-components-webpack5": "8.6.12",
|
||||||
"@types/chrome": "0.0.306",
|
"@types/chrome": "0.1.12",
|
||||||
"@types/firefox-webext-browser": "120.0.4",
|
"@types/firefox-webext-browser": "120.0.4",
|
||||||
"@types/inquirer": "8.2.10",
|
"@types/inquirer": "8.2.10",
|
||||||
"@types/jest": "29.5.14",
|
"@types/jest": "29.5.14",
|
||||||
@@ -13377,9 +13377,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/chrome": {
|
"node_modules/@types/chrome": {
|
||||||
"version": "0.0.306",
|
"version": "0.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.306.tgz",
|
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.12.tgz",
|
||||||
"integrity": "sha512-95kgcqvTNcaZCXmx/kIKY6uo83IaRNT3cuPxYqlB2Iu+HzKDCP4t7TUe7KhJijTdibcvn+SzziIcfSLIlgRnhQ==",
|
"integrity": "sha512-jEkxs9GPQHx7g49WjkA8QDNcqODbMGDuBbWQOtjiS/Wf9AiEcDmQMIAgJvC/Xi36WoCVNx584g0Dd9ThJQCAiw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
"@storybook/test-runner": "0.22.0",
|
"@storybook/test-runner": "0.22.0",
|
||||||
"@storybook/theming": "8.6.12",
|
"@storybook/theming": "8.6.12",
|
||||||
"@storybook/web-components-webpack5": "8.6.12",
|
"@storybook/web-components-webpack5": "8.6.12",
|
||||||
"@types/chrome": "0.0.306",
|
"@types/chrome": "0.1.12",
|
||||||
"@types/firefox-webext-browser": "120.0.4",
|
"@types/firefox-webext-browser": "120.0.4",
|
||||||
"@types/inquirer": "8.2.10",
|
"@types/inquirer": "8.2.10",
|
||||||
"@types/jest": "29.5.14",
|
"@types/jest": "29.5.14",
|
||||||
|
|||||||
Reference in New Issue
Block a user