Skip to content

[PM-41931] feat(dirt): Add the exclude from browser health endpoint - #8700

Draft
AlexRubik wants to merge 20 commits into
dirt/pm-41931/report-exclusions-apifrom
dirt/pm-41931/exclude-from-reports-endpoint
Draft

AlexRubik wants to merge 20 commits into
dirt/pm-41931/report-exclusions-apifrom
dirt/pm-41931/exclude-from-reports-endpoint

Conversation

@AlexRubik

@AlexRubik AlexRubik commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🎟️ Tracking

PM-41931

📔 Objective

This PR adds PUT ciphers/{id}/exclude-from-browser-health. It is stacked on #8669, which adds the storage. Merge #8669 first.

The endpoint:

  • Is behind the pm-39196-health-report-exclusions feature flag.
  • Requires premium. A free user gets a 400 error.
  • Returns 404 if the cipher is not the caller's own personal, not-deleted login.
  • Pushes a cipher sync to the user's other devices.
  • Changes only the account revision date, not the cipher RevisionDate. This follows Favorites and Folders, so other devices do not get edit conflicts.

Tests: unit tests, and a live API test of 31 checks against a local server.

Security note. With this endpoint, the server learns which personal logins a user excluded. The client shows Exclude only on at-risk logins. The nearest precedent is the organization SecurityTask table. AppSec must review this before the PR leaves draft.

The clients PR that calls this endpoint is bitwarden/clients#24109.

📸 Screenshots

Not applicable. This PR has no UI changes.

@AlexRubik AlexRubik added t:feature Change Type - Feature Development ai-review Request a Claude code review labels Oct 23, 2026
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

This review covers head 5216750. The PR adds PUT ciphers/{id}/exclude-from-browser-health behind the pm-39196-health-report-exclusions feature flag. The endpoint calls ExcludeCipherFromBrowserHealthCommand, which requires premium, returns 404 when no row is updated, and pushes a cipher sync that skips the calling device. The new commit adds a required @Exclude BIT parameter to Cipher_UpdateManyBrowserHealthExclusions, in both the SSDT procedure and the migration. With @Exclude = 1 it writes true as before, and with @Exclude = 0 it passes NULL to JSON_MODIFY, which removes the user's key. The Dapper repository always passes Exclude = true, so the current behavior is unchanged, and the same change is already on the base branch, dirt/pm-41931/report-exclusions-api.

Code Review Details

No code findings.

@AlexRubik
AlexRubik added this pull request to stack #8701 October 23, 2026 15:59
@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.52%. Comparing base (f52fc32) to head (5216750).
⚠️ Report is 1 commits behind head on dirt/pm-41931/report-exclusions-api.

Additional details and impacted files
@@                         Coverage Diff                          @@
##           dirt/pm-41931/report-exclusions-api    #8700   +/-   ##
====================================================================
  Coverage                                74.51%   74.52%           
====================================================================
  Files                                     2735     2737    +2     
  Lines                                   117243   117274   +31     
  Branches                                 10626    10628    +2     
====================================================================
+ Hits                                     87364    87393   +29     
- Misses                                   27215    27219    +4     
+ Partials                                  2664     2662    -2     

☔ 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.

Per-user JSON map of cipher report exclusions, a sibling of Archives.
Vault write procedures accept the new parameter but never write it, so
saving a cipher cannot erase another user's exclusion.
…iphers

Reads this user's entry from ReportExclusions into CipherDetails and the
cipher response, so the standard sync delivers every exclusion. EF
replaces never write the column.
DIRT-owned writer for Cipher.ReportExclusions. Only the user's own
personal, not-deleted logins can be excluded, and only the account
revision is bumped, so other devices sync without an edit conflict.
PUT ciphers/{id}/exclude-from-reports, behind the health report
exclusions flag. Requires premium, and pushes a cipher sync so the
user's other devices pick up the exclusion.
Repository tests run on every database and pin the scope rules, the
per-user read, the revision date behavior, and that Vault replaces keep
the exclusion. Adds command and controller unit tests.
… organizations

The EF GetManyByUserIdAsync branch for users without organizations
rebuilds CipherDetails field by field and dropped ReportExcludedDate, so
sync on Postgres, MySQL and SQLite returned null for users with no org.
MSSQL was unaffected (its procedure selects every column).
Store { "<userId>": true } instead of the exclusion date, matching the
tech breakdown and the Favorites pattern. Nothing reads the date, and a
flag tells the server less. Ciphers now expose a per-user
ExcludedFromReports boolean in place of ReportExcludedDate.
This PR now holds only the database and data-access changes, so it can
merge before the endpoint. The command, controller and their unit tests
move to a stacked PR.
Main gained newer migrations, so the SQL script moves to 2026-10-23 and
the three EF migrations are regenerated on top of main's model.
Follow the SQL naming guide: Cipher_UpdateManyBrowserHealthExclusions.
@AlexRubik
AlexRubik force-pushed the dirt/pm-41931/exclude-from-reports-endpoint branch from 0792477 to 8bc97ff Compare October 26, 2026 21:58
@AlexRubik AlexRubik changed the title [PM-41931] feat(dirt): Add the exclude from reports endpoint [PM-41931] feat(dirt): Add the exclude from browser health endpoint Oct 26, 2026
PUT ciphers/{id}/exclude-from-reports, behind the health report
exclusions flag. Requires premium, and pushes a cipher sync so the
user's other devices pick up the exclusion.
@AlexRubik
AlexRubik force-pushed the dirt/pm-41931/exclude-from-reports-endpoint branch from 8bc97ff to 97b6f5d Compare October 27, 2026 17:27
…edure

Lets the restore feature reuse the procedure. Passing 0 removes the user's key, because the SQL Server read treats any stored value as excluded.

This branch has not been deployed

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

Labels

ai-review Request a Claude code review t:feature Change Type - Feature Development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant