-
+
diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts
index a209523dc7c..0c626c68794 100644
--- a/apps/browser/src/autofill/background/overlay.background.ts
+++ b/apps/browser/src/autofill/background/overlay.background.ts
@@ -139,7 +139,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
this.triggerDestroyInlineMenuListeners(sender.tab, message.subFrameData.frameId),
collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender),
unlockCompleted: ({ message }) => this.unlockCompleted(message),
- doFullSync: () => this.updateOverlayCiphers(true),
+ doFullSync: () => this.updateOverlayCiphers(),
addedCipher: () => this.updateOverlayCiphers(),
addEditCipherSubmitted: () => this.updateOverlayCiphers(),
editedCipher: () => this.updateOverlayCiphers(),
@@ -272,7 +272,10 @@ export class OverlayBackground implements OverlayBackgroundInterface {
this.closeInlineMenuAfterCiphersUpdate().catch((error) => this.logService.error(error));
}
- if (!currentTab) {
+ if (!currentTab || !currentTab.url?.startsWith("http")) {
+ if (updateAllCipherTypes) {
+ this.cardAndIdentityCiphers = null;
+ }
return;
}
diff --git a/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.spec.ts b/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.spec.ts
index d53d9e685ed..f5f8dd770c7 100644
--- a/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.spec.ts
+++ b/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.spec.ts
@@ -4,12 +4,21 @@ describe("FIDO2 page-script for manifest v2", () => {
let createdScriptElement: HTMLScriptElement;
jest.spyOn(window.document, "createElement");
+ beforeEach(() => {
+ jest.useFakeTimers();
+ });
+
afterEach(() => {
Object.defineProperty(window.document, "contentType", { value: "text/html", writable: true });
jest.clearAllMocks();
+ jest.clearAllTimers();
jest.resetModules();
});
+ afterAll(() => {
+ jest.useRealTimers();
+ });
+
it("skips appending the `page-script.js` file if the document contentType is not `text/html`", () => {
Object.defineProperty(window.document, "contentType", { value: "text/plain", writable: true });
@@ -19,7 +28,7 @@ describe("FIDO2 page-script for manifest v2", () => {
});
it("appends the `page-script.js` file to the document head when the contentType is `text/html`", () => {
- jest.spyOn(window.document.head, "insertBefore").mockImplementation((node) => {
+ jest.spyOn(window.document.head, "prepend").mockImplementation((node) => {
createdScriptElement = node as HTMLScriptElement;
return node;
});
@@ -28,16 +37,13 @@ describe("FIDO2 page-script for manifest v2", () => {
expect(window.document.createElement).toHaveBeenCalledWith("script");
expect(chrome.runtime.getURL).toHaveBeenCalledWith(Fido2ContentScript.PageScript);
- expect(window.document.head.insertBefore).toHaveBeenCalledWith(
- expect.any(HTMLScriptElement),
- window.document.head.firstChild,
- );
+ expect(window.document.head.prepend).toHaveBeenCalledWith(expect.any(HTMLScriptElement));
expect(createdScriptElement.src).toBe(`chrome-extension://id/${Fido2ContentScript.PageScript}`);
});
it("appends the `page-script.js` file to the document element if the head is not available", () => {
window.document.documentElement.removeChild(window.document.head);
- jest.spyOn(window.document.documentElement, "insertBefore").mockImplementation((node) => {
+ jest.spyOn(window.document.documentElement, "prepend").mockImplementation((node) => {
createdScriptElement = node as HTMLScriptElement;
return node;
});
@@ -46,9 +52,8 @@ describe("FIDO2 page-script for manifest v2", () => {
expect(window.document.createElement).toHaveBeenCalledWith("script");
expect(chrome.runtime.getURL).toHaveBeenCalledWith(Fido2ContentScript.PageScript);
- expect(window.document.documentElement.insertBefore).toHaveBeenCalledWith(
+ expect(window.document.documentElement.prepend).toHaveBeenCalledWith(
expect.any(HTMLScriptElement),
- window.document.documentElement.firstChild,
);
expect(createdScriptElement.src).toBe(`chrome-extension://id/${Fido2ContentScript.PageScript}`);
});
@@ -63,6 +68,7 @@ describe("FIDO2 page-script for manifest v2", () => {
jest.spyOn(createdScriptElement, "remove");
createdScriptElement.dispatchEvent(new Event("load"));
+ jest.runAllTimers();
expect(createdScriptElement.remove).toHaveBeenCalled();
});
diff --git a/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.ts b/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.ts
index 4e806d29908..e5280c088bc 100644
--- a/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.ts
+++ b/apps/browser/src/autofill/fido2/content/fido2-page-script-append.mv2.ts
@@ -2,18 +2,20 @@
* This script handles injection of the FIDO2 override page script into the document.
* This is required for manifest v2, but will be removed when we migrate fully to manifest v3.
*/
-import { Fido2ContentScript } from "../enums/fido2-content-script.enum";
-
(function (globalContext) {
if (globalContext.document.contentType !== "text/html") {
return;
}
const script = globalContext.document.createElement("script");
- script.src = chrome.runtime.getURL(Fido2ContentScript.PageScript);
- script.addEventListener("load", () => script.remove());
+ script.src = chrome.runtime.getURL("content/fido2-page-script.js");
+ script.addEventListener("load", removeScriptOnLoad);
const scriptInsertionPoint =
globalContext.document.head || globalContext.document.documentElement;
- scriptInsertionPoint.insertBefore(script, scriptInsertionPoint.firstChild);
+ scriptInsertionPoint.prepend(script);
+
+ function removeScriptOnLoad() {
+ globalThis.setTimeout(() => script?.remove(), 5000);
+ }
})(globalThis);
diff --git a/apps/browser/src/autofill/fido2/content/fido2-page-script-delay-append.mv2.ts b/apps/browser/src/autofill/fido2/content/fido2-page-script-delay-append.mv2.ts
index 4afeb76a0d3..c75a37c1b65 100644
--- a/apps/browser/src/autofill/fido2/content/fido2-page-script-delay-append.mv2.ts
+++ b/apps/browser/src/autofill/fido2/content/fido2-page-script-delay-append.mv2.ts
@@ -2,26 +2,35 @@
* This script handles injection of the FIDO2 override page script into the document.
* This is required for manifest v2, but will be removed when we migrate fully to manifest v3.
*/
-import { Fido2ContentScript } from "../enums/fido2-content-script.enum";
-
(function (globalContext) {
if (globalContext.document.contentType !== "text/html") {
return;
}
- if (globalContext.document.readyState === "complete") {
- loadScript();
+ const script = globalContext.document.createElement("script");
+ script.src = chrome.runtime.getURL("content/fido2-page-script.js");
+ script.addEventListener("load", removeScriptOnLoad);
+
+ // We are ensuring that the script injection is delayed in the event that we are loading
+ // within an iframe element. This prevents an issue with web mail clients that load content
+ // using ajax within iframes. In particular, Zimbra web mail client was observed to have this issue.
+ // @see https://github.com/bitwarden/clients/issues/9618
+ const delayScriptInjection =
+ globalContext.window.top !== globalContext.window &&
+ globalContext.document.readyState !== "complete";
+ if (delayScriptInjection) {
+ globalContext.document.addEventListener("DOMContentLoaded", injectScript);
} else {
- globalContext.addEventListener("DOMContentLoaded", loadScript);
+ injectScript();
}
- function loadScript() {
- const script = globalContext.document.createElement("script");
- script.src = chrome.runtime.getURL(Fido2ContentScript.PageScript);
- script.addEventListener("load", () => script.remove());
-
+ function injectScript() {
const scriptInsertionPoint =
globalContext.document.head || globalContext.document.documentElement;
- scriptInsertionPoint.insertBefore(script, scriptInsertionPoint.firstChild);
+ scriptInsertionPoint.prepend(script);
+ }
+
+ function removeScriptOnLoad() {
+ globalThis.setTimeout(() => script?.remove(), 5000);
}
})(globalThis);
diff --git a/apps/browser/src/autofill/fido2/content/messaging/message.ts b/apps/browser/src/autofill/fido2/content/messaging/message.ts
index d42c10a5d88..5815be9eb60 100644
--- a/apps/browser/src/autofill/fido2/content/messaging/message.ts
+++ b/apps/browser/src/autofill/fido2/content/messaging/message.ts
@@ -18,7 +18,7 @@ export enum MessageType {
}
/**
- * The params provided by the page-script are created in an insecure environemnt and
+ * The params provided by the page-script are created in an insecure environment and
* should not be trusted. This type is used to ensure that the content-script does not
* trust the `origin` or `sameOriginWithAncestors` params.
*/
@@ -38,7 +38,7 @@ export type CredentialCreationResponse = {
};
/**
- * The params provided by the page-script are created in an insecure environemnt and
+ * The params provided by the page-script are created in an insecure environment and
* should not be trusted. This type is used to ensure that the content-script does not
* trust the `origin` or `sameOriginWithAncestors` params.
*/
diff --git a/apps/browser/src/autofill/popup/fido2/fido2-cipher-row-v1.component.html b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row-v1.component.html
new file mode 100644
index 00000000000..852fd4a0e81
--- /dev/null
+++ b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row-v1.component.html
@@ -0,0 +1,36 @@
+
+
+
+
+
diff --git a/apps/browser/src/autofill/popup/fido2/fido2-cipher-row-v1.component.ts b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row-v1.component.ts
new file mode 100644
index 00000000000..d9d492bdcc1
--- /dev/null
+++ b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row-v1.component.ts
@@ -0,0 +1,39 @@
+import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from "@angular/core";
+
+import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
+
+@Component({
+ selector: "app-fido2-cipher-row-v1",
+ templateUrl: "fido2-cipher-row-v1.component.html",
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class Fido2CipherRowV1Component {
+ @Output() onSelected = new EventEmitter();
+ @Input() cipher: CipherView;
+ @Input() last: boolean;
+ @Input() title: string;
+ @Input() isSearching: boolean;
+ @Input() isSelected: boolean;
+
+ protected selectCipher(c: CipherView) {
+ this.onSelected.emit(c);
+ }
+
+ /**
+ * Returns a subname for the cipher.
+ * If this has a FIDO2 credential, and the cipher.name is different from the FIDO2 credential's rpId, return the rpId.
+ * @param c Cipher
+ * @returns
+ */
+ protected getSubName(c: CipherView): string | null {
+ const fido2Credentials = c.login?.fido2Credentials;
+
+ if (!fido2Credentials || fido2Credentials.length === 0) {
+ return null;
+ }
+
+ const [fido2Credential] = fido2Credentials;
+
+ return c.name !== fido2Credential.rpId ? fido2Credential.rpId : null;
+ }
+}
diff --git a/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.html b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.html
index 852fd4a0e81..0328a91bff5 100644
--- a/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.html
+++ b/apps/browser/src/autofill/popup/fido2/fido2-cipher-row.component.html
@@ -1,36 +1,21 @@
-