Commit Graph

7320 Commits

Author SHA1 Message Date
Matt Bishop
bf683c2d84 Merge remote-tracking branch 'origin' into ci/github-code-coverage-upload 2026-05-29 09:52:19 -04:00
Rui Tomé
9e4bef5ee7 [PM-34776/PM-37797] Add invite link email domain validation endpoint (#7683)
* Add email domain validation to OrganizationInviteLink

- Introduced IsEmailDomainAllowed method to check if an email's domain is permitted based on allowed domains.
- Added necessary using directives for MailAddress and domain sanitization utilities.

* Refactor OrganizationInviteLink by removing email domain validation

- Removed the IsEmailDomainAllowed method and associated using directives for MailAddress.
- Cleaned up the code by eliminating unused methods related to email domain validation.

* Add InviteLinkDomainValidator for email domain validation

- Introduced InviteLinkDomainValidator class with IsEmailDomainAllowed method to validate if an email's domain is in the list of allowed domains.
- Utilized MailAddress for email parsing and added domain sanitization logic.

* Add email domain validation endpoint for organization invite links

- Implemented ValidateEmailDomain method in OrganizationInviteLinksController to check if an email's domain is allowed based on the invite link's permitted domains.
- Created OrganizationInviteLinkValidateEmailDomainRequestModel for request validation and OrganizationInviteLinkValidateEmailDomainResponseModel for response formatting.
- Integrated IOrganizationInviteLinkRepository to retrieve invite link details by code.

* Add unit tests for InviteLinkDomainValidator

- Created InviteLinkDomainValidatorTests class to validate email domain functionality.
- Added tests for various scenarios including invalid emails, empty domain lists, and matching domains.
- Ensured comprehensive coverage of the IsEmailDomainAllowed method's behavior.

* Add integration test for email domain validation in OrganizationInviteLinksController

- Implemented a test to validate that an allowed email domain returns the expected result when checked against an organization invite link.
- Ensured the test verifies the creation of an invite link and the subsequent validation of an email domain against the allowed domains list.

* Add validation query and interface for organization invite link email domain

- Introduced ValidateOrganizationInviteLinkEmailDomainQuery class to validate if an email's domain is allowed based on the invite link's permitted domains.
- Created IValidateOrganizationInviteLinkEmailDomainQuery interface to define the validation method.
- Added unit tests for the validation query to ensure correct behavior for various scenarios, including link not found and domain matching.

* Refactor OrganizationInviteLinksController to use validation query for email domain

- Updated ValidateEmailDomain method to utilize IValidateOrganizationInviteLinkEmailDomainQuery for domain validation instead of directly accessing the repository.
- Removed unnecessary repository dependency and streamlined the response handling for validation results.
- Registered the new validation query in OrganizationServiceCollectionExtensions for dependency injection.

* Refactor InviteLinkDomainValidator and replace MailAddress usage with existing email validation method
2026-05-29 12:23:15 +01:00
Jordan Aasen
583626c0e5 Revert "remove legacy collections endpoint" (#7738)
This reverts commit 4fb318c6dd.
2026-05-28 17:33:34 -07:00
Dave
8b2cb89390 [PM-35394] MasterPasswordService Admin Console Integration (#7629)
* test(org-user-request-model): Add model validation tests.

* feat(request-models): Add Authentication and Unlock Data fields with annotations.

* test(recover-command): Add tests for Authentication and Unlock Data payload signature.

* feat(recover-command): Add overload for Authentication and Unlock Data payload signature.

* test(recover-command): Add tests for behavior with authentication and unlock data.

* feat(recover-command): Add impl for hash and key, authentication and unlock data inputs.

* test(org-users-controller): Add controller tests for dispatch.

* feat(org-users-controller): Add controller impl for dispatch for both request payload variants.

* chore: lint.

* fix(request-model): Validation method drifted in base; rename.

* test(request-model): Update validation tests.

* feat(request-model): Support 2FA-only validation at the boundary.

* test(request-model): Express handling of v1 vs v2 requests.

* PM-35394 - Per reviewer's request, mark  AdminRecoverAccountCommand.RecoverAccountAsync that doesn't accept new models obselete

* PM-35394 - Fix using directive after model namespace move

Merge from main moved OrganizationUserResetPasswordRequestModel to the
AdminConsole namespace; update the test's using directive to match,
restoring both the build and dotnet format checks.

---------

Co-authored-by: Jared Snider <jsnider@bitwarden.com>
2026-05-28 16:37:43 -04:00
Matt Bishop
b72edb5816 docs: expand CACHING.md (non-Redis L2, sizing/cost, SRE coordination) (#7736)
* docs: follow up to #6682 — cover non-Redis L2 support in ExtendedCache

PR #6682 added support for any IDistributedCache (Cosmos, SQL, EF) as the
L2 store under ExtendedCache, but the docs continued to read as Redis-only.
Update CACHING.md to document the new modes, show wiring for pairing with
Cosmos, and explain the backplane / L1-staleness tradeoff.

* docs: address review feedback on non-Redis L2 documentation

- Drop L1/L2 shorthand from decision tree; define vocabulary once in the
  ExtendedCache section.
- Fix Option 5 inline comment about the "persistent" keyed cache —
  Cosmos in cloud, aliased to the unnamed IDistributedCache in self-hosted.
- Note that ExtendedCache prefixes every key with cacheName: so aliased
  consumers cannot collide with the raw "persistent" namespace.
- Pairing-with-Cosmos: clarify that FusionCache writes per-document ttl
  (not container TTL) and call out the RU / eager-refresh tradeoff.
- Add a worked Specific Example for ExtendedCache + Cosmos
  (Long-Lived Per-Tenant Computed Aggregates).
- Footnote the Configuration Priority table to point at the opt-in
  Cosmos pairing path.

* docs: add sizing, throughput, and cost guidance to caching doc

Volume, write rate, and cache size are first-order constraints that gate which
backend can hold a workload — but the prior decision tree silently assumed the
answer fit. Address that:

- New "Sizing, Throughput, and Cost" section after the overview table, covering
  working-set size (L1 bounded by heap, L2 ceilings per backend), read rate
  (when L1 absorbs vs. becomes overhead), write rate (backplane saturation,
  eager-refresh cost), and per-backend cost shape.
- Callout above the decision tree pointing at the new section.
- Decision-tree branches now include sizing/write-rate gates that can override
  the API recommendation.
- SSO grants and Org/Provider Abilities "Why" lists now include the size and
  rate profile that makes ExtendedCache appropriate there.
- ExtendedCache Cons and "When NOT to Use" expanded with the two main outs:
  working sets too large for L1, and sustained-high write rates that saturate
  the Redis backplane.

* docs: call out SRE / infrastructure coordination as a prerequisite

Picking a caching option in code is only half of standing up a new cache.
The runtime — Redis sizing, Cosmos provisioning, RU budgets, eviction
policies, monitoring — is owned by SRE and is not stood up by the
AddExtendedCache / AddDistributedCache registrations.

- New "Coordinating with Infrastructure" section after "Sizing, Throughput,
  and Cost", covering: loop SRE in early, defaults are not production
  configuration, shared infrastructure has unseen tenants, new backends
  need provisioning beyond code, and self-hosted environments differ from
  cloud.
- Decision-tree preamble now points at both Sizing and Coordinating
  with Infrastructure as prerequisites before using the tree.
2026-05-28 16:20:00 -04:00
Jake Fink
4e764cdc13 [PM-27298] Remove consolidated-session-timeout-component feature flag (#7718) 2026-05-28 15:59:40 -04:00
Stephon Brown
4dece669ea Migrate Web Frontend to Official Aspire JavaScript Hosting (#7731)
* chore(deps): remove Node.js community plugin

* refactor(AppHost): integrate web frontend with Aspire JS hosting

* docs(AppHost): update web frontend and Aspire documentation

* feat(AppHost): configure Azurite emulator with persistent data volume

* docs(AppHost): fix ClientsPath description to reference worktrees section

* fix(Apphost): run dotnet format
2026-05-28 13:33:47 -04:00
Jared
970cacdc29 [PM-38273] feat(admin-console): Add InjectOrganizationAttribute and OrganizationModelBinder (#7659)
* feat(admin-console): Add InjectOrganizationAttribute and OrganizationModelBinder for automatic organization parameter binding

* feat(admin-console): Introduce BindOrganizationAttribute and OrganizationModelBinder for organization parameter binding with unit tests

* feat(admin-console): Update GetResetPasswordDetails to use BindOrganization for organization parameter

* fix(admin-console): Correct organization ID check in GetResetPasswordDetails method to use bound organization

* Refactor OrganizationUsersControllerTests to use bound organization in GetResetPasswordDetails method

- Updated test cases to pass the organization directly instead of relying on repository calls.
- Ensured that the tests correctly assert NotFoundException when the organization user does not match the bound organization.
- Improved clarity in test setup by explicitly binding the organization to the method calls.

* Fix UTF-8 BOM issue in BindOrganizationAttribute.cs

* Add integration tests for OrganizationUsersController's BindOrganization functionality

- Introduced OrganizationUsersControllerBindOrganizationTests to validate the behavior of the GET reset-password-details endpoint.
- Implemented tests for successful retrieval of reset password details, handling of non-existent organization users, and cases where the user belongs to a different organization.
- Ensured comprehensive coverage of scenarios to verify correct status responses and organization binding logic.
2026-05-28 13:06:25 -04:00
Addison Beck
7d0e729e03 refactor(server): consolidate cloud region config (#7728)
* refactor(server): move CloudRegion enum from Setup to Core

Decouples CloudRegion from Bit.Setup.Enums so any project consuming
Core can reference it without a circular dependency back into the
Setup utility. Updates the three downstream Setup references
(Context.cs, Program.cs, Setup.csproj) to point at the new
Bit.Core.Enums namespace. Lands as a standalone PR ahead of
PM-35087 (FedRAMP / bitwarden-gov.com) so SHOT can review the
Setup->Core boundary move in isolation.

Refs: PM-38015

* refactor(server): consolidate cloud region config

Introduces Bit.Core.Settings.CloudRegionConfig -- a sealed class with
a static All array (US + EU entries) and FindByDomain/FindByRegion
helpers -- so per-region URLs live in one place. Refactors three
consumers that previously duplicated hardcoded US/EU strings:
Constants.cs derives BitwardenCloudDomains and
BitwardenMobileSsoCallbackUris from CloudRegionConfig.All;
ServiceCollectionExtensions.cs replaces two hardcoded
AddSwaggerServerWithSecurity calls with a foreach;
HandlebarsMailService.GetCloudVaultSubscriptionUrl is widened to
public and switches from a string switch to FindByRegion(). Adding a
new region is now a single entry in CloudRegionConfig.All. We'll be using
this right away to add the Gov region.

Refs: PM-38015
2026-05-28 12:43:21 -04:00
Ned Thompson
bce6358577 add favorite for card, identity, secure note, and sshkey scenes (#7710) 2026-05-28 12:08:55 -04:00
Addison Beck
30940f1626 refactor(server): move CloudRegion enum from Setup to Core (#7727)
Decouples CloudRegion from Bit.Setup.Enums so any project consuming
Core can reference it without a circular dependency back into the
Setup utility. Updates the three downstream Setup references
(Context.cs, Program.cs, Setup.csproj) to point at the new
Bit.Core.Enums namespace. Lands as a standalone PR ahead of
PM-35087 (FedRAMP / bitwarden-gov.com) so SHOT can review the
Setup->Core boundary move in isolation.

Refs: PM-38015
2026-05-28 10:42:18 -04:00
Nik Gilmore
e10eb5e0fb PM-37727: Fix exceptions when serialzing blob-encrypted ciphers (#7667) 2026-05-27 16:17:55 -07:00
Jared
eacafaecfe [PM-33951] feat(admin-console): Add bulk confirmation and pending auto-confirmation (#7661)
* feat(admin-console): Add bulk confirmation and pending auto-confirmation methods for organization users

- Implemented ConfirmManyOrganizationUsersAsync to confirm multiple users in a single operation.
- Added GetManyPendingAutoConfirmAsync to retrieve users pending automatic confirmation.
- Created stored procedures for bulk confirmation and fetching pending users.
- Updated relevant repository interfaces and implementations across Dapper and Entity Framework.

* refactor(admin-console): Change parameter type for ConfirmManyOrganizationUsersAsync to IReadOnlyCollection

- Updated the ConfirmManyOrganizationUsersAsync method signature in the IOrganizationUserRepository and its implementations to use IReadOnlyCollection instead of IEnumerable for better performance and clarity.
- Adjusted related repository methods in both Dapper and Entity Framework implementations to reflect this change.
- Added unit tests to ensure the new implementation behaves as expected, including scenarios for mixed batches and idempotency.

* Remove OrganizationUser_ReadByOrganizationIdStatus stored procedure as part of database cleanup.

* Add integration tests for ConfirmManyOrganizationUsers and GetManyPendingAutoConfirm methods

- Introduced ConfirmManyOrganizationUsersTests to validate the confirmation of multiple organization users, ensuring only accepted users are confirmed and idempotency is maintained.
- Added GetManyPendingAutoConfirmTests to verify retrieval of pending auto-confirm users, ensuring only eligible users are returned based on specific criteria.
- Removed duplicate test implementations from OrganizationUserRepositoryTests to maintain clarity and organization in the test suite.

* Implement OrganizationUser_UpdateStatusKey stored procedure and update related repository method

- Added OrganizationUser_UpdateStatusKey stored procedure to handle updating the status and key of organization users based on a JSON input.
- Updated OrganizationUserRepository to call the new stored procedure instead of the previous confirmation procedure.
- Modified OrganizationUser_ReadByPendingAutoConfirm stored procedure to filter users by a new type value.
- Enhanced integration tests to verify the correct behavior of the updated confirmation logic, ensuring revision dates are accurately tracked.

* Refactor OrganizationUser_UpdateStatusKey to OrganizationUser_UpdateManyStatusKey

- Renamed the stored procedure to OrganizationUser_UpdateManyStatusKey to better reflect its functionality of updating multiple organization users' statuses.
- Updated the OrganizationUserRepository to call the new stored procedure.
- Adjusted the migration script to create or alter the procedure accordingly.

* Update data type for Key column in AddOrganizationUserUpdateStatusKey migration script

- Changed the data type of the Key column from NVARCHAR(MAX) to VARCHAR(MAX) in the UsersToUpdate table and the corresponding JSON parsing logic to improve compatibility and performance.

* Updated spacing

* Add stored procedures for organization user status updates and retrieval

- Created OrganizationUser_UpdateManyStatusKey to update multiple organization users' statuses based on a JSON input, including handling revision dates and tracking updated IDs for idempotency.
- Added OrganizationUser_ReadByPendingAutoConfirm to retrieve organization users pending auto-confirmation based on organization ID and specific status and type filters.

---------

Co-authored-by: mkincaid-bw <mkincaid@bitwarden.com>
2026-05-27 18:05:57 -04:00
Ike
fa850390c4 [PM-35830] Add ChangeEmailCommand (#7650)
feat: add ChangeEmailCommand [PM-35830]

- Add ChangeEmailCommand to encapsulate core email change logic 
- Add OrganizationDomainAllowEmailChangeQuery returning OrganizationDomainAllowEmailChangeDenialReason enum so callers can branch on the specific denial reason, if any
- Surface tailored BadRequestException messages per denial reason via a switch expression that fails closed on unknown values
- Push sync-only notification (no logout)
- Add unit tests covering denial reasons, domain case invariance, and the null-customerId-with-gateway path
2026-05-27 17:06:05 -04:00
renovate[bot]
9b73cd708a [deps]: Update aspire monorepo to 13.3.4 (#7729)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-27 14:49:20 -04:00
renovate[bot]
6bcf8c72cc [deps]: Pin dependencies (#7703)
* [deps]: Pin dependencies

* [deps]: Pin dependencies

* Move Aspire SDK version to global.json

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
2026-05-27 17:14:55 +00:00
Maciej Zieniuk
c57d220e04 [PM-31191] Move KDF from Auth to KM constants (#7709)
* Move KDF from Auth to KM constants

* formatting
2026-05-27 12:00:29 -05:00
Stephon Brown
5d96a614ba [PM-37820] Update Missing Tax Logic for US Customers (#7719)
* fix(billing): guard US customers from missing tax ID warning when automatic tax flag is enabled

  US has no customer-facing VAT/Tax ID equivalent, so the warning should never appear for US customers regardless of the PM37597 flag state.

* fix(billing): fix provider warnings test asserting buggy US tax ID warning behavior
2026-05-27 11:27:13 -04:00
Rui Tomé
705995d790 [PM-25691] Create OrganizationUpdateCollectionManagementCommand (#7682)
* Implement UpdateCollectionManagementSettingsCommand and associated interface for managing organization collection settings

* Add UpdateCollectionManagementSettingsCommand to handle updates to organization collection management settings.
* Create IUpdateCollectionManagementSettingsCommand interface to define the update method.
* Implement unit tests for UpdateCollectionManagementSettingsCommand to verify event logging and exception handling.

* Add IUpdateCollectionManagementSettingsCommand to service collection

* Register IUpdateCollectionManagementSettingsCommand and its implementation, UpdateCollectionManagementSettingsCommand, in the service collection for managing organization collection settings.

* Rename command

* Update OrganizationsController to use IOrganizationUpdateCollectionManagementCommand

* Added IOrganizationUpdateCollectionManagementCommand to the OrganizationsController for managing collection settings updates.
* Updated the constructor to inject the new command and modified the PutCollectionManagement method to utilize it.
* Adjusted unit tests to reflect the changes in the command used for updating collection management settings.

* Refactor IOrganizationService and OrganizationService to remove UpdateCollectionManagementSettingsAsync method

* Removed the UpdateCollectionManagementSettingsAsync method from IOrganizationService and its implementation in OrganizationService.
* Cleaned up unused usings related to collection management settings in both service files.
* Updated unit tests to reflect the removal of the collection management settings update functionality.
2026-05-27 14:10:02 +01:00
cyprain-okeke
d07a941896 [PM-37092] feat: Add business plan migration handler to SubscriptionUpdatedHandler (#7707)
* feat(billing): add Organization.ChangePlan extension for structural plan shape

Pure helper that writes plan-derived structural columns (PlanType, Plan,
Use* capability flags, UsersGetPremium, MaxCollections) without touching
customer-purchase columns. Preserves the existing UseKeyConnector carve-out.
Behavior-preserving extraction of the field-copy block at lines 287-310
of UpgradeOrganizationPlanCommand.UpgradePlanAsync.

* refactor(billing): use Organization.ChangePlan in UpgradePlanAsync

Replaces the inline structural field-copy block with a call to the new
ChangePlan helper. Customer-purchase columns (Seats, MaxStorageGb,
Enabled, UseSecretsManager) and the PremiumAccessAddon override on
UsersGetPremium stay inline at the call site. Behavior-preserving.

* feat(billing): register Teams 2020 -> current migration paths

Appends Teams2020AnnualToCurrent (byte 3) and Teams2020MonthlyToCurrent
(byte 4) to MigrationPathId and the MigrationPaths registry. Required for
the business migration handler to resolve cohorts mapped to Teams source
plans; without these entries MigrationPaths.FromId returns null and the
handler no-ops on Teams orgs in Cohort A1. Snapshot tests updated.

* chore(billing): inject migration cohort repositories into SubscriptionUpdatedHandler

Adds IOrganizationPlanMigrationCohortRepository and
IOrganizationPlanMigrationCohortAssignmentRepository as constructor
dependencies in preparation for HandleScheduleTriggeredBusinessMigrationAsync.
No behavior change.

* feat(billing): scaffold business plan Phase-2 migration handler

Adds HandleScheduleTriggeredBusinessMigrationAsync as a sibling call in
HandleAsync's organization branch, gated on PM35215_BusinessPlanPriceMigration.
Initial implementation short-circuits when ScheduleId is null. Locks the
no-op behaviour with NoScheduleId + FeatureFlagOff tests. Full handler body
lands in subsequent commits.

* feat(billing): gate business migration handler on registered source price IDs

Builds the source-price allowlist from MigrationPaths.All, using the
seat-vs-non-seat pattern (HasNonSeatBasedPasswordManagerPlan). All four
Track A 2020 plans register automatically. Skips when the previous
subscription items don't include any registered 2020 source price.

* feat(billing): resolve cohort via assignment row for business migration handler

Reads assignment by organization id (DB is source of truth), then resolves
the cohort and migration path. Stripe subscription.Metadata['migration_cohort_id']
remains stamped by PriceIncreaseScheduler for dashboard attribution but is
not consulted by the handler. Skips with a warning when the assignment is
missing, the cohort is missing, or MigrationPathId references an unregistered
path. Idempotent: skips with info-level log when assignment.MigratedDate is
already set, before any further DB reads.

* feat(billing): defensive target-price sanity check for business migration

After resolving the target plan from cohort.MigrationPath.ToPlan, verifies
the current subscription items contain the target's PM price ID (seat-aware).
Skips with a warning on mismatch to protect against operator data errors or
off-path schedule transitions.

* feat(billing): apply plan shape and mark assignment migrated on Phase 2

Completes HandleScheduleTriggeredBusinessMigrationAsync: loads the org,
calls Organization.ChangePlan(targetPlan), persists via ReplaceAsync, and
sets assignment.MigratedDate + RevisionDate before persisting the
assignment. Happy-path coverage for all four Track A pairs (Teams +
Enterprise, monthly + annual). Teams tests assert the UseScim flip - the
load-bearing capability gain for Teams 2020 -> current.

* Add more unit test

* fix: add UTF-8 BOM to .cs files for editorconfig charset compliance

* Add exception handle

* Code refactoring

* Add more unit testing

* Resolve the pr comment
2026-05-27 10:51:44 +00:00
sven-bitwarden
5a919908fc Remove outdated sprocs (#7712) 2026-05-26 16:17:47 -05:00
Stephon Brown
ee07462d28 [PM-37084] Business Aware Schedule Recovery and Cancellation (#7686)
* feat(billing): introduce unified subscription price increase scheduler API

* feat(billing): implement unified subscription price increase scheduler logic

* refactor(billing): update subscription handlers to use unified scheduler

* feat(billing): extend price migration feature flag checks

* test(billing): add and update tests for unified price increase scheduler

* fix(billing): run dotnet format

* feat(billing): expand customer and customer.discount on subscription fetch

* refactor(ReinstateSubscriptionCommandTests): rename test method for broader scope

* feat(billing): expand customer.discount in update handler

* test(billing): update test name

* feat(billing): add test clock waiting mechanism for upcoming invoices

* feat(billing): introduce cancelling user ID metadata key

* feat(billing): store cancelling user ID on subscription cancellation

* feat(billing): clear cancelling user ID on subscription reinstatement

* test(billing): update subscriber service tests for cancelling user ID

* style(SubscriberService): use 'is not null' pattern matching

* feat(SubscriberService): add PM35215 migration cohort metadata handling

* feat(SubscriberService): extend price migration deferral to PM35215

* test(SubscriberService): add and update tests for PM35215 feature

* feat(billing): Introduce OrganizationPriceIncreaseOptions

* refactor(billing): Centralize price increase eligibility in scheduler

* refactor(billing): Delegate price increase validation from UpcomingInvoiceHandler

* feat(billing): Manage price increase schedules during subscription lifecycle events

* test(billing): Update UpcomingInvoiceHandlerTests for centralized validation

* test(billing): Add PriceIncreaseScheduler tests for SkipIfAlreadyScheduled option

* test(billing): Add SubscriberService tests for price increase schedule management

* fix(billing): run dotnet format

* fix(billing): remove redundant customer expansion

* fix(billing): expand discounts for customer and subscription

* refactor(billing): Rename method to clarify dispatching role for organization scheduling

* fix(billing): Prevent clearing migration cohort metadata on cancellation

* fix(billing): Fallback to standard email when price increase migration fails

* feat(billing): improve observability for missing migration path data

* refactor(billing): simplify business plan type identification
2026-05-26 17:16:18 -04:00
Jake Fink
c8f4bb4db8 [PM-25174] Remove disable-type-0-decryption feature flag (#7717) 2026-05-26 16:04:34 -04:00
Matt Bishop
c0749eaa8d ci: pin dotnet-coverage version 2026-05-26 15:47:42 -04:00
Matt Bishop
2aeee517df Merge remote-tracking branch 'origin' into ci/github-code-coverage-upload 2026-05-26 15:33:36 -04:00
Jimmy Vo
fa1397d6ff [PM-34502] Remove the IPolicyValidator pattern (#7714) 2026-05-26 14:59:34 -04:00
sven-bitwarden
83038f3dbf remove vNext policy endpoints (#7711) 2026-05-26 12:34:40 -05:00
Matt Bishop
6c459782c0 ci: upload coverage to GitHub Actions code coverage preview
Mirror the existing codecov.io upload to GitHub's new code coverage
feature (public preview, announced 2026-05-26) so coverage shows up
directly on pull requests. Merges per-project Cobertura files with
dotnet-coverage before upload.
2026-05-26 13:28:56 -04:00
Justin Baur
8cf34b85b6 Use fixture to share state between PushControllerTests (#7433) 2026-05-26 13:26:05 -04:00
cyprain-okeke
81bec7cfff [PM 35227](server) Extend checkout endpoint for browser/desktop platforms (#7550)
* Implementation desktop and browser checkout

* Fixed the failing test

* Add a logger to see gobal settings in qa

* Add log

* fix the lint error

* Removed the log
2026-05-26 15:12:20 +01:00
John Harrington
0dd51376e9 [PM-36563] Send access event logs (#7679)
* added event type and control flow

* add EventType, control flow, and test coverage

* fix failing test and de-dupe enums

* access event log traps on auth and anon endpoints

* prioritize FF check in conditional statements
2026-05-26 07:09:50 -07:00
Rui Tomé
a56946fd13 [PM-37486] Remove IPolicyService and associated dead code (#7672)
* Refactor InitPendingOrganizationValidator to remove IPolicyService dependency and replace with IPolicyRequirementQuery for policy checks. Update related tests to reflect changes in policy validation logic.

* Refactor AccountsController and related validators to replace IPolicyService with IPolicyRequirementQuery for policy checks. Update tests accordingly to reflect changes in policy validation logic.

* Remove IPolicyService and related implementations from the codebase, updating PolicyServiceCollectionExtensions and deleting associated tests. This change streamlines policy management by relying on IPolicyRequirementQuery for policy checks.

* Refactor OrganizationUserRepository to remove GetByUserIdWithPolicyDetailsAsync method and associated tests.

* Remove unused stored procedures: OrganizationUser_ReadByUserIdWithPolicyDetails and PolicyDetails_ReadByUserId, as they are no longer called in the codebase.

* Remove OrganizationUserPolicyDetails class and associated test fixtures, as they are no longer needed in the codebase.

* Refactor BaseRequestValidatorTests to replace IPolicyService with IPolicyRequirementQuery for SSO validation checks. Update related test logic to ensure accurate policy validation outcomes. Clean up unused test fixtures in PolicyFixtures.cs to streamline the codebase.

* Refactor BaseRequestValidator and SsoRequestValidator to improve readability by storing policy requirement results in local variables before returning values. This change enhances code clarity while maintaining existing functionality.

* Refactor AccountsController to improve clarity by storing the result of the policy requirement query in a local variable before returning the enforced options. This change enhances code readability while preserving existing functionality.

* Revert "Remove unused stored procedures: OrganizationUser_ReadByUserIdWithPolicyDetails and PolicyDetails_ReadByUserId, as they are no longer called in the codebase."

This reverts commit 0f4fdca6e7.
2026-05-25 14:27:47 +01:00
Alex Dragovich
8bd4af7a38 [PM-35479] updating AutoMapper to v14 and adding cve workaround (#7521) 2026-05-22 13:33:13 -07:00
neuronull
07ac35b27c Add feature flag for SSH ecdsa (#7697) 2026-05-22 13:37:20 -06:00
Ike
e987d232ab fix: remove warning (#7698) 2026-05-22 15:35:26 -04:00
Ned Thompson
7f0aaa8a7c add folder id to cipher scenes, add full identity cipher scene (#7694) 2026-05-22 14:03:20 -04:00
Nick Krantz
659dd7b683 [PM-37785] Add vault batch bar feature flags (#7696) 2026-05-22 12:28:03 -05:00
Alex Morask
b1395aafbe [PM-37083] feat: Add per-phase price resolution to UpdateOrganizationSubscriptionCommand (#7695)
* [PM-37083] feat: Add per-phase price resolution to UpdateOrganizationSubscriptionCommand

Resolve source vs. target plan pricing per schedule phase so item changes
target the correct phase-specific price ID. Move cohort metadata onto the
schedule phases themselves to avoid Stripe normalization triggered by
direct subscription metadata updates. Filter the schedule-aware update
path to phases where EndDate > now, and drop the feature-flag gate on
PriceIncreaseScheduler.Release so schedule existence is the gate.

* Add defensive guard for source-priced single-phase migration schedules
2026-05-22 11:32:13 -05:00
Thomas Rittson
d903096a77 Move remaining Admin Password Reset code to AC Team (#7680) 2026-05-21 17:51:20 -04:00
sven-bitwarden
b848298543 [PM-37593] Add OrganizationUserStatusTypeNew - 🪓 Revoked (#7666)
* adds new OrganizationUserStatusTypeNew property to OrganizationUser

* Correctly order columns

* refresh all associated views
2026-05-21 14:08:30 -05:00
rr-bw
dcf4c486b2 [PM-35401] Update exception handling in CreateAuthRequestAsync() and PostAdminRequest() (#7615)
Adds a BadRequestException case to CreateAuthRequestAsync() and PostAdminRequest().
2026-05-21 10:49:16 -07:00
Bernd Schoolmann
31821d4a42 Add shared unlock feature flags (#7687) 2026-05-21 11:53:58 -05:00
renovate[bot]
c27eebbcff [deps]: Update dotnet monorepo to v10 (major) (#6634)
* [deps]: Update dotnet monorepo to v10

* fix up pins causing downgrades

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Derek Nance <dnance@bitwarden.com>
2026-05-21 11:28:32 -05:00
Rui Tomé
7180015ed6 [PM-37251] Add public invite link GET status endpoint (#7656)
* Implement GetOrganizationInviteLinkStatusQuery to retrieve invite link status

- Added GetOrganizationInviteLinkStatusQuery class to handle fetching the status of an organization invite link based on its code.
- Introduced OrganizationInviteLinkStatus and OrganizationInviteLinkSsoStatus records to encapsulate the invite link status and SSO information.
- Created IGetOrganizationInviteLinkStatusQuery interface to define the contract for the query implementation.

* Add unit tests for GetOrganizationInviteLinkStatusQuery

- Introduced comprehensive unit tests for GetOrganizationInviteLinkStatusQuery to validate various scenarios including successful retrieval of invite link status, handling of not found errors, and seat availability checks.
- Utilized Xunit and NSubstitute for testing and mocking dependencies, ensuring robust coverage of the query's functionality.

* Add IGetOrganizationInviteLinkStatusQuery to service collection

- Registered IGetOrganizationInviteLinkStatusQuery with the service collection to enable retrieval of organization invite link status.
- This addition supports the recently implemented GetOrganizationInviteLinkStatusQuery functionality.

* Add OrganizationInviteLinksPublicController and response models

- Introduced OrganizationInviteLinksPublicController to handle requests for organization invite link status.
- Implemented GetStatus endpoint to retrieve the status of an invite link using its GUID code.
- Added OrganizationInviteLinkStatusResponseModel and OrganizationInviteLinkSsoResponseModel to structure the response data for the invite link status.
- Ensured the endpoint is accessible to anonymous users while requiring application authorization for other actions.

* Add integration tests for OrganizationInviteLinksPublicController

- Introduced integration tests for OrganizationInviteLinksPublicController to validate the GetStatus endpoint functionality.
- Implemented tests to ensure correct handling of existing invite links and appropriate responses for valid and not found scenarios.
- Utilized Xunit and NSubstitute for testing and mocking dependencies, enhancing test coverage for invite link status retrieval.

* Updated GetOrganizationInviteLinkStatusQuery to return SSO status based on organization settings, including UseSso and UsePolicies

* Move status endpoint into OrganizationInviteLinksController as POST

* Refactor OrganizationInviteLinkStatusResponseModel and OrganizationInviteLinkStatus to remove OrganizationId property

- Removed OrganizationId property from both OrganizationInviteLinkStatusResponseModel and OrganizationInviteLinkStatus records to streamline the data model.
- Updated constructors accordingly to reflect the changes in the response models.

* Refactor GetOrganizationInviteLinkStatusQuery to simplify organization checks

- Updated the logic in GetOrganizationInviteLinkStatusQuery to streamline organization validation by combining null and enabled checks.
- Removed the dependency on IApplicationCacheService and adjusted the seat availability logic to enhance clarity and efficiency.
- Modified the return statement to use organization name directly instead of organization ID.

* Add integration tests for OrganizationInviteLinksController

- Introduced a new test method to validate the GetStatus functionality for existing invite links in OrganizationInviteLinksControllerTests.
- Enhanced existing tests to ensure correct responses for valid and not found scenarios.
- Removed OrganizationInviteLinksPublicControllerTests as its functionality is now covered in the OrganizationInviteLinksControllerTests.

* Refactor OrganizationInviteLinksControllerTests

- Updated test methods in OrganizationInviteLinksControllerTests to utilize GetOrganizationInviteLinkStatusRequestModel instead of individual parameters.
- Added a new test case to handle scenarios where the invite link status is not available, returning a BadRequest response.
- Enhanced existing tests to ensure consistent handling of valid and not found scenarios.

* Update GetOrganizationInviteLinkStatusQueryTests to enable organization for invite link tests
2026-05-21 16:27:54 +01:00
Jonathan Prusik
24bd2b5257 [PM-31021] Resolve authoring exclusions (#7688)
* remove cloud.microsoft

* Adding new Microsoft TLD to equivalent domains list

See 
https://learn.microsoft.com/en-us/microsoft-365/enterprise/cloud-microsoft-domain?view=o365-worldwide

Microsoft has a new TLD that it's migrating to

* remove Twitter equivalent domains

* Add x.com/twitter.com alias

Since twitter.com now redirects to x.com, accounts created on the old domain aren't detected automatically.

---------

Co-authored-by: silversword411 <github.com@datmail.com>
Co-authored-by: Rhys Perry <rhysperry111@gmail.com>
2026-05-21 11:12:51 -04:00
cyprain-okeke
761d8d055a [PM-36964] Add per-org migration cohort assignment to the Admin portal (#7681)
* [PM-36949] Add OrganizationPlanMigrationCohort schema and Core domain types

Add the foundation for cohort-based plan migrations:
- Two tables: OrganizationPlanMigrationCohort and OrganizationPlanMigrationCohortAssignment
- Two views and nine stored procedures (four CRUD on cohort, four CRUD plus
  ReadByOrganizationId on assignment)
- Single Migrator script for MSSQL deployment
- Core entities, MigrationPath value object and its registry, and bare repository
  interfaces under Bit.Core.Billing.Organizations.PlanMigration

The cohort table holds the human-managed metadata (name, discount coupons,
MigrationPathId byte) and the assignment table records each organization's
position in the migration lifecycle (scheduled, migrated, churn-mitigated).
Both Update SPs follow the accept-but-don't-assign pattern: immutable columns
(OrganizationId, CohortId, CreatedAt) are parameters but not SET clauses.

* [PM-36949] Add Dapper repositories for plan migration cohort tables

OrganizationPlanMigrationCohortRepository inherits the base Repository<T, TId>
CRUD methods unchanged. OrganizationPlanMigrationCohortAssignmentRepository
also relies on the base for CRUD and adds GetByOrganizationIdAsync which
returns at most one row (the UNIQUE constraint on OrganizationId at the
database layer guarantees this).

* [PM-36949] Add EF Core configurations, repositories, and provider migrations for plan migration cohort tables

- EF models wrap the Core entities; the assignment model exposes nav properties
  for Organization and Cohort so the FK + cascade-delete is inferred by EF.
- EntityTypeConfiguration classes pin ID generation to application code
  (ValueGeneratedNever) and declare the UNIQUE indexes plus the composite
  (CohortId, ScheduledAt, MigratedAt) index.
- Repositories follow the OrganizationInstallationRepository template; the
  assignment repo adds GetByOrganizationIdAsync to mirror the SP exposed on
  the MSSQL side.
- DatabaseContext gets two DbSet properties; auto-discovery picks up the
  configuration classes.
- Generated migrations for MySQL, Postgres, and SQLite create matching schemas;
  EF truncates FK and index names on providers with 64-char identifier limits,
  which is consistent with the rest of the codebase.

* [PM-36949] Wire up DI and add tests for plan migration cohort repositories

Register both Dapper and EF Core repositories in their respective service
collection extensions, following the existing AddSingleton convention in
these files.

Add tests:
- MigrationPathIdsSnapshotTests guards the immortal byte IDs that downstream
  code pins on. The class- and method-level comments document why these
  values can never be renumbered.
- MigrationPathTests covers the FromId round-trip and the null-on-unknown
  behavior the registry promises to callers.
- OrganizationPlanMigrationCohortRepositoryTests exercises CRUD, the UNIQUE
  Name constraint, and verifies that ReplaceAsync ignores CreatedAt
  mutations (per the accept-but-don't-assign Update SP).
- OrganizationPlanMigrationCohortAssignmentRepositoryTests exercises CRUD,
  GetByOrganizationIdAsync, the UNIQUE OrganizationId constraint,
  cascade-delete from both Organization and Cohort, and verifies that
  ReplaceAsync ignores OrganizationId, CohortId, and CreatedAt mutations.

* [PM-36949] Use PlanType and MigrationPathId enums on MigrationPath

Replace the byte Id with a byte-backed MigrationPathId enum and replace
the string FromPlan/ToPlan fields with PlanType. Persistence is
unchanged -- EF normalises enum-backed properties to their underlying
type in the model snapshot, and Dapper handles enum-to-byte parameter
mapping automatically.

* [PM-36949] Add *.lscache to .gitignore

* [PM-36949] fix: Override ReplaceAsync on EF cohort repositories for immutability parity

The Dapper _Update SPs accept-but-don't-assign certain columns (CreatedAt
on cohort; OrganizationId, CohortId, and CreatedAt on assignment), but
the base EF Repository<T,TEntity,Guid>.ReplaceAsync uses SetValues which
writes every scalar. Override on both repos and mark the immutable
properties as IsModified = false so MySQL/Postgres/Sqlite match MSSQL
behavior. Mirrors the existing DeviceRepository.ReplaceAsync pattern.

* [PM-36949] fix: Bound cohort string columns and widen Name to 255 chars

Add [MaxLength] attributes to the three cohort string properties so the
EF providers (MySQL/Postgres/Sqlite) enforce the same limits as MSSQL,
where the columns were already NVARCHAR-capped. Widen Name from 64 to
255 chars across MSSQL DDL, both _Create/_Update SP signatures, the
Migrator script, the entity, and all three regenerated EF migrations.
Coupon codes stay at 64 (Stripe IDs are short).

* [PM-36949] test: Lock FromPlan and ToPlan per MigrationPath

The snapshot test class doc says "byte N means a specific FromPlan ->
ToPlan transition forever", but only the byte value was being asserted.
A silent refactor of the registry's PlanType references would not have
been caught. Add per-path FromPlan/ToPlan assertions to close the gap.

* [PM-36949] chore: Apply dotnet format

* [PM-36949] test: Use LaxDateTimeComparer for round-tripped DateTimes

Postgres timestamp and MySQL datetime(6) store microsecond precision (6
fractional digits), but .NET DateTime is 100ns ticks (7 digits). Exact
Assert.Equal fails by a single tick on round-trip. Switch the three
DateTime comparisons in ReplaceAsync_UpdatesMutableColumns_AndIgnoresImmutableOnes
to LaxDateTimeComparer.Default -- the same 2ms-tolerance comparer used
by SendRepositoryTests and InstallationRepositoryTests for the same
precision issue.

* Add implementation for dropdown

* Reconcile dropdown work with renamed PM-36949 schema

After merging origin/main, the cohort schema now uses *Date suffixes
(ScheduledDate / MigratedDate / ChurnDiscountAppliedDate / CreationDate).
Rename references in the dropdown work, restore IsLocked() on the merged
entity, and re-add GetManyAsync() to the cohort repository (interface +
Dapper + EF) since the merge took main's pre-dropdown versions.

Also remove the six superseded provider migration files (20260515*) -- the
20260518* renames from origin/main are now the only cohort migrations.

* Fix UTF-8 BOM on cohort assignment unit test file

* Resolve the FF and permission issue

* Extract migration cohort resolution into a helper

Addresses PR feedback to keep the Edit action focused: the cohort
resolution/validation now lives in ResolveMigrationCohortAssignmentChangeAsync
and returns a MigrationCohortAssignmentChange record. The endpoint still
owns the page return.

---------

Co-authored-by: Alex Morask <amorask@bitwarden.com>
Co-authored-by: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com>
2026-05-21 15:17:00 +01:00
Jared McCannon
acf0c48a00 [PM-37259] - Update Sso Request Validator (#7676)
* Updated SsoRequestValidator to leverage OrgId from req

* Undoing unrelated change

* Updating tests. Removed unused query and tests. Updated SsoRequestValidator to leverage OrgId and retain multiple match hardening.

* updated xml. updated ssoorgids to orgids

* fixing some issues
2026-05-21 08:16:57 -05:00
Dave
59ded309df feat(kdf-settings-validator): Enforce salt cannot be empty string. (#7628)
* feat(kdf-settings-validator): Enforce salt cannot be empty string.

* fix(kdf-settings-validator): Prefer IsNullOrWhitespace.

* feat(salt): Make AllowEmptyStrings false for request models.
2026-05-20 17:53:48 -04:00
John Harrington
bef6306ae1 Add passkey and password history to a subset of seeded credentials (#7635)
* initial addition of passwordHistory and fido2Credentials

* distinct RpId and RpName, fix pwd strength fall-through, add tests
2026-05-20 13:57:59 -07:00
John Harrington
455a3456c0 [PM-4128] Remove nullability of Send.Data and Send.Keys (#7266)
* Send.Key and Send.Data NOT NULL

* backfill EF providers with empty strings for NULL Data or Key values

* update migration names to match current date
2026-05-20 13:05:10 -07:00