From d3cb27325698682d0002bd52ffa30600b9e629d2 Mon Sep 17 00:00:00 2001 From: Jonathan Prusik Date: Wed, 18 Oct 2023 12:40:50 -0400 Subject: [PATCH] [PM-4141] Bugfix - Non-Premium accounts can autofill TOTP codes with the autofill keyboard shortcut (#6496) * null totp seed from retrieved login cipher for autofill if the account does not have access to premium features * update tests --- .../services/autofill.service.spec.ts | 25 ++++++++++++++++--- .../src/autofill/services/autofill.service.ts | 5 ++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/browser/src/autofill/services/autofill.service.spec.ts b/apps/browser/src/autofill/services/autofill.service.spec.ts index f8f12fa7dd..544b0da1a5 100644 --- a/apps/browser/src/autofill/services/autofill.service.spec.ts +++ b/apps/browser/src/autofill/services/autofill.service.spec.ts @@ -519,8 +519,9 @@ describe("AutofillService", () => { it("returns a TOTP value", async () => { const totpCode = "123456"; autofillOptions.cipher.login.totp = "totp"; - jest.spyOn(stateService, "getDisableAutoTotpCopy").mockResolvedValueOnce(false); - jest.spyOn(totpService, "getCode").mockReturnValueOnce(Promise.resolve(totpCode)); + jest.spyOn(stateService, "getCanAccessPremium").mockResolvedValue(true); + jest.spyOn(stateService, "getDisableAutoTotpCopy").mockResolvedValue(false); + jest.spyOn(totpService, "getCode").mockResolvedValue(totpCode); const autofillResult = await autofillService.doAutoFill(autofillOptions); @@ -529,6 +530,18 @@ describe("AutofillService", () => { expect(autofillResult).toBe(totpCode); }); + it("does not return a TOTP value if the user does not have premium features", async () => { + autofillOptions.cipher.login.totp = "totp"; + jest.spyOn(stateService, "getCanAccessPremium").mockResolvedValue(false); + jest.spyOn(stateService, "getDisableAutoTotpCopy").mockResolvedValue(false); + + const autofillResult = await autofillService.doAutoFill(autofillOptions); + + expect(stateService.getDisableAutoTotpCopy).not.toHaveBeenCalled(); + expect(totpService.getCode).not.toHaveBeenCalled(); + expect(autofillResult).toBeNull(); + }); + it("returns a null value if the cipher type is not for a Login", async () => { autofillOptions.cipher.type = CipherType.Identity; autofillOptions.cipher.identity = mock(); @@ -563,11 +576,15 @@ describe("AutofillService", () => { it("returns a null value if the user has disabled `auto TOTP copy`", async () => { autofillOptions.cipher.login.totp = "totp"; autofillOptions.cipher.organizationUseTotp = true; - jest.spyOn(stateService, "getCanAccessPremium").mockResolvedValueOnce(true); - jest.spyOn(stateService, "getDisableAutoTotpCopy").mockResolvedValueOnce(true); + jest.spyOn(stateService, "getCanAccessPremium").mockResolvedValue(true); + jest.spyOn(stateService, "getDisableAutoTotpCopy").mockResolvedValue(true); + jest.spyOn(totpService, "getCode"); const autofillResult = await autofillService.doAutoFill(autofillOptions); + expect(stateService.getCanAccessPremium).toHaveBeenCalled(); + expect(stateService.getDisableAutoTotpCopy).toHaveBeenCalled(); + expect(totpService.getCode).not.toHaveBeenCalled(); expect(autofillResult).toBeNull(); }); }); diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index aca7256228..8ab2002775 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -153,6 +153,10 @@ export default class AutofillService implements AutofillServiceInterface { const canAccessPremium = await this.stateService.getCanAccessPremium(); const defaultUriMatch = (await this.stateService.getDefaultUriMatch()) ?? UriMatchType.Domain; + if (!canAccessPremium) { + options.cipher.login.totp = null; + } + let didAutofill = false; await Promise.all( options.pageDetails.map(async (pd) => { @@ -203,6 +207,7 @@ export default class AutofillService implements AutofillServiceInterface { { frameId: pd.frameId } ); + // Skip getting the TOTP code for clipboard in these cases if ( options.cipher.type !== CipherType.Login || totp !== null ||