Skip to content

[PM-40530] feat: Hide the hide my email switch when enforced by SendControls policy - #7244

Open
andrebispo5 wants to merge 5 commits into
PM-40528-send-controls-precedence-enforcementfrom
PM-40530-hide-hide-my-email-switch-when-enforced
Open

[PM-40530] feat: Hide the hide my email switch when enforced by SendControls policy#7244
andrebispo5 wants to merge 5 commits into
PM-40528-send-controls-precedence-enforcementfrom
PM-40530-hide-hide-my-email-switch-when-enforced

Conversation

@andrebispo5

@andrebispo5 andrebispo5 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-40530

📔 Objective

When an org's SendControls policy sets disableHideEmail, the "Hide my email" switch on the Add/Edit Send screen now disappears completely instead of just being greyed out.

The "One or more organization policies are affecting your Send options" notice goes away too in that case. That banner exists to explain why a control is greyed out, and once the control isn't there at all it just leaves people wondering what was affected.

Both of those only apply when the pm-31885-send-controls flag is on. With the flag off, an org's legacy SendOptions policy still greys out the switch and still shows the notice, exactly as before. Each path has its own test so the old behaviour can't quietly drift.

Nothing needed to change on the View Send screen since it has no hide-email field to begin with.

Stacked on #7239 (PM-40528), which is where the effective send policy comes from, so this targets that branch rather than main.

📸 Screenshots

Flag OFF, Policy OFF:
image

Flag OFF, Policy ON:
image

Flag ON, Policy OFF:
image

Flag ON, Policy ON:
image

@github-actions github-actions Bot added app:password-manager Bitwarden Password Manager app context t:feature Change Type - Feature Development labels Aug 5, 2026
@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.99%. Comparing base (7889a70) to head (c2e3343).

Files with missing lines Patch % Lines
...tools/feature/send/addedit/AddEditSendViewModel.kt 94.11% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@                                Coverage Diff                                @@
##           PM-40528-send-controls-precedence-enforcement    #7244      +/-   ##
=================================================================================
+ Coverage                                          85.75%   85.99%   +0.23%     
=================================================================================
  Files                                                937     1027      +90     
  Lines                                              67000    67782     +782     
  Branches                                            9794     9834      +40     
=================================================================================
+ Hits                                               57453    58286     +833     
+ Misses                                              6053     5976      -77     
- Partials                                            3494     3520      +26     
Flag Coverage Δ
app-data 17.99% <0.00%> (+0.35%) ⬆️
app-ui-auth-tools 19.03% <96.00%> (+0.36%) ⬆️
app-ui-platform 17.00% <0.00%> (+0.47%) ⬆️
app-ui-vault 27.93% <0.00%> (-0.03%) ⬇️
authenticator 6.06% <0.00%> (-0.01%) ⬇️
lib-core-network-bridge 4.09% <0.00%> (-0.01%) ⬇️
lib-data-ui 1.17% <0.00%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@andrebispo5
andrebispo5 marked this pull request as ready for review August 5, 2026 12:04
Copilot AI review requested due to automatic review settings August 5, 2026 12:04
@andrebispo5
andrebispo5 requested a review from a team as a code owner August 5, 2026 12:04
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: REQUEST CHANGES

Reviewed the hide-my-email toggle visibility change on the Add/Edit Send screen, the new isSendControlsEnabled state field, the combined policy/feature-flag observer in AddEditSendViewModel, and the updated screen and ViewModel tests. The UDF wiring follows the codebase conventions — flow results are mapped to an internal action, state is derived in the state class, and both flag-on and flag-off paths have test coverage. Two findings relate to how the hidden toggle interacts with an existing send's hideEmail value and to gating on the feature flag rather than the policy source.

Code Review Details
  • ⚠️ : Hiding the switch removes the only way to turn off hideEmail on an existing send; toSendView() still saves the restricted value
    • app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendContent.kt:472-487
  • ❓ : Gating on the feature flag rather than the policy source means legacy SendOptions orgs also lose the toggle and the notice, contrary to the KDoc
    • app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt:990-997

Comment on lines +472 to +487
if (!shouldHideEmailAddressToggle) {
Spacer(modifier = Modifier.height(height = 8.dp))
BitwardenSwitch(
modifier = Modifier
.testTag("SendHideEmailSwitch")
.fillMaxWidth()
.standardHorizontalMargin(),
label = stringResource(id = BitwardenString.hide_email),
isChecked = state.common.isHideEmailChecked,
onCheckedChange = addSendHandlers.onHideEmailToggle,
readOnly = isSendsRestrictedByPolicy,
enabled = state.common.isHideEmailChecked ||
state.common.isHideEmailAddressEnabled,
cardStyle = CardStyle.Full,
)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ IMPORTANT: Hiding the switch removes the only way to turn off hideEmail on an existing send.

Details and fix

The retained enabled = isHideEmailChecked || isHideEmailAddressEnabled exists so that a send created before the policy took effect (with hideEmail = true) can still be turned off by the user, even while the policy forbids turning it on. With the flag on and disableHideEmail = true, that switch is now gone, but AddEditSendState.toSendView() still writes hideEmail = common.isHideEmailChecked (util/AddEditSendStateExtensions.kt:36), so editing that send silently re-saves the policy-violating value with no way for the user to comply.

Two possible fixes:

  • Keep the switch visible when isHideEmailChecked is true (shouldHideEmailAddressToggle gains && !isHideEmailChecked), preserving the legacy escape hatch, or
  • Coerce isHideEmailChecked = false in handleEffectiveSendPolicyReceive when effectiveSendPolicy.disableHideEmail is true, so the hidden control cannot carry a restricted value into the save.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the intended behaviour.

Comment on lines +990 to +997
/**
* Helper to determine if the "hide my email" toggle should be hidden entirely rather than
* simply disabled. The SendControls policy hides the toggle, while the legacy send options
* policy continues to only disable it.
*/
val shouldHideEmailAddressToggle: Boolean
get() = isSendControlsEnabled &&
(viewState as? ViewState.Content)?.common?.isHideEmailAddressEnabled == false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QUESTION: The gate is the feature flag, not the policy source, so legacy SendOptions orgs also lose the toggle and the notice.

Details

resolveEffectiveSendPolicy folds legacy SendOptions into the effective policy when the flag is on for orgs with no SendControls policy (PolicyManagerImpl.kt:239-250: remainingSendOptions.any { it.shouldDisableHideEmail ?: false }). Once the flag rolls out, those users get the hidden toggle and, via shouldDisplayPolicyWarning, no explanatory notice either — which is the opposite of what this KDoc describes ("the legacy send options policy continues to only disable it").

Is flag-based gating the intent for rollout? If so, the KDoc on both helpers reads as policy-source-based and could be reworded; if not, both helpers would need to key off whether a SendControls policy is actually in effect.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is working as intended because once the Flag is enabled it will also use the new Send Control policy.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Add/Edit Send experience so that when SendControls policy enforcement disables “Hide my email” (behind the pm-31885-send-controls flag), the toggle is removed entirely and the legacy “policies affecting Send options” notice is no longer shown.

Changes:

  • Added isSendControlsEnabled + shouldHideEmailAddressToggle to AddEditSendState, and propagate through screen/content composables to conditionally omit the “Hide my email” switch.
  • Observes effective send policy + SendControls feature-flag changes in AddEditSendViewModel to keep UI state up to date while the screen is open.
  • Expanded unit + Compose UI tests to cover flag/policy combinations and dynamic updates.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt Tracks SendControls flag in state, observes effective policy/flag flows, and adds state helpers to hide the toggle + suppress the legacy policy notice.
app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendScreen.kt Passes new shouldHideEmailAddressToggle state through to content.
app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendContent.kt Hides the “Hide my email” switch when instructed by state.
app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt Adds coverage for SendControls flag and effective-policy updates impacting the new state fields/helpers.
app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendScreenTest.kt Adds Compose UI assertions for legacy disabled-toggle behavior vs SendControls hidden-toggle behavior + notice suppression.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:password-manager Bitwarden Password Manager app context t:feature Change Type - Feature Development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants