diff --git a/apps/browser/src/autofill/background/notification.background.ts b/apps/browser/src/autofill/background/notification.background.ts index 1f0cc469e2c..6589252d94b 100644 --- a/apps/browser/src/autofill/background/notification.background.ts +++ b/apps/browser/src/autofill/background/notification.background.ts @@ -16,6 +16,7 @@ import { } from "@bitwarden/common/autofill/constants"; import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; import { UserNotificationSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/user-notification-settings.service"; +import { ProductTierType } from "@bitwarden/common/billing/enums/product-tier-type.enum"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { NeverDomains } from "@bitwarden/common/models/domain/domain-service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; @@ -41,7 +42,11 @@ import { SecurityTask } from "@bitwarden/common/vault/tasks/models/security-task import { openUnlockPopout } from "../../auth/popup/utils/auth-popout-window"; import { BrowserApi } from "../../platform/browser/browser-api"; import { openAddEditVaultItemPopout } from "../../vault/popup/utils/vault-popout-window"; -import { NotificationCipherData } from "../content/components/cipher/types"; +import { + OrganizationCategory, + OrganizationCategories, + NotificationCipherData, +} from "../content/components/cipher/types"; import { NotificationQueueMessageType } from "../enums/notification-queue-message-type.enum"; import { AutofillService } from "../services/abstractions/autofill.service"; @@ -174,8 +179,29 @@ export default class NotificationBackground { activeUserId, ); + const organizations = await firstValueFrom( + this.organizationService.organizations$(activeUserId), + ); + return decryptedCiphers.map((view) => { - const { id, name, reprompt, favorite, login } = view; + const { id, name, reprompt, favorite, login, organizationId } = view; + + const organizationType = organizationId + ? organizations.find((org) => org.id === organizationId)?.productTierType + : null; + + const organizationCategories: OrganizationCategory[] = []; + + if ( + [ProductTierType.Teams, ProductTierType.Enterprise, ProductTierType.TeamsStarter].includes( + organizationType, + ) + ) { + organizationCategories.push(OrganizationCategories.business); + } + if ([ProductTierType.Families, ProductTierType.Free].includes(organizationType)) { + organizationCategories.push(OrganizationCategories.family); + } return { id, @@ -183,6 +209,7 @@ export default class NotificationBackground { type: CipherType.Login, reprompt, favorite, + ...(organizationCategories.length ? { organizationCategories } : {}), icon: buildCipherIcon(iconsServerUrl, view, showFavicons), login: login && { username: login.username, diff --git a/apps/browser/src/autofill/content/components/cipher/cipher-indicator-icons.ts b/apps/browser/src/autofill/content/components/cipher/cipher-indicator-icons.ts index 9096149f510..e4fe012a678 100644 --- a/apps/browser/src/autofill/content/components/cipher/cipher-indicator-icons.ts +++ b/apps/browser/src/autofill/content/components/cipher/cipher-indicator-icons.ts @@ -1,30 +1,35 @@ import { css } from "@emotion/css"; -import { html } from "lit"; +import { html, TemplateResult } from "lit"; import { Theme } from "@bitwarden/common/platform/enums"; import { themes } from "../../../content/components/constants/styles"; import { Business, Users } from "../../../content/components/icons"; -// @TODO connect data source to icon checks -// @TODO support other indicator types (attachments, etc) +import { OrganizationCategories, OrganizationCategory } from "./types"; + +const cipherIndicatorIconsMap: Record< + OrganizationCategory, + (args: { color: string; theme: Theme }) => TemplateResult +> = { + [OrganizationCategories.business]: Business, + [OrganizationCategories.family]: Users, +}; + export function CipherInfoIndicatorIcons({ - showBusinessIcon, - showFamilyIcon, + organizationCategories = [], theme, }: { - showBusinessIcon?: boolean; - showFamilyIcon?: boolean; + organizationCategories?: OrganizationCategory[]; theme: Theme; }) { - const indicatorIcons = [ - ...(showBusinessIcon ? [Business({ color: themes[theme].text.muted, theme })] : []), - ...(showFamilyIcon ? [Users({ color: themes[theme].text.muted, theme })] : []), - ]; - - return indicatorIcons.length - ? html` ${indicatorIcons} ` - : null; // @TODO null case should be handled by parent + return html` + + ${organizationCategories.map((name) => + cipherIndicatorIconsMap[name]?.({ color: themes[theme].text.muted, theme }), + )} + + `; } const cipherInfoIndicatorIconsStyles = css` diff --git a/apps/browser/src/autofill/content/components/cipher/cipher-info.ts b/apps/browser/src/autofill/content/components/cipher/cipher-info.ts index 6ff32353938..e3d237b9bc6 100644 --- a/apps/browser/src/autofill/content/components/cipher/cipher-info.ts +++ b/apps/browser/src/autofill/content/components/cipher/cipher-info.ts @@ -1,5 +1,5 @@ import { css } from "@emotion/css"; -import { html } from "lit"; +import { html, nothing } from "lit"; import { Theme } from "@bitwarden/common/platform/enums"; @@ -8,14 +8,22 @@ import { themes, typography } from "../../../content/components/constants/styles import { CipherInfoIndicatorIcons } from "./cipher-indicator-icons"; import { NotificationCipherData } from "./types"; -// @TODO support other cipher types (card, identity, notes, etc) export function CipherInfo({ cipher, theme }: { cipher: NotificationCipherData; theme: Theme }) { - const { name, login } = cipher; + const { name, login, organizationCategories } = cipher; + const hasIndicatorIcons = organizationCategories?.length; return html`