diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts index 6cfecd59403a..8255b3cc3ed2 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.ts @@ -19,7 +19,11 @@ import { } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; -import { PolicyType, ProviderType } from "@bitwarden/common/admin-console/enums"; +import { + OrganizationUserType, + PolicyType, + ProviderType, +} from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -208,6 +212,13 @@ export class ProductSwitcherService { external: false, }; + // Check if SM ads should be disabled for any organization + // SM ads are only disabled if the user is a regular User (not Admin or Owner) + // in an organization that has useDisableSMAdsForUsers enabled + const shouldDisableSMAds = orgs.some( + (org) => org.useDisableSMAdsForUsers && org.type === OrganizationUserType.User, + ); + const products = { pm: { name: "Password Manager", @@ -267,7 +278,8 @@ export class ProductSwitcherService { if (smOrg) { bento.push(products.sm); - } else { + } else if (!shouldDisableSMAds) { + // Only show SM in "other" section if ads are not disabled other.push(products.sm); } diff --git a/libs/common/src/admin-console/models/data/organization.data.spec.ts b/libs/common/src/admin-console/models/data/organization.data.spec.ts index bc74dd189ba9..faea69971076 100644 --- a/libs/common/src/admin-console/models/data/organization.data.spec.ts +++ b/libs/common/src/admin-console/models/data/organization.data.spec.ts @@ -64,6 +64,7 @@ describe("ORGANIZATIONS state", () => { isAdminInitiated: false, ssoEnabled: false, ssoMemberDecryptionType: undefined, + useDisableSMAdsForUsers: false, }, }; const result = sut.deserializer(JSON.parse(JSON.stringify(expectedResult))); diff --git a/libs/common/src/admin-console/models/data/organization.data.ts b/libs/common/src/admin-console/models/data/organization.data.ts index e6bf9dbaaa39..c671890a7a84 100644 --- a/libs/common/src/admin-console/models/data/organization.data.ts +++ b/libs/common/src/admin-console/models/data/organization.data.ts @@ -64,6 +64,7 @@ export class OrganizationData { userIsManagedByOrganization: boolean; useRiskInsights: boolean; useAdminSponsoredFamilies: boolean; + useDisableSMAdsForUsers: boolean; isAdminInitiated: boolean; ssoEnabled: boolean; ssoMemberDecryptionType?: MemberDecryptionType; @@ -132,6 +133,7 @@ export class OrganizationData { this.userIsManagedByOrganization = response.userIsManagedByOrganization; this.useRiskInsights = response.useRiskInsights; this.useAdminSponsoredFamilies = response.useAdminSponsoredFamilies; + this.useDisableSMAdsForUsers = response.useDisableSMAdsForUsers; this.isAdminInitiated = response.isAdminInitiated; this.ssoEnabled = response.ssoEnabled; this.ssoMemberDecryptionType = response.ssoMemberDecryptionType; diff --git a/libs/common/src/admin-console/models/domain/organization.ts b/libs/common/src/admin-console/models/domain/organization.ts index f320a675b62c..a3b67aa79db2 100644 --- a/libs/common/src/admin-console/models/domain/organization.ts +++ b/libs/common/src/admin-console/models/domain/organization.ts @@ -95,6 +95,7 @@ export class Organization { userIsManagedByOrganization: boolean; useRiskInsights: boolean; useAdminSponsoredFamilies: boolean; + useDisableSMAdsForUsers: boolean; isAdminInitiated: boolean; ssoEnabled: boolean; ssoMemberDecryptionType?: MemberDecryptionType; @@ -159,6 +160,7 @@ export class Organization { this.userIsManagedByOrganization = obj.userIsManagedByOrganization; this.useRiskInsights = obj.useRiskInsights; this.useAdminSponsoredFamilies = obj.useAdminSponsoredFamilies; + this.useDisableSMAdsForUsers = obj.useDisableSMAdsForUsers; this.isAdminInitiated = obj.isAdminInitiated; this.ssoEnabled = obj.ssoEnabled; this.ssoMemberDecryptionType = obj.ssoMemberDecryptionType; diff --git a/libs/common/src/admin-console/models/response/organization.response.ts b/libs/common/src/admin-console/models/response/organization.response.ts index 235ea2f8d962..ed4184f36a87 100644 --- a/libs/common/src/admin-console/models/response/organization.response.ts +++ b/libs/common/src/admin-console/models/response/organization.response.ts @@ -39,6 +39,7 @@ export class OrganizationResponse extends BaseResponse { limitItemDeletion: boolean; allowAdminAccessToAllCollectionItems: boolean; useRiskInsights: boolean; + useDisableSMAdsForUsers: boolean; constructor(response: any) { super(response); @@ -81,5 +82,6 @@ export class OrganizationResponse extends BaseResponse { "AllowAdminAccessToAllCollectionItems", ); this.useRiskInsights = this.getResponseProperty("UseRiskInsights"); + this.useDisableSMAdsForUsers = this.getResponseProperty("UseDisableSMAdsForUsers"); } } diff --git a/libs/common/src/admin-console/models/response/profile-organization.response.ts b/libs/common/src/admin-console/models/response/profile-organization.response.ts index dc5090f2c05e..23290cd0ae54 100644 --- a/libs/common/src/admin-console/models/response/profile-organization.response.ts +++ b/libs/common/src/admin-console/models/response/profile-organization.response.ts @@ -59,6 +59,7 @@ export class ProfileOrganizationResponse extends BaseResponse { userIsManagedByOrganization: boolean; useRiskInsights: boolean; useAdminSponsoredFamilies: boolean; + useDisableSMAdsForUsers: boolean; isAdminInitiated: boolean; ssoEnabled: boolean; ssoMemberDecryptionType?: MemberDecryptionType; @@ -131,6 +132,7 @@ export class ProfileOrganizationResponse extends BaseResponse { this.userIsManagedByOrganization = this.getResponseProperty("UserIsManagedByOrganization"); this.useRiskInsights = this.getResponseProperty("UseRiskInsights"); this.useAdminSponsoredFamilies = this.getResponseProperty("UseAdminSponsoredFamilies"); + this.useDisableSMAdsForUsers = this.getResponseProperty("UseDisableSMAdsForUsers"); this.isAdminInitiated = this.getResponseProperty("IsAdminInitiated"); this.ssoEnabled = this.getResponseProperty("SsoEnabled") ?? false; this.ssoMemberDecryptionType = this.getResponseProperty("SsoMemberDecryptionType");