1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 13:53:34 +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:
renovate[bot]
2025-09-26 17:02:39 +02:00
committed by GitHub
parent 466bf18d51
commit e5c5bf63ca
26 changed files with 157 additions and 117 deletions

View File

@@ -19,7 +19,7 @@ export type LoginSecurityTaskInfo = {
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 = {
uri: string;

View File

@@ -110,11 +110,11 @@ describe("AutoSubmitLoginBackground", () => {
});
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", () => {
beforeEach(async () => {
webRequestDetails = mock<chrome.webRequest.WebRequestBodyDetails>({
webRequestDetails = mock<chrome.webRequest.WebRequestDetails>({
initiator: validIpdUrl1,
url: validAutoSubmitUrl,
type: "main_frame",
@@ -196,7 +196,7 @@ describe("AutoSubmitLoginBackground", () => {
describe("cancelling an active auto-submit login workflow", () => {
beforeEach(async () => {
webRequestDetails = mock<chrome.webRequest.WebRequestBodyDetails>({
webRequestDetails = mock<chrome.webRequest.WebRequestDetails>({
initiator: validIpdUrl1,
url: validAutoSubmitUrl,
type: "main_frame",
@@ -280,7 +280,7 @@ describe("AutoSubmitLoginBackground", () => {
});
describe("requests that occur within a sub-frame", () => {
const webRequestDetails = mock<chrome.webRequest.WebRequestBodyDetails>({
const webRequestDetails = mock<chrome.webRequest.WebRequestDetails>({
url: validAutoSubmitUrl,
frameId: 1,
});
@@ -324,7 +324,7 @@ describe("AutoSubmitLoginBackground", () => {
it("updates the most recent idp host when a tab is activated", async () => {
jest.spyOn(BrowserApi, "getTab").mockResolvedValue(newTab);
triggerTabOnActivatedEvent(mock<chrome.tabs.TabActiveInfo>({ tabId: newTabId }));
triggerTabOnActivatedEvent(mock<chrome.tabs.OnActivatedInfo>({ tabId: newTabId }));
await flushPromises();
expect(autoSubmitLoginBackground["mostRecentIdpHost"]).toStrictEqual({
@@ -336,7 +336,7 @@ describe("AutoSubmitLoginBackground", () => {
it("updates the most recent id host when a tab is updated", () => {
triggerTabOnUpdatedEvent(
newTabId,
mock<chrome.tabs.TabChangeInfo>({ url: validIpdUrl1 }),
mock<chrome.tabs.OnUpdatedInfo>({ url: validIpdUrl1 }),
newTab,
);
@@ -389,7 +389,7 @@ describe("AutoSubmitLoginBackground", () => {
tabId: newTabId,
};
triggerTabOnRemovedEvent(newTabId, mock<chrome.tabs.TabRemoveInfo>());
triggerTabOnRemovedEvent(newTabId, mock<chrome.tabs.OnRemovedInfo>());
expect(autoSubmitLoginBackground["currentAutoSubmitHostData"]).toStrictEqual({});
});
@@ -403,14 +403,14 @@ describe("AutoSubmitLoginBackground", () => {
tabId: tabId,
};
triggerWebRequestOnBeforeRedirectEvent(
mock<chrome.webRequest.WebRedirectionResponseDetails>({
mock<chrome.webRequest.OnBeforeRedirectDetails>({
url: validIpdUrl1,
redirectUrl: validIpdUrl2,
frameId: 0,
}),
);
triggerWebRequestOnBeforeRedirectEvent(
mock<chrome.webRequest.WebRedirectionResponseDetails>({
mock<chrome.webRequest.OnBeforeRedirectDetails>({
url: validIpdUrl2,
redirectUrl: validAutoSubmitUrl,
frameId: 0,
@@ -418,7 +418,7 @@ describe("AutoSubmitLoginBackground", () => {
);
triggerWebRequestOnBeforeRequestEvent(
mock<chrome.webRequest.WebRequestBodyDetails>({
mock<chrome.webRequest.WebRequestDetails>({
tabId: tabId,
url: `https://${validAutoSubmitHost}`,
initiator: null,

View File

@@ -161,7 +161,9 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
*
* @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 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.
*/
private postRequestEncounteredAfterSubmission = (
details: chrome.webRequest.WebRequestBodyDetails,
details: chrome.webRequest.OnBeforeRequestDetails,
isValidInitiator: boolean,
) => {
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.
*/
private requestRedirectsToInvalidHost = (
details: chrome.webRequest.WebRequestBodyDetails,
details: chrome.webRequest.OnBeforeRequestDetails,
isValidInitiator: boolean,
) => {
return (
@@ -221,7 +223,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
*
* @param details - The details of the request.
*/
private setupAutoSubmitFlow = (details: chrome.webRequest.WebRequestBodyDetails) => {
private setupAutoSubmitFlow = (details: chrome.webRequest.OnBeforeRequestDetails) => {
if (this.isRequestInMainFrame(details)) {
this.currentAutoSubmitHostData = {
url: details.url,
@@ -288,7 +290,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
* @param details - The details of the request.
*/
private handleWebRequestOnBeforeRedirect = (
details: chrome.webRequest.WebRedirectionResponseDetails,
details: chrome.webRequest.OnBeforeRedirectDetails,
) => {
if (this.isRequestInMainFrame(details) && this.urlContainsAutoSubmitHash(details.redirectUrl)) {
this.validAutoSubmitHosts.add(this.getUrlHost(details.redirectUrl));
@@ -354,7 +356,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
*/
private disableAutoSubmitFlow = async (
requestInitiator: string,
details: chrome.webRequest.WebRequestBodyDetails,
details: chrome.webRequest.OnBeforeRequestDetails,
) => {
if (this.isValidAutoSubmitHost(requestInitiator)) {
this.removeUrlFromAutoSubmitHosts(requestInitiator);
@@ -390,7 +392,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
* @param initiator - The initiator of the request.
*/
private shouldRouteTriggerAutoSubmit = (
details: chrome.webRequest.ResourceRequest,
details: chrome.webRequest.OnBeforeRequestDetails,
initiator: string,
) => {
if (this.isRequestInMainFrame(details)) {
@@ -449,7 +451,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
*
* @param details - The details of the request.
*/
private getRequestInitiator = (details: chrome.webRequest.ResourceRequest) => {
private getRequestInitiator = (details: chrome.webRequest.OnBeforeRequestDetails) => {
if (!this.isSafariBrowser) {
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.
*/
private isRequestInMainFrame = (details: chrome.webRequest.ResourceRequest) => {
private isRequestInMainFrame = (
details: SetPartial<
chrome.webRequest.WebRequestDetails,
"documentId" | "documentLifecycle" | "frameType"
>,
) => {
if (this.isSafariBrowser) {
return details.frameId === 0;
}
@@ -545,7 +552,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
*
* @param activeInfo - The active tab information.
*/
private handleSafariTabOnActivated = async (activeInfo: chrome.tabs.TabActiveInfo) => {
private handleSafariTabOnActivated = async (activeInfo: chrome.tabs.OnActivatedInfo) => {
if (activeInfo.tabId < 0) {
return;
}
@@ -562,7 +569,7 @@ export class AutoSubmitLoginBackground implements AutoSubmitLoginBackgroundAbstr
* @param tabId - The tab ID associated with the URL.
* @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) {
this.setMostRecentIdpHost(changeInfo.url, tabId);
}

View File

@@ -385,7 +385,7 @@ describe("OverlayNotificationsBackground", () => {
it("ignores requests that are not part of an active form submission", async () => {
triggerWebRequestOnCompletedEvent(
mock<chrome.webRequest.WebResponseDetails>({
mock<chrome.webRequest.OnCompletedDetails>({
url: sender.url,
tabId: sender.tab.id,
requestId: "123345",
@@ -409,7 +409,7 @@ describe("OverlayNotificationsBackground", () => {
await flushPromises();
triggerWebRequestOnCompletedEvent(
mock<chrome.webRequest.WebResponseDetails>({
mock<chrome.webRequest.OnCompletedDetails>({
url: sender.url,
tabId: sender.tab.id,
requestId,
@@ -438,7 +438,7 @@ describe("OverlayNotificationsBackground", () => {
await flushPromises();
triggerWebRequestOnCompletedEvent(
mock<chrome.webRequest.WebResponseDetails>({
mock<chrome.webRequest.OnCompletedDetails>({
url: sender.url,
tabId: sender.tab.id,
statusCode: 404,
@@ -492,7 +492,7 @@ describe("OverlayNotificationsBackground", () => {
);
});
triggerWebRequestOnCompletedEvent(
mock<chrome.webRequest.WebResponseDetails>({
mock<chrome.webRequest.OnCompletedDetails>({
url: sender.url,
tabId: sender.tab.id,
requestId,
@@ -541,7 +541,7 @@ describe("OverlayNotificationsBackground", () => {
});
triggerWebRequestOnCompletedEvent(
mock<chrome.webRequest.WebResponseDetails>({
mock<chrome.webRequest.OnCompletedDetails>({
url: sender.url,
tabId: sender.tab.id,
requestId,
@@ -643,7 +643,7 @@ describe("OverlayNotificationsBackground", () => {
});
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);
});
@@ -652,7 +652,7 @@ describe("OverlayNotificationsBackground", () => {
it("skips clearing the website origins if the changeInfo does not contain a `loading` status", () => {
triggerTabOnUpdatedEvent(
sender.tab.id,
mock<chrome.tabs.TabChangeInfo>({ status: "complete" }),
mock<chrome.tabs.OnUpdatedInfo>({ 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", () => {
triggerTabOnUpdatedEvent(
sender.tab.id,
mock<chrome.tabs.TabChangeInfo>({ status: "loading", url: "" }),
mock<chrome.tabs.OnUpdatedInfo>({ status: "loading", url: "" }),
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", () => {
triggerTabOnUpdatedEvent(
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 }),
);
@@ -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", () => {
triggerTabOnUpdatedEvent(
sender.tab.id,
mock<chrome.tabs.TabChangeInfo>({
mock<chrome.tabs.OnUpdatedInfo>({
status: "loading",
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", () => {
triggerTabOnUpdatedEvent(
sender.tab.id,
mock<chrome.tabs.TabChangeInfo>({ status: "loading" }),
mock<chrome.tabs.OnUpdatedInfo>({ status: "loading" }),
mock<chrome.tabs.Tab>({ status: "loading" }),
);

View File

@@ -228,7 +228,9 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
*
* @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)) {
this.setupNotificationInitTrigger(
details.tabId,
@@ -275,7 +277,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
*
* @param details - The details of the web request
*/
private isPostSubmissionFormRedirection = (details: chrome.webRequest.WebRequestDetails) => {
private isPostSubmissionFormRedirection = (details: chrome.webRequest.OnBeforeRequestDetails) => {
return (
details.method?.toUpperCase() === "GET" &&
this.activeFormSubmissionRequests.has(details.requestId) &&
@@ -289,7 +291,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
*
* @param details - The details of the web request
*/
private isValidFormSubmissionRequest = (details: chrome.webRequest.WebRequestDetails) => {
private isValidFormSubmissionRequest = (details: chrome.webRequest.OnBeforeRequestDetails) => {
return (
!this.requestHostIsInvalid(details) &&
this.formSubmissionRequestMethods.has(details.method?.toUpperCase())
@@ -325,7 +327,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
*
* @param details - The details of the web response
*/
private handleOnCompletedRequestEvent = async (details: chrome.webRequest.WebResponseDetails) => {
private handleOnCompletedRequestEvent = async (details: chrome.webRequest.OnCompletedDetails) => {
if (
this.requestHostIsInvalid(details) ||
!this.activeFormSubmissionRequests.has(details.requestId)
@@ -382,8 +384,8 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
* @param modifyLoginData - The modified login form data
*/
private delayNotificationInitUntilTabIsComplete = async (
tabId: chrome.webRequest.ResourceRequest["tabId"],
requestId: chrome.webRequest.ResourceRequest["requestId"],
tabId: chrome.webRequest.WebRequestDetails["tabId"],
requestId: chrome.webRequest.WebRequestDetails["requestId"],
modifyLoginData: ModifyLoginCipherFormData,
) => {
const handleWebNavigationOnCompleted = async () => {
@@ -403,7 +405,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
* @param tab - The tab details
*/
private processNotifications = async (
requestId: chrome.webRequest.ResourceRequest["requestId"],
requestId: chrome.webRequest.WebRequestDetails["requestId"],
modifyLoginData: ModifyLoginCipherFormData,
tab: chrome.tabs.Tab,
config: { skippable: NotificationType[] } = { skippable: [] },
@@ -477,7 +479,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
* @param tab - The tab details
*/
private clearCompletedWebRequest = (
requestId: chrome.webRequest.ResourceRequest["requestId"],
requestId: chrome.webRequest.WebRequestDetails["requestId"],
tabId: chrome.tabs.Tab["id"],
) => {
this.activeFormSubmissionRequests.delete(requestId);
@@ -492,7 +494,12 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
*
* @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;
};
@@ -553,7 +560,7 @@ export class OverlayNotificationsBackground implements OverlayNotificationsBackg
* @param tabId - The id of the tab that was updated
* @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) {
return;
}

View File

@@ -3371,7 +3371,7 @@ describe("OverlayBackground", () => {
});
await flushPromises();
triggerWebRequestOnCompletedEvent(
mock<chrome.webRequest.WebResponseCacheDetails>({
mock<chrome.webRequest.OnCompletedDetails>({
statusCode: 401,
}),
);
@@ -3391,7 +3391,7 @@ describe("OverlayBackground", () => {
});
await flushPromises();
triggerWebRequestOnCompletedEvent(
mock<chrome.webRequest.WebResponseCacheDetails>({
mock<chrome.webRequest.OnCompletedDetails>({
statusCode: 200,
}),
);

View File

@@ -1238,7 +1238,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
* @param details - The web request details
*/
private handlePasskeyAuthenticationOnCompleted = (
details: chrome.webRequest.WebResponseCacheDetails,
details: chrome.webRequest.OnCompletedDetails,
) => {
chrome.webRequest.onCompleted.removeListener(this.handlePasskeyAuthenticationOnCompleted);

View File

@@ -81,7 +81,7 @@ export default class TabsBackground {
*/
private handleTabOnUpdated = async (
tabId: number,
changeInfo: chrome.tabs.TabChangeInfo,
changeInfo: chrome.tabs.OnUpdatedInfo,
tab: chrome.tabs.Tab,
) => {
if (this.focusedWindowId > 0 && tab.windowId !== this.focusedWindowId) {

View File

@@ -26,7 +26,10 @@ export default class WebRequestBackground {
startListening() {
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 (callback) {
callback(null);
@@ -42,7 +45,7 @@ export default class WebRequestBackground {
} else {
await this.resolveAuthCredentials(details.url, callback, callback);
}
},
}) as any,
{ urls: ["http://*/*", "https://*/*"] },
[this.isFirefox ? "blocking" : "asyncBlocking"],
);
@@ -50,16 +53,17 @@ export default class WebRequestBackground {
this.webRequest.onCompleted.addListener((details) => this.completeAuthRequest(details), {
urls: ["http://*/*"],
});
this.webRequest.onErrorOccurred.addListener(
(details: any) => this.completeAuthRequest(details),
{
urls: ["http://*/*"],
},
);
this.webRequest.onErrorOccurred.addListener((details) => this.completeAuthRequest(details), {
urls: ["http://*/*"],
});
}
// eslint-disable-next-line
private async resolveAuthCredentials(domain: string, success: Function, error: Function) {
private async resolveAuthCredentials(
domain: string,
success: (response: chrome.webRequest.BlockingResponse) => void,
// eslint-disable-next-line
error: Function,
) {
const activeUserId = await firstValueFrom(
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);
}
}

View File

@@ -218,7 +218,10 @@ export class Fido2Background implements Fido2BackgroundInterface {
tabId: tab.id,
injectDetails: { frame: "all_frames", ...this.sharedInjectionDetails },
mv2Details: { file: await this.getFido2PageScriptAppendFileName() },
mv3Details: { file: Fido2ContentScript.PageScript, world: "MAIN" },
mv3Details: {
file: Fido2ContentScript.PageScript,
world: chrome.scripting.ExecutionWorld.MAIN,
},
});
void this.scriptInjectorService.inject({

View File

@@ -75,7 +75,7 @@ describe("Fido2 Content Script", () => {
data: mock<InsecureCreateCredentialParams>(),
});
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
// eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -167,7 +167,9 @@ describe("Fido2 Content Script", () => {
data: mock<InsecureCreateCredentialParams>(),
});
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
// eslint-disable-next-line @typescript-eslint/no-require-imports

View File

@@ -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(
(call) => {
const callback = call[0];
@@ -98,7 +98,7 @@ export function triggerTabOnReplacedEvent(addedTabId: number, removedTabId: numb
export function triggerTabOnUpdatedEvent(
tabId: number,
changeInfo: chrome.tabs.TabChangeInfo,
changeInfo: chrome.tabs.OnUpdatedInfo,
tab: chrome.tabs.Tab,
) {
(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) => {
const callback = call[0];
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(
(call) => {
const callback = call[0];

View File

@@ -46,7 +46,7 @@ export default class IdleBackground {
if (this.idle.onStateChanged) {
this.idle.onStateChanged.addListener(
async (newState: chrome.idle.IdleState | browser.idle.IdleState) => {
async (newState: `${chrome.idle.IdleState}` | browser.idle.IdleState) => {
if (newState === "locked") {
// Need to check if any of the current users have their timeout set to `onLocked`
const allUsers = await firstValueFrom(this.accountService.accounts$);

View File

@@ -230,7 +230,7 @@ export class PhishingDetectionService {
*/
private static async _processNavigation(
tabId: number,
changeInfo: chrome.tabs.TabChangeInfo,
changeInfo: chrome.tabs.OnUpdatedInfo,
tab: chrome.tabs.Tab,
): Promise<void> {
if (changeInfo.status !== "complete" || !tab.url) {
@@ -253,7 +253,7 @@ export class PhishingDetectionService {
private static _handleNavigationEvent(
tabId: number,
changeInfo: chrome.tabs.TabChangeInfo,
changeInfo: chrome.tabs.OnUpdatedInfo,
tab: chrome.tabs.Tab,
): boolean {
this._navigationEventsSubject.next({ tabId, changeInfo, tab });

View File

@@ -30,6 +30,6 @@ export type CaughtPhishingDomain = {
export type PhishingDetectionNavigationEvent = {
tabId: number;
changeInfo: chrome.tabs.TabChangeInfo;
changeInfo: chrome.tabs.OnUpdatedInfo;
tab: chrome.tabs.Tab;
};

View File

@@ -141,8 +141,24 @@ function buildRegisterContentScriptsPolyfill() {
return [possibleArray];
}
function arrayOrUndefined(value?: number) {
return value === undefined ? undefined : [value];
function createTarget(
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(
@@ -170,15 +186,17 @@ function buildRegisterContentScriptsPolyfill() {
}
if (gotScripting) {
return chrome.scripting.insertCSS({
target: {
tabId,
frameIds: arrayOrUndefined(frameId),
allFrames: frameId === undefined ? allFrames : undefined,
},
files: "file" in content ? [content.file] : undefined,
css: "code" in content ? content.code : undefined,
});
if ("file" in content) {
return chrome.scripting.insertCSS({
target: createTarget(tabId, frameId, allFrames),
files: [content.file],
});
} else {
return chrome.scripting.insertCSS({
target: createTarget(tabId, frameId, allFrames),
css: content.code,
});
}
}
return chromeProxy.tabs.insertCSS(tabId, {
@@ -226,11 +244,7 @@ function buildRegisterContentScriptsPolyfill() {
if (gotScripting) {
assertNoCode(normalizedFiles);
const injection = chrome.scripting.executeScript({
target: {
tabId,
frameIds: arrayOrUndefined(frameId),
allFrames: frameId === undefined ? allFrames : undefined,
},
target: createTarget(tabId, frameId, allFrames),
files: normalizedFiles.map(({ file }: { file: string }) => file),
});
@@ -397,7 +411,7 @@ function buildRegisterContentScriptsPolyfill() {
};
const tabListener = async (
tabId: number,
{ status }: chrome.tabs.TabChangeInfo,
{ status }: chrome.tabs.OnUpdatedInfo,
{ url }: chrome.tabs.Tab,
) => {
if (status === "loading" && url) {

View File

@@ -375,7 +375,7 @@ describe("BrowserApi", () => {
describe("executeScriptInTab", () => {
it("calls to the extension api to execute a script within the give tabId", async () => {
const tabId = 1;
const injectDetails = mock<chrome.tabs.InjectDetails>();
const injectDetails = mock<chrome.extensionTypes.InjectDetails>();
jest.spyOn(BrowserApi, "manifestVersion", "get").mockReturnValue(2);
(chrome.tabs.executeScript as jest.Mock).mockImplementation(
(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 () => {
const tabId = 1;
const injectDetails = mock<chrome.tabs.InjectDetails>({
const injectDetails = mock<chrome.extensionTypes.InjectDetails>({
file: "file.js",
allFrames: true,
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 () => {
const tabId = 1;
const frameId = 2;
const injectDetails = mock<chrome.tabs.InjectDetails>({
const injectDetails = mock<chrome.extensionTypes.InjectDetails>({
file: "file.js",
allFrames: true,
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 () => {
const tabId = 1;
const injectDetails = mock<chrome.tabs.InjectDetails>({
const injectDetails = mock<chrome.extensionTypes.InjectDetails>({
file: null,
allFrames: true,
runAt: "document_start",

View File

@@ -685,29 +685,27 @@ export class BrowserApi {
*/
static executeScriptInTab(
tabId: number,
details: chrome.tabs.InjectDetails,
details: chrome.extensionTypes.InjectDetails,
scriptingApiDetails?: {
world: chrome.scripting.ExecutionWorld;
},
): Promise<unknown> {
if (BrowserApi.isManifestVersion(3)) {
const target: chrome.scripting.InjectionTarget = {
tabId,
};
let target: chrome.scripting.InjectionTarget;
if (typeof details.frameId === "number") {
target.frameIds = [details.frameId];
}
if (!target.frameIds?.length && details.allFrames) {
target.allFrames = details.allFrames;
target = { tabId, frameIds: [details.frameId] };
} else if (details.allFrames) {
target = { tabId, allFrames: true };
} else {
target = { tabId };
}
return chrome.scripting.executeScript({
target,
files: details.file ? [details.file] : null,
injectImmediately: details.runAt === "document_start",
world: scriptingApiDetails?.world || "ISOLATED",
world: scriptingApiDetails?.world || chrome.scripting.ExecutionWorld.ISOLATED,
});
}

View File

@@ -52,7 +52,7 @@ describe("ChromeStorageApiService", () => {
});
afterEach(() => {
chrome.runtime.lastError = undefined;
(chrome.runtime.lastError as any) = undefined;
});
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 () => {
setMock.mockImplementation((data, callback) => {
chrome.runtime.lastError = new Error("Test Error");
(chrome.runtime.lastError as any) = new Error("Test Error");
callback();
});
@@ -101,7 +101,7 @@ describe("ChromeStorageApiService", () => {
});
afterEach(() => {
chrome.runtime.lastError = undefined;
(chrome.runtime.lastError as any) = undefined;
});
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 () => {
getMock.mockImplementation((key, callback) => {
chrome.runtime.lastError = new Error("Test Error");
(chrome.runtime.lastError as any) = new Error("Test Error");
callback();
chrome.runtime.lastError = undefined;
(chrome.runtime.lastError as any) = undefined;
});
await expect(async () => await service.get("test")).rejects.toThrow("Test Error");

View File

@@ -41,7 +41,10 @@ describe("ScriptInjectorService", () => {
const mv2SpecificFile = "content/autofill-init-mv2.js";
const mv2Details = { file: mv2SpecificFile };
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 = {
runAt: "document_start",
};

View File

@@ -63,7 +63,7 @@ export class BrowserScriptInjectorService extends ScriptInjectorService {
if (BrowserApi.isManifestVersion(3)) {
try {
await BrowserApi.executeScriptInTab(tabId, injectionDetails, {
world: mv3Details?.world ?? "ISOLATED",
world: mv3Details?.world ?? chrome.scripting.ExecutionWorld.ISOLATED,
});
} catch (error) {
// 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(
injectDetails: CommonScriptInjectionDetails,
file: string,
): chrome.tabs.InjectDetails {
): chrome.extensionTypes.InjectDetails {
const { frame, runAt } = injectDetails;
const injectionDetails: chrome.tabs.InjectDetails = { file };
const injectionDetails: chrome.extensionTypes.InjectDetails = { file };
if (runAt) {
injectionDetails.runAt = runAt;

View File

@@ -167,7 +167,7 @@ describe("Browser Utils Service", () => {
it("returns false if special error is sent", async () => {
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.",
);
callback(undefined);
@@ -177,7 +177,7 @@ describe("Browser Utils Service", () => {
expect(isViewOpen).toBe(false);
chrome.runtime.lastError = null;
(chrome.runtime.lastError as any) = null;
});
});

View File

@@ -46,7 +46,7 @@ export class BrowserSystemNotificationService implements SystemNotificationsServ
return new Promise<string>((resolve) => {
const deviceType: DeviceType = this.platformUtilsService.getDevice();
const options: chrome.notifications.NotificationOptions<true> = {
const options: chrome.notifications.NotificationCreateOptions = {
iconUrl: chrome.runtime.getURL("images/icon128.png"),
message: createInfo.body,
type: "basic",
@@ -70,6 +70,7 @@ export class BrowserSystemNotificationService implements SystemNotificationsServ
}
async clear(clearInfo: SystemNotificationClearInfo): Promise<undefined> {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
chrome.notifications.clear(clearInfo.id);
}

View File

@@ -79,6 +79,7 @@ const scripting = {
executeScript: jest.fn(),
registerContentScripts: jest.fn(),
unregisterContentScripts: jest.fn(),
ExecutionWorld: { ISOLATED: "ISOLATED", MAIN: "MAIN" },
};
const windows = {

8
package-lock.json generated
View File

@@ -97,7 +97,7 @@
"@storybook/test-runner": "0.22.0",
"@storybook/theming": "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/inquirer": "8.2.10",
"@types/jest": "29.5.14",
@@ -13377,9 +13377,9 @@
}
},
"node_modules/@types/chrome": {
"version": "0.0.306",
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.306.tgz",
"integrity": "sha512-95kgcqvTNcaZCXmx/kIKY6uo83IaRNT3cuPxYqlB2Iu+HzKDCP4t7TUe7KhJijTdibcvn+SzziIcfSLIlgRnhQ==",
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.12.tgz",
"integrity": "sha512-jEkxs9GPQHx7g49WjkA8QDNcqODbMGDuBbWQOtjiS/Wf9AiEcDmQMIAgJvC/Xi36WoCVNx584g0Dd9ThJQCAiw==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -61,7 +61,7 @@
"@storybook/test-runner": "0.22.0",
"@storybook/theming": "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/inquirer": "8.2.10",
"@types/jest": "29.5.14",