diff --git a/src/Core/Billing/Pricing/PlanAdapter.cs b/src/Core/Billing/Pricing/PlanAdapter.cs
index f719fd1e87..45a48c3f80 100644
--- a/src/Core/Billing/Pricing/PlanAdapter.cs
+++ b/src/Core/Billing/Pricing/PlanAdapter.cs
@@ -31,6 +31,7 @@ public record PlanAdapter : Plan
HasScim = HasFeature("scim");
HasResetPassword = HasFeature("resetPassword");
UsersGetPremium = HasFeature("usersGetPremium");
+ HasCustomPermissions = HasFeature("customPermissions");
UpgradeSortOrder = plan.AdditionalData.TryGetValue("upgradeSortOrder", out var upgradeSortOrder)
? int.Parse(upgradeSortOrder)
: 0;
@@ -141,6 +142,7 @@ public record PlanAdapter : Plan
var stripeSeatPlanId = GetStripeSeatPlanId(seats);
var hasAdditionalSeatsOption = seats.IsScalable;
var seatPrice = GetSeatPrice(seats);
+ var baseSeats = GetBaseSeats(seats);
var maxSeats = GetMaxSeats(seats);
var allowSeatAutoscale = seats.IsScalable;
var maxProjects = plan.AdditionalData.TryGetValue("secretsManager.maxProjects", out var value) ? short.Parse(value) : 0;
@@ -156,6 +158,7 @@ public record PlanAdapter : Plan
StripeSeatPlanId = stripeSeatPlanId,
HasAdditionalSeatsOption = hasAdditionalSeatsOption,
SeatPrice = seatPrice,
+ BaseSeats = baseSeats,
MaxSeats = maxSeats,
AllowSeatAutoscale = allowSeatAutoscale,
MaxProjects = maxProjects
@@ -168,8 +171,16 @@ public record PlanAdapter : Plan
private static decimal GetBasePrice(PurchasableDTO purchasable)
=> purchasable.FromPackaged(x => x.Price);
+ private static int GetBaseSeats(FreeOrScalableDTO freeOrScalable)
+ => freeOrScalable.Match(
+ free => free.Quantity,
+ scalable => scalable.Provided);
+
private static int GetBaseSeats(PurchasableDTO purchasable)
- => purchasable.FromPackaged(x => x.Quantity);
+ => purchasable.Match(
+ free => free.Quantity,
+ packaged => packaged.Quantity,
+ scalable => scalable.Provided);
private static short GetBaseServiceAccount(FreeOrScalableDTO freeOrScalable)
=> freeOrScalable.Match(
diff --git a/src/Core/Exceptions/BadRequestException.cs b/src/Core/Exceptions/BadRequestException.cs
index 042f853a57..b27bc7510f 100644
--- a/src/Core/Exceptions/BadRequestException.cs
+++ b/src/Core/Exceptions/BadRequestException.cs
@@ -3,6 +3,8 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class BadRequestException : Exception
{
public BadRequestException() : base()
@@ -41,5 +43,5 @@ public class BadRequestException : Exception
}
}
- public ModelStateDictionary ModelState { get; set; }
+ public ModelStateDictionary? ModelState { get; set; }
}
diff --git a/src/Core/Exceptions/ConflictException.cs b/src/Core/Exceptions/ConflictException.cs
index 27b90a657f..92fcc52d7f 100644
--- a/src/Core/Exceptions/ConflictException.cs
+++ b/src/Core/Exceptions/ConflictException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class ConflictException : Exception
{
public ConflictException() : base("Conflict.") { }
diff --git a/src/Core/Exceptions/DnsQueryException.cs b/src/Core/Exceptions/DnsQueryException.cs
index 57b2c56daa..e3f605dec4 100644
--- a/src/Core/Exceptions/DnsQueryException.cs
+++ b/src/Core/Exceptions/DnsQueryException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class DnsQueryException : Exception
{
public DnsQueryException(string message)
diff --git a/src/Core/Exceptions/DomainClaimedException.cs b/src/Core/Exceptions/DomainClaimedException.cs
index 09ccb3d0d8..9ac6972fa1 100644
--- a/src/Core/Exceptions/DomainClaimedException.cs
+++ b/src/Core/Exceptions/DomainClaimedException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class DomainClaimedException : Exception
{
public DomainClaimedException()
diff --git a/src/Core/Exceptions/DomainVerifiedException.cs b/src/Core/Exceptions/DomainVerifiedException.cs
index d3a3fd4de4..1fb704bd55 100644
--- a/src/Core/Exceptions/DomainVerifiedException.cs
+++ b/src/Core/Exceptions/DomainVerifiedException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class DomainVerifiedException : Exception
{
public DomainVerifiedException()
diff --git a/src/Core/Exceptions/DuplicateDomainException.cs b/src/Core/Exceptions/DuplicateDomainException.cs
index 8d347dda55..4f61f333f5 100644
--- a/src/Core/Exceptions/DuplicateDomainException.cs
+++ b/src/Core/Exceptions/DuplicateDomainException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class DuplicateDomainException : Exception
{
public DuplicateDomainException()
diff --git a/src/Core/Exceptions/FeatureUnavailableException.cs b/src/Core/Exceptions/FeatureUnavailableException.cs
index 7bea350956..80fd7d0635 100644
--- a/src/Core/Exceptions/FeatureUnavailableException.cs
+++ b/src/Core/Exceptions/FeatureUnavailableException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
///
/// Exception to throw when a requested feature is not yet enabled/available for the requesting context.
///
diff --git a/src/Core/Exceptions/GatewayException.cs b/src/Core/Exceptions/GatewayException.cs
index 73e8cd7613..4b24c8d107 100644
--- a/src/Core/Exceptions/GatewayException.cs
+++ b/src/Core/Exceptions/GatewayException.cs
@@ -1,8 +1,10 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class GatewayException : Exception
{
- public GatewayException(string message, Exception innerException = null)
+ public GatewayException(string message, Exception? innerException = null)
: base(message, innerException)
{ }
}
diff --git a/src/Core/Exceptions/InvalidEmailException.cs b/src/Core/Exceptions/InvalidEmailException.cs
index 1f17acf62e..c38ec0ac38 100644
--- a/src/Core/Exceptions/InvalidEmailException.cs
+++ b/src/Core/Exceptions/InvalidEmailException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class InvalidEmailException : Exception
{
public InvalidEmailException()
diff --git a/src/Core/Exceptions/InvalidGatewayCustomerIdException.cs b/src/Core/Exceptions/InvalidGatewayCustomerIdException.cs
index cfc7c56c1c..6ec15da308 100644
--- a/src/Core/Exceptions/InvalidGatewayCustomerIdException.cs
+++ b/src/Core/Exceptions/InvalidGatewayCustomerIdException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class InvalidGatewayCustomerIdException : Exception
{
public InvalidGatewayCustomerIdException()
diff --git a/src/Core/Exceptions/NotFoundException.cs b/src/Core/Exceptions/NotFoundException.cs
index 70769d41ed..6a61e35868 100644
--- a/src/Core/Exceptions/NotFoundException.cs
+++ b/src/Core/Exceptions/NotFoundException.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.Exceptions;
+#nullable enable
+
public class NotFoundException : Exception
{
public NotFoundException() : base()
diff --git a/src/Core/HostedServices/ApplicationCacheHostedService.cs b/src/Core/HostedServices/ApplicationCacheHostedService.cs
index 9021782d20..a699a26fcc 100644
--- a/src/Core/HostedServices/ApplicationCacheHostedService.cs
+++ b/src/Core/HostedServices/ApplicationCacheHostedService.cs
@@ -10,9 +10,11 @@ using Microsoft.Extensions.Logging;
namespace Bit.Core.HostedServices;
+#nullable enable
+
public class ApplicationCacheHostedService : IHostedService, IDisposable
{
- private readonly InMemoryServiceBusApplicationCacheService _applicationCacheService;
+ private readonly InMemoryServiceBusApplicationCacheService? _applicationCacheService;
private readonly IOrganizationRepository _organizationRepository;
protected readonly ILogger _logger;
private readonly ServiceBusClient _serviceBusClient;
@@ -20,8 +22,8 @@ public class ApplicationCacheHostedService : IHostedService, IDisposable
private readonly ServiceBusAdministrationClient _serviceBusAdministrationClient;
private readonly string _subName;
private readonly string _topicName;
- private CancellationTokenSource _cts;
- private Task _executingTask;
+ private CancellationTokenSource? _cts;
+ private Task? _executingTask;
public ApplicationCacheHostedService(
@@ -67,13 +69,17 @@ public class ApplicationCacheHostedService : IHostedService, IDisposable
{
await _subscriptionReceiver.CloseAsync(cancellationToken);
await _serviceBusClient.DisposeAsync();
- _cts.Cancel();
+ _cts?.Cancel();
try
{
await _serviceBusAdministrationClient.DeleteSubscriptionAsync(_topicName, _subName, cancellationToken);
}
catch { }
- await _executingTask;
+
+ if (_executingTask != null)
+ {
+ await _executingTask;
+ }
}
public virtual void Dispose()
diff --git a/src/Core/HostedServices/IpRateLimitSeedStartupService.cs b/src/Core/HostedServices/IpRateLimitSeedStartupService.cs
index a6869d929c..827dd94806 100644
--- a/src/Core/HostedServices/IpRateLimitSeedStartupService.cs
+++ b/src/Core/HostedServices/IpRateLimitSeedStartupService.cs
@@ -3,6 +3,8 @@ using Microsoft.Extensions.Hosting;
namespace Bit.Core.HostedServices;
+#nullable enable
+
///
/// A startup service that will seed the IP rate limiting stores with any values in the
/// GlobalSettings configuration.
diff --git a/src/Core/Jobs/BaseJob.cs b/src/Core/Jobs/BaseJob.cs
index 56c39014a7..a56045f659 100644
--- a/src/Core/Jobs/BaseJob.cs
+++ b/src/Core/Jobs/BaseJob.cs
@@ -3,6 +3,8 @@ using Quartz;
namespace Bit.Core.Jobs;
+#nullable enable
+
public abstract class BaseJob : IJob
{
protected readonly ILogger _logger;
diff --git a/src/Core/Jobs/BaseJobsHostedService.cs b/src/Core/Jobs/BaseJobsHostedService.cs
index 897a382a2b..2ade53c6bb 100644
--- a/src/Core/Jobs/BaseJobsHostedService.cs
+++ b/src/Core/Jobs/BaseJobsHostedService.cs
@@ -8,6 +8,8 @@ using Quartz.Impl.Matchers;
namespace Bit.Core.Jobs;
+#nullable enable
+
public abstract class BaseJobsHostedService : IHostedService, IDisposable
{
private const int MaximumJobRetries = 10;
@@ -16,7 +18,7 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable
private readonly ILogger _listenerLogger;
protected readonly ILogger _logger;
- private IScheduler _scheduler;
+ private IScheduler? _scheduler;
protected GlobalSettings _globalSettings;
public BaseJobsHostedService(
@@ -31,7 +33,7 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable
_globalSettings = globalSettings;
}
- public IEnumerable> Jobs { get; protected set; }
+ public IEnumerable>? Jobs { get; protected set; }
public virtual async Task StartAsync(CancellationToken cancellationToken)
{
@@ -61,10 +63,19 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable
_scheduler.ListenerManager.AddJobListener(new JobListener(_listenerLogger),
GroupMatcher.AnyGroup());
await _scheduler.Start(cancellationToken);
+
+ var jobKeys = new List();
+ var triggerKeys = new List();
+
if (Jobs != null)
{
foreach (var (job, trigger) in Jobs)
{
+ jobKeys.Add(JobBuilder.Create(job)
+ .WithIdentity(job.FullName!)
+ .Build().Key);
+ triggerKeys.Add(trigger.Key);
+
for (var retry = 0; retry < MaximumJobRetries; retry++)
{
// There's a race condition when starting multiple containers simultaneously, retry until it succeeds..
@@ -77,7 +88,7 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable
}
var jobDetail = JobBuilder.Create(job)
- .WithIdentity(job.FullName)
+ .WithIdentity(job.FullName!)
.Build();
var dupeJ = await _scheduler.GetJobDetail(jobDetail.Key);
@@ -106,13 +117,6 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable
// Delete old Jobs and Triggers
var existingJobKeys = await _scheduler.GetJobKeys(GroupMatcher.AnyGroup());
- var jobKeys = Jobs.Select(j =>
- {
- var job = j.Item1;
- return JobBuilder.Create(job)
- .WithIdentity(job.FullName)
- .Build().Key;
- });
foreach (var key in existingJobKeys)
{
@@ -126,7 +130,6 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable
}
var existingTriggerKeys = await _scheduler.GetTriggerKeys(GroupMatcher.AnyGroup());
- var triggerKeys = Jobs.Select(j => j.Item2.Key);
foreach (var key in existingTriggerKeys)
{
@@ -142,7 +145,10 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
- await _scheduler?.Shutdown(cancellationToken);
+ if (_scheduler is not null)
+ {
+ await _scheduler.Shutdown(cancellationToken);
+ }
}
public virtual void Dispose()
diff --git a/src/Core/Jobs/JobFactory.cs b/src/Core/Jobs/JobFactory.cs
index 6529443d97..8289a90322 100644
--- a/src/Core/Jobs/JobFactory.cs
+++ b/src/Core/Jobs/JobFactory.cs
@@ -4,6 +4,8 @@ using Quartz.Spi;
namespace Bit.Core.Jobs;
+#nullable enable
+
public class JobFactory : IJobFactory
{
private readonly IServiceProvider _container;
@@ -16,7 +18,7 @@ public class JobFactory : IJobFactory
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var scope = _container.CreateScope();
- return scope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob;
+ return (scope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob)!;
}
public void ReturnJob(IJob job)
diff --git a/src/Core/Jobs/JobListener.cs b/src/Core/Jobs/JobListener.cs
index e5e05e4b6b..0dc865655d 100644
--- a/src/Core/Jobs/JobListener.cs
+++ b/src/Core/Jobs/JobListener.cs
@@ -3,6 +3,8 @@ using Quartz;
namespace Bit.Core.Jobs;
+#nullable enable
+
public class JobListener : IJobListener
{
private readonly ILogger _logger;
@@ -28,7 +30,7 @@ public class JobListener : IJobListener
return Task.FromResult(0);
}
- public Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException,
+ public Task JobWasExecuted(IJobExecutionContext context, JobExecutionException? jobException,
CancellationToken cancellationToken = default(CancellationToken))
{
_logger.LogInformation(Constants.BypassFiltersEventId, null, "Finished job {0} at {1}.",
diff --git a/src/Core/NotificationHub/INotificationHubClientProxy.cs b/src/Core/NotificationHub/INotificationHubClientProxy.cs
index 82b4d39591..78eb0206d6 100644
--- a/src/Core/NotificationHub/INotificationHubClientProxy.cs
+++ b/src/Core/NotificationHub/INotificationHubClientProxy.cs
@@ -2,6 +2,8 @@
namespace Bit.Core.NotificationHub;
+#nullable enable
+
public interface INotificationHubProxy
{
Task<(INotificationHubClient Client, NotificationOutcome Outcome)[]> SendTemplateNotificationAsync(IDictionary properties, string tagExpression);
diff --git a/src/Core/NotificationHub/INotificationHubPool.cs b/src/Core/NotificationHub/INotificationHubPool.cs
index 3981598118..25a31d62f4 100644
--- a/src/Core/NotificationHub/INotificationHubPool.cs
+++ b/src/Core/NotificationHub/INotificationHubPool.cs
@@ -2,6 +2,8 @@
namespace Bit.Core.NotificationHub;
+#nullable enable
+
public interface INotificationHubPool
{
NotificationHubConnection ConnectionFor(Guid comb);
diff --git a/src/Core/NotificationHub/NotificationHubClientProxy.cs b/src/Core/NotificationHub/NotificationHubClientProxy.cs
index 815ac88363..b47069fe21 100644
--- a/src/Core/NotificationHub/NotificationHubClientProxy.cs
+++ b/src/Core/NotificationHub/NotificationHubClientProxy.cs
@@ -2,6 +2,8 @@
namespace Bit.Core.NotificationHub;
+#nullable enable
+
public class NotificationHubClientProxy : INotificationHubProxy
{
private readonly IEnumerable _clients;
diff --git a/src/Core/NotificationHub/NotificationHubConnection.cs b/src/Core/NotificationHub/NotificationHubConnection.cs
index a68134450e..a61f2ded8f 100644
--- a/src/Core/NotificationHub/NotificationHubConnection.cs
+++ b/src/Core/NotificationHub/NotificationHubConnection.cs
@@ -1,4 +1,5 @@
-using System.Security.Cryptography;
+using System.Diagnostics.CodeAnalysis;
+using System.Security.Cryptography;
using System.Text;
using System.Web;
using Bit.Core.Settings;
@@ -7,21 +8,23 @@ using Microsoft.Azure.NotificationHubs;
namespace Bit.Core.NotificationHub;
+#nullable enable
+
public class NotificationHubConnection
{
- public string HubName { get; init; }
- public string ConnectionString { get; init; }
+ public string? HubName { get; init; }
+ public string? ConnectionString { get; init; }
private Lazy _parsedConnectionString;
public Uri Endpoint => _parsedConnectionString.Value.Endpoint;
private string SasKey => _parsedConnectionString.Value.SharedAccessKey;
private string SasKeyName => _parsedConnectionString.Value.SharedAccessKeyName;
public bool EnableSendTracing { get; init; }
- private NotificationHubClient _hubClient;
+ private NotificationHubClient? _hubClient;
///
/// Gets the NotificationHubClient for this connection.
- ///
+ ///
/// If the client is null, it will be initialized.
- ///
+ ///
/// Exception if the connection is invalid.
///
public NotificationHubClient HubClient
@@ -45,13 +48,13 @@ public class NotificationHubConnection
}
///
/// Gets the start date for registration.
- ///
+ ///
/// If null, registration is always disabled.
///
public DateTime? RegistrationStartDate { get; init; }
///
/// Gets the end date for registration.
- ///
+ ///
/// If null, registration has no end date.
///
public DateTime? RegistrationEndDate { get; init; }
@@ -155,9 +158,10 @@ public class NotificationHubConnection
};
}
+ [MemberNotNull(nameof(_hubClient))]
private NotificationHubConnection Init()
{
- HubClient = NotificationHubClient.CreateClientFromConnectionString(ConnectionString, HubName, EnableSendTracing);
+ _hubClient = NotificationHubClient.CreateClientFromConnectionString(ConnectionString, HubName, EnableSendTracing);
return this;
}
diff --git a/src/Core/NotificationHub/NotificationHubPool.cs b/src/Core/NotificationHub/NotificationHubPool.cs
index 6b48e82f88..38192c11fc 100644
--- a/src/Core/NotificationHub/NotificationHubPool.cs
+++ b/src/Core/NotificationHub/NotificationHubPool.cs
@@ -5,6 +5,8 @@ using Microsoft.Extensions.Logging;
namespace Bit.Core.NotificationHub;
+#nullable enable
+
public class NotificationHubPool : INotificationHubPool
{
private List _connections { get; }
diff --git a/src/Core/NotificationHub/NotificationHubPushNotificationService.cs b/src/Core/NotificationHub/NotificationHubPushNotificationService.cs
index bb3de80977..368c0f731b 100644
--- a/src/Core/NotificationHub/NotificationHubPushNotificationService.cs
+++ b/src/Core/NotificationHub/NotificationHubPushNotificationService.cs
@@ -19,6 +19,8 @@ using Notification = Bit.Core.NotificationCenter.Entities.Notification;
namespace Bit.Core.NotificationHub;
+#nullable enable
+
///
/// Sends mobile push notifications to the Azure Notification Hub.
/// Used by Cloud-Hosted environments.
diff --git a/src/Core/NotificationHub/NotificationHubPushRegistrationService.cs b/src/Core/NotificationHub/NotificationHubPushRegistrationService.cs
index f44fcf91a0..dc494eecd6 100644
--- a/src/Core/NotificationHub/NotificationHubPushRegistrationService.cs
+++ b/src/Core/NotificationHub/NotificationHubPushRegistrationService.cs
@@ -13,6 +13,8 @@ using Microsoft.Extensions.Logging;
namespace Bit.Core.NotificationHub;
+#nullable enable
+
public class NotificationHubPushRegistrationService : IPushRegistrationService
{
private static readonly JsonSerializerOptions webPushSerializationOptions = new()
@@ -37,7 +39,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
}
public async Task CreateOrUpdateRegistrationAsync(PushRegistrationData data, string deviceId, string userId,
- string identifier, DeviceType type, IEnumerable organizationIds, Guid installationId)
+ string? identifier, DeviceType type, IEnumerable organizationIds, Guid installationId)
{
var orgIds = organizationIds.ToList();
var clientType = DeviceTypes.ToClientType(type);
@@ -79,7 +81,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
}
private async Task CreateOrUpdateMobileRegistrationAsync(Installation installation, string userId,
- string identifier, ClientType clientType, List organizationIds, DeviceType type, Guid installationId)
+ string? identifier, ClientType clientType, List organizationIds, DeviceType type, Guid installationId)
{
if (string.IsNullOrWhiteSpace(installation.PushChannel))
{
@@ -137,7 +139,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
}
private async Task CreateOrUpdateWebRegistrationAsync(string endpoint, string p256dh, string auth, Installation installation, string userId,
- string identifier, ClientType clientType, List organizationIds, Guid installationId)
+ string? identifier, ClientType clientType, List organizationIds, Guid installationId)
{
// The Azure SDK is currently lacking support for web push registrations.
// We need to use the REST API directly.
@@ -187,7 +189,7 @@ public class NotificationHubPushRegistrationService : IPushRegistrationService
}
private static KeyValuePair BuildInstallationTemplate(string templateId, [StringSyntax(StringSyntaxAttribute.Json)] string templateBody,
- string userId, string identifier, ClientType clientType, List organizationIds, Guid installationId)
+ string userId, string? identifier, ClientType clientType, List organizationIds, Guid installationId)
{
var fullTemplateId = $"template:{templateId}";
diff --git a/src/Core/NotificationHub/PushRegistrationData.cs b/src/Core/NotificationHub/PushRegistrationData.cs
index 20e1cf0936..c11ee7be23 100644
--- a/src/Core/NotificationHub/PushRegistrationData.cs
+++ b/src/Core/NotificationHub/PushRegistrationData.cs
@@ -1,5 +1,7 @@
namespace Bit.Core.NotificationHub;
+#nullable enable
+
public record struct WebPushRegistrationData
{
public string Endpoint { get; init; }
@@ -9,9 +11,9 @@ public record struct WebPushRegistrationData
public record class PushRegistrationData
{
- public string Token { get; set; }
+ public string? Token { get; set; }
public WebPushRegistrationData? WebPush { get; set; }
- public PushRegistrationData(string token)
+ public PushRegistrationData(string? token)
{
Token = token;
}
diff --git a/test/Api.Test/KeyManagement/Controllers/AccountsKeyManagementControllerTests.cs b/test/Api.Test/KeyManagement/Controllers/AccountsKeyManagementControllerTests.cs
index d2775762e8..05b1aa5a4d 100644
--- a/test/Api.Test/KeyManagement/Controllers/AccountsKeyManagementControllerTests.cs
+++ b/test/Api.Test/KeyManagement/Controllers/AccountsKeyManagementControllerTests.cs
@@ -175,7 +175,7 @@ public class AccountsKeyManagementControllerTests
}
catch (BadRequestException ex)
{
- Assert.NotEmpty(ex.ModelState.Values);
+ Assert.NotEmpty(ex.ModelState!.Values);
}
}
@@ -210,7 +210,7 @@ public class AccountsKeyManagementControllerTests
var badRequestException =
await Assert.ThrowsAsync(() => sutProvider.Sut.PostSetKeyConnectorKeyAsync(data));
- Assert.Equal(1, badRequestException.ModelState.ErrorCount);
+ Assert.Equal(1, badRequestException.ModelState!.ErrorCount);
Assert.Equal("set key connector key error", badRequestException.ModelState.Root.Errors[0].ErrorMessage);
await sutProvider.GetDependency().Received(1)
.SetKeyConnectorKeyAsync(Arg.Do(user =>
@@ -284,7 +284,7 @@ public class AccountsKeyManagementControllerTests
var badRequestException =
await Assert.ThrowsAsync(() => sutProvider.Sut.PostConvertToKeyConnectorAsync());
- Assert.Equal(1, badRequestException.ModelState.ErrorCount);
+ Assert.Equal(1, badRequestException.ModelState!.ErrorCount);
Assert.Equal("convert to key connector error", badRequestException.ModelState.Root.Errors[0].ErrorMessage);
await sutProvider.GetDependency().Received(1)
.ConvertToKeyConnectorAsync(Arg.Is(expectedUser));