fix(ui): suppress privacy mode account title leaks

This commit is contained in:
Tam Nhu Tran
2026-05-30 15:37:47 -04:00
parent dd62027d3f
commit f592260049
2 changed files with 54 additions and 4 deletions
@@ -172,6 +172,8 @@ export function AccountSurfaceCard({
const { t } = useTranslation();
const identity = getAccountIdentityPresentation(accountId, email, tokenFile);
const title = displayEmail || identity.email || accountId;
const sensitiveTitle = (value: string | null | undefined) =>
privacyMode ? undefined : (value ?? undefined);
const normalizedProvider = provider.toLowerCase();
const effectiveTier = resolveEffectiveTier(tier, quota);
const effectiveCodexBadge =
@@ -202,7 +204,7 @@ export function AccountSurfaceCard({
{normalizedProvider === 'codex'
? effectiveCodexBadge?.label && (
<span
title={effectiveCodexBadge.label}
title={sensitiveTitle(effectiveCodexBadge.label)}
className={cn(
'text-[8px] font-semibold px-1.5 py-0.5 rounded-md border shrink-0',
privacyMode && PRIVACY_BLUR_CLASS,
@@ -214,7 +216,7 @@ export function AccountSurfaceCard({
)
: identity.audienceLabel && (
<span
title={identity.audienceLabel}
title={sensitiveTitle(identity.audienceLabel)}
className={cn(
'text-[8px] font-semibold px-1.5 py-0.5 rounded-md shrink-0',
privacyMode && PRIVACY_BLUR_CLASS,
@@ -226,7 +228,7 @@ export function AccountSurfaceCard({
)}
{normalizedProvider !== 'codex' && identity.compactDetailLabel && (
<span
title={identity.detailLabel ?? identity.compactDetailLabel}
title={sensitiveTitle(identity.detailLabel ?? identity.compactDetailLabel)}
className={cn(
'text-[8px] font-semibold px-1.5 py-0.5 rounded-md border shrink-0',
privacyMode && PRIVACY_BLUR_CLASS,
@@ -281,7 +283,7 @@ export function AccountSurfaceCard({
className={cn('flex items-center min-w-0', isCompact ? 'gap-1.5' : 'gap-2 flex-wrap')}
>
<span
title={title}
title={sensitiveTitle(title)}
className={cn(
isCompact
? 'flex-1 min-w-0 text-xs font-semibold tracking-tight truncate leading-none'
@@ -0,0 +1,48 @@
import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { AccountSurfaceCard } from '@/components/account/shared/account-surface-card';
describe('AccountSurfaceCard privacy titles', () => {
it('keeps sensitive account title attributes available outside privacy mode', () => {
const { container } = render(
<AccountSurfaceCard
mode="compact"
provider="gemini"
accountId="person@example.com#abcdef12-team"
email="person@example.com"
/>
);
expect(screen.getByText('person@example.com')).toHaveAttribute('title', 'person@example.com');
expect(container.querySelector('[title="Business"]')).toBeInTheDocument();
expect(container.querySelector('[title="Workspace abcdef12"]')).toBeInTheDocument();
});
it('removes sensitive account title attributes in privacy mode', () => {
const { container } = render(
<>
<AccountSurfaceCard
mode="compact"
provider="gemini"
accountId="person@example.com#abcdef12-team"
email="person@example.com"
privacyMode
/>
<AccountSurfaceCard
mode="compact"
provider="codex"
accountId="codex@example.com#enterprise-pro"
email="codex@example.com"
privacyMode
/>
</>
);
expect(screen.getByText('person@example.com')).not.toHaveAttribute('title');
expect(screen.getByText('codex@example.com')).not.toHaveAttribute('title');
expect(container.querySelector('[title="Business"]')).not.toBeInTheDocument();
expect(container.querySelector('[title="Workspace abcdef12"]')).not.toBeInTheDocument();
expect(container.querySelector('[title*="Enterprise"]')).not.toBeInTheDocument();
});
});