mirror of
https://github.com/bitwarden/server.git
synced 2025-04-25 06:42:22 -05:00
[PM-336] Nullable Platform & Unowned Services (#5646)
* Nullable Platform & Unowned Services * Fix build errors * Format
This commit is contained in:
parent
84a984a9e6
commit
2242a70e50
@ -1,4 +1,6 @@
|
|||||||
namespace Bit.Core.Platform.Installations;
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Bit.Core.Platform.Installations;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command interface responsible for updating data on an `Installation`
|
/// Command interface responsible for updating data on an `Installation`
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Bit.Core.Platform.Installations;
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Bit.Core.Platform.Installations;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Commands responsible for updating an installation from
|
/// Commands responsible for updating an installation from
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Bit.Core.Platform.Installations;
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Bit.Core.Platform.Installations;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries responsible for fetching an installation from
|
/// Queries responsible for fetching an installation from
|
||||||
@ -19,7 +21,7 @@ public class GetInstallationQuery : IGetInstallationQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IGetInstallationQuery.GetByIdAsync"/>
|
/// <inheritdoc cref="IGetInstallationQuery.GetByIdAsync"/>
|
||||||
public async Task<Installation> GetByIdAsync(Guid installationId)
|
public async Task<Installation?> GetByIdAsync(Guid installationId)
|
||||||
{
|
{
|
||||||
if (installationId == default(Guid))
|
if (installationId == default(Guid))
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Bit.Core.Platform.Installations;
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Bit.Core.Platform.Installations;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Query interface responsible for fetching an installation from
|
/// Query interface responsible for fetching an installation from
|
||||||
@ -16,5 +18,5 @@ public interface IGetInstallationQuery
|
|||||||
/// <param name="installationId">The GUID id of the installation.</param>
|
/// <param name="installationId">The GUID id of the installation.</param>
|
||||||
/// <returns>A task containing an `Installation`.</returns>
|
/// <returns>A task containing an `Installation`.</returns>
|
||||||
/// <seealso cref="T:Bit.Core.Platform.Installations.Repositories.IInstallationRepository"/>
|
/// <seealso cref="T:Bit.Core.Platform.Installations.Repositories.IInstallationRepository"/>
|
||||||
Task<Installation> GetByIdAsync(Guid installationId);
|
Task<Installation?> GetByIdAsync(Guid installationId);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.Platform.Installations;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.Platform.Installations;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Bit.Core.Platform;
|
namespace Bit.Core.Platform;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.Enums;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.NotificationHub;
|
using Bit.Core.NotificationHub;
|
||||||
|
|
||||||
namespace Bit.Core.Platform.Push;
|
namespace Bit.Core.Platform.Push;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.Enums;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.NotificationHub;
|
using Bit.Core.NotificationHub;
|
||||||
|
|
||||||
namespace Bit.Core.Platform.Push.Internal;
|
namespace Bit.Core.Platform.Push.Internal;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.Enums;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.IdentityServer;
|
using Bit.Core.IdentityServer;
|
||||||
using Bit.Core.Models.Api;
|
using Bit.Core.Models.Api;
|
||||||
using Bit.Core.NotificationHub;
|
using Bit.Core.NotificationHub;
|
||||||
|
@ -48,7 +48,7 @@ public interface ICollectionRepository : IRepository<Collection, Guid>
|
|||||||
Task<CollectionAdminDetails?> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId, bool includeAccessRelationships);
|
Task<CollectionAdminDetails?> GetByIdWithPermissionsAsync(Guid collectionId, Guid? userId, bool includeAccessRelationships);
|
||||||
|
|
||||||
Task CreateAsync(Collection obj, IEnumerable<CollectionAccessSelection>? groups, IEnumerable<CollectionAccessSelection>? users);
|
Task CreateAsync(Collection obj, IEnumerable<CollectionAccessSelection>? groups, IEnumerable<CollectionAccessSelection>? users);
|
||||||
Task ReplaceAsync(Collection obj, IEnumerable<CollectionAccessSelection> groups, IEnumerable<CollectionAccessSelection> users);
|
Task ReplaceAsync(Collection obj, IEnumerable<CollectionAccessSelection>? groups, IEnumerable<CollectionAccessSelection>? users);
|
||||||
Task DeleteUserAsync(Guid collectionId, Guid organizationUserId);
|
Task DeleteUserAsync(Guid collectionId, Guid organizationUserId);
|
||||||
Task UpdateUsersAsync(Guid id, IEnumerable<CollectionAccessSelection> users);
|
Task UpdateUsersAsync(Guid id, IEnumerable<CollectionAccessSelection> users);
|
||||||
Task<ICollection<CollectionAccessSelection>> GetManyUsersByIdAsync(Guid id);
|
Task<ICollection<CollectionAccessSelection>> GetManyUsersByIdAsync(Guid id);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Security.Claims;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Security.Claims;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
@ -12,14 +14,14 @@ public interface ILicensingService
|
|||||||
Task<bool> ValidateUserPremiumAsync(User user);
|
Task<bool> ValidateUserPremiumAsync(User user);
|
||||||
bool VerifyLicense(ILicense license);
|
bool VerifyLicense(ILicense license);
|
||||||
byte[] SignLicense(ILicense license);
|
byte[] SignLicense(ILicense license);
|
||||||
Task<OrganizationLicense> ReadOrganizationLicenseAsync(Organization organization);
|
Task<OrganizationLicense?> ReadOrganizationLicenseAsync(Organization organization);
|
||||||
Task<OrganizationLicense> ReadOrganizationLicenseAsync(Guid organizationId);
|
Task<OrganizationLicense?> ReadOrganizationLicenseAsync(Guid organizationId);
|
||||||
ClaimsPrincipal GetClaimsPrincipalFromLicense(ILicense license);
|
ClaimsPrincipal? GetClaimsPrincipalFromLicense(ILicense license);
|
||||||
|
|
||||||
Task<string> CreateOrganizationTokenAsync(
|
Task<string?> CreateOrganizationTokenAsync(
|
||||||
Organization organization,
|
Organization organization,
|
||||||
Guid installationId,
|
Guid installationId,
|
||||||
SubscriptionInfo subscriptionInfo);
|
SubscriptionInfo subscriptionInfo);
|
||||||
|
|
||||||
Task<string> CreateUserTokenAsync(User user, SubscriptionInfo subscriptionInfo);
|
Task<string?> CreateUserTokenAsync(User user, SubscriptionInfo subscriptionInfo);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Entities.Provider;
|
using Bit.Core.AdminConsole.Entities.Provider;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Billing.Enums;
|
using Bit.Core.Billing.Enums;
|
||||||
@ -55,7 +57,7 @@ public interface IMailService
|
|||||||
bool mentionInvoices);
|
bool mentionInvoices);
|
||||||
Task SendPaymentFailedAsync(string email, decimal amount, bool mentionInvoices);
|
Task SendPaymentFailedAsync(string email, decimal amount, bool mentionInvoices);
|
||||||
Task SendAddedCreditAsync(string email, decimal amount);
|
Task SendAddedCreditAsync(string email, decimal amount);
|
||||||
Task SendLicenseExpiredAsync(IEnumerable<string> emails, string organizationName = null);
|
Task SendLicenseExpiredAsync(IEnumerable<string> emails, string? organizationName = null);
|
||||||
Task SendNewDeviceLoggedInEmail(string email, string deviceType, DateTime timestamp, string ip);
|
Task SendNewDeviceLoggedInEmail(string email, string deviceType, DateTime timestamp, string ip);
|
||||||
Task SendRecoverTwoFactorEmail(string email, DateTime timestamp, string ip);
|
Task SendRecoverTwoFactorEmail(string email, DateTime timestamp, string ip);
|
||||||
Task SendOrganizationUserRemovedForPolicySingleOrgEmailAsync(string organizationName, string email);
|
Task SendOrganizationUserRemovedForPolicySingleOrgEmailAsync(string organizationName, string email);
|
||||||
@ -96,9 +98,11 @@ public interface IMailService
|
|||||||
Task SendInitiateDeletProviderEmailAsync(string email, Provider provider, string token);
|
Task SendInitiateDeletProviderEmailAsync(string email, Provider provider, string token);
|
||||||
Task SendInitiateDeleteOrganzationEmailAsync(string email, Organization organization, string token);
|
Task SendInitiateDeleteOrganzationEmailAsync(string email, Organization organization, string token);
|
||||||
Task SendRequestSMAccessToAdminEmailAsync(IEnumerable<string> adminEmails, string organizationName, string userRequestingAccess, string emailContent);
|
Task SendRequestSMAccessToAdminEmailAsync(IEnumerable<string> adminEmails, string organizationName, string userRequestingAccess, string emailContent);
|
||||||
|
#nullable disable
|
||||||
Task SendFamiliesForEnterpriseRemoveSponsorshipsEmailAsync(string email, string offerAcceptanceDate, string organizationId,
|
Task SendFamiliesForEnterpriseRemoveSponsorshipsEmailAsync(string email, string offerAcceptanceDate, string organizationId,
|
||||||
string organizationName);
|
string organizationName);
|
||||||
|
#nullable enable
|
||||||
Task SendClaimedDomainUserEmailAsync(ClaimedUserDomainClaimedEmails emailList);
|
Task SendClaimedDomainUserEmailAsync(ClaimedUserDomainClaimedEmails emailList);
|
||||||
Task SendDeviceApprovalRequestedNotificationEmailAsync(IEnumerable<string> adminEmails, Guid organizationId, string email, string userName);
|
Task SendDeviceApprovalRequestedNotificationEmailAsync(IEnumerable<string> adminEmails, Guid organizationId, string email, string? userName);
|
||||||
Task SendBulkSecurityTaskNotificationsAsync(Organization org, IEnumerable<UserSecurityTasksCount> securityTaskNotifications, IEnumerable<string> adminOwnerEmails);
|
Task SendBulkSecurityTaskNotificationsAsync(Organization org, IEnumerable<UserSecurityTasksCount> securityTaskNotifications, IEnumerable<string> adminOwnerEmails);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Amazon;
|
#nullable enable
|
||||||
|
|
||||||
|
using Amazon;
|
||||||
using Amazon.SimpleEmail;
|
using Amazon.SimpleEmail;
|
||||||
using Amazon.SimpleEmail.Model;
|
using Amazon.SimpleEmail.Model;
|
||||||
using Bit.Core.Models.Mail;
|
using Bit.Core.Models.Mail;
|
||||||
@ -17,7 +19,7 @@ public class AmazonSesMailDeliveryService : IMailDeliveryService, IDisposable
|
|||||||
private readonly IAmazonSimpleEmailService _client;
|
private readonly IAmazonSimpleEmailService _client;
|
||||||
private readonly string _source;
|
private readonly string _source;
|
||||||
private readonly string _senderTag;
|
private readonly string _senderTag;
|
||||||
private readonly string _configSetName;
|
private readonly string? _configSetName;
|
||||||
|
|
||||||
public AmazonSesMailDeliveryService(
|
public AmazonSesMailDeliveryService(
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Text;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Azure.Storage.Queues;
|
using Azure.Storage.Queues;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.Context;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
@ -34,8 +36,8 @@ public class CollectionService : ICollectionService
|
|||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveAsync(Collection collection, IEnumerable<CollectionAccessSelection> groups = null,
|
public async Task SaveAsync(Collection collection, IEnumerable<CollectionAccessSelection>? groups = null,
|
||||||
IEnumerable<CollectionAccessSelection> users = null)
|
IEnumerable<CollectionAccessSelection>? users = null)
|
||||||
{
|
{
|
||||||
var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
|
var org = await _organizationRepository.GetByIdAsync(collection.OrganizationId);
|
||||||
if (org == null)
|
if (org == null)
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
using System.Net;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
@ -213,6 +216,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
|
|
||||||
public async Task SendOrganizationAutoscaledEmailAsync(Organization organization, int initialSeatCount, IEnumerable<string> ownerEmails)
|
public async Task SendOrganizationAutoscaledEmailAsync(Organization organization, int initialSeatCount, IEnumerable<string> ownerEmails)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(organization.Seats.HasValue, "Organization is expected to have a non-null value for seats at the time of sending this email");
|
||||||
var message = CreateDefaultMessage($"{organization.DisplayName()} Seat Count Has Increased", ownerEmails);
|
var message = CreateDefaultMessage($"{organization.DisplayName()} Seat Count Has Increased", ownerEmails);
|
||||||
var model = new OrganizationSeatsAutoscaledViewModel
|
var model = new OrganizationSeatsAutoscaledViewModel
|
||||||
{
|
{
|
||||||
@ -286,7 +290,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
|
|
||||||
var messageModels = orgInvitesInfo.OrgUserTokenPairs.Select(orgUserTokenPair =>
|
var messageModels = orgInvitesInfo.OrgUserTokenPairs.Select(orgUserTokenPair =>
|
||||||
{
|
{
|
||||||
|
Debug.Assert(orgUserTokenPair.OrgUser.Email is not null);
|
||||||
var orgUserInviteViewModel = OrganizationUserInvitedViewModel.CreateFromInviteInfo(
|
var orgUserInviteViewModel = OrganizationUserInvitedViewModel.CreateFromInviteInfo(
|
||||||
orgInvitesInfo, orgUserTokenPair.OrgUser, orgUserTokenPair.Token, _globalSettings);
|
orgInvitesInfo, orgUserTokenPair.OrgUser, orgUserTokenPair.Token, _globalSettings);
|
||||||
return CreateMessage(orgUserTokenPair.OrgUser.Email, orgUserInviteViewModel);
|
return CreateMessage(orgUserTokenPair.OrgUser.Email, orgUserInviteViewModel);
|
||||||
@ -358,7 +362,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
|
||||||
SiteName = _globalSettings.SiteName,
|
SiteName = _globalSettings.SiteName,
|
||||||
ProviderId = provider.Id,
|
ProviderId = provider.Id,
|
||||||
ProviderName = CoreHelpers.SanitizeForEmail(provider.DisplayName(), false),
|
ProviderName = CoreHelpers.SanitizeForEmail(provider.DisplayName()!, false),
|
||||||
ProviderNameUrlEncoded = WebUtility.UrlEncode(provider.Name),
|
ProviderNameUrlEncoded = WebUtility.UrlEncode(provider.Name),
|
||||||
ProviderBillingEmail = provider.BillingEmail,
|
ProviderBillingEmail = provider.BillingEmail,
|
||||||
ProviderCreationDate = provider.CreationDate.ToLongDateString(),
|
ProviderCreationDate = provider.CreationDate.ToLongDateString(),
|
||||||
@ -448,7 +452,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
await _mailDeliveryService.SendEmailAsync(message);
|
await _mailDeliveryService.SendEmailAsync(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendLicenseExpiredAsync(IEnumerable<string> emails, string organizationName = null)
|
public async Task SendLicenseExpiredAsync(IEnumerable<string> emails, string? organizationName = null)
|
||||||
{
|
{
|
||||||
var message = CreateDefaultMessage("License Expired", emails);
|
var message = CreateDefaultMessage("License Expired", emails);
|
||||||
var model = new LicenseExpiredViewModel();
|
var model = new LicenseExpiredViewModel();
|
||||||
@ -598,12 +602,14 @@ public class HandlebarsMailService : IMailService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddMessageContentAsync<T>(MailMessage message, string templateName, T model)
|
private async Task AddMessageContentAsync<T>(MailMessage message, string templateName, T model)
|
||||||
|
where T : notnull
|
||||||
{
|
{
|
||||||
message.HtmlContent = await RenderAsync($"{templateName}.html", model);
|
message.HtmlContent = await RenderAsync($"{templateName}.html", model);
|
||||||
message.TextContent = await RenderAsync($"{templateName}.text", model);
|
message.TextContent = await RenderAsync($"{templateName}.text", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> RenderAsync<T>(string templateName, T model)
|
private async Task<string?> RenderAsync<T>(string templateName, T model)
|
||||||
|
where T : notnull
|
||||||
{
|
{
|
||||||
await RegisterHelpersAndPartialsAsync();
|
await RegisterHelpersAndPartialsAsync();
|
||||||
if (!_templateCache.TryGetValue(templateName, out var template))
|
if (!_templateCache.TryGetValue(templateName, out var template))
|
||||||
@ -618,7 +624,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
return template != null ? template(model) : null;
|
return template != null ? template(model) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ReadSourceAsync(string templateName)
|
private async Task<string?> ReadSourceAsync(string templateName)
|
||||||
{
|
{
|
||||||
var assembly = typeof(HandlebarsMailService).GetTypeInfo().Assembly;
|
var assembly = typeof(HandlebarsMailService).GetTypeInfo().Assembly;
|
||||||
var fullTemplateName = $"{Namespace}.{templateName}.hbs";
|
var fullTemplateName = $"{Namespace}.{templateName}.hbs";
|
||||||
@ -626,7 +632,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
using (var s = assembly.GetManifestResourceStream(fullTemplateName))
|
using (var s = assembly.GetManifestResourceStream(fullTemplateName)!)
|
||||||
using (var sr = new StreamReader(s))
|
using (var sr = new StreamReader(s))
|
||||||
{
|
{
|
||||||
return await sr.ReadToEndAsync();
|
return await sr.ReadToEndAsync();
|
||||||
@ -757,7 +763,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
var emailList = new List<string>();
|
var emailList = new List<string>();
|
||||||
if (parameters[0] is JsonElement jsonElement && jsonElement.ValueKind == JsonValueKind.Array)
|
if (parameters[0] is JsonElement jsonElement && jsonElement.ValueKind == JsonValueKind.Array)
|
||||||
{
|
{
|
||||||
emailList = jsonElement.EnumerateArray().Select(e => e.GetString()).ToList();
|
emailList = jsonElement.EnumerateArray().Select(e => e.GetString()!).ToList();
|
||||||
}
|
}
|
||||||
else if (parameters[0] is IEnumerable<string> emails)
|
else if (parameters[0] is IEnumerable<string> emails)
|
||||||
{
|
{
|
||||||
@ -1276,7 +1282,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
await _mailDeliveryService.SendEmailAsync(message);
|
await _mailDeliveryService.SendEmailAsync(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendDeviceApprovalRequestedNotificationEmailAsync(IEnumerable<string> adminEmails, Guid organizationId, string email, string userName)
|
public async Task SendDeviceApprovalRequestedNotificationEmailAsync(IEnumerable<string> adminEmails, Guid organizationId, string email, string? userName)
|
||||||
{
|
{
|
||||||
var templateName = _globalSettings.SelfHosted ?
|
var templateName = _globalSettings.SelfHosted ?
|
||||||
"AdminConsole.SelfHostNotifyAdminDeviceApprovalRequested" :
|
"AdminConsole.SelfHostNotifyAdminDeviceApprovalRequested" :
|
||||||
@ -1313,7 +1319,7 @@ public class HandlebarsMailService : IMailService
|
|||||||
await EnqueueMailAsync(messageModels.ToList());
|
await EnqueueMailAsync(messageModels.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetUserIdentifier(string email, string userName)
|
private static string GetUserIdentifier(string email, string? userName)
|
||||||
{
|
{
|
||||||
return string.IsNullOrEmpty(userName) ? email : CoreHelpers.SanitizeForEmail(userName, false);
|
return string.IsNullOrEmpty(userName) ? email : CoreHelpers.SanitizeForEmail(userName, false);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Reflection;
|
#nullable enable
|
||||||
|
|
||||||
using Bit.Core.Resources;
|
using Bit.Core.Resources;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
@ -10,8 +11,8 @@ public class I18nService : II18nService
|
|||||||
|
|
||||||
public I18nService(IStringLocalizerFactory factory)
|
public I18nService(IStringLocalizerFactory factory)
|
||||||
{
|
{
|
||||||
var assemblyName = new AssemblyName(typeof(SharedResources).GetTypeInfo().Assembly.FullName);
|
var assemblyName = typeof(SharedResources).Assembly.GetName()!;
|
||||||
_localizer = factory.Create("SharedResources", assemblyName.Name);
|
_localizer = factory.Create("SharedResources", assemblyName.Name!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalizedString GetLocalizedHtmlString(string key)
|
public LocalizedString GetLocalizedHtmlString(string key)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Reflection;
|
#nullable enable
|
||||||
|
|
||||||
using Bit.Core.Resources;
|
using Bit.Core.Resources;
|
||||||
using Microsoft.AspNetCore.Mvc.Localization;
|
using Microsoft.AspNetCore.Mvc.Localization;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
@ -13,9 +14,9 @@ public class I18nViewLocalizer : IViewLocalizer
|
|||||||
public I18nViewLocalizer(IStringLocalizerFactory stringFactory,
|
public I18nViewLocalizer(IStringLocalizerFactory stringFactory,
|
||||||
IHtmlLocalizerFactory htmlFactory)
|
IHtmlLocalizerFactory htmlFactory)
|
||||||
{
|
{
|
||||||
var assemblyName = new AssemblyName(typeof(SharedResources).GetTypeInfo().Assembly.FullName);
|
var assemblyName = typeof(SharedResources).Assembly.GetName()!;
|
||||||
_stringLocalizer = stringFactory.Create("SharedResources", assemblyName.Name);
|
_stringLocalizer = stringFactory.Create("SharedResources", assemblyName.Name!);
|
||||||
_htmlLocalizer = htmlFactory.Create("SharedResources", assemblyName.Name);
|
_htmlLocalizer = htmlFactory.Create("SharedResources", assemblyName.Name!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalizedHtmlString this[string name] => _htmlLocalizer[name];
|
public LocalizedHtmlString this[string name] => _htmlLocalizer[name];
|
||||||
|
@ -22,12 +22,17 @@ public class MailKitSmtpMailDeliveryService : IMailDeliveryService
|
|||||||
ILogger<MailKitSmtpMailDeliveryService> logger,
|
ILogger<MailKitSmtpMailDeliveryService> logger,
|
||||||
IOptions<X509ChainOptions> x509ChainOptions)
|
IOptions<X509ChainOptions> x509ChainOptions)
|
||||||
{
|
{
|
||||||
if (globalSettings.Mail?.Smtp?.Host == null)
|
if (globalSettings.Mail.Smtp?.Host == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(globalSettings.Mail.Smtp.Host));
|
throw new ArgumentNullException(nameof(globalSettings.Mail.Smtp.Host));
|
||||||
}
|
}
|
||||||
|
|
||||||
_replyEmail = CoreHelpers.PunyEncode(globalSettings.Mail?.ReplyToEmail);
|
if (globalSettings.Mail.ReplyToEmail == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("A GlobalSettings.Mail.ReplyToEmail is required to be set up.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_replyEmail = CoreHelpers.PunyEncode(globalSettings.Mail.ReplyToEmail);
|
||||||
|
|
||||||
if (_replyEmail.Contains("@"))
|
if (_replyEmail.Contains("@"))
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Security.Claims;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Security.Claims;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Models.Business;
|
using Bit.Core.Models.Business;
|
||||||
@ -45,28 +47,28 @@ public class NoopLicensingService : ILicensingService
|
|||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<OrganizationLicense> ReadOrganizationLicenseAsync(Organization organization)
|
public Task<OrganizationLicense?> ReadOrganizationLicenseAsync(Organization organization)
|
||||||
{
|
{
|
||||||
return Task.FromResult<OrganizationLicense>(null);
|
return Task.FromResult<OrganizationLicense?>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<OrganizationLicense> ReadOrganizationLicenseAsync(Guid organizationId)
|
public Task<OrganizationLicense?> ReadOrganizationLicenseAsync(Guid organizationId)
|
||||||
{
|
{
|
||||||
return Task.FromResult<OrganizationLicense>(null);
|
return Task.FromResult<OrganizationLicense?>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClaimsPrincipal GetClaimsPrincipalFromLicense(ILicense license)
|
public ClaimsPrincipal? GetClaimsPrincipalFromLicense(ILicense license)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<string> CreateOrganizationTokenAsync(Organization organization, Guid installationId, SubscriptionInfo subscriptionInfo)
|
public Task<string?> CreateOrganizationTokenAsync(Organization organization, Guid installationId, SubscriptionInfo subscriptionInfo)
|
||||||
{
|
{
|
||||||
return Task.FromResult<string>(null);
|
return Task.FromResult<string?>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<string> CreateUserTokenAsync(User user, SubscriptionInfo subscriptionInfo)
|
public Task<string?> CreateUserTokenAsync(User user, SubscriptionInfo subscriptionInfo)
|
||||||
{
|
{
|
||||||
return Task.FromResult<string>(null);
|
return Task.FromResult<string?>(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
#nullable enable
|
||||||
|
|
||||||
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Entities.Provider;
|
using Bit.Core.AdminConsole.Entities.Provider;
|
||||||
using Bit.Core.Auth.Entities;
|
using Bit.Core.Auth.Entities;
|
||||||
using Bit.Core.Billing.Enums;
|
using Bit.Core.Billing.Enums;
|
||||||
@ -137,7 +139,7 @@ public class NoopMailService : IMailService
|
|||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendLicenseExpiredAsync(IEnumerable<string> emails, string organizationName = null)
|
public Task SendLicenseExpiredAsync(IEnumerable<string> emails, string? organizationName = null)
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
@ -324,7 +326,7 @@ public class NoopMailService : IMailService
|
|||||||
}
|
}
|
||||||
public Task SendClaimedDomainUserEmailAsync(ClaimedUserDomainClaimedEmails emailList) => Task.CompletedTask;
|
public Task SendClaimedDomainUserEmailAsync(ClaimedUserDomainClaimedEmails emailList) => Task.CompletedTask;
|
||||||
|
|
||||||
public Task SendDeviceApprovalRequestedNotificationEmailAsync(IEnumerable<string> adminEmails, Guid organizationId, string email, string userName)
|
public Task SendDeviceApprovalRequestedNotificationEmailAsync(IEnumerable<string> adminEmails, Guid organizationId, string email, string? userName)
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
using System.Globalization;
|
#nullable enable
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
@ -116,11 +119,11 @@ public static class CoreHelpers
|
|||||||
return Regex.Replace(thumbprint, @"[^\da-fA-F]", string.Empty).ToUpper();
|
return Regex.Replace(thumbprint, @"[^\da-fA-F]", string.Empty).ToUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate2 GetCertificate(string thumbprint)
|
public static X509Certificate2? GetCertificate(string thumbprint)
|
||||||
{
|
{
|
||||||
thumbprint = CleanCertificateThumbprint(thumbprint);
|
thumbprint = CleanCertificateThumbprint(thumbprint);
|
||||||
|
|
||||||
X509Certificate2 cert = null;
|
X509Certificate2? cert = null;
|
||||||
var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
|
var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
|
||||||
certStore.Open(OpenFlags.ReadOnly);
|
certStore.Open(OpenFlags.ReadOnly);
|
||||||
var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
|
var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
|
||||||
@ -141,7 +144,7 @@ public static class CoreHelpers
|
|||||||
public async static Task<X509Certificate2> GetEmbeddedCertificateAsync(string file, string password)
|
public async static Task<X509Certificate2> GetEmbeddedCertificateAsync(string file, string password)
|
||||||
{
|
{
|
||||||
var assembly = typeof(CoreHelpers).GetTypeInfo().Assembly;
|
var assembly = typeof(CoreHelpers).GetTypeInfo().Assembly;
|
||||||
using (var s = assembly.GetManifestResourceStream($"Bit.Core.{file}"))
|
using (var s = assembly.GetManifestResourceStream($"Bit.Core.{file}")!)
|
||||||
using (var ms = new MemoryStream())
|
using (var ms = new MemoryStream())
|
||||||
{
|
{
|
||||||
await s.CopyToAsync(ms);
|
await s.CopyToAsync(ms);
|
||||||
@ -153,14 +156,14 @@ public static class CoreHelpers
|
|||||||
{
|
{
|
||||||
var assembly = Assembly.GetCallingAssembly();
|
var assembly = Assembly.GetCallingAssembly();
|
||||||
var resourceName = assembly.GetManifestResourceNames().Single(n => n.EndsWith(file));
|
var resourceName = assembly.GetManifestResourceNames().Single(n => n.EndsWith(file));
|
||||||
using (var stream = assembly.GetManifestResourceStream(resourceName))
|
using (var stream = assembly.GetManifestResourceStream(resourceName)!)
|
||||||
using (var reader = new StreamReader(stream))
|
using (var reader = new StreamReader(stream))
|
||||||
{
|
{
|
||||||
return reader.ReadToEnd();
|
return reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async static Task<X509Certificate2> GetBlobCertificateAsync(string connectionString, string container, string file, string password)
|
public async static Task<X509Certificate2?> GetBlobCertificateAsync(string connectionString, string container, string file, string password)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -233,7 +236,7 @@ public static class CoreHelpers
|
|||||||
throw new ArgumentOutOfRangeException(nameof(length), "length cannot be less than zero.");
|
throw new ArgumentOutOfRangeException(nameof(length), "length cannot be less than zero.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((characters?.Length ?? 0) == 0)
|
if (string.IsNullOrEmpty(characters))
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException(nameof(characters), "characters invalid.");
|
throw new ArgumentOutOfRangeException(nameof(characters), "characters invalid.");
|
||||||
}
|
}
|
||||||
@ -346,10 +349,10 @@ public static class CoreHelpers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static T CloneObject<T>(T obj)
|
public static T CloneObject<T>(T obj)
|
||||||
{
|
{
|
||||||
return JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(obj));
|
return JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(obj))!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool SettingHasValue(string setting)
|
public static bool SettingHasValue([NotNullWhen(true)] string? setting)
|
||||||
{
|
{
|
||||||
var normalizedSetting = setting?.ToLowerInvariant();
|
var normalizedSetting = setting?.ToLowerInvariant();
|
||||||
return !string.IsNullOrWhiteSpace(normalizedSetting) && !normalizedSetting.Equals("secret") &&
|
return !string.IsNullOrWhiteSpace(normalizedSetting) && !normalizedSetting.Equals("secret") &&
|
||||||
@ -448,7 +451,8 @@ public static class CoreHelpers
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string PunyEncode(string text)
|
[return: NotNullIfNotNull(nameof(text))]
|
||||||
|
public static string? PunyEncode(string? text)
|
||||||
{
|
{
|
||||||
if (text == "")
|
if (text == "")
|
||||||
{
|
{
|
||||||
@ -473,21 +477,21 @@ public static class CoreHelpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FormatLicenseSignatureValue(object val)
|
public static string? FormatLicenseSignatureValue(object val)
|
||||||
{
|
{
|
||||||
if (val == null)
|
if (val == null)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val.GetType() == typeof(DateTime))
|
if (val is DateTime dateTimeVal)
|
||||||
{
|
{
|
||||||
return ToEpocSeconds((DateTime)val).ToString();
|
return ToEpocSeconds(dateTimeVal).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val.GetType() == typeof(bool))
|
if (val is bool boolVal)
|
||||||
{
|
{
|
||||||
return val.ToString().ToLowerInvariant();
|
return boolVal.ToString().ToLowerInvariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val is PlanType planType)
|
if (val is PlanType planType)
|
||||||
@ -625,7 +629,7 @@ public static class CoreHelpers
|
|||||||
return subName;
|
return subName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetIpAddress(this Microsoft.AspNetCore.Http.HttpContext httpContext,
|
public static string? GetIpAddress(this Microsoft.AspNetCore.Http.HttpContext httpContext,
|
||||||
GlobalSettings globalSettings)
|
GlobalSettings globalSettings)
|
||||||
{
|
{
|
||||||
if (httpContext == null)
|
if (httpContext == null)
|
||||||
@ -652,7 +656,7 @@ public static class CoreHelpers
|
|||||||
(!globalSettings.SelfHosted && origin == "https://bitwarden.com");
|
(!globalSettings.SelfHosted && origin == "https://bitwarden.com");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate2 GetIdentityServerCertificate(GlobalSettings globalSettings)
|
public static X509Certificate2? GetIdentityServerCertificate(GlobalSettings globalSettings)
|
||||||
{
|
{
|
||||||
if (globalSettings.SelfHosted &&
|
if (globalSettings.SelfHosted &&
|
||||||
SettingHasValue(globalSettings.IdentityServer.CertificatePassword)
|
SettingHasValue(globalSettings.IdentityServer.CertificatePassword)
|
||||||
@ -804,14 +808,16 @@ public static class CoreHelpers
|
|||||||
/// <param name="jsonData">The JSON data</param>
|
/// <param name="jsonData">The JSON data</param>
|
||||||
/// <typeparam name="T">The type to deserialize into</typeparam>
|
/// <typeparam name="T">The type to deserialize into</typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T LoadClassFromJsonData<T>(string jsonData) where T : new()
|
public static T LoadClassFromJsonData<T>(string? jsonData) where T : new()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(jsonData))
|
if (string.IsNullOrWhiteSpace(jsonData))
|
||||||
{
|
{
|
||||||
return new T();
|
return new T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nullable disable // TODO: Remove this and fix any callee warnings.
|
||||||
return System.Text.Json.JsonSerializer.Deserialize<T>(jsonData, _jsonSerializerOptions);
|
return System.Text.Json.JsonSerializer.Deserialize<T>(jsonData, _jsonSerializerOptions);
|
||||||
|
#nullable enable
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ClassToJsonData<T>(T data)
|
public static string ClassToJsonData<T>(T data)
|
||||||
@ -829,7 +835,7 @@ public static class CoreHelpers
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DecodeMessageText(this QueueMessage message)
|
public static string? DecodeMessageText(this QueueMessage message)
|
||||||
{
|
{
|
||||||
var text = message?.MessageText;
|
var text = message?.MessageText;
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
@ -852,7 +858,7 @@ public static class CoreHelpers
|
|||||||
Encoding.UTF8.GetBytes(input1), Encoding.UTF8.GetBytes(input2));
|
Encoding.UTF8.GetBytes(input1), Encoding.UTF8.GetBytes(input2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ObfuscateEmail(string email)
|
public static string? ObfuscateEmail(string email)
|
||||||
{
|
{
|
||||||
if (email == null)
|
if (email == null)
|
||||||
{
|
{
|
||||||
@ -886,7 +892,7 @@ public static class CoreHelpers
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetEmailDomain(string email)
|
public static string? GetEmailDomain(string email)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(email))
|
if (!string.IsNullOrWhiteSpace(email))
|
||||||
{
|
{
|
||||||
@ -906,7 +912,7 @@ public static class CoreHelpers
|
|||||||
return _whiteSpaceRegex.Replace(input, newValue);
|
return _whiteSpaceRegex.Replace(input, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string RedactEmailAddress(string email)
|
public static string? RedactEmailAddress(string email)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(email))
|
if (string.IsNullOrWhiteSpace(email))
|
||||||
{
|
{
|
||||||
|
@ -513,15 +513,21 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ReplaceAsync(Core.Entities.Collection collection, IEnumerable<CollectionAccessSelection> groups,
|
public async Task ReplaceAsync(Core.Entities.Collection collection, IEnumerable<CollectionAccessSelection>? groups,
|
||||||
IEnumerable<CollectionAccessSelection> users)
|
IEnumerable<CollectionAccessSelection>? users)
|
||||||
{
|
{
|
||||||
await UpsertAsync(collection);
|
await UpsertAsync(collection);
|
||||||
using (var scope = ServiceScopeFactory.CreateScope())
|
using (var scope = ServiceScopeFactory.CreateScope())
|
||||||
{
|
{
|
||||||
var dbContext = GetDatabaseContext(scope);
|
var dbContext = GetDatabaseContext(scope);
|
||||||
await ReplaceCollectionGroupsAsync(dbContext, collection, groups);
|
if (groups != null)
|
||||||
await ReplaceCollectionUsersAsync(dbContext, collection, users);
|
{
|
||||||
|
await ReplaceCollectionGroupsAsync(dbContext, collection, groups);
|
||||||
|
}
|
||||||
|
if (users != null)
|
||||||
|
{
|
||||||
|
await ReplaceCollectionUsersAsync(dbContext, collection, users);
|
||||||
|
}
|
||||||
await dbContext.UserBumpAccountRevisionDateByCollectionIdAsync(collection.Id, collection.OrganizationId);
|
await dbContext.UserBumpAccountRevisionDateByCollectionIdAsync(collection.Id, collection.OrganizationId);
|
||||||
await dbContext.SaveChangesAsync();
|
await dbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user