mirror of
https://github.com/bitwarden/android.git
synced 2024-12-27 03:18:27 +03:00
[SG-703] Login request is not removed after dismissing push notification (#2125)
* [SG-703] Handle iOS dismiss notification action. Added core logic to remove passwordless notification from local storage. * [SG-702] Added broadcast receiver to catch dismiss notfication events on android. * [SG-703] PR fixes. * [SG-703] Fix constants namespaces. Lazyloading services on broadcast receiver. * [SG-703] Change services to use lazy loading * [SG-703] Change lazy loading to be parameterless.
This commit is contained in:
parent
3972e3de8a
commit
569922805f
8 changed files with 138 additions and 67 deletions
|
@ -152,6 +152,7 @@
|
||||||
<Compile Include="Utilities\IntentExtensions.cs" />
|
<Compile Include="Utilities\IntentExtensions.cs" />
|
||||||
<Compile Include="Renderers\CustomPageRenderer.cs" />
|
<Compile Include="Renderers\CustomPageRenderer.cs" />
|
||||||
<Compile Include="Effects\NoEmojiKeyboardEffect.cs" />
|
<Compile Include="Effects\NoEmojiKeyboardEffect.cs" />
|
||||||
|
<Compile Include="Receivers\NotificationDismissReceiver.cs" />
|
||||||
<Compile Include="Services\FileService.cs" />
|
<Compile Include="Services\FileService.cs" />
|
||||||
<Compile Include="Services\AutofillHandler.cs" />
|
<Compile Include="Services\AutofillHandler.cs" />
|
||||||
<Compile Include="Constants.cs" />
|
<Compile Include="Constants.cs" />
|
||||||
|
|
41
src/Android/Receivers/NotificationDismissReceiver.cs
Normal file
41
src/Android/Receivers/NotificationDismissReceiver.cs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
using Android.Content;
|
||||||
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.App.Models;
|
||||||
|
using Bit.App.Services;
|
||||||
|
using Bit.Core;
|
||||||
|
using Bit.Core.Abstractions;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using CoreConstants = Bit.Core.Constants;
|
||||||
|
|
||||||
|
namespace Bit.Droid.Receivers
|
||||||
|
{
|
||||||
|
[BroadcastReceiver(Name = Constants.PACKAGE_NAME + "." + nameof(NotificationDismissReceiver), Exported = false)]
|
||||||
|
public class NotificationDismissReceiver : BroadcastReceiver
|
||||||
|
{
|
||||||
|
private readonly LazyResolve<IPushNotificationListenerService> _pushNotificationListenerService = new LazyResolve<IPushNotificationListenerService>();
|
||||||
|
private readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
|
||||||
|
|
||||||
|
public override void OnReceive(Context context, Intent intent)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (intent?.GetStringExtra(CoreConstants.NotificationData) is string notificationDataJson)
|
||||||
|
{
|
||||||
|
var notificationType = JToken.Parse(notificationDataJson).SelectToken(CoreConstants.NotificationDataType);
|
||||||
|
if (notificationType.ToString() == PasswordlessNotificationData.TYPE)
|
||||||
|
{
|
||||||
|
_pushNotificationListenerService.Value.OnNotificationDismissed(JsonConvert.DeserializeObject<PasswordlessNotificationData>(notificationDataJson)).FireAndForget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Value.Exception(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,9 +10,12 @@ using Bit.App.Abstractions;
|
||||||
using Bit.App.Models;
|
using Bit.App.Models;
|
||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
using Bit.Core.Abstractions;
|
using Bit.Core.Abstractions;
|
||||||
|
using Bit.Droid.Receivers;
|
||||||
using Bit.Droid.Utilities;
|
using Bit.Droid.Utilities;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
using static Xamarin.Essentials.Platform;
|
||||||
|
using Intent = Android.Content.Intent;
|
||||||
|
|
||||||
namespace Bit.Droid.Services
|
namespace Bit.Droid.Services
|
||||||
{
|
{
|
||||||
|
@ -79,16 +82,21 @@ namespace Bit.Droid.Services
|
||||||
|
|
||||||
var context = Android.App.Application.Context;
|
var context = Android.App.Application.Context;
|
||||||
var intent = new Intent(context, typeof(MainActivity));
|
var intent = new Intent(context, typeof(MainActivity));
|
||||||
intent.PutExtra(Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
intent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
||||||
|
|
||||||
var pendingIntentFlags = AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, true);
|
var pendingIntentFlags = AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, true);
|
||||||
var pendingIntent = PendingIntent.GetActivity(context, 20220801, intent, pendingIntentFlags);
|
var pendingIntent = PendingIntent.GetActivity(context, 20220801, intent, pendingIntentFlags);
|
||||||
var builder = new NotificationCompat.Builder(context, Core.Constants.AndroidNotificationChannelId)
|
|
||||||
|
var deleteIntent = new Intent(context, typeof(NotificationDismissReceiver));
|
||||||
|
deleteIntent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
||||||
|
var deletePendingIntent = PendingIntent.GetBroadcast(context, 20220802, deleteIntent, pendingIntentFlags);
|
||||||
|
|
||||||
|
var builder = new NotificationCompat.Builder(context, Bit.Core.Constants.AndroidNotificationChannelId)
|
||||||
.SetContentIntent(pendingIntent)
|
.SetContentIntent(pendingIntent)
|
||||||
.SetContentTitle(title)
|
.SetContentTitle(title)
|
||||||
.SetContentText(message)
|
.SetContentText(message)
|
||||||
.SetSmallIcon(Resource.Drawable.ic_notification)
|
.SetSmallIcon(Resource.Drawable.ic_notification)
|
||||||
.SetColor((int)Android.Graphics.Color.White)
|
.SetColor((int)Android.Graphics.Color.White)
|
||||||
|
.SetDeleteIntent(deletePendingIntent)
|
||||||
.SetAutoCancel(true);
|
.SetAutoCancel(true);
|
||||||
|
|
||||||
if (data is PasswordlessNotificationData passwordlessNotificationData && passwordlessNotificationData.TimeoutInMinutes > 0)
|
if (data is PasswordlessNotificationData passwordlessNotificationData && passwordlessNotificationData.TimeoutInMinutes > 0)
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace Bit.App.Abstractions
|
||||||
void OnUnregistered(string device);
|
void OnUnregistered(string device);
|
||||||
void OnError(string message, string device);
|
void OnError(string message, string device);
|
||||||
Task OnNotificationTapped(BaseNotificationData data);
|
Task OnNotificationTapped(BaseNotificationData data);
|
||||||
|
Task OnNotificationDismissed(BaseNotificationData data);
|
||||||
bool ShouldShowNotification();
|
bool ShouldShowNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,5 +34,10 @@ namespace Bit.App.Services
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task OnNotificationDismissed(BaseNotificationData data)
|
||||||
|
{
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,20 +26,18 @@ namespace Bit.App.Services
|
||||||
const string TAG = "##PUSH NOTIFICATIONS";
|
const string TAG = "##PUSH NOTIFICATIONS";
|
||||||
|
|
||||||
private bool _showNotification;
|
private bool _showNotification;
|
||||||
private bool _resolved;
|
private LazyResolve<ISyncService> _syncService = new LazyResolve<ISyncService>();
|
||||||
private ISyncService _syncService;
|
private LazyResolve<IStateService> _stateService = new LazyResolve<IStateService>();
|
||||||
private IStateService _stateService;
|
private LazyResolve<IAppIdService> _appIdService = new LazyResolve<IAppIdService>();
|
||||||
private IAppIdService _appIdService;
|
private LazyResolve<IApiService> _apiService = new LazyResolve<IApiService>();
|
||||||
private IApiService _apiService;
|
private LazyResolve<IMessagingService> _messagingService = new LazyResolve<IMessagingService>();
|
||||||
private IMessagingService _messagingService;
|
private LazyResolve<IPushNotificationService> _pushNotificationService = new LazyResolve<IPushNotificationService>();
|
||||||
private IPushNotificationService _pushNotificationService;
|
private LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
|
||||||
private ILogger _logger;
|
|
||||||
|
|
||||||
public async Task OnMessageAsync(JObject value, string deviceType)
|
public async Task OnMessageAsync(JObject value, string deviceType)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"{TAG} OnMessageAsync called");
|
Debug.WriteLine($"{TAG} OnMessageAsync called");
|
||||||
|
|
||||||
Resolve();
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -65,14 +63,14 @@ namespace Bit.App.Services
|
||||||
|
|
||||||
Debug.WriteLine($"{TAG} - Notification object created: t:{notification?.Type} - p:{notification?.Payload}");
|
Debug.WriteLine($"{TAG} - Notification object created: t:{notification?.Type} - p:{notification?.Payload}");
|
||||||
|
|
||||||
var appId = await _appIdService.GetAppIdAsync();
|
var appId = await _appIdService.Value.GetAppIdAsync();
|
||||||
if (notification?.Payload == null || notification.ContextId == appId)
|
if (notification?.Payload == null || notification.ContextId == appId)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var myUserId = await _stateService.GetActiveUserIdAsync();
|
var myUserId = await _stateService.Value.GetActiveUserIdAsync();
|
||||||
var isAuthenticated = await _stateService.IsAuthenticatedAsync();
|
var isAuthenticated = await _stateService.Value.IsAuthenticatedAsync();
|
||||||
switch (notification.Type)
|
switch (notification.Type)
|
||||||
{
|
{
|
||||||
case NotificationType.SyncCipherUpdate:
|
case NotificationType.SyncCipherUpdate:
|
||||||
|
@ -81,7 +79,7 @@ namespace Bit.App.Services
|
||||||
notification.Payload);
|
notification.Payload);
|
||||||
if (isAuthenticated && cipherCreateUpdateMessage.UserId == myUserId)
|
if (isAuthenticated && cipherCreateUpdateMessage.UserId == myUserId)
|
||||||
{
|
{
|
||||||
await _syncService.SyncUpsertCipherAsync(cipherCreateUpdateMessage,
|
await _syncService.Value.SyncUpsertCipherAsync(cipherCreateUpdateMessage,
|
||||||
notification.Type == NotificationType.SyncCipherUpdate);
|
notification.Type == NotificationType.SyncCipherUpdate);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -91,7 +89,7 @@ namespace Bit.App.Services
|
||||||
notification.Payload);
|
notification.Payload);
|
||||||
if (isAuthenticated && folderCreateUpdateMessage.UserId == myUserId)
|
if (isAuthenticated && folderCreateUpdateMessage.UserId == myUserId)
|
||||||
{
|
{
|
||||||
await _syncService.SyncUpsertFolderAsync(folderCreateUpdateMessage,
|
await _syncService.Value.SyncUpsertFolderAsync(folderCreateUpdateMessage,
|
||||||
notification.Type == NotificationType.SyncFolderUpdate);
|
notification.Type == NotificationType.SyncFolderUpdate);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -101,7 +99,7 @@ namespace Bit.App.Services
|
||||||
notification.Payload);
|
notification.Payload);
|
||||||
if (isAuthenticated && loginDeleteMessage.UserId == myUserId)
|
if (isAuthenticated && loginDeleteMessage.UserId == myUserId)
|
||||||
{
|
{
|
||||||
await _syncService.SyncDeleteCipherAsync(loginDeleteMessage);
|
await _syncService.Value.SyncDeleteCipherAsync(loginDeleteMessage);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotificationType.SyncFolderDelete:
|
case NotificationType.SyncFolderDelete:
|
||||||
|
@ -109,7 +107,7 @@ namespace Bit.App.Services
|
||||||
notification.Payload);
|
notification.Payload);
|
||||||
if (isAuthenticated && folderDeleteMessage.UserId == myUserId)
|
if (isAuthenticated && folderDeleteMessage.UserId == myUserId)
|
||||||
{
|
{
|
||||||
await _syncService.SyncDeleteFolderAsync(folderDeleteMessage);
|
await _syncService.Value.SyncDeleteFolderAsync(folderDeleteMessage);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotificationType.SyncCiphers:
|
case NotificationType.SyncCiphers:
|
||||||
|
@ -117,27 +115,27 @@ namespace Bit.App.Services
|
||||||
case NotificationType.SyncSettings:
|
case NotificationType.SyncSettings:
|
||||||
if (isAuthenticated)
|
if (isAuthenticated)
|
||||||
{
|
{
|
||||||
await _syncService.FullSyncAsync(false);
|
await _syncService.Value.FullSyncAsync(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotificationType.SyncOrgKeys:
|
case NotificationType.SyncOrgKeys:
|
||||||
if (isAuthenticated)
|
if (isAuthenticated)
|
||||||
{
|
{
|
||||||
await _apiService.RefreshIdentityTokenAsync();
|
await _apiService.Value.RefreshIdentityTokenAsync();
|
||||||
await _syncService.FullSyncAsync(true);
|
await _syncService.Value.FullSyncAsync(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotificationType.LogOut:
|
case NotificationType.LogOut:
|
||||||
if (isAuthenticated)
|
if (isAuthenticated)
|
||||||
{
|
{
|
||||||
_messagingService.Send("logout");
|
_messagingService.Value.Send("logout");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotificationType.AuthRequest:
|
case NotificationType.AuthRequest:
|
||||||
var passwordlessLoginMessage = JsonConvert.DeserializeObject<PasswordlessRequestNotification>(notification.Payload);
|
var passwordlessLoginMessage = JsonConvert.DeserializeObject<PasswordlessRequestNotification>(notification.Payload);
|
||||||
|
|
||||||
// if the user has not enabled passwordless logins ignore requests
|
// if the user has not enabled passwordless logins ignore requests
|
||||||
if (!await _stateService.GetApprovePasswordlessLoginsAsync(passwordlessLoginMessage?.UserId))
|
if (!await _stateService.Value.GetApprovePasswordlessLoginsAsync(passwordlessLoginMessage?.UserId))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -148,8 +146,8 @@ namespace Bit.App.Services
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _stateService.SetPasswordlessLoginNotificationAsync(passwordlessLoginMessage, passwordlessLoginMessage?.UserId);
|
await _stateService.Value.SetPasswordlessLoginNotificationAsync(passwordlessLoginMessage, passwordlessLoginMessage?.UserId);
|
||||||
var userEmail = await _stateService.GetEmailAsync(passwordlessLoginMessage?.UserId);
|
var userEmail = await _stateService.Value.GetEmailAsync(passwordlessLoginMessage?.UserId);
|
||||||
|
|
||||||
var notificationData = new PasswordlessNotificationData()
|
var notificationData = new PasswordlessNotificationData()
|
||||||
{
|
{
|
||||||
|
@ -158,8 +156,8 @@ namespace Bit.App.Services
|
||||||
UserEmail = userEmail,
|
UserEmail = userEmail,
|
||||||
};
|
};
|
||||||
|
|
||||||
_pushNotificationService.SendLocalNotification(AppResources.LogInRequested, String.Format(AppResources.ConfimLogInAttempForX, userEmail), notificationData);
|
_pushNotificationService.Value.SendLocalNotification(AppResources.LogInRequested, String.Format(AppResources.ConfimLogInAttempForX, userEmail), notificationData);
|
||||||
_messagingService.Send("passwordlessLoginRequest", passwordlessLoginMessage);
|
_messagingService.Value.Send("passwordlessLoginRequest", passwordlessLoginMessage);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -168,31 +166,30 @@ namespace Bit.App.Services
|
||||||
|
|
||||||
public async Task OnRegisteredAsync(string token, string deviceType)
|
public async Task OnRegisteredAsync(string token, string deviceType)
|
||||||
{
|
{
|
||||||
Resolve();
|
|
||||||
Debug.WriteLine($"{TAG} - Device Registered - Token : {token}");
|
Debug.WriteLine($"{TAG} - Device Registered - Token : {token}");
|
||||||
var isAuthenticated = await _stateService.IsAuthenticatedAsync();
|
var isAuthenticated = await _stateService.Value.IsAuthenticatedAsync();
|
||||||
if (!isAuthenticated)
|
if (!isAuthenticated)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"{TAG} - not auth");
|
Debug.WriteLine($"{TAG} - not auth");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var appId = await _appIdService.GetAppIdAsync();
|
var appId = await _appIdService.Value.GetAppIdAsync();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
await _stateService.SetPushInstallationRegistrationErrorAsync(null);
|
await _stateService.Value.SetPushInstallationRegistrationErrorAsync(null);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
await _apiService.PutDeviceTokenAsync(appId,
|
await _apiService.Value.PutDeviceTokenAsync(appId,
|
||||||
new Core.Models.Request.DeviceTokenRequest { PushToken = token });
|
new Core.Models.Request.DeviceTokenRequest { PushToken = token });
|
||||||
|
|
||||||
Debug.WriteLine($"{TAG} Registered device with server.");
|
Debug.WriteLine($"{TAG} Registered device with server.");
|
||||||
|
|
||||||
await _stateService.SetPushLastRegistrationDateAsync(DateTime.UtcNow);
|
await _stateService.Value.SetPushLastRegistrationDateAsync(DateTime.UtcNow);
|
||||||
if (deviceType == Device.Android)
|
if (deviceType == Device.Android)
|
||||||
{
|
{
|
||||||
await _stateService.SetPushCurrentTokenAsync(token);
|
await _stateService.Value.SetPushCurrentTokenAsync(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -200,11 +197,11 @@ namespace Bit.App.Services
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"{TAG} Failed to register device.");
|
Debug.WriteLine($"{TAG} Failed to register device.");
|
||||||
|
|
||||||
await _stateService.SetPushInstallationRegistrationErrorAsync(apiEx.Error?.Message);
|
await _stateService.Value.SetPushInstallationRegistrationErrorAsync(apiEx.Error?.Message);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
await _stateService.SetPushInstallationRegistrationErrorAsync(e.Message);
|
await _stateService.Value.SetPushInstallationRegistrationErrorAsync(e.Message);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -226,22 +223,44 @@ namespace Bit.App.Services
|
||||||
|
|
||||||
public async Task OnNotificationTapped(BaseNotificationData data)
|
public async Task OnNotificationTapped(BaseNotificationData data)
|
||||||
{
|
{
|
||||||
Resolve();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (data is PasswordlessNotificationData passwordlessNotificationData)
|
if (data is PasswordlessNotificationData passwordlessNotificationData)
|
||||||
{
|
{
|
||||||
var notificationUserId = await _stateService.GetUserIdAsync(passwordlessNotificationData.UserEmail);
|
var notificationUserId = await _stateService.Value.GetUserIdAsync(passwordlessNotificationData.UserEmail);
|
||||||
if (notificationUserId != null)
|
if (notificationUserId != null)
|
||||||
{
|
{
|
||||||
await _stateService.SetActiveUserAsync(notificationUserId);
|
await _stateService.Value.SetActiveUserAsync(notificationUserId);
|
||||||
_messagingService.Send(AccountsManagerMessageCommands.SWITCHED_ACCOUNT);
|
_messagingService.Value.Send(AccountsManagerMessageCommands.SWITCHED_ACCOUNT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Exception(ex);
|
_logger.Value.Exception(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnNotificationDismissed(BaseNotificationData data)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (data is PasswordlessNotificationData passwordlessNotificationData)
|
||||||
|
{
|
||||||
|
var notificationUserId = await _stateService.Value.GetUserIdAsync(passwordlessNotificationData.UserEmail);
|
||||||
|
if (notificationUserId != null)
|
||||||
|
{
|
||||||
|
var savedNotification = await _stateService.Value.GetPasswordlessLoginNotificationAsync(notificationUserId);
|
||||||
|
if (savedNotification != null)
|
||||||
|
{
|
||||||
|
await _stateService.Value.SetPasswordlessLoginNotificationAsync(null, notificationUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Value.Exception(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,22 +268,6 @@ namespace Bit.App.Services
|
||||||
{
|
{
|
||||||
return _showNotification;
|
return _showNotification;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Resolve()
|
|
||||||
{
|
|
||||||
if (_resolved)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
|
||||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
|
||||||
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
|
|
||||||
_apiService = ServiceContainer.Resolve<IApiService>("apiService");
|
|
||||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
|
||||||
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
|
|
||||||
_logger = ServiceContainer.Resolve<ILogger>();
|
|
||||||
_resolved = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
public const string PasswordlessNotificationId = "26072022";
|
public const string PasswordlessNotificationId = "26072022";
|
||||||
public const string AndroidNotificationChannelId = "general_notification_channel";
|
public const string AndroidNotificationChannelId = "general_notification_channel";
|
||||||
public const string NotificationData = "notificationData";
|
public const string NotificationData = "notificationData";
|
||||||
public const string NotificationDataType = "NotificationType";
|
public const string NotificationDataType = "Type";
|
||||||
public const int SelectFileRequestCode = 42;
|
public const int SelectFileRequestCode = 42;
|
||||||
public const int SelectFilePermissionRequestCode = 43;
|
public const int SelectFilePermissionRequestCode = 43;
|
||||||
public const int SaveFileRequestCode = 44;
|
public const int SaveFileRequestCode = 44;
|
||||||
|
|
|
@ -96,9 +96,12 @@ namespace Bit.iOS.Services
|
||||||
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
|
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"{TAG} DidReceiveNotificationResponse {response?.Notification?.Request?.Content?.UserInfo}");
|
Debug.WriteLine($"{TAG} DidReceiveNotificationResponse {response?.Notification?.Request?.Content?.UserInfo}");
|
||||||
|
if ((response?.Notification?.Request?.Content?.UserInfo) == null)
|
||||||
if (response.IsDefaultAction && response?.Notification?.Request?.Content?.UserInfo != null)
|
|
||||||
{
|
{
|
||||||
|
completionHandler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var userInfo = response?.Notification?.Request?.Content?.UserInfo;
|
var userInfo = response?.Notification?.Request?.Content?.UserInfo;
|
||||||
OnMessageReceived(userInfo);
|
OnMessageReceived(userInfo);
|
||||||
|
|
||||||
|
@ -106,11 +109,20 @@ namespace Bit.iOS.Services
|
||||||
{
|
{
|
||||||
var token = JToken.Parse(NSString.FromObject(nsObject).ToString());
|
var token = JToken.Parse(NSString.FromObject(nsObject).ToString());
|
||||||
var typeToken = token.SelectToken(Constants.NotificationDataType);
|
var typeToken = token.SelectToken(Constants.NotificationDataType);
|
||||||
|
if (response.IsDefaultAction)
|
||||||
|
{
|
||||||
if (typeToken.ToString() == PasswordlessNotificationData.TYPE)
|
if (typeToken.ToString() == PasswordlessNotificationData.TYPE)
|
||||||
{
|
{
|
||||||
_pushNotificationListenerService.OnNotificationTapped(token.ToObject<PasswordlessNotificationData>());
|
_pushNotificationListenerService.OnNotificationTapped(token.ToObject<PasswordlessNotificationData>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (response.IsDismissAction)
|
||||||
|
{
|
||||||
|
if (typeToken.ToString() == PasswordlessNotificationData.TYPE)
|
||||||
|
{
|
||||||
|
_pushNotificationListenerService.OnNotificationDismissed(token.ToObject<PasswordlessNotificationData>());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform caller it has been handled
|
// Inform caller it has been handled
|
||||||
|
|
Loading…
Reference in a new issue