From f038e8c5e4e064b469f35ccf94e676e46536b447 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Tue, 11 Mar 2025 16:22:00 +0100 Subject: [PATCH 1/4] Create desktop-send-ui-refresh feature flag (#5487) Co-authored-by: Daniel James Smith --- src/Core/Constants.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 6baa9227e1..0591617f5e 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -114,6 +114,7 @@ public static class FeatureFlagKeys public const string ItemShare = "item-share"; public const string RiskInsightsCriticalApplication = "pm-14466-risk-insights-critical-application"; public const string EnableRiskInsightsNotifications = "enable-risk-insights-notifications"; + public const string DesktopSendUIRefresh = "desktop-send-ui-refresh"; public const string ReturnErrorOnExistingKeypair = "return-error-on-existing-keypair"; public const string UseTreeWalkerApiForPageDetailsCollection = "use-tree-walker-api-for-page-details-collection"; From 0153d9dfd9e4014bbf12f3d33a361d61da6704d9 Mon Sep 17 00:00:00 2001 From: Vince Grassia <593223+vgrassia@users.noreply.github.com> Date: Tue, 11 Mar 2025 16:01:23 -0400 Subject: [PATCH 2/4] Update DockerCompose template to point to ghcr.io registry (#5491) --- util/Setup/Templates/DockerCompose.hbs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/util/Setup/Templates/DockerCompose.hbs b/util/Setup/Templates/DockerCompose.hbs index ffe9121089..741e1085f9 100644 --- a/util/Setup/Templates/DockerCompose.hbs +++ b/util/Setup/Templates/DockerCompose.hbs @@ -15,7 +15,7 @@ services: mssql: - image: bitwarden/mssql:{{{CoreVersion}}} + image: ghcr.io/bitwarden/mssql:{{{CoreVersion}}} container_name: bitwarden-mssql restart: always stop_grace_period: 60s @@ -33,7 +33,7 @@ services: - ../env/mssql.override.env web: - image: bitwarden/web:{{{WebVersion}}} + image: ghcr.io/bitwarden/web:{{{WebVersion}}} container_name: bitwarden-web restart: always volumes: @@ -43,7 +43,7 @@ services: - ../env/uid.env attachments: - image: bitwarden/attachments:{{{CoreVersion}}} + image: ghcr.io/bitwarden/attachments:{{{CoreVersion}}} container_name: bitwarden-attachments restart: always volumes: @@ -53,7 +53,7 @@ services: - ../env/uid.env api: - image: bitwarden/api:{{{CoreVersion}}} + image: ghcr.io/bitwarden/api:{{{CoreVersion}}} container_name: bitwarden-api restart: always volumes: @@ -69,7 +69,7 @@ services: - public identity: - image: bitwarden/identity:{{{CoreVersion}}} + image: ghcr.io/bitwarden/identity:{{{CoreVersion}}} container_name: bitwarden-identity restart: always volumes: @@ -86,7 +86,7 @@ services: - public sso: - image: bitwarden/sso:{{{CoreVersion}}} + image: ghcr.io/bitwarden/sso:{{{CoreVersion}}} container_name: bitwarden-sso restart: always volumes: @@ -103,7 +103,7 @@ services: - public admin: - image: bitwarden/admin:{{{CoreVersion}}} + image: ghcr.io/bitwarden/admin:{{{CoreVersion}}} container_name: bitwarden-admin restart: always depends_on: @@ -121,7 +121,7 @@ services: - public icons: - image: bitwarden/icons:{{{CoreVersion}}} + image: ghcr.io/bitwarden/icons:{{{CoreVersion}}} container_name: bitwarden-icons restart: always volumes: @@ -135,7 +135,7 @@ services: - public notifications: - image: bitwarden/notifications:{{{CoreVersion}}} + image: ghcr.io/bitwarden/notifications:{{{CoreVersion}}} container_name: bitwarden-notifications restart: always volumes: @@ -150,7 +150,7 @@ services: - public events: - image: bitwarden/events:{{{CoreVersion}}} + image: ghcr.io/bitwarden/events:{{{CoreVersion}}} container_name: bitwarden-events restart: always volumes: @@ -165,7 +165,7 @@ services: - public nginx: - image: bitwarden/nginx:{{{CoreVersion}}} + image: ghcr.io/bitwarden/nginx:{{{CoreVersion}}} container_name: bitwarden-nginx restart: always depends_on: @@ -195,7 +195,7 @@ services: {{#if EnableKeyConnector}} key-connector: - image: bitwarden/key-connector:{{{KeyConnectorVersion}}} + image: ghcr.io/bitwarden/key-connector:{{{KeyConnectorVersion}}} container_name: bitwarden-key-connector restart: always volumes: @@ -212,7 +212,7 @@ services: {{#if EnableScim}} scim: - image: bitwarden/scim:{{{CoreVersion}}} + image: ghcr.io/bitwarden/scim:{{{CoreVersion}}} container_name: bitwarden-scim restart: always volumes: From 1b90bfe2a114e73b583100e955e57ac48b9733b9 Mon Sep 17 00:00:00 2001 From: Ike <137194738+ike-kottlowski@users.noreply.github.com> Date: Tue, 11 Mar 2025 17:01:50 -0400 Subject: [PATCH 3/4] [PM-18944] Update error response from invalid OTP (#5485) * fix(newDeviceVerification): updated error response from invalid OTP --- .../IdentityServer/RequestValidators/DeviceValidator.cs | 8 ++++---- test/Identity.Test/IdentityServer/DeviceValidatorTests.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs b/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs index 3ddc28c0e1..4744f4aca3 100644 --- a/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs +++ b/src/Identity/IdentityServer/RequestValidators/DeviceValidator.cs @@ -252,19 +252,19 @@ public class DeviceValidator( { case DeviceValidationResultType.InvalidUser: result.ErrorDescription = "Invalid user"; - customResponse.Add("ErrorModel", new ErrorResponseModel("invalid user")); + customResponse.Add("ErrorModel", new ErrorResponseModel("Invalid user.")); break; case DeviceValidationResultType.InvalidNewDeviceOtp: result.ErrorDescription = "Invalid New Device OTP"; - customResponse.Add("ErrorModel", new ErrorResponseModel("invalid new device otp")); + customResponse.Add("ErrorModel", new ErrorResponseModel("Invalid new device OTP. Try again.")); break; case DeviceValidationResultType.NewDeviceVerificationRequired: result.ErrorDescription = "New device verification required"; - customResponse.Add("ErrorModel", new ErrorResponseModel("new device verification required")); + customResponse.Add("ErrorModel", new ErrorResponseModel("New device verification required.")); break; case DeviceValidationResultType.NoDeviceInformationProvided: result.ErrorDescription = "No device information provided"; - customResponse.Add("ErrorModel", new ErrorResponseModel("no device information provided")); + customResponse.Add("ErrorModel", new ErrorResponseModel("No device information provided.")); break; } return (result, customResponse); diff --git a/test/Identity.Test/IdentityServer/DeviceValidatorTests.cs b/test/Identity.Test/IdentityServer/DeviceValidatorTests.cs index b71dd6c230..bcb357d640 100644 --- a/test/Identity.Test/IdentityServer/DeviceValidatorTests.cs +++ b/test/Identity.Test/IdentityServer/DeviceValidatorTests.cs @@ -172,7 +172,7 @@ public class DeviceValidatorTests Assert.False(result); Assert.NotNull(context.CustomResponse["ErrorModel"]); - var expectedErrorModel = new ErrorResponseModel("no device information provided"); + var expectedErrorModel = new ErrorResponseModel("No device information provided."); var actualResponse = (ErrorResponseModel)context.CustomResponse["ErrorModel"]; Assert.Equal(expectedErrorModel.Message, actualResponse.Message); } @@ -418,7 +418,7 @@ public class DeviceValidatorTests Assert.False(result); Assert.NotNull(context.CustomResponse["ErrorModel"]); // PM-13340: The error message should be "invalid user" instead of "no device information provided" - var expectedErrorMessage = "no device information provided"; + var expectedErrorMessage = "No device information provided."; var actualResponse = (ErrorResponseModel)context.CustomResponse["ErrorModel"]; Assert.Equal(expectedErrorMessage, actualResponse.Message); } @@ -552,7 +552,7 @@ public class DeviceValidatorTests Assert.False(result); Assert.NotNull(context.CustomResponse["ErrorModel"]); - var expectedErrorMessage = "invalid new device otp"; + var expectedErrorMessage = "Invalid new device OTP. Try again."; var actualResponse = (ErrorResponseModel)context.CustomResponse["ErrorModel"]; Assert.Equal(expectedErrorMessage, actualResponse.Message); } @@ -604,7 +604,7 @@ public class DeviceValidatorTests Assert.False(result); Assert.NotNull(context.CustomResponse["ErrorModel"]); - var expectedErrorMessage = "new device verification required"; + var expectedErrorMessage = "New device verification required."; var actualResponse = (ErrorResponseModel)context.CustomResponse["ErrorModel"]; Assert.Equal(expectedErrorMessage, actualResponse.Message); } From ef3b8b782a1a02fd9fccc80c1742b19092f7975f Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:56:47 -0400 Subject: [PATCH 4/4] Provide plans to OrganizationEditModel for resellers (#5493) --- .../AdminConsole/Controllers/ProvidersController.cs | 10 ++++++++-- src/Admin/AdminConsole/Models/OrganizationEditModel.cs | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Admin/AdminConsole/Controllers/ProvidersController.cs b/src/Admin/AdminConsole/Controllers/ProvidersController.cs index 9e3dc00cd6..c38bb64419 100644 --- a/src/Admin/AdminConsole/Controllers/ProvidersController.cs +++ b/src/Admin/AdminConsole/Controllers/ProvidersController.cs @@ -11,6 +11,7 @@ using Bit.Core.AdminConsole.Services; using Bit.Core.Billing.Entities; using Bit.Core.Billing.Enums; using Bit.Core.Billing.Extensions; +using Bit.Core.Billing.Pricing; using Bit.Core.Billing.Repositories; using Bit.Core.Billing.Services; using Bit.Core.Billing.Services.Contracts; @@ -42,6 +43,7 @@ public class ProvidersController : Controller private readonly IFeatureService _featureService; private readonly IProviderPlanRepository _providerPlanRepository; private readonly IProviderBillingService _providerBillingService; + private readonly IPricingClient _pricingClient; private readonly string _stripeUrl; private readonly string _braintreeMerchantUrl; private readonly string _braintreeMerchantId; @@ -60,7 +62,8 @@ public class ProvidersController : Controller IFeatureService featureService, IProviderPlanRepository providerPlanRepository, IProviderBillingService providerBillingService, - IWebHostEnvironment webHostEnvironment) + IWebHostEnvironment webHostEnvironment, + IPricingClient pricingClient) { _organizationRepository = organizationRepository; _organizationService = organizationService; @@ -75,6 +78,7 @@ public class ProvidersController : Controller _featureService = featureService; _providerPlanRepository = providerPlanRepository; _providerBillingService = providerBillingService; + _pricingClient = pricingClient; _stripeUrl = webHostEnvironment.GetStripeUrl(); _braintreeMerchantUrl = webHostEnvironment.GetBraintreeMerchantUrl(); _braintreeMerchantId = globalSettings.Braintree.MerchantId; @@ -415,7 +419,9 @@ public class ProvidersController : Controller return RedirectToAction("Index"); } - return View(new OrganizationEditModel(provider)); + var plans = await _pricingClient.ListPlans(); + + return View(new OrganizationEditModel(provider, plans)); } [HttpPost] diff --git a/src/Admin/AdminConsole/Models/OrganizationEditModel.cs b/src/Admin/AdminConsole/Models/OrganizationEditModel.cs index 729b4f7990..1d23afd491 100644 --- a/src/Admin/AdminConsole/Models/OrganizationEditModel.cs +++ b/src/Admin/AdminConsole/Models/OrganizationEditModel.cs @@ -22,13 +22,14 @@ public class OrganizationEditModel : OrganizationViewModel public OrganizationEditModel() { } - public OrganizationEditModel(Provider provider) + public OrganizationEditModel(Provider provider, List plans) { Provider = provider; BillingEmail = provider.Type == ProviderType.Reseller ? provider.BillingEmail : string.Empty; PlanType = Core.Billing.Enums.PlanType.TeamsMonthly; Plan = Core.Billing.Enums.PlanType.TeamsMonthly.GetDisplayAttribute()?.GetName(); LicenseKey = RandomLicenseKey; + _plans = plans; } public OrganizationEditModel(