mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
Hide card option from context menu when user is affected by card policy (#15272)
* Hide card option from context menu when user is affected by card policy * Remove unused code
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
import { of } from "rxjs";
|
import { BehaviorSubject, of } from "rxjs";
|
||||||
|
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import {
|
import {
|
||||||
@@ -22,6 +22,10 @@ import { UserId } from "@bitwarden/common/types/guid";
|
|||||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
import {
|
||||||
|
RestrictedCipherType,
|
||||||
|
RestrictedItemTypesService,
|
||||||
|
} from "@bitwarden/common/vault/services/restricted-item-types.service";
|
||||||
|
|
||||||
import { MainContextMenuHandler } from "./main-context-menu-handler";
|
import { MainContextMenuHandler } from "./main-context-menu-handler";
|
||||||
|
|
||||||
@@ -69,6 +73,8 @@ describe("context-menu", () => {
|
|||||||
let logService: MockProxy<LogService>;
|
let logService: MockProxy<LogService>;
|
||||||
let billingAccountProfileStateService: MockProxy<BillingAccountProfileStateService>;
|
let billingAccountProfileStateService: MockProxy<BillingAccountProfileStateService>;
|
||||||
let accountService: MockProxy<AccountService>;
|
let accountService: MockProxy<AccountService>;
|
||||||
|
let restricted$: BehaviorSubject<RestrictedCipherType[]>;
|
||||||
|
let restrictedItemTypesService: RestrictedItemTypesService;
|
||||||
|
|
||||||
let removeAllSpy: jest.SpyInstance<void, [callback?: () => void]>;
|
let removeAllSpy: jest.SpyInstance<void, [callback?: () => void]>;
|
||||||
let createSpy: jest.SpyInstance<
|
let createSpy: jest.SpyInstance<
|
||||||
@@ -85,6 +91,10 @@ describe("context-menu", () => {
|
|||||||
logService = mock();
|
logService = mock();
|
||||||
billingAccountProfileStateService = mock();
|
billingAccountProfileStateService = mock();
|
||||||
accountService = mock();
|
accountService = mock();
|
||||||
|
restricted$ = new BehaviorSubject<RestrictedCipherType[]>([]);
|
||||||
|
restrictedItemTypesService = {
|
||||||
|
restricted$,
|
||||||
|
} as Partial<RestrictedItemTypesService> as RestrictedItemTypesService;
|
||||||
|
|
||||||
removeAllSpy = jest
|
removeAllSpy = jest
|
||||||
.spyOn(chrome.contextMenus, "removeAll")
|
.spyOn(chrome.contextMenus, "removeAll")
|
||||||
@@ -105,6 +115,7 @@ describe("context-menu", () => {
|
|||||||
logService,
|
logService,
|
||||||
billingAccountProfileStateService,
|
billingAccountProfileStateService,
|
||||||
accountService,
|
accountService,
|
||||||
|
restrictedItemTypesService,
|
||||||
);
|
);
|
||||||
|
|
||||||
jest.spyOn(MainContextMenuHandler, "remove");
|
jest.spyOn(MainContextMenuHandler, "remove");
|
||||||
@@ -147,6 +158,24 @@ describe("context-menu", () => {
|
|||||||
expect(createdMenu).toBeTruthy();
|
expect(createdMenu).toBeTruthy();
|
||||||
expect(createSpy).toHaveBeenCalledTimes(11);
|
expect(createSpy).toHaveBeenCalledTimes(11);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("has menu enabled and has premium, but card type is restricted", async () => {
|
||||||
|
billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(true));
|
||||||
|
|
||||||
|
restricted$.next([{ cipherType: CipherType.Card, allowViewOrgIds: [] }]);
|
||||||
|
|
||||||
|
const createdMenu = await sut.init();
|
||||||
|
expect(createdMenu).toBeTruthy();
|
||||||
|
expect(createSpy).toHaveBeenCalledTimes(10);
|
||||||
|
});
|
||||||
|
it("has menu enabled, does not have premium, and card type is restricted", async () => {
|
||||||
|
billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(false));
|
||||||
|
restricted$.next([{ cipherType: CipherType.Card, allowViewOrgIds: [] }]);
|
||||||
|
|
||||||
|
const createdMenu = await sut.init();
|
||||||
|
expect(createdMenu).toBeTruthy();
|
||||||
|
expect(createSpy).toHaveBeenCalledTimes(9);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("loadOptions", () => {
|
describe("loadOptions", () => {
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
|||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
import { RestrictedItemTypesService } from "@bitwarden/common/vault/services/restricted-item-types.service";
|
||||||
|
|
||||||
import { InitContextMenuItems } from "./abstractions/main-context-menu-handler";
|
import { InitContextMenuItems } from "./abstractions/main-context-menu-handler";
|
||||||
|
|
||||||
@@ -157,6 +158,7 @@ export class MainContextMenuHandler {
|
|||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
|
private restrictedItemTypesService: RestrictedItemTypesService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,6 +183,10 @@ export class MainContextMenuHandler {
|
|||||||
this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id),
|
this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isCardRestricted = (
|
||||||
|
await firstValueFrom(this.restrictedItemTypesService.restricted$)
|
||||||
|
).some((rt) => rt.cipherType === CipherType.Card);
|
||||||
|
|
||||||
for (const menuItem of this.initContextMenuItems) {
|
for (const menuItem of this.initContextMenuItems) {
|
||||||
const {
|
const {
|
||||||
requiresPremiumAccess,
|
requiresPremiumAccess,
|
||||||
@@ -192,6 +198,9 @@ export class MainContextMenuHandler {
|
|||||||
if (requiresPremiumAccess && !hasPremium) {
|
if (requiresPremiumAccess && !hasPremium) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (menuItem.id.startsWith(AUTOFILL_CARD_ID) && isCardRestricted) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
await MainContextMenuHandler.create({ ...otherOptions, contexts: ["all"] });
|
await MainContextMenuHandler.create({ ...otherOptions, contexts: ["all"] });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,6 +437,8 @@ export default class MainBackground {
|
|||||||
|
|
||||||
private popupViewCacheBackgroundService: PopupViewCacheBackgroundService;
|
private popupViewCacheBackgroundService: PopupViewCacheBackgroundService;
|
||||||
|
|
||||||
|
private restrictedItemTypesService: RestrictedItemTypesService;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// Services
|
// Services
|
||||||
const lockedCallback = async (userId: UserId) => {
|
const lockedCallback = async (userId: UserId) => {
|
||||||
@@ -1307,6 +1309,13 @@ export default class MainBackground {
|
|||||||
this.stateProvider,
|
this.stateProvider,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.restrictedItemTypesService = new RestrictedItemTypesService(
|
||||||
|
this.configService,
|
||||||
|
this.accountService,
|
||||||
|
this.organizationService,
|
||||||
|
this.policyService,
|
||||||
|
);
|
||||||
|
|
||||||
this.mainContextMenuHandler = new MainContextMenuHandler(
|
this.mainContextMenuHandler = new MainContextMenuHandler(
|
||||||
this.stateService,
|
this.stateService,
|
||||||
this.autofillSettingsService,
|
this.autofillSettingsService,
|
||||||
@@ -1314,6 +1323,7 @@ export default class MainBackground {
|
|||||||
this.logService,
|
this.logService,
|
||||||
this.billingAccountProfileStateService,
|
this.billingAccountProfileStateService,
|
||||||
this.accountService,
|
this.accountService,
|
||||||
|
this.restrictedItemTypesService,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cipherContextMenuHandler = new CipherContextMenuHandler(
|
this.cipherContextMenuHandler = new CipherContextMenuHandler(
|
||||||
|
|||||||
Reference in New Issue
Block a user