mirror of
https://github.com/bitwarden/server.git
synced 2025-04-17 20:36:21 +02:00
[SG-72] Sync changed email address with stripe (#2042)
* sync changed email address with strip * sync changed email address with strip * fixed formatting * throw exception if not successful * Added revert if stripe sync fails * Added revert if stripe sync fails * Added revert if stripe sync fails * created stripe sync service * fixed lint issue * reverted to use stripe exception message * added null checks to customer id and email address * added braces * removed empty email
This commit is contained in:
parent
b39a43210d
commit
8e79c20dce
13
src/Core/Exceptions/InvalidEmailException.cs
Normal file
13
src/Core/Exceptions/InvalidEmailException.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace Bit.Core.Exceptions
|
||||
{
|
||||
public class InvalidEmailException : Exception
|
||||
{
|
||||
public InvalidEmailException()
|
||||
: base("Invalid email.")
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
13
src/Core/Exceptions/InvalidGatewayCustomerIdException.cs
Normal file
13
src/Core/Exceptions/InvalidGatewayCustomerIdException.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace Bit.Core.Exceptions
|
||||
{
|
||||
public class InvalidGatewayCustomerIdException : Exception
|
||||
{
|
||||
public InvalidGatewayCustomerIdException()
|
||||
: base("Invalid gateway customerId.")
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
9
src/Core/Services/IStripeSyncService.cs
Normal file
9
src/Core/Services/IStripeSyncService.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public interface IStripeSyncService
|
||||
{
|
||||
Task UpdateCustomerEmailAddress(string gatewayCustomerId, string emailAddress);
|
||||
}
|
||||
}
|
33
src/Core/Services/Implementations/StripeSyncService.cs
Normal file
33
src/Core/Services/Implementations/StripeSyncService.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Exceptions;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class StripeSyncService : IStripeSyncService
|
||||
{
|
||||
private readonly IStripeAdapter _stripeAdapter;
|
||||
|
||||
public StripeSyncService(IStripeAdapter stripeAdapter)
|
||||
{
|
||||
_stripeAdapter = stripeAdapter;
|
||||
}
|
||||
|
||||
public async Task UpdateCustomerEmailAddress(string gatewayCustomerId, string emailAddress)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(gatewayCustomerId))
|
||||
{
|
||||
throw new InvalidGatewayCustomerIdException();
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(emailAddress))
|
||||
{
|
||||
throw new InvalidEmailException();
|
||||
}
|
||||
|
||||
var customer = await _stripeAdapter.CustomerGetAsync(gatewayCustomerId);
|
||||
|
||||
await _stripeAdapter.CustomerUpdateAsync(customer.Id,
|
||||
new Stripe.CustomerUpdateOptions { Email = emailAddress });
|
||||
}
|
||||
}
|
||||
}
|
@ -52,6 +52,7 @@ namespace Bit.Core.Services
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IProviderUserRepository _providerUserRepository;
|
||||
private readonly IDeviceRepository _deviceRepository;
|
||||
private readonly IStripeSyncService _stripeSyncService;
|
||||
|
||||
public UserService(
|
||||
IUserRepository userRepository,
|
||||
@ -81,7 +82,8 @@ namespace Bit.Core.Services
|
||||
IGlobalSettings globalSettings,
|
||||
IOrganizationService organizationService,
|
||||
IProviderUserRepository providerUserRepository,
|
||||
IDeviceRepository deviceRepository)
|
||||
IDeviceRepository deviceRepository,
|
||||
IStripeSyncService stripeSyncService)
|
||||
: base(
|
||||
store,
|
||||
optionsAccessor,
|
||||
@ -117,6 +119,7 @@ namespace Bit.Core.Services
|
||||
_organizationService = organizationService;
|
||||
_providerUserRepository = providerUserRepository;
|
||||
_deviceRepository = deviceRepository;
|
||||
_stripeSyncService = stripeSyncService;
|
||||
}
|
||||
|
||||
public Guid? GetProperUserId(ClaimsPrincipal principal)
|
||||
@ -543,6 +546,14 @@ namespace Bit.Core.Services
|
||||
return IdentityResult.Failed(_identityErrorDescriber.DuplicateEmail(newEmail));
|
||||
}
|
||||
|
||||
var previousState = new
|
||||
{
|
||||
Key = user.Key,
|
||||
MasterPassword = user.MasterPassword,
|
||||
SecurityStamp = user.SecurityStamp,
|
||||
Email = user.Email
|
||||
};
|
||||
|
||||
var result = await UpdatePasswordHash(user, newMasterPassword);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
@ -554,6 +565,32 @@ namespace Bit.Core.Services
|
||||
user.EmailVerified = true;
|
||||
user.RevisionDate = user.AccountRevisionDate = DateTime.UtcNow;
|
||||
await _userRepository.ReplaceAsync(user);
|
||||
|
||||
if (user.Gateway == GatewayType.Stripe)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
await _stripeSyncService.UpdateCustomerEmailAddress(user.GatewayCustomerId,
|
||||
user.BillingEmailAddress());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//if sync to strip fails, update email and securityStamp to previous
|
||||
user.Key = previousState.Key;
|
||||
user.Email = previousState.Email;
|
||||
user.RevisionDate = user.AccountRevisionDate = DateTime.UtcNow;
|
||||
user.MasterPassword = previousState.MasterPassword;
|
||||
user.SecurityStamp = previousState.SecurityStamp;
|
||||
|
||||
await _userRepository.ReplaceAsync(user);
|
||||
return IdentityResult.Failed(new IdentityError
|
||||
{
|
||||
Description = ex.Message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await _pushService.PushLogOutAsync(user.Id);
|
||||
|
||||
return IdentityResult.Success;
|
||||
|
@ -148,6 +148,7 @@ namespace Bit.SharedWeb.Utilities
|
||||
};
|
||||
});
|
||||
services.AddSingleton<IPaymentService, StripePaymentService>();
|
||||
services.AddSingleton<IStripeSyncService, StripeSyncService>();
|
||||
services.AddSingleton<IMailService, HandlebarsMailService>();
|
||||
services.AddSingleton<ILicensingService, LicensingService>();
|
||||
services.AddTokenizers();
|
||||
|
Loading…
Reference in New Issue
Block a user