mirror of
https://github.com/bitwarden/server.git
synced 2025-01-22 21:51:22 +01:00
do not send push notifications to device that intiated the cipher create/update/delete since that device should arleady be handling the action after API response.
This commit is contained in:
parent
929e264549
commit
f07e9e9dd0
@ -9,5 +9,6 @@ namespace Bit.Core
|
|||||||
public class CurrentContext
|
public class CurrentContext
|
||||||
{
|
{
|
||||||
public virtual User User { get; set; }
|
public virtual User User { get; set; }
|
||||||
|
public virtual string DeviceIdentifier { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Http.Authentication;
|
|||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Bit.Core.Domains;
|
using Bit.Core.Domains;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Bit.Core.Identity
|
namespace Bit.Core.Identity
|
||||||
{
|
{
|
||||||
@ -37,6 +38,11 @@ namespace Bit.Core.Identity
|
|||||||
// register the current context user
|
// register the current context user
|
||||||
var currentContext = context.HttpContext.RequestServices.GetRequiredService<CurrentContext>();
|
var currentContext = context.HttpContext.RequestServices.GetRequiredService<CurrentContext>();
|
||||||
currentContext.User = user;
|
currentContext.User = user;
|
||||||
|
var deviceIdentifierClaim = context.Ticket.Principal.Claims.SingleOrDefault(c => c.Type == "DeviceIdentifier");
|
||||||
|
if(deviceIdentifierClaim != null)
|
||||||
|
{
|
||||||
|
currentContext.DeviceIdentifier = deviceIdentifierClaim.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task AuthenticationFailedAsync(AuthenticationFailedContext context)
|
public static Task AuthenticationFailedAsync(AuthenticationFailedContext context)
|
||||||
|
@ -68,7 +68,7 @@ namespace Bit.Core.Identity
|
|||||||
|
|
||||||
if(await UserManager.CheckPasswordAsync(user, password))
|
if(await UserManager.CheckPasswordAsync(user, password))
|
||||||
{
|
{
|
||||||
var result = await SignInOrTwoFactorAsync(user);
|
var result = await SignInOrTwoFactorAsync(user, device);
|
||||||
if(result.Succeeded && device != null)
|
if(result.Succeeded && device != null)
|
||||||
{
|
{
|
||||||
var existingDevice = await _deviceRepository.GetByIdentifierAsync(device.Identifier, user.Id);
|
var existingDevice = await _deviceRepository.GetByIdentifierAsync(device.Identifier, user.Id);
|
||||||
@ -105,7 +105,7 @@ namespace Bit.Core.Identity
|
|||||||
|
|
||||||
if(await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
|
if(await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
|
||||||
{
|
{
|
||||||
var token = await SignInAsync(user, false);
|
var token = await SignInAsync(user, false, device);
|
||||||
|
|
||||||
var success = JwtBearerSignInResult.Success;
|
var success = JwtBearerSignInResult.Success;
|
||||||
success.Token = token;
|
success.Token = token;
|
||||||
@ -127,7 +127,7 @@ namespace Bit.Core.Identity
|
|||||||
return JwtBearerSignInResult.Failed;
|
return JwtBearerSignInResult.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> SignInAsync(User user, bool twoFactor)
|
private async Task<string> SignInAsync(User user, bool twoFactor, Device device)
|
||||||
{
|
{
|
||||||
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
|
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
|
||||||
|
|
||||||
@ -150,6 +150,11 @@ namespace Bit.Core.Identity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(device != null && !string.IsNullOrWhiteSpace(device.Identifier))
|
||||||
|
{
|
||||||
|
userPrincipal.Identities.First().AddClaim(new Claim("DeviceIdentifier", device.Identifier));
|
||||||
|
}
|
||||||
|
|
||||||
var descriptor = new SecurityTokenDescriptor
|
var descriptor = new SecurityTokenDescriptor
|
||||||
{
|
{
|
||||||
Issuer = JwtIdentityOptions.Issuer,
|
Issuer = JwtIdentityOptions.Issuer,
|
||||||
@ -164,13 +169,13 @@ namespace Bit.Core.Identity
|
|||||||
return handler.WriteToken(securityToken);
|
return handler.WriteToken(securityToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<JwtBearerSignInResult> SignInOrTwoFactorAsync(User user)
|
private async Task<JwtBearerSignInResult> SignInOrTwoFactorAsync(User user, Device device)
|
||||||
{
|
{
|
||||||
if(UserManager.SupportsUserTwoFactor &&
|
if(UserManager.SupportsUserTwoFactor &&
|
||||||
await UserManager.GetTwoFactorEnabledAsync(user) &&
|
await UserManager.GetTwoFactorEnabledAsync(user) &&
|
||||||
(await UserManager.GetValidTwoFactorProvidersAsync(user)).Count > 0)
|
(await UserManager.GetValidTwoFactorProvidersAsync(user)).Count > 0)
|
||||||
{
|
{
|
||||||
var twoFactorToken = await SignInAsync(user, true);
|
var twoFactorToken = await SignInAsync(user, true, device);
|
||||||
|
|
||||||
var twoFactorResult = JwtBearerSignInResult.TwoFactorRequired;
|
var twoFactorResult = JwtBearerSignInResult.TwoFactorRequired;
|
||||||
twoFactorResult.Token = twoFactorToken;
|
twoFactorResult.Token = twoFactorToken;
|
||||||
@ -179,7 +184,7 @@ namespace Bit.Core.Identity
|
|||||||
return twoFactorResult;
|
return twoFactorResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
var token = await SignInAsync(user, false);
|
var token = await SignInAsync(user, false, device);
|
||||||
|
|
||||||
var result = JwtBearerSignInResult.Success;
|
var result = JwtBearerSignInResult.Success;
|
||||||
result.Token = token;
|
result.Token = token;
|
||||||
|
@ -22,17 +22,20 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
private readonly IDeviceRepository _deviceRepository;
|
private readonly IDeviceRepository _deviceRepository;
|
||||||
private readonly ILogger<IPushService> _logger;
|
private readonly ILogger<IPushService> _logger;
|
||||||
|
private readonly CurrentContext _currentContext;
|
||||||
private GcmServiceBroker _gcmBroker;
|
private GcmServiceBroker _gcmBroker;
|
||||||
private ApnsServiceBroker _apnsBroker;
|
private ApnsServiceBroker _apnsBroker;
|
||||||
|
|
||||||
public PushService(
|
public PushService(
|
||||||
IDeviceRepository deviceRepository,
|
IDeviceRepository deviceRepository,
|
||||||
ILogger<IPushService> logger,
|
ILogger<IPushService> logger,
|
||||||
|
CurrentContext currentContext,
|
||||||
IHostingEnvironment hostingEnvironment,
|
IHostingEnvironment hostingEnvironment,
|
||||||
GlobalSettings globalSettings)
|
GlobalSettings globalSettings)
|
||||||
{
|
{
|
||||||
_deviceRepository = deviceRepository;
|
_deviceRepository = deviceRepository;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_currentContext = currentContext;
|
||||||
|
|
||||||
InitGcmBroker(globalSettings);
|
InitGcmBroker(globalSettings);
|
||||||
InitApnsBroker(globalSettings, hostingEnvironment);
|
InitApnsBroker(globalSettings, hostingEnvironment);
|
||||||
@ -74,7 +77,13 @@ namespace Bit.Core.Services
|
|||||||
Aps = new PushNotification.AppleData { ContentAvailable = 1 }
|
Aps = new PushNotification.AppleData { ContentAvailable = 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
await PushToAllUserDevicesAsync(cipher.UserId, JObject.FromObject(message));
|
var excludedTokens = new List<string>();
|
||||||
|
if(!string.IsNullOrWhiteSpace(_currentContext.DeviceIdentifier))
|
||||||
|
{
|
||||||
|
excludedTokens.Add(_currentContext.DeviceIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
await PushToAllUserDevicesAsync(cipher.UserId, JObject.FromObject(message), excludedTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PushSyncCiphersAsync(Guid userId)
|
public async Task PushSyncCiphersAsync(Guid userId)
|
||||||
@ -87,7 +96,7 @@ namespace Bit.Core.Services
|
|||||||
Aps = new PushNotification.AppleData { ContentAvailable = 1 }
|
Aps = new PushNotification.AppleData { ContentAvailable = 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
await PushToAllUserDevicesAsync(userId, JObject.FromObject(message));
|
await PushToAllUserDevicesAsync(userId, JObject.FromObject(message), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitGcmBroker(GlobalSettings globalSettings)
|
private void InitGcmBroker(GlobalSettings globalSettings)
|
||||||
@ -255,9 +264,10 @@ namespace Bit.Core.Services
|
|||||||
// timestamp is the time the token was reported as expired
|
// timestamp is the time the token was reported as expired
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushToAllUserDevicesAsync(Guid userId, JObject message)
|
private async Task PushToAllUserDevicesAsync(Guid userId, JObject message, IEnumerable<string> tokensToSkip)
|
||||||
{
|
{
|
||||||
var devices = (await _deviceRepository.GetManyByUserIdAsync(userId)).Where(d => !string.IsNullOrWhiteSpace(d.PushToken));
|
var devices = (await _deviceRepository.GetManyByUserIdAsync(userId))
|
||||||
|
.Where(d => !string.IsNullOrWhiteSpace(d.PushToken) && (!tokensToSkip?.Contains(d.PushToken) ?? true));
|
||||||
if(devices.Count() == 0)
|
if(devices.Count() == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user