1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 13:23:34 +00:00

Viewing a cipher from autofill menu should retrigger the password reprompt. (#13969)

* Extend the password reprompt to the view cipher method.

* Handle password reprompt in view cipher component.

* Remove possible out-of-date comment.

* Use new constant for view item load action.

* Revert "Remove possible out-of-date comment."

This reverts commit 4c30aaacb423f5bcb40c6a8cb9240076267a003d.

* Mock the password reprompt service.

* Remove redundant view-item LoadAction.

---------

Co-authored-by: Robyn MacCallum <robyntmaccallum@gmail.com>
This commit is contained in:
Miles Blackwood
2025-04-03 12:46:40 -04:00
committed by GitHub
parent 2ceb8272b7
commit 34ddf77872
3 changed files with 24 additions and 3 deletions

View File

@@ -2100,6 +2100,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
} }
this.closeInlineMenu(sender); this.closeInlineMenu(sender);
await this.openViewVaultItemPopout(sender.tab, { await this.openViewVaultItemPopout(sender.tab, {
cipherId: cipher.id, cipherId: cipher.id,
action: SHOW_AUTOFILL_BUTTON, action: SHOW_AUTOFILL_BUTTON,

View File

@@ -24,7 +24,7 @@ import { CipherType } from "@bitwarden/common/vault/enums";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service";
import { DialogService, ToastService } from "@bitwarden/components"; import { DialogService, ToastService } from "@bitwarden/components";
import { CopyCipherFieldService } from "@bitwarden/vault"; import { CopyCipherFieldService, PasswordRepromptService } from "@bitwarden/vault";
import { BrowserApi } from "../../../../../platform/browser/browser-api"; import { BrowserApi } from "../../../../../platform/browser/browser-api";
import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils";
@@ -51,6 +51,7 @@ describe("ViewV2Component", () => {
const openSimpleDialog = jest.fn().mockResolvedValue(true); const openSimpleDialog = jest.fn().mockResolvedValue(true);
const stop = jest.fn(); const stop = jest.fn();
const showToast = jest.fn(); const showToast = jest.fn();
const showPasswordPrompt = jest.fn().mockResolvedValue(true);
const getFeatureFlag$ = jest.fn().mockReturnValue(of(true)); const getFeatureFlag$ = jest.fn().mockReturnValue(of(true));
const mockCipher = { const mockCipher = {
@@ -64,6 +65,9 @@ describe("ViewV2Component", () => {
}, },
} as unknown as CipherView; } as unknown as CipherView;
const mockPasswordRepromptService = {
showPasswordPrompt,
};
const mockVaultPopupAutofillService = { const mockVaultPopupAutofillService = {
doAutofill, doAutofill,
}; };
@@ -91,6 +95,7 @@ describe("ViewV2Component", () => {
openSimpleDialog.mockClear(); openSimpleDialog.mockClear();
back.mockClear(); back.mockClear();
showToast.mockClear(); showToast.mockClear();
showPasswordPrompt.mockClear();
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [ViewV2Component], imports: [ViewV2Component],
@@ -132,6 +137,10 @@ describe("ViewV2Component", () => {
provide: CopyCipherFieldService, provide: CopyCipherFieldService,
useValue: mockCopyCipherFieldService, useValue: mockCopyCipherFieldService,
}, },
{
provide: PasswordRepromptService,
useValue: mockPasswordRepromptService,
},
], ],
}) })
.overrideProvider(DialogService, { .overrideProvider(DialogService, {

View File

@@ -29,7 +29,7 @@ import { UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service"; import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service"; import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service";
import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service";
import { import {
@@ -46,6 +46,7 @@ import {
CipherViewComponent, CipherViewComponent,
CopyCipherFieldService, CopyCipherFieldService,
DefaultChangeLoginPasswordService, DefaultChangeLoginPasswordService,
PasswordRepromptService,
} from "@bitwarden/vault"; } from "@bitwarden/vault";
import { BrowserApi } from "../../../../../platform/browser/browser-api"; import { BrowserApi } from "../../../../../platform/browser/browser-api";
@@ -113,6 +114,7 @@ export class ViewV2Component {
protected showFooter$: Observable<boolean>; protected showFooter$: Observable<boolean>;
constructor( constructor(
private passwordRepromptService: PasswordRepromptService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private i18nService: I18nService, private i18nService: I18nService,
@@ -283,7 +285,10 @@ export class ViewV2Component {
* @param senderTabId * @param senderTabId
* @private * @private
*/ */
private async _handleLoadAction(loadAction: LoadAction, senderTabId?: number): Promise<void> { private async _handleLoadAction(
loadAction: LoadAction,
senderTabId?: number,
): Promise<void | boolean> {
let actionSuccess = false; let actionSuccess = false;
// Both vaultPopupAutofillService and copyCipherFieldService will perform password re-prompting internally. // Both vaultPopupAutofillService and copyCipherFieldService will perform password re-prompting internally.
@@ -291,6 +296,12 @@ export class ViewV2Component {
switch (loadAction) { switch (loadAction) {
case "show-autofill-button": case "show-autofill-button":
// This action simply shows the cipher view, no need to do anything. // This action simply shows the cipher view, no need to do anything.
if (
this.cipher.reprompt !== CipherRepromptType.None &&
!(await this.passwordRepromptService.showPasswordPrompt())
) {
await closeViewVaultItemPopout(`${VaultPopoutType.viewVaultItem}_${this.cipher.id}`);
}
return; return;
case "autofill": case "autofill":
actionSuccess = await this.vaultPopupAutofillService.doAutofill(this.cipher, false); actionSuccess = await this.vaultPopupAutofillService.doAutofill(this.cipher, false);