diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index 92f0cc1380..b04acaebc6 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -12,6 +12,7 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherService } from "@bitwarden/common/vault/services/cipher.service"; import { BrowserApi } from "../../platform/browser/browser-api"; +import BrowserPlatformUtilsService from "../../platform/services/browser-platform-utils.service"; import { BrowserStateService } from "../../platform/services/browser-state.service"; import { SHOW_AUTOFILL_BUTTON } from "../constants"; import { @@ -47,6 +48,7 @@ describe("OverlayBackground", () => { const settingsService = mock(); const stateService = mock(); const i18nService = mock(); + const platformUtilsService = mock(); const initOverlayElementPorts = (options = { initList: true, initButton: true }) => { const { initList, initButton } = options; if (initButton) { @@ -71,6 +73,7 @@ describe("OverlayBackground", () => { settingsService, stateService, i18nService, + platformUtilsService, ); overlayBackground.init(); }); @@ -1263,6 +1266,24 @@ describe("OverlayBackground", () => { ]).entries(), ); }); + + it("copies the cipher's totp code to the clipboard after filling", async () => { + const cipher1 = mock({ id: "overlay-cipher-1" }); + overlayBackground["overlayLoginCiphers"] = new Map([["overlay-cipher-1", cipher1]]); + isPasswordRepromptRequiredSpy.mockResolvedValue(false); + const copyToClipboardSpy = jest + .spyOn(overlayBackground["platformUtilsService"], "copyToClipboard") + .mockImplementation(); + doAutoFillSpy.mockReturnValueOnce("totp-code"); + + sendPortMessage(listPortSpy, { + command: "fillSelectedListItem", + overlayCipherId: "overlay-cipher-2", + }); + await flushPromises(); + + expect(copyToClipboardSpy).toHaveBeenCalledWith("totp-code", { window }); + }); }); describe("getNewVaultItemDetails", () => { diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index f760ee22e6..0d4fbc2e60 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -3,6 +3,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -91,6 +92,7 @@ class OverlayBackground implements OverlayBackgroundInterface { private settingsService: SettingsService, private stateService: StateService, private i18nService: I18nService, + private platformUtilsService: PlatformUtilsService, ) { this.iconsServerUrl = this.environmentService.getIconsUrl(); } @@ -227,7 +229,7 @@ class OverlayBackground implements OverlayBackgroundInterface { if (await this.autofillService.isPasswordRepromptRequired(cipher, sender.tab)) { return; } - await this.autofillService.doAutoFill({ + const totpCode = await this.autofillService.doAutoFill({ tab: sender.tab, cipher: cipher, pageDetails: this.pageDetailsForTab[sender.tab.id], @@ -235,6 +237,10 @@ class OverlayBackground implements OverlayBackgroundInterface { allowTotpAutofill: true, }); + if (totpCode) { + this.platformUtilsService.copyToClipboard(totpCode, { window }); + } + this.overlayLoginCiphers = new Map([[overlayCipherId, cipher], ...this.overlayLoginCiphers]); } diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 2eda6e31ca..3568c6bf5e 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -728,6 +728,7 @@ export default class MainBackground { this.settingsService, this.stateService, this.i18nService, + this.platformUtilsService, ); this.filelessImporterBackground = new FilelessImporterBackground( this.configService,