Commit Graph

760 Commits

Author SHA1 Message Date
SmithThe4th
2581be634a
[PM-40201] SSH key items with a null public key or fingerprint fail to decrypt and break the vault (#21778)
* Made public key and key finger print optional to allow derivation through the SDK

* Added feature flag constant

* Updated package

* Fixed conflicts
2026-07-20 09:15:01 -07:00
Thomas Rittson
1d382daaae
[PM-34857] Remove PoliciesInAcceptedState feature flag (#21761)
Keeping both old and new state and response properties
for now, state migration will be a separate PR.
2026-07-17 08:20:59 +10:00
Ike
f1247a86a0
[PM-27844] Set email on sync (#21349)
* feat: User is no longer logged out when their email is changed. This must be behind a feature flag until salt and email are seperated.

Addressed tech-debt as well enforcing strict typing, signals, and onPush for all components in this PR.
2026-07-16 20:20:18 +00:00
Jonathan Prusik
b13d842281
[PM-40457] Fix typos in the message catalogs (#21882)
* fix typos and update catalog references

* update message catalog keys for value-only changes
2026-07-16 09:36:33 -07:00
Bernd Schoolmann
b38c116fa6
[PM-39259] Remove deprecated randomBytes/aesGenerateKey/createKey (#21713)
Removes unused functions.
2026-07-16 06:26:36 -04:00
Jordan Aasen
44c808ea27
[PM-40195] feat: add shared-folder localization keys (#21832)
Add base English keys (sharedFolder, sharedFolders, myFolder, myFolders)
to the web, browser, desktop, and CLI en/messages.json files. Existing
collection*/folder* keys are preserved intact for rollback.
2026-07-15 16:22:58 -07:00
Bernd Schoolmann
dd31e70cc1
[PM-39259] Migrate auth token key generation to SDK (#21706)
* [PM-39259] Migrate auth to SDK key generation

* Fix login command tests
2026-07-15 06:04:57 -04:00
Ike
1a2f041cb3
[PM-27060] feat: Call SDK for password prelogin (#21777)
feat: call SDK for password prelogin (PM-27060)

- Add PM27060_PasswordPreloginFromSdk feature flag (default off) to gate the new behavior
- Update `DefaultPasswordPreloginService` to call the SDK for prelogin when the flag is enabled, falling back to the existing API-based path otherwise
2026-07-13 15:57:41 -04:00
Jared Snider
b88e564e78
Auth/PM-3813 - 2FA Management Endpoints - User Verification Refactor (#21385)
* PM-38137 - Per-provider 2FA request and response models on client

Mirror the server-side per-provider model rewrite on the client:

- Existing PUT/DELETE setup request models drop SecretVerificationRequest
  inheritance and become standalone with explicit userVerificationToken
  fields. two-factor-email.request keeps its inheritance because it also
  serves the login flow.
- New per-provider delete request models (YubiKey, Duo, Email,
  OrganizationDuo, WebAuthn delete-all) — token-only shape mirroring
  the server.
- Authenticator delete request file/class renamed from
  disable-two-factor-authenticator to delete-two-factor-authenticator
  to match server naming.
- New TwoFactorWebAuthnChallengeResponse wrapper around the FIDO2
  options + minted token (replaces the bare ChallengeResponse payload
  from get-webauthn-challenge).
- Response models for Duo, Email, WebAuthn, and YubiKey gain
  userVerificationToken.
- Obsolete two-factor-provider.request deleted (no remaining consumers
  after the disable-model rewrite).

* PM-38137 - Expose per-provider delete methods on 2FA service layer

Both TwoFactorApiService and TwoFactorService (abstractions and
implementations) pick up:

- New methods deleteTwoFactorYubiKey, deleteTwoFactorDuo,
  deleteTwoFactorEmail, deleteTwoFactorOrganizationDuo, and
  deleteTwoFactorWebAuthnAll routing to the corresponding per-provider
  DELETE endpoints.
- Removal of legacy putTwoFactorDisable and
  putTwoFactorOrganizationDisable (server endpoints are gone).
- Updated return type on getTwoFactorWebAuthnChallenge to the new
  TwoFactorWebAuthnChallengeResponse wrapper.

DefaultTwoFactorApiService spec: legacy put*Disable tests removed,
five new deleteTwoFactor* tests added, WebAuthn challenge test asserts
the new wrapper.

* PM-38137 - Thread UV token through web 2FA setup components

Per-provider setup components (Authenticator, YubiKey, Duo, Email,
WebAuthn) instantiate request models directly, cache the user
verification token from the GET response, and thread it through every
PUT / DELETE / setup-POST call. Each component implements its own
disableMethod against the appropriate per-provider DELETE endpoint:

- Authenticator, YubiKey, Email each call their corresponding
  deleteTwoFactor* method.
- Duo branches on organizationId between deleteTwoFactorDuo and
  deleteTwoFactorOrganizationDuo (the component is shared between
  personal Duo and OrgDuo setup).
- WebAuthn's "Disable All Keys" button calls
  deleteTwoFactorWebAuthnAll (single round-trip; server-side handles
  the wipe atomically). Per-credential remove continues to use
  deleteTwoFactorWebAuthn.
- WebAuthn challenge consumer reads options + userVerificationToken
  from the new wrapper response.

Base setup component disableMethod becomes protected abstract — every
subclass provides its own override. Parent settings page stops
rendering the lapsed-premium-only secondary "Disable" button; the
standard "Manage" button is now enabled for lapsed-premium users on
already-enrolled premium providers, so the same GET → DELETE flow
handles them.

* PM-38137 - Preserve lapsed-premium 2FA disable shortcut on settings list

Restores the dedicated "Disable" button shown on the 2FA settings list
when a user has lost premium but still has an enrolled premium provider
(YubiKey or Duo), and restores the disabled "Manage" button for
unenrolled premium providers — i.e., the exact UX present before this
branch.

Under the hood the shortcut now uses the new per-provider DELETE
architecture: in the user-verification dialog's verificationFn the
component calls the per-provider GET (now non-premium-gated) to mint a
UV token, then the per-provider DELETE with that token. Two server
round-trips behind one UV dialog interaction.

Avoids the regression where the standard manage flow would have opened
the full provider configuration screen to a lapsed-premium user and
let them attempt to add more keys before failing at PUT-time on the
server.

* PM-38137 - Add TODO to get rid of base 2FA setup component.

* PM-38137 - Rename 2FA update request models to TwoFactor<Provider>Update shape

Aligns every client 2FA update request-model class to the file-wide
TwoFactor<Provider> prefix already used by the Delete family:

  UpdateTwoFactorAuthenticatorRequest  -> TwoFactorAuthenticatorUpdateRequest
  UpdateTwoFactorDuoRequest            -> TwoFactorDuoUpdateRequest
  UpdateTwoFactorYubikeyOtpRequest     -> TwoFactorYubiKeyUpdateRequest
  UpdateTwoFactorEmailRequest          -> TwoFactorEmailUpdateRequest
  UpdateTwoFactorWebAuthnRequest       -> TwoFactorWebAuthnUpdateRequest
  UpdateTwoFactorWebAuthnDeleteRequest -> TwoFactorWebAuthnDeleteRequest

The YubiKey rename also aligns the class name with the TwoFactorProviderType
enum value (YubiKey, not YubicoOtp). No HTTP route or wire-shape changes.

* PM-38137 - Split Email 2FA request models by flow

The shared TwoFactorEmailRequest split into purpose-specific models:

- TwoFactorEmailLoginRequest (anonymous login flow, secret-based) drops
  the userVerificationToken field that the server-side login model no
  longer accepts.
- TwoFactorEmailSetupRequest (authenticated setup-send, token-only:
  email + userVerificationToken). postTwoFactorEmailSetup now takes this
  narrower shape instead of the union.

* PM-38137 - Guard cached UV token against null overwrite on PUT response

Only PUT responses that re-mint a user-verification token should
overwrite the cached value on the component. Without the guard, a PUT
response with a null token clobbers the live token from the prior GET,
breaking any follow-up DELETE that still runs against the same component
instance.

Matches the existing guard pattern in two-factor-setup-webauthn.component.ts.

* PM-38137 - Refactor 2FA request DTOs to constructor parameters

Convert the 13 per-provider 2FA request models added in this branch from
field-assignment classes (with `!` definite-assignment assertions) to
constructor-parameter classes. Callers now pass every required field at
construction; missing fields become compile-time errors instead of silent
`undefined` payloads.

Consumers updated:
- apps/web/src/app/auth/settings/two-factor/two-factor-setup-{authenticator,duo,email,webauthn,yubikey,}.component.ts
- libs/common/src/auth/two-factor/services/default-two-factor-api.service.spec.ts

* PM-38137 - Add 2FA provider Details and per-action response classes

Client mirror of the new server response shapes. Adds:

- TwoFactor<Provider>DetailsResponse — five per-provider Details types
  (Authenticator, Duo, Email, WebAuthn, YubiKey) carrying the shared
  provider state used by both GET and Update response wrappers.
- TwoFactor<Provider>UpdateResponse — five per-endpoint PUT responses,
  one per provider, each composing the matching Details type with no
  user-verification token slot.
- TwoFactorOrganizationDuoResponse / TwoFactorOrganizationDuoUpdateResponse —
  split from the user-scoped Duo wrappers so the two scopes can evolve
  independently while sharing the inner TwoFactorDuoDetails.
- TwoFactorWebAuthnDeleteResponse — returned by the per-credential
  WebAuthn DELETE; the updated credentials list travels in the body.

No service-surface or component wiring yet; those land in the next
commits.

* PM-38137 - Extract WebAuthn challenge response class and rename for clarity

The FIDO2 credential-creation options class previously lived inside
two-factor-web-authn.response.ts under the generic name
ChallengeResponse, which read like it could be any challenge response.
Moves the class to its own file (web-authn-challenge.response.ts) and
renames it to WebAuthnChallengeResponse so its scope is obvious at
every read site.

Touches the 2FA WebAuthn challenge wrapper (TwoFactorWebAuthnChallengeResponse)
and both passkey-login consumers (WebauthnLoginCredentialCreateOptionsResponse,
CredentialCreateOptionsView) to import the renamed type from its new
home.

* PM-38137 - Refactor 2FA service surface and components to per-action response types

Wires the client to the new per-action response shapes. The five
existing TwoFactor<Provider>Response classes are repurposed as the GET
response wrappers — each composes a TwoFactor<Provider>DetailsResponse
plus the freshly-minted user-verification token.

Service surface updated:
- DefaultTwoFactorApiService.getTwoFactor<Provider> returns the GET
  wrapper; put returns the matching *UpdateResponse.
- The six hard-delete methods return Promise<void> and pass
  hasResponse: false to ApiService.send — the matching server endpoints
  now return 204 No Content with no body. deleteTwoFactorWebAuthn
  (per-credential) keeps a body and returns TwoFactorWebAuthnDeleteResponse.
- TwoFactorService pass-through and abstractions updated to match.
- TwoFactorResponse discriminated union updated to reference the
  per-provider GET response classes (plus TwoFactorOrganizationDuoResponse).

Web setup components updated:
- processResponse split into per-action handlers (GET, Update, Delete
  where applicable) so each handler reads from the nested data
  property on its specific response type.
- The runtime `if (response.userVerificationToken)` cache guard from
  PM-38137-prior is dropped — the GET response type now guarantees the
  token non-optionally, and Update/Delete response types carry no token
  slot at all.
- DTO read sites updated from flat (`response.host`) to nested
  (`response.duo.host`) across all five providers.
- The admin-console organization parent setup component is updated for
  the new TwoFactorOrganizationDuoResponse name.

* PM-38137 - Move 2FA request/response models into two-factor feature folder

Relocates 2FA request and response model files from the convention folders
(libs/common/src/auth/models/{request,response}/) into the two-factor feature
folder, per the libs/common/src/auth/CLAUDE.md rule that new auth code belongs
in feature folders. Adds request/ and response/ barrels and re-exports them
from the two-factor index. Updates consumer imports across web, cli,
libs/auth, and libs/common.

Leaves identity-two-factor.response.ts (login-flow response, identity-token
group) and web-authn-challenge.response.ts (shared with webauthn-login)
in place to avoid cross-feature coupling.

* PM-38137 - Align authenticator delete request naming with sibling DTOs

Renames DeleteTwoFactorAuthenticatorRequest to TwoFactorAuthenticatorDeleteRequest
(file: two-factor-authenticator-delete.request.ts) so the authenticator delete
request matches the TwoFactor<Provider>Delete shape used by the duo, email,
yubikey, web-authn, and organization-duo deletes.

* PM-38137 - Move 2FA type aliases into two-factor feature folder with clearer names

Relocates the 2FA type aliases out of the convention folder
(libs/common/src/auth/types/) and into the two-factor feature folder per the
libs/common/src/auth/CLAUDE.md feature-folder rule. Renames the types so they
describe what they actually are: AuthResponseBase becomes
TwoFactorUserVerificationResult (the master-password/OTP verification proof
threaded into 2FA management request DTOs) and AuthResponse<T> becomes
TwoFactorSetupDialogData<T> (the payload passed as DIALOG_DATA into per-
provider 2FA setup dialogs). Consumers now import from the
@bitwarden/common/auth/two-factor barrel.

* PM-38137 - Correct 2FA dialog-data type docs to match constructor-param flow

TwoFactorUserVerificationResult feeds the initial GET / WebAuthn challenge POST
that mints the user-verification token, not the per-provider PUT/DELETE
endpoints — those take the cached UV token string directly. Also clarifies
that TwoFactorSetupDialogData<T> is the return type of TwoFactorVerifyDialog
before being forwarded as DIALOG_DATA to the per-provider setup dialogs.

* PM-38137 - Split TwoFactorUserVerificationResult into its own file

Extracts TwoFactorUserVerificationResult from two-factor-setup-dialog-data.ts
into two-factor-user-verification-result.ts so each type lives in its own
file. Consumers continue to import from the @bitwarden/common/auth/two-factor
barrel and are unchanged.

* PM-38137 - Convert two-factor API service imports to relative paths

Restores relative imports inside the three two-factor API service files
to match the pattern that landed on main. Sibling two-factor service files
were already relative; these three drifted to absolute @bitwarden/common
paths during the refactor.

* PM-38137 - Drop !: on cached userVerificationToken in 2FA setup components

Replaces the definite-assignment assertion on the cached
userVerificationToken with an honest string | undefined type and a
requireUserVerificationToken() helper that throws if the field hasn't
been populated yet. Aligns with the typescript-strict ADR (!: is reserved
for required @Input properties) and turns a silent undefined-into-request
hazard into an explicit runtime error. The base-class composition refactor
tracked by PM-39385 will eventually eliminate the cached field entirely.

* PM-38137 - Rename applyXxxState param to details for clarity

The applyXxxState helpers in the Duo, Email, WebAuthn, and YubiKey setup
components took a TwoFactorXxxDetailsResponse but named the parameter after
the wrapper field (yubiKey, duo, emailData, webAuthn), which made accesses
like yubiKey.key1 read as if poking the wrapper rather than the details.
Renames the parameter to details across all four; the enclosing function
name already establishes which provider it is.

* PM-38137 - 2FA Setup comp base - add TODO

* PM-38137 - Prefix applyXxxState param with provider name

Renames the applyXxxState parameter from details to <provider>Details in
the Duo, Email, WebAuthn, and YubiKey setup components. Trades a few extra
characters per access for clearer reading at the call site
(e.g. yubiKeyDetails.key1 over details.key1).

* PM-38137 - Rename applyXxxState to applyXxxDetails in 2FA setup components

The applyXxxState helpers project a per-provider details payload into
local form controls and display flags; "State" misleadingly suggested
writes to the app's state framework. Renames to applyXxxDetails across
authenticator, duo, email, webauthn, and yubikey setup components.

* PM-38137 - Run prettier on 2FA setup/verify components

* PM-38137 - Reword 2FA delete doc strings to drop stale disable verbiage

Updates the per-provider delete docstrings on the 2FA service abstractions
and one inline WebAuthn comment that still described the operation as
"disabling the provider" — the operation is a hard delete, not a soft
disable. User-facing UI strings (the "Disable" button label, dialog
title) and method names that mirror that UI concept are unchanged.

* PM-38137 - Inline processUpdate/processDeleteResponse pass-throughs

Removes the processUpdateResponse and processDeleteResponse helpers
in the 5 2FA setup components — each body was a single-line wrapper
that called applyXxxDetails(response.xxx). Call sites now apply the
details directly, which makes the unwrap visible inline. The
processGetResponse helper stays because it bundles two coordinated
steps (cache user-verification token + apply details).

Also drops now-unused TwoFactor*UpdateResponse imports in each file.

* PM-38137 - Replace endpoint-fragile 2FA response docstrings with single sentences

Each 2FA wrapper response file had a docstring naming the specific server
endpoint that produced it (e.g. \`POST /two-factor/get-authenticator\`),
which breaks the moment the server renames an endpoint. Replaces with
one-sentence descriptions that describe what the response represents —
no endpoint coupling.

* PM-38137 - Replay UV token on get-webauthn-challenge client call

Switches the WebAuthn challenge client call from a single-use
SecretVerificationRequest to the new TwoFactorWebAuthnChallengeRequest
carrying the cached user-verification token minted by
getTwoFactorWebAuthn. Drops the now-stale userVerificationToken field
from TwoFactorWebAuthnChallengeResponse — the original token stays
valid through the subsequent PUT. Fixes the passwordless (TDE /
Key Connector) WebAuthn enrollment failure where the second use of
the OTP was rejected.

* PM-38137 - Guard cached UV token in 2FA authenticator setup component

Adds the requireUserVerificationToken() helper already present in the
duo/email/webauthn/yubikey setup components. Authenticator was the
only setup component still passing the raw string | undefined field
into request DTOs — silently allowed only because the file is
@ts-strict-ignore. The helper throws if the token wasn't populated,
keeping all five components consistent.

---------

Co-authored-by: Patrick-Pimentel-Bitwarden <ppimentel@bitwarden.com>
2026-07-13 14:04:15 -04:00
github-actions[bot]
e711cc99e5
Bumped client version(s) (#21811)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-13 11:32:28 -04:00
Addison Beck
7882bedb3e
feat(platform): introduce GovModeService for FedRAMP region gating [PM-38020] (#21366)
GovModeService is a shared Platform service that downstream teams consume to
gate FedRAMP-specific behavior.

The MVP implementation infers the gov-mode signal from the client-side Region
(true when `env.getRegion() === Region.Gov`). PM-36520 will replace the
implementation with a server-backed check while keeping this contract stable.

The service exposes two Observable surfaces: `globalIsGovMode$` (pre-login) and
`isGovMode$(userId)` (when a UserId is in scope). Consumers needing a Promise
snapshot bridge with `firstValueFrom` at the call-site -- the synthesis memory
A5086F94 captured the decision to omit Promise overloads from the service
surface.

Registered in all four app bootstraps: Angular DI (jslib-services.module),
browser background, CLI service-container, and desktop main. Unit tests cover
all four regions (Gov, US, EU, SelfHosted) for both API surfaces.
2026-07-10 11:57:11 -04:00
adudek-bw
474e3eb2b7
[PM-38392] Route password-protected Send saves through the SDK (#21725)
* [PM-38392] Route password-protected Send saves through the SDK

The SDK now exposes a `hashedPassword` SendAuthType variant (PM-38391,
sdk-internal #1197, present in the pinned 0.2.0-main.872) that forwards the
client-derived keyB64 verbatim without re-applying PBKDF2. Drop the temporary
workaround that routed password-protected saves to the legacy SendApiService.

- buildSendAuth: add AuthType.Password case returning
  { type: "hashedPassword", keyB64: sendView.password }, guarded against a
  missing derived key. keyB64 is a proof-of-knowledge and is never logged.
- Remove the password-protected save guards from SendApiServiceSelector and
  SendSdkApiService; the new-file-send fallback is unchanged.
- Update the now-stale workaround doc comments.
- Tests: flip selector password create/edit assertions to SDK routing; add
  send-sdk-api.service.spec.ts covering the hashedPassword output, the
  null-key guard, the none variant, and the new-file-send guard.

* [PM-38392] Use SDK high-level password auth for password-protected sends

The prior approach forwarded the client's pre-derived keyB64 to the SDK via
the hashedPassword variant. That is broken for creates: the SDK's create
generates its own send key, so a keyB64 derived over the client's (discarded)
key yields a password the user can never satisfy (verified end-to-end: correct
password rejected on receive). A maintainer also asked to move clients onto the
higher-level password API rather than the low-level hashed variant
(sdk-internal#1197).

Route password-protected sends through the SDK's plaintext `password` auth
variant so the SDK derives the proof-of-knowledge over the key it uses,
keeping password and key consistent by construction:

- Thread an optional plaintext password through SendApiService.save (abstraction
  + selector + legacy [ignored] + SDK impl) from the four callers that hold it
  at the encrypt() call (CLI create/edit, send-ui form service, angular
  add-edit).
- buildSendAuth: emit { type: "password", password } when a plaintext is present
  (create / password-change); emit { type: "hashedPassword", keyB64 } only for
  preserve-on-edit, where the SDK reuses the existing send key so the stored
  keyB64 stays valid. The existing keyB64 is recovered from stored state via
  getFromState (the freshly-encrypted Send carries none on a preserving edit).
- Plaintext password and keyB64 are Protected Data; never logged.

Verified: password create via SDK -> receive with correct password decrypts,
wrong password rejected. Unit tests cover all four buildSendAuth cases.

* [PM-38392] Only recover existing send password for password-protected edits

Address review S1: the existing-keyB64 recovery via getFromState fired on
every non-create save, including name-only edits of None/Email sends, whose
result buildSendAuth then ignores. Gate the state read on
send.authType === AuthType.Password so it only runs when the preserve-on-edit
branch can actually use it.

* Update apps/cli/src/tools/send/commands/create.command.ts

Co-authored-by: John Harrington <84741727+harr1424@users.noreply.github.com>

* Update apps/cli/src/tools/send/commands/edit.command.ts

Co-authored-by: John Harrington <84741727+harr1424@users.noreply.github.com>

---------

Co-authored-by: John Harrington <84741727+harr1424@users.noreply.github.com>
2026-07-10 09:30:18 -04:00
John Harrington
a87d5c026a
[PM-38387] Introduce KeePass KDBX importer (#21052)
* initial implementation

* mapped otp/totp

* move business logic to SDK

* address ai review findings

* implement design specs

* fix i18n value

* update help url

* refactor imports to use relative paths

* remove warning callout and add external-icon

---------

Co-authored-by: Alex Dragovich <46065570+itsadrago@users.noreply.github.com>
2026-07-10 06:23:31 -07:00
Addison Beck
97ea9c7dcd
feat: add Region.Gov to available environments (#21211)
* feat(platform): add Region.Gov and Gov entry to PRODUCTION_REGIONS [PM-38018]

Adds Gov: "Gov" to the Region const object (between EU and SelfHosted)
and appends a third entry to PRODUCTION_REGIONS alongside US and EU.
The CloudRegion type (Exclude<Region, "Self-hosted">) automatically
includes Gov.

The Gov entry uses bitwarden-gov.com as its domain with all subdomain
URLs explicit. The send URL is stored bare (no trailing /#/) per the
convention established by PM-2588 — getSendUrl() appends the hash at
read time.

Region.Gov is the foundational constant for the GovMode / FedRAMP cloud
environment work tracked under PM-35087. Flag-gated visibility in the
environment selector is introduced separately in PM-38019 via
AvailableRegionsService; this commit deliberately makes the region
unconditionally returned by EnvironmentService.availableRegions().

DEFAULT_MARKETING_EMAILS_PREF_BY_REGION in registration-start.component
gets a Gov: false entry to satisfy the Record<Region, boolean> type.

* feat: introduce AvailableRegionsService for runtime region filtering

Creates AvailableRegionsService and DefaultAvailableRegionsService in
libs/common/src/platform/. The service exposes availableRegions$, a
flag-gated Observable that wraps EnvironmentService.availableRegions()
and filters Region.Gov by the FedRampGovRegion feature flag. US and EU
are always present regardless of flag state.

EnvironmentService cannot hold this filter directly: ConfigService
depends on EnvironmentService to resolve API URLs, so wiring the
feature-flag check into EnvironmentService would create a circular
dependency. AvailableRegionsService sits above both and composes them.

The implementation uses startWith(false) so Gov is hidden until the flag
value arrives from the server. This avoids a flicker where Gov would
briefly appear during cold start before the flag resolves.

Registered in the renderer Angular DI module (covers web and desktop
renderer), the browser background script, and the CLI service container.
apps/desktop/src/main.ts intentionally excludes the service: no
main-process consumer needs a flag-gated region list, and desktop main
does not construct ConfigService, so registering here would require a
feature-flag shim to satisfy a constructor dependency with no consumer.

The accompanying spec covers four behaviors: Gov inclusion when the flag
is true, Gov exclusion when the flag is false, Gov exclusion on the
initial startWith(false) seed before the flag emits, and the US/EU
invariant across both flag states. Asserts inspect the last emission of
a take(2) window rather than firstValueFrom because the startWith(false)
seed always emits first regardless of the flag value, so asserting the
first emission would falsely pass for the wrong reason.

The selector-component migration that consumes this service lands in
a follow-up commit on the same branch. Shipping both in one PR closes
the release window where Gov could leak into the environment selector
because unmigrated selectors read EnvironmentService.availableRegions()
directly and never observe the flag.

* refactor(auth): migrate environment selector components to AvailableRegionsService

Migrates the three environment-selector components from
EnvironmentService.availableRegions() to AvailableRegionsService.
availableRegions$. Each component receives AvailableRegionsService via
constructor injection and replaces the synchronous availableRegions
array with the flag-gated Observable. All three templates switch from
synchronous-field iteration to the | async pipe.

The web selector resolves currentRegion synchronously via
EnvironmentService.availableRegions() rather than the flag-gated stream,
because origin validation must succeed regardless of flag state. The dropdown
options continue to use availableRegions$ | async. This pattern matches the
JSDoc guidance on AvailableRegionsService: the service is the UI display
source, while EnvironmentService.availableRegions() is the source for URL
resolution, origin validation, and stored-region rehydration.

The shared and registration components use combineLatest to pair the
flag-gated region list with the active-environment stream so
selectedRegion$ stays in sync with changes to either source. The
registration component's Environment import becomes unused after
combineLatest infers the type that the previous map(env: Environment)
annotation required, and is removed to satisfy ESLint's
@typescript-eslint/no-unused-vars rule.

Shipping this migration in the same PR as the AvailableRegionsService
introduction closes the release window where Gov could leak into any
client's environment selector. Unmigrated selectors read
EnvironmentService.availableRegions() directly and would surface Gov
unconditionally; migrating them in this PR makes the FedRampGovRegion
flag the single gate for selector visibility.

These three components live in Auth-owned paths
(libs/angular/src/auth/, apps/web/src/app/components/, and
libs/auth/src/angular/registration/). Auth is a required reviewer on
this PR.

* fix(auth): provide AvailableRegionsService mock in stories

* fix(auth): align env-picker dropdown icon vertically

The trigger's <bit-icon bwi-angle-down> renders inline-block with
vertical-align: baseline, which hangs below the baseline of the
line box. Combined with bitLink's tw-leading-none, this clipped
the text descenders of the "Accessing:" label on desktop and
browser login footers.

Adding tw-align-middle to the icon restores normal line-box
metrics and eliminates the clipping.

Root cause latent since PR #18816 migrated the trigger icon from
<i class="bwi"> to <bit-icon>. Web is unaffected because its
trigger uses an inline-flex <a bitLink>. This fix is
flag-independent — FedRampGovRegion only gates dropdown contents,
not the trigger label.

Refs: PM-39401

* Revert "fix(auth): align env-picker dropdown icon vertically"

This reverts commit 2d51461be9.

---------

Co-authored-by: kmancusi0105 <kmancusi@bitwarden.com>
2026-07-09 15:17:26 -04:00
Brandon Treston
637f134c3c
[PM-38595] Update local collections from server response (#21744)
* update local collections from server response

* fix conditional
2026-07-09 11:35:25 -04:00
Bernd Schoolmann
a8f8605a69
[PM-39259] Migrate vault export and generator to SDK random number client (#21708)
* [PM-39259] Migrate tools to SDK randomness

* fix(tests): Fix tests for sdk randomizer
2026-07-09 07:38:31 -07:00
adudek-bw
aeb73d25a3
[PM-31068] Wire send SDK repository for edit/removePassword (#21579)
* [PM-31068] Wire send SDK repository for edit/removePassword

Add domain<->SDK Send conversions (toSdkSend/fromSdkSend/toSendData on
Send, SendText, SendFile), a SendRecordMapper backed by
SEND_USER_ENCRYPTED, and register the `send` repository in
client-managed-state so the SDK can read/write the existing send from the
same state legacy sync already populates.

SendClient.edit/get/list/remove_password resolve the existing send via
state().get::<Send>(); without a registered send repository that state was
empty, so SDK-backed send edit hung and remove-password failed (PM-39432).
Registering the repository fixes both (validated end-to-end on web + the
browser extension).

Requires an @bitwarden/sdk-internal version that exposes `send` in
Repositories (paired SDK PR). package.json is still pinned to 0.2.0-main.803;
bump to the published version once the SDK change lands — until then this
branch does not type-check/build on a clean checkout.

* Address review: fix stale mapper doc comment, normalize fromSdkSend text/file to null

* Bump @bitwarden/sdk-internal to 0.2.0-main.870 for send repository

* [PM-39436] Fix CLI SDK sends: construct sdkService before send services

SendApiServiceSelector was constructed with `new SendSdkApiService(this.sdkService, ...)`
before `this.sdkService` was assigned, so SendSdkApiService captured `undefined`. With
the pm-30110-sdk-sends-api flag on, every SDK-routed send mutation (create/edit/delete/
remove-password) threw `Cannot read properties of undefined (reading 'userClient$')`.
Reads worked because they read local state, not the SDK.

Move the sdkClientFactory/sdkLoadService/sdkService construction above the send-service
block. All DefaultSdkService dependencies are defined earlier in the method, and
registerSdkService still references sdkClientFactory from the same scope.

Validated end-to-end on a local self-hosted server (flag on): create, edit,
remove-password, and delete all succeed via the SDK path.

* Re-trigger CI on node 24/npm 11 workflows (post node-24 migration)
2026-07-09 10:27:33 -04:00
Dmitry Yakimenko
bb3748f265
[PM-33198] Keeper direct importer (#19395)
* Direct Keeper importer UI and a dummy access module (WIP)

* Add Keeper importer impl, fix it to run in the browser not node (WIP)

* Add request logging to Keeper client

* Auto-close Keeper device approval dialog on websocket notification

When user approves their device via email link, the websocket receives a
device_verified notification. Previously the dialog remained open requiring
manual dismissal. Now the dialog closes automatically when approval succeeds.

* Remove Continue button from Keeper device approval dialog

The button did not actually do anything useful since approval happens via
email link click. Updated dialog to show a message that it will close
automatically. Added missing Keeper i18n messages to web app.

* Add device approval method selection dialog for Keeper import

- Created KeeperApprovalMethodSelectComponent to let user choose between
  Email and Keeper Push approval methods
- Removed TwoFactor from DeviceApprovalChannel (not supported yet)
- Show waiting dialog for Keeper Push approval (was missing)
- Added i18n messages for approval method selection
- Added debug logging for push requests

* Add Keeper data center region selection dropdown

- Added region dropdown with US, EU, AU, CA, JP, US (GOV) options
- Region is passed to Keeper client when opening vault
- Updated test script to select EU region
- Added i18n messages for region label

* Add verification code input to Keeper device approval dialog

Users can now either click the approval link in the email or enter the
6-digit verification code directly in the dialog. Both methods work to
approve the device and continue the import flow.

* Fix AES-CBC no-padding decryption for Keeper encryption params

Web Crypto API requires PKCS7 padding for AES-CBC decryption. The previous
workaround of appending zeros failed because decrypted zeros do not produce
valid PKCS7 padding bytes.

New approach: encrypt a proper PKCS7 padding block (16 bytes of 0x10) using
the last ciphertext block as IV, then append this encrypted padding to create
valid padded ciphertext that Web Crypto can decrypt.

* More scripts for testing

* Remove generated files we don't need

* Test scripts (remove later)

* Refactor the sync-down processing to be able to test easier

* Fix lint errors

* Cleanup

* New token

* New fixture and export

* Some tests

* Move the code into a new place

* Simplify Vault spec

* Use BaseImporter

* Add more record types

* Disable console.log in tests

* Update test data and tests

* Test each record type

* Fix folders

* Major refactor

* Decrypt shared record keys

* Remove account summary

* Add folders to records

* Build all paths

* Collect paths for all records

* uidToString

* Refactor base64 URL encoding/decoding using Utils from common library

* Add README for Direct Keeper importer and refactor VaultItem handling

* Refactor KeeperDirectImporter to streamline password and username handling in import process

* Implement reference collection and resolution in KeeperDirectImporter

* TODO

* More TODOs

* 2FA selection

* Handle SMS

* Add .proto and proto compiler to generate .ts from .proto

* Remove debugging code

* Delete debug scripts

* Update readme

* Update proto build script to disable ESLint checks for generated files

* Remove keeper-export.json

* Refactor ClientOptions to use KeeperRegion const object

* Remove includeSharedFolders option

* Make sure nx serve builds proto

* Clean up crypto

* Clean up crypto.ts

* cleanup

* Remove unnecessary exception class

* Move fixture into proper place, fix tests

* Move code around to match lastpass/access structure better

* Add protobuf generation step to CI test workflow

* Fix date expectations in keeper direct importer tests

* Build .proto files before typechecking

* Fix npm run test:types errors

* Rename .proto files to kebap case to prevent CI lint warnings about having capital case letters in filenames

* Commit generated protobuf TS files and remove build-time proto generation

The protobuf build step was causing CI issues. Generated TS files are now
committed directly. Proto source files remain as reference with a README
documenting how to regenerate.

* Change npx instruction to run directly from npm

* Add generated files README, update proto README

* Update TODO comment in vault.ts

* Add @protobuf-ts/runtime to Tools dep ownership in renovate config

* Implement Duo 2FA support for Keeper direct importer

- Fix Duo Passcode/SMS using wrong value type (TWO_FA_CODE_TOTP -> TWO_FA_CODE_DUO)
- Remove unnecessary socket wait after Passcode/SMS validation (token returned directly by API)
- Add waiting dialog for Duo Push/Voice methods instead of just showing a spinner
- Add code input support for Duo Passcode/SMS methods
- Make all Ui interface methods required

* Fix README

* Changes suggested by @quexten (doc comments)

* Fix TS type checked warnings

* Filter out unsupported 2FA methods from UI

* Skip file-based import flow for Keeper direct import

* Show error when no supported 2FA found but 2FA is required

* Migrate from @protobuf-ts/runtime to @bufbuild/protobuf

* Track possible cycles in the folder strcuture and break them (was suggested in review)

* Fix leftover merge conflict marker in web messages.json

* [PM-33198] angular modernization changes

* Remove KeeperPush from supported 2FAs for now, update README with more TODOs

* Reuse existing 'email' i18n key instead of keeperApprovalMethodEmail

* Reuse existing 'verificationCode' i18n key instead of keeperVerificationCode

* Replace keeperMFADesc with generic mfaTotpDesc i18n key

* Consolidate keeperTwoFactorSms and keeperDuoSms into generic textMessageSms i18n key

* Rename keeperTwoFactorBackup and keeperTwoFactorDuo to generic i18n keys

* Rename keeperDuo* i18n keys to generic duoVerification/duoPushWaiting/duoSmsWaiting/duoVoiceWaiting

* Consolidate keeperTwoFactorUnknown and keeperDuoUnknown into generic unknownMethod i18n key

* Reuse existing 'passcode' i18n key instead of keeperDuoPasscode

* Rename keeperRegion to generic dataCenterLocation i18n key

* Rename keeperSelectApprovalMethod* to generic selectApprovalMethod* i18n keys

* Rename keeperDeviceApprovalEmailDesc to generic approvalEmailDesc i18n key

* Rename generic keeper-prefixed i18n keys to content-driven names

* Rename keeperSelect* i18n keys to generic selectTwoFactorMethod/selectDuoMethod

* Rename remaining keeper-prefixed i18n keys to content-driven names

Consolidate keeperApprovalMethodPush and keeperTwoFactorKeeperPush into
single keeperPush key.

* Add Keeper DNA Push 2FA support for direct importer

* Add Keeper DNA manual code entry

* Add two-factor authentication as device approval method

* Mark DNA and backup codes as done.

* Add TryAnother sentinel and loop device approval flow

* Add 'Try another method' button to Keeper device approval

* Unify Keeper importer auth flow into a single dialog

* Remove unused per-state Keeper dialog components

* Hide empty Keeper email hint to remove gap below the field

* Defer Keeper password prompt until server requests it

* Split Keeper direct importer into its own format option

* Refine Keeper email and region field labels

* Redesign Keeper auth dialog and route Try another method back to selection

* Restyle Keeper master password dialog and route close to cancel

* Show Keeper email subtitle on every auth dialog stage

* Add Cancel to single-button Keeper auth stages and use Continue label

* Use radio buttons for Keeper two-factor method selection

* Group Keeper auth dialog by stage via reusable shell

Each @case now contains one self-contained <keeper-stage-shell> block
with a comment header. The shell wraps bit-dialog and holds the
stage-independent header bits (X close button, title with email
subtitle), forwarding bitDialogContent and bitDialogFooter slots through
via ngProjectAs. Footer projection is gated by an explicit [hasFooter]
input — bit-dialog detects its footer via contentChild on a real
DialogFooterDirective, and ngProjectAs alone does not satisfy that
check.

The shell also sets disableAnimations on the inner bit-dialog, so stage
transitions no longer slide.

* Use radio buttons for Keeper Duo and DNA method selection

* Move Keeper auth dialog footer buttons into the stage shell

* Match Keeper email approval dialog to design and fix Resend

- Split approvalCode email vs push: email gets "Email verification"
  title, no spinner, and a Resend code link
- Update i18n copy for Approval methods, descriptions, and add
  emailVerification, twoFactorMethod, plus refined approvalEmailDesc
- Fix Resend handling in handleDeviceApproval so re-requesting the
  verification email keeps the dialog open instead of throwing

* Match Keeper push approval dialog to design

* Match Keeper 2FA code dialog to design and support resend

* Trigger 2FA push on device approval and wire resend

* Show method-specific copy for TOTP and SMS 2FA prompts

* Streamline Keeper DNA flow and pick up watch approval via socket

* Show loading spinner on Continue while validating master password

* Drop Try another method from 2FA and DNA push dialogs

* Tidy Keeper import callout copy and rename email field

* Unify device approval dialog titles and restore Try another method on 2FA approval

* Add Keeper Cloud SSO, admin approval, and browser auto-capture

* Add Keeper import Method dropdown for direct, CSV, and JSON

* Auto-capture Keeper SSO token in browser via spinner stage

* Mark temp feature for removal

* Retry Keeper approval and 2FA codes on server rejection

* Update Keeper push/admin approval dialog copy and add heading

* Skip Keeper SSO dialog on browser extension

* Confirm before cancelling Keeper admin approval flow

* Attach Keeper import async validator to email control

* Simplify Keeper spinner block spacing to typography defaults

* Restyle admin approval cancel confirmation as danger

* Restore missing ImportResult import after upstream merge

* Retry Keeper master password on server rejection

* Clean up PR hygiene: remove stray lock file and proto EOF blanks

* Use bitIconButton label input for accessible close button

* Reject Keeper SSO login when user closes IdP tab

* Restore Keeper csv/json importers for CLI and hide from web dropdown

* Move Keeper direct import out of async validator into explicit submit

* Fix strict-mode type errors in Keeper device approval flow

* Set organizationId on Keeper direct importer so org imports keep folders

* Require email for Keeper direct import and show login errors in the field

* Keep browser import in persistent context

* Fix package-lock.json to match @bufbuild/protobuf 2.11.0 in package.json

* Remove leftover merge conflict marker in web messages.json

* Fix formatting in vault.spec.ts

* Update Keeper importer README reviewers section

* Clarify Windows File Send test name

* Anchor Keeper SSO callback URL regex to https:// to prevent substring matches

* Route Keeper SSO script injection through BrowserApi abstraction

* Reject default Keeper SSO monitor promise instead of leaving it pending

* Replace string-matched Keeper auth errors with typed error codes

* Clean up Keeper importer dead code and i18n inconsistencies

* Resolve linked record keys and report skipped items in Keeper direct import

* Update partial import dialog copy and aggregate skipped items by type

* Show skipped item types in Keeper partial import dialog

* List skipped item names instead of record types in Keeper import dialog

* Revert "List skipped item names instead of record types in Keeper import dialog"

This reverts commit b504becf45.

* Identify Keeper import errors by record UID instead of decrypted name

* Relabel Keeper driverLicense import type as Driver's licence

* Fix NG0100 in import dialog when selecting Keeper format

* [PM-33198] adding opaque types for type safety

* [PM-33198] implement constant time checks to prevent timing attacks

* Address Keeper direct importer review feedback

- Move keeper from the pinned top of featuredImportOptions to its
  alphabetical position after KeePass 2 (featured list renders in array order)
- Reword the import-keeper component comment from a review note into
  production documentation
- Drop the now-resolved README note about the temporary pinning

* Abort Keeper import when a push socket message can't be processed

A push frame that failed to decrypt or parse was silently swallowed, so the
consumer racing on waitForMessage never resolved and the import hung with no
trace. Fail the socket instead: reject the waiting consumer, which unwinds the
login and surfaces a connection error to the user. The error carries only
structural metadata (stage, byte count, error name), never frame contents.

* Restart Keeper login when the login token expires during device approval

* Merge bitwarden:main

* Revert "Merge bitwarden:main"

This reverts commit b9c1f2df96.

* Map Keeper Direct import identity records to correct item types

driverLicense, ssnCard and passport now import as Identity and invalid SSH keys fall back to a secure note, matching the Keeper JSON importer.

---------

Co-authored-by: Alex Dragovich <adragovich@bitwarden.com>
Co-authored-by: Alex Dragovich <46065570+itsadrago@users.noreply.github.com>
2026-07-09 06:14:15 -07:00
Bernd Schoolmann
7fd44eb77d
[PM-39259] Migrate key-management key-generation to SDK (#21707) 2026-07-09 17:25:06 +09:00
Daniel García
8eed0189bb
[PM-35903] Update clients to node 24 (#20400)
* [PM-35903] Update clients to node 24

* Fix lockfile

* Add missing jest dep

* Fix dispose polyfill

* Revert jest-jsdom

* Bump dockerfile

* Add missing dep

* Fix node 24.16 bug

---------

Co-authored-by: kmancusi0105 <kmancusi@bitwarden.com>
2026-07-08 16:32:10 +02:00
renovate[bot]
d6f933078e
[deps] Vault: Update multer to v2.2.0 [SECURITY] (#21396)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-29 09:51:02 -07:00
renovate[bot]
38550c7bc1
[deps] Vault: Update form-data to v4.0.6 [SECURITY] (#21279)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-29 08:44:32 -07:00
Brandon Treston
8d073aec13
[PM-36407] Ts strict bulk member components (#21455)
* refactor bulk memmber action dialogs to be ts-strict

* add stories

* fix type errors in stories

* fix stories, fix more types

* fix type errors
2026-06-29 11:04:16 -04:00
bmbitwarden
5d49771fe8
PM-39449 resolved root url issues (#21468)
* PM-39449 resolved root url issues

* PM-39449 resolved pr comments

* Update comments in getSendUrl method

Clarified comments regarding trailing slashes for Bitwarden environments and self-hosted URLs.

* Enhance custom send URL handling

Added handling for custom send URLs in default-environment service.

* PM-39449 just ran the prettier

* [PM-39449] no eu send vanity link

* [PM-39449] fixing test

* [PM-39449] fixing tests

---------

Co-authored-by: Alex Dragovich <46065570+itsadrago@users.noreply.github.com>
Co-authored-by: Alex Dragovich <adragovich@bitwarden.com>
2026-06-25 10:36:38 -07:00
renovate[bot]
9187f02c7d
[deps] Vault: Update https-proxy-agent to v9.1.0 (#21408)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-24 15:58:43 -07:00
renovate[bot]
a889ab9422
[deps] Vault: Update @koa/router to v15.6.0 (#21114)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-24 15:15:37 -07:00
Jordan Aasen
8ce7ca7afb
[PM-27041] - CLI - respect passphrase param in /generate (#21290)
* CLI - respect passphrase param in /generate

* remove ts-ignore
2026-06-24 09:53:45 -07:00
Bernd Schoolmann
2592ccf7ad
[PM-37875] Automatic V2 Upgrade Migration (#20831) 2026-06-23 17:47:47 +09:00
bmbitwarden
187a3b741a
PM-31884 implemented controls for send policy access dropdown (#19777)
* initial send controls

* initial send controls

* fix tests

* extract service and respond to other review comments

* remove unused import

* dry up policy service, null safety, and test coverage

* add missing import

* remove unused AccountBillingClient

* fix lints

* OR SendPolicyService status

* replace import lost during merge

* PM-31884 implemented controls for send policy access dropdown

* PM-31884 implemented enforce the policy on the web client

* [PM-31884] Add Send control policy access control fields

* PM-31884 support disabled use case in form and table

* Correct Send auth type option display logic, a couple other fixes

* PM-31884 refactored as WhoCanAccessType type

* PM-31884 iterating over strings

* PM-31884 resolved typos

* A few more fixes

* Update design, address PR comments

* Final design review tweaks, address PR comments, simplify translation key changes

* Address two comments

* Adjust select option type, add start value for enabled valueChange

* Cleanup from fixing merge conflicts, finalize design, add to browser

* Address AI review comments

* One more AI review fix

* Two design tweaks to policy editor

* Address some QA findings and standardize discard edits translation keys

* Correct design when disabled Send cannot be copied

* Address a couple bugs

* Resolve build error and one display bug

---------

Co-authored-by: John Harrington <84741727+harr1424@users.noreply.github.com>
Co-authored-by: Mike Amirault <mamirault@bitwarden.com>
2026-06-16 10:31:05 -04:00
github-actions[bot]
da6603de29
Bumped client version(s) (#21271)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-15 13:14:17 -04:00
bmbitwarden
ccf047fc63
PM-2588 resolved sends root url conditionally (#20684)
* PM-2588 resolved sends root url conditionally

* PM-2588 resolved pr request to add sens to option list

* PM-2588 resolved pr comment re url hash

* PM-2588 resolved pr comment re getUrl pattern

* PM-2588 resolved pr comment re availableRegions()

* PM-2588 resolved pr comment re web url plumbing

* PM=2588 resolved failing tests

* PM-2588 resolved pr comment  the inconsistency for the || null

* PM-2588 resolved pr comment re: Hydration of the saved Send URL

* PM-2588 resolved pr comment re translation key

* PM-2588 resolved pr comment Self-hosted regression when only webVault is configured

* PM-2588 resolved pr comment re update the selfHostedEnvSettingsFormValidator logic to consider the send url
2026-06-10 17:28:53 -04:00
renovate[bot]
110ee89f8d
[deps] Autofill: Update tldts to v7.4.2 (#21112)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-10 08:11:13 -07:00
Bernd Schoolmann
5ddbf986cd
[PM-31059] Implement SDK managed PIN unlock (#20395)
* Implement state bridge support

* Implement SDK managed PIN unlock

* Update package.lock

* Update sdk

* Prettier

* Fix test mock

* Cleanup

* Cleanup

* Fix name

* Add timeout

* Fix type issue

* prettier

* Remove unecessary try catch

* Add comment

* Cleanup

* Delete spec file

* Fix missing userid

* Cleanup

* Fix DI

* Fix build errors

* Fix tests

* Fix desktop and browser builds

* Fix spec

* Remove unused vars

* Fix eslint

* Prettier and replace pin polling

* Cleanup

* Clean up unlock service

* Undo change to spec ts

* Rename unlock decrypted key

* Remove unused var

* Remove unused import

* Prettier

* Merge

* Remove unused import

* Clean up comment

* Await with pin settings client calls

* Make sdk service emit locked instance

* Fix build

* Remove unused import

* Fix tests and move assertions to annotation

* Add unit tests

* Prettier

* Fix eslint

* Initialize state and flags for locked client

* Prettier

* Cleanup

* Remove unused import
2026-06-10 09:19:48 -05:00
Nick Krantz
1272b2d4a2
check for collection access before move (#21010) 2026-06-10 08:36:23 -05:00
Thomas Avery
dfd6a8f100
[PM-31054] Add V2UpgradeToken handling to sync (#20641)
* Add state service for V2UpgradeToken

* Update clear to not write to disk every call

* Fix unit test

* Add V2UpgradeToken handling to sync

* Add passing V2UpgradeToken to SDK unlocks

* Fix new DefaultUnlockService in main background

---------

Co-authored-by: Bernd Schoolmann <mail@quexten.com>
2026-06-10 16:52:24 +09:00
Addison Beck
a74e433542
fix(cli): harden bw serve origin-protection against DNS rebinding [PM-36600] (#20881)
* fix(cli): harden bw serve origin-protection against DNS rebinding

Closes PM-36600 / VULN-536. HackerOne report 3684172.

The prior origin-protection middleware only checked for the presence
of an Origin header, which DNS-rebinding attacks bypass: the browser
rebinds an attacker-controlled hostname to 127.0.0.1, then issues
same-origin GETs that carry no Origin header (per the Fetch spec) but
carry the attacker's hostname in the Host header. Any malicious page
the victim visits could silently read the unlocked vault.

The fix introduces two middleware layers, guarding every route
method-agnostically:

Layer 1 (new) — Host-header allowlist. Requests are rejected unless
their Host header matches localhost:PORT, 127.0.0.1:PORT, [::1]:PORT,
or the user-configured --hostname value at the configured port. This
closes the DNS-rebinding vector: a rebound request carries the
attacker's hostname in Host, not a loopback identifier. The allowlist
construction is extracted into an exported helper
`buildServeAllowedHosts(hostname, port)` so it is unit-testable.

Layer 2 (retained, behavior unchanged) — Origin check. Rewritten from
`!= undefined` to `!== undefined` for stylistic consistency with Layer
1. This is a runtime no-op: Node's IncomingHttpHeaders types
`ctx.headers.origin` as `string | string[] | undefined` and never
produces JS null, so an HTTP `Origin: null` header arrives as the
string "null" and was already rejected by the prior check. Layer 2 is
retained as defense-in-depth for classical cross-origin fetches: any
defined Origin header value is rejected.

A new spec encodes the four-probe regression contract:
  Probe 1: cross-origin attack (Origin: https://evil.example) -> 403
  Probe 2: legitimate localhost (Host: 127.0.0.1, no Origin) -> 200
  Probe 3: DNS-rebind (Host: evil.example, no Origin) -> 403 [THE FIX]
  Probe 4: empty Origin (forward-regression guard) -> 403

Three additional unit tests cover the `buildServeAllowedHosts` helper.
No new npm dependencies introduced.

* fix(cli): refine Host allowlist for --hostname all and default ports

Two allowlist gaps were found in automated review of PR #20881 and
addressed here.

1. --hostname all: `buildServeAllowedHosts` produced a set containing
   literal "all:PORT", so LAN clients sending `Host: 192.168.1.5:PORT`
   received a 403. The operator already opted into multi-interface
   binding by passing `--hostname all`; enumerating live IPs at runtime
   is fragile. Fix: when `hostname === "all"`, pass `null` for
   `allowedHosts`, disabling Layer 1 while keeping Layer 2 (Origin
   check) active. A startup log entry makes the posture visible.

2. RFC 7230 §5.4 default-port omission: HTTP clients omit the default
   port from `Host` when it matches the scheme default (80 for http,
   443 for https). `bw serve --hostname bwapi.mydomain.com --port 80`
   produced a 403 because `Host: bwapi.mydomain.com` was not in the
   allowlist. Fix: when port is 80 or 443, also push bare-host variants
   (`localhost`, `127.0.0.1`, `[::1]`, configured hostname) onto the
   set. Non-default ports are intentionally excluded — a missing port
   against a non-default port is a genuine client misconfiguration.

`buildOriginProtectionMiddleware`'s `allowedHosts` parameter widens to
`ReadonlySet<string> | null` to express "Layer 1 disabled."

7 new test cases added (12 passing total, up from 5): covers null
allowedHosts behavior and bare-host entries at ports 80, 443, and
8087 (negative case).

Refs: PM-36600

* review: coerce port to a number
2026-06-09 17:14:17 -04:00
Colton Hurst
ab23ad7243
Change configRetrievalIntervalMs (#21143)
* Change configRetrievalIntervalMs to be one minute to prevent impacts of looped polling

* Aligned on 5s
2026-06-09 11:34:13 -04:00
Colton Hurst
fea4b85d58
Remove FF caching for dev env by default (#21131)
* Remove FF caching for dev env by default

* Fix CLI
2026-06-09 08:34:28 -04:00
Jackson Engstrom
39021a4225
Updates attachment file write to use path.basename (#20790) 2026-06-03 13:46:25 -07:00
adudek-bw
f9c569379c
Add new SendApiServer that uses the SDK (#20170)
* Add new SendApiServer that uses the SDK
2026-06-02 14:19:45 -04:00
Thomas Rittson
007b5d9335
[PM-34157] Wire up SDK to NewPolicyService (#20377)
* Add shim in PolicyService to NewPolicyService
* Wire up NewPoilcyService to SDK
* Use SDK enum
2026-05-28 07:14:53 +10:00
renovate[bot]
37db9d091c
[deps] Vault: Update @koa/router to v15.5.0 (#20580)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-27 09:04:25 -07:00
Bernd Schoolmann
cf914e86e4
Remove unlock-via-sdk-flag (#20832) 2026-05-27 15:04:07 +09:00
renovate[bot]
6e4fcd74b8
[deps] Vault: Update https-proxy-agent to v9 (#20124)
* [deps] Vault: Update https-proxy-agent to v9

* Inline https-proxy-agent for pkg ESM compatibility

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: SmithThe4th <gsmith@bitwarden.com>
Co-authored-by: gbubemismith <gsmithwalter@gmail.com>
2026-05-21 18:44:22 -04:00
github-actions[bot]
87aa085375
Bumped client version(s) (#20690)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Addison Beck <github@addisonbeck.com>
2026-05-18 17:06:15 +00:00
Nick Krantz
7caeab7de5
[PM-34114] Add Passport item type to the CLI (#20621)
* Add Passport item type to the CLI

* formatting
2026-05-18 10:46:13 -05:00
Bernd Schoolmann
ab941afa89
[PM-31061] Implement biometrics migration (#20506)
* Revert "Revert "[PM-31061] Implement biometrics migration (#20127)" (#20455)"

This reverts commit 7ddfddc695.

* Update sdk

* Clean up lock file

* Restore package lock

* Package lock

* Fix tests

* Remove unused mocks

* Cleanup

* Remove imports

* Revert changes to main.ts

* Deduplicate setting of key id

* Cleanup

* Prettier

* Update libs/common/src/key-management/encrypted-migrator/default-encrypted-migrator.spec.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Update apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

---------

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
2026-05-15 12:22:41 +09:00
Nick Krantz
7f25ac0aba
Add Driver's License item type to the CLI (#20620) 2026-05-14 09:30:59 -05:00
Alex Dragovich
e6088fe618
[PM-36973] lazy-loading jsdom (#20568) 2026-05-13 11:21:16 -07:00
Alex Dragovich
4909b2a0aa
Revert "[deps] Tools: Update jsdom to v29 [PM-34333] (#19850)" (#20565)
This reverts commit 2b0de61fc2.
2026-05-08 14:07:59 -07:00