[PM-29521]Remove ts strict ignore in fido 2 background (#19473)

* [PM-29521]Remove @ts-strict-ignore in fido2.background.ts

* reduce expanded pattern used while testing

* Update apps/browser/src/autofill/fido2/background/fido2.background.ts

Co-authored-by: Jonathan Prusik <jprusik@users.noreply.github.com>

* account for slash or colon on local host

* fix lint format

---------

Co-authored-by: Jonathan Prusik <jprusik@users.noreply.github.com>
This commit is contained in:
Daniel Riera 2026-03-11 08:10:11 -04:00 committed by GitHub
parent 0465bb2fb1
commit 628d155498
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,5 +1,3 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { firstValueFrom, startWith, Subscription } from "rxjs";
import { pairwise } from "rxjs/operators";
@ -32,11 +30,12 @@ import {
} from "./abstractions/fido2.background";
export class Fido2Background implements Fido2BackgroundInterface {
private currentAuthStatus$: Subscription;
private currentAuthStatus$: Subscription = Subscription.EMPTY;
private abortManager = new AbortManager();
private fido2ContentScriptPortsSet = new Set<chrome.runtime.Port>();
private activeCredentialRequests = new Set<number>();
private registeredContentScripts: browser.contentScripts.RegisteredContentScript;
private registeredContentScripts: browser.contentScripts.RegisteredContentScript | undefined =
undefined;
private readonly sharedInjectionDetails: SharedFido2ScriptInjectionDetails = {
runAt: "document_start",
};
@ -85,7 +84,11 @@ export class Fido2Background implements Fido2BackgroundInterface {
.subscribe(([previous, current]) => this.handleEnablePasskeysUpdate(previous, current));
this.currentAuthStatus$ = this.authService.activeAccountStatus$
.pipe(startWith(undefined), pairwise())
.subscribe(([_previous, current]) => this.handleAuthStatusUpdate(current));
.subscribe(([_previous, current]) => {
if (current !== undefined) {
void this.handleAuthStatusUpdate(current);
}
});
}
/**
@ -113,8 +116,12 @@ export class Fido2Background implements Fido2BackgroundInterface {
for (let index = 0; index < tabs.length; index++) {
const tab = tabs[index];
if (tab.url?.startsWith("https")) {
const url = tab.url ?? "";
if (
url.startsWith("https://") ||
url.startsWith("http://localhost/") ||
url.startsWith("http://localhost:")
) {
void this.injectFido2ContentScripts(tab);
}
}
@ -137,14 +144,14 @@ export class Fido2Background implements Fido2BackgroundInterface {
* @param enablePasskeys - The new value of the enablePasskeys setting.
*/
private async handleEnablePasskeysUpdate(
previousEnablePasskeysSetting: boolean,
enablePasskeys: boolean,
previousEnablePasskeysSetting: boolean | undefined,
enablePasskeys: boolean | undefined,
) {
if ((await this.getAuthStatus()) === AuthenticationStatus.LoggedOut) {
return;
}
if (previousEnablePasskeysSetting === undefined) {
if (previousEnablePasskeysSetting === undefined || enablePasskeys === undefined) {
return;
}
@ -178,7 +185,7 @@ export class Fido2Background implements Fido2BackgroundInterface {
private async updateMv2ContentScriptsRegistration() {
if (!(await this.isPasskeySettingEnabled())) {
await this.registeredContentScripts?.unregister();
this.registeredContentScripts = undefined;
return;
}
@ -225,8 +232,12 @@ export class Fido2Background implements Fido2BackgroundInterface {
* @param tab - The current tab to inject the scripts into.
*/
private async injectFido2ContentScripts(tab: chrome.tabs.Tab): Promise<void> {
const tabId = tab.id;
if (tabId == null) {
return;
}
void this.scriptInjectorService.inject({
tabId: tab.id,
tabId,
injectDetails: { frame: "all_frames", ...this.sharedInjectionDetails },
mv2Details: { file: await this.getFido2PageScriptAppendFileName() },
mv3Details: {
@ -236,7 +247,7 @@ export class Fido2Background implements Fido2BackgroundInterface {
});
void this.scriptInjectorService.inject({
tabId: tab.id,
tabId,
injectDetails: {
file: Fido2ContentScript.ContentScript,
frame: "all_frames",
@ -250,10 +261,10 @@ export class Fido2Background implements Fido2BackgroundInterface {
* and disconnects them, destroying the content scripts.
*/
private destroyLoadedFido2ContentScripts() {
this.fido2ContentScriptPortsSet.forEach((port) => {
for (const port of this.fido2ContentScriptPortsSet) {
port.disconnect();
this.fido2ContentScriptPortsSet.delete(port);
});
}
this.fido2ContentScriptPortsSet.clear();
}
/**
@ -262,7 +273,9 @@ export class Fido2Background implements Fido2BackgroundInterface {
* @param message - The FIDO2 extension message containing the requestId to abort.
*/
private abortRequest(message: Fido2ExtensionMessage) {
this.abortManager.abort(message.abortedRequestId);
if (message.abortedRequestId != null) {
this.abortManager.abort(message.abortedRequestId);
}
}
/**
@ -277,8 +290,13 @@ export class Fido2Background implements Fido2BackgroundInterface {
): Promise<CreateCredentialResult> {
return await this.handleCredentialRequest<CreateCredentialResult>(
message,
sender.tab,
this.fido2ClientService.createCredential.bind(this.fido2ClientService),
sender.tab!,
(data, tabParam, abortController) =>
this.fido2ClientService.createCredential(
data as CreateCredentialParams,
tabParam,
abortController,
),
);
}
@ -294,8 +312,13 @@ export class Fido2Background implements Fido2BackgroundInterface {
): Promise<AssertCredentialResult> {
return await this.handleCredentialRequest<AssertCredentialResult>(
message,
sender.tab,
this.fido2ClientService.assertCredential.bind(this.fido2ClientService),
sender.tab!,
(data, tabParam, abortController) =>
this.fido2ClientService.assertCredential(
data as AssertCredentialParams,
tabParam,
abortController,
),
);
}
@ -309,27 +332,37 @@ export class Fido2Background implements Fido2BackgroundInterface {
* @param tab - The tab associated with the request.
* @param callback - The callback to call with the request data, tab, and abort controller.
*/
private handleCredentialRequest = async <T>(
{ requestId, data }: Fido2ExtensionMessage,
private handleCredentialRequest = async <CredentialResult>(
message: Fido2ExtensionMessage,
tab: chrome.tabs.Tab,
callback: (
data: AssertCredentialParams | CreateCredentialParams,
tab: chrome.tabs.Tab,
abortController: AbortController,
) => Promise<T>,
) => {
this.activeCredentialRequests.add(tab.id);
) => Promise<CredentialResult>,
): Promise<CredentialResult> => {
const { requestId, data } = message;
const tabId = tab.id;
if (tabId != null) {
this.activeCredentialRequests.add(tabId);
}
try {
return await this.abortManager.runWithAbortController(requestId, async (abortController) => {
return await this.abortManager.runWithAbortController(requestId!, async (abortController) => {
try {
return await callback(data, tab, abortController);
return await callback(data!, tab, abortController);
} finally {
await BrowserApi.focusTab(tab.id);
await BrowserApi.focusWindow(tab.windowId);
if (tab.id != null) {
await BrowserApi.focusTab(tab.id);
}
if (tab.windowId != null) {
await BrowserApi.focusWindow(tab.windowId);
}
}
});
} finally {
this.activeCredentialRequests.delete(tab.id);
if (tabId != null) {
this.activeCredentialRequests.delete(tabId);
}
}
};
@ -352,15 +385,26 @@ export class Fido2Background implements Fido2BackgroundInterface {
message: Fido2ExtensionMessage,
sender: chrome.runtime.MessageSender,
sendResponse: (response?: any) => void,
) => {
): boolean | void => {
const handler: CallableFunction | undefined = this.extensionMessageHandlers[message?.command];
if (!handler) {
return null;
return;
}
const isCredentialCommand =
message?.command === "fido2RegisterCredentialRequest" ||
message?.command === "fido2GetCredentialRequest";
if (
isCredentialCommand &&
(sender.tab == null || message.requestId == null || message.data == null)
) {
sendResponse(undefined);
return true;
}
const messageResponse = handler({ message, sender });
if (typeof messageResponse === "undefined") {
return null;
return;
}
Promise.resolve(messageResponse)