diff --git a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs index c6d55030d..66ed6acd5 100644 --- a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs +++ b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Bit.Core.Enums; using Bit.Core.Models.Domain; using Xamarin.Forms; +using ZXing.Client.Result; namespace Bit.App.Pages { @@ -132,7 +133,15 @@ namespace Bit.App.Pages { var debugText = string.Format("{0}: {1} ({2})", AppResources.Version, _platformUtilsService.GetApplicationVersion(), _deviceActionService.GetBuildNumber()); - var text = string.Format("© Bitwarden Inc. 2015-{0}\n\n{1}", DateTime.Now.Year, debugText); + var pushNotificationsRegistered = ServiceContainer.Resolve("pushNotificationService").IsRegisteredForPush; + var pnServerRegDate = await _storageService.GetAsync(Constants.PushLastRegistrationDateKey); + var pnServerError = await _storageService.GetAsync(Constants.PushInstallationRegistrationError); + + var pnServerRegDateMessage = default(DateTime) == pnServerRegDate ? "-" : $"{pnServerRegDate.ToShortDateString()}-{pnServerRegDate.ToShortTimeString()} UTC"; + var errorMessage = string.IsNullOrEmpty(pnServerError) ? string.Empty : $"Push Notifications Server Registration error: {pnServerError}"; + + var text = string.Format("© Bitwarden Inc. 2015-{0}\n\n{1}\nPush Notifications registered:{2}\nPush Notifications Server Last Date :{3}\n{4}", DateTime.Now.Year, debugText, pushNotificationsRegistered, pnServerRegDateMessage, errorMessage); + var copy = await _platformUtilsService.ShowDialogAsync(text, AppResources.Bitwarden, AppResources.Copy, AppResources.Close); if (copy) diff --git a/src/App/Services/PushNotificationListenerService.cs b/src/App/Services/PushNotificationListenerService.cs index dd6aa73c1..68301cb98 100644 --- a/src/App/Services/PushNotificationListenerService.cs +++ b/src/App/Services/PushNotificationListenerService.cs @@ -17,6 +17,8 @@ namespace Bit.App.Services { public class PushNotificationListenerService : IPushNotificationListenerService { + const string TAG = "##PUSH NOTIFICATIONS"; + private bool _showNotification; private bool _resolved; private IStorageService _storageService; @@ -28,6 +30,8 @@ namespace Bit.App.Services public async Task OnMessageAsync(JObject value, string deviceType) { + Console.WriteLine($"{TAG} OnMessageAsync called"); + Resolve(); if (value == null) { @@ -35,7 +39,7 @@ namespace Bit.App.Services } _showNotification = false; - Debug.WriteLine("Message Arrived: {0}", JsonConvert.SerializeObject(value)); + Console.WriteLine($"{TAG} Message Arrived: {JsonConvert.SerializeObject(value)}"); NotificationResponse notification = null; if (deviceType == Device.Android) @@ -52,6 +56,8 @@ namespace Bit.App.Services notification = dataToken.ToObject(); } + Console.WriteLine($"{TAG} - Notification object created: t:{notification?.Type} - p:{notification?.Payload}"); + var appId = await _appIdService.GetAppIdAsync(); if (notification?.Payload == null || notification.ContextId == appId) { @@ -128,39 +134,50 @@ namespace Bit.App.Services public async Task OnRegisteredAsync(string token, string deviceType) { Resolve(); - Debug.WriteLine(string.Format("Push Notification - Device Registered - Token : {0}", token)); + Console.WriteLine($"{TAG} - Device Registered - Token : {token}"); var isAuthenticated = await _userService.IsAuthenticatedAsync(); if (!isAuthenticated) { + Console.WriteLine($"{TAG} - not auth"); return; } var appId = await _appIdService.GetAppIdAsync(); + Console.WriteLine($"{TAG} - app id: {appId}"); try { + await _storageService.RemoveAsync(Constants.PushInstallationRegistrationError); + await _apiService.PutDeviceTokenAsync(appId, new Core.Models.Request.DeviceTokenRequest { PushToken = token }); - Debug.WriteLine("Registered device with server."); + Console.WriteLine($"{TAG} Registered device with server."); await _storageService.SaveAsync(Constants.PushLastRegistrationDateKey, DateTime.UtcNow); if (deviceType == Device.Android) { await _storageService.SaveAsync(Constants.PushCurrentTokenKey, token); } } - catch (ApiException) + catch (ApiException apiEx) { - Debug.WriteLine("Failed to register device."); + Console.WriteLine($"{TAG} Failed to register device."); + + await _storageService.SaveAsync(Constants.PushInstallationRegistrationError, apiEx.Error?.Message); + } + catch (Exception e) + { + await _storageService.SaveAsync(Constants.PushInstallationRegistrationError, e.Message); + throw; } } public void OnUnregistered(string deviceType) { - Debug.WriteLine("Push Notification - Device Unnregistered"); + Console.WriteLine($"{TAG} - Device Unnregistered"); } public void OnError(string message, string deviceType) { - Debug.WriteLine(string.Format("Push notification error - {0}", message)); + Console.WriteLine($"{TAG} error - {message}"); } public bool ShouldShowNotification() diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 90cd12e22..1751856aa 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -23,6 +23,7 @@ public static string PushCurrentTokenKey = "pushCurrentToken"; public static string PushLastRegistrationDateKey = "pushLastRegistrationDate"; public static string PushInitialPromptShownKey = "pushInitialPromptShown"; + public static string PushInstallationRegistrationError = "pushInstallationRegistrationError"; public static string ThemeKey = "theme"; public static string ClearClipboardKey = "clearClipboard"; public static string LastBuildKey = "lastBuild"; diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs index 48c1bdd64..3c834775b 100644 --- a/src/iOS/AppDelegate.cs +++ b/src/iOS/AppDelegate.cs @@ -251,30 +251,36 @@ namespace Bit.iOS return base.ContinueUserActivity(application, userActivity, completionHandler); } + const string TAG = "##PUSH NOTIFICATIONS"; public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { + Console.WriteLine($"{TAG} FailedToRegisterForRemoteNotifications"); _pushHandler?.OnErrorReceived(error); } public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { + Console.WriteLine($"{TAG} RegisteredForRemoteNotifications"); _pushHandler?.OnRegisteredSuccess(deviceToken); } public override void DidRegisterUserNotificationSettings(UIApplication application, UIUserNotificationSettings notificationSettings) { + Console.WriteLine($"{TAG} DidRegisterUserNotificationSettings"); application.RegisterForRemoteNotifications(); } public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action completionHandler) { + Console.WriteLine($"{TAG} DidReceiveRemoteNotification"); _pushHandler?.OnMessageReceived(userInfo); } public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { + Console.WriteLine($"{TAG} ReceivedRemoteNotification"); _pushHandler?.OnMessageReceived(userInfo); } @@ -315,6 +321,8 @@ namespace Bit.iOS private void RegisterPush() { + Console.WriteLine($"{TAG} RegisterPush"); + var notificationListenerService = new PushNotificationListenerService(); ServiceContainer.Register( "pushNotificationListenerService", notificationListenerService); diff --git a/src/iOS/Services/iOSPushNotificationHandler.cs b/src/iOS/Services/iOSPushNotificationHandler.cs index 8d8c5a022..2d17a932b 100644 --- a/src/iOS/Services/iOSPushNotificationHandler.cs +++ b/src/iOS/Services/iOSPushNotificationHandler.cs @@ -12,7 +12,9 @@ namespace Bit.iOS.Services public class iOSPushNotificationHandler : NSObject, IUNUserNotificationCenterDelegate { private const string TokenSetting = "token"; - private const string DomainName = "iOSPushNotificationService"; + //private const string DomainName = "iOSPushNotificationService"; + + const string TAG = "##PUSH NOTIFICATIONS"; private readonly IPushNotificationListenerService _pushNotificationListenerService; @@ -26,6 +28,8 @@ namespace Bit.iOS.Services { try { + Console.WriteLine($"{TAG} - OnMessageReceived."); + var json = DictionaryToJson(userInfo); var values = JObject.Parse(json); var keyAps = new NSString("aps"); @@ -49,19 +53,19 @@ namespace Bit.iOS.Services public void OnErrorReceived(NSError error) { - Debug.WriteLine("{0} - Registration Failed.", DomainName); + Console.WriteLine($"{TAG} - Registration Failed."); _pushNotificationListenerService.OnError(error.LocalizedDescription, Device.iOS); } public void OnRegisteredSuccess(NSData token) { - Debug.WriteLine("{0} - Successfully Registered.", DomainName); + Console.WriteLine($"{TAG} - Successfully Registered."); var hexDeviceToken = BitConverter.ToString(token.ToArray()) .Replace("-", string.Empty) .ToLowerInvariant(); - Debug.WriteLine("{0} - Token: {1}", DomainName, hexDeviceToken); + Console.WriteLine($"{TAG} - Token: {hexDeviceToken}"); UNUserNotificationCenter.Current.Delegate = this; @@ -80,7 +84,7 @@ namespace Bit.iOS.Services [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")] public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action completionHandler) { - Debug.WriteLine($"{DomainName} WillPresentNotification {notification?.Request?.Content?.UserInfo}"); + Console.WriteLine($"{TAG} WillPresentNotification {notification?.Request?.Content?.UserInfo}"); OnMessageReceived(notification?.Request?.Content?.UserInfo); completionHandler(UNNotificationPresentationOptions.Alert); @@ -89,7 +93,7 @@ namespace Bit.iOS.Services [Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")] public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler) { - Debug.WriteLine($"{DomainName} DidReceiveNotificationResponse {response?.Notification?.Request?.Content?.UserInfo}"); + Console.WriteLine($"{TAG} DidReceiveNotificationResponse {response?.Notification?.Request?.Content?.UserInfo}"); if (response.IsDefaultAction) { diff --git a/src/iOS/Services/iOSPushNotificationService.cs b/src/iOS/Services/iOSPushNotificationService.cs index ceab64c25..b7f27b120 100644 --- a/src/iOS/Services/iOSPushNotificationService.cs +++ b/src/iOS/Services/iOSPushNotificationService.cs @@ -11,6 +11,7 @@ namespace Bit.iOS.Services public class iOSPushNotificationService : NSObject, IPushNotificationService, IUNUserNotificationCenterDelegate { private const string TokenSetting = "token"; + const string TAG = "##PUSH NOTIFICATIONS"; public Task GetTokenAsync() { @@ -21,6 +22,8 @@ namespace Bit.iOS.Services public async Task RegisterAsync() { + Console.WriteLine($"{TAG} RegisterAsync"); + var tcs = new TaskCompletionSource(); var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound; @@ -28,11 +31,11 @@ namespace Bit.iOS.Services { if (error != null) { - Debug.WriteLine($"Push Notifications {error}"); + Console.WriteLine($"{TAG} {error}"); } else { - Debug.WriteLine($"Push Notifications {granted}"); + Console.WriteLine($"{TAG} {granted}"); } tcs.SetResult(granted); @@ -40,12 +43,15 @@ namespace Bit.iOS.Services if (await tcs.Task) { + Console.WriteLine($"{TAG} RegisterForRemoteNotifications"); UIApplication.SharedApplication.RegisterForRemoteNotifications(); } } public Task UnregisterAsync() { + Console.WriteLine($"{TAG} UnregisterAsync"); + UIApplication.SharedApplication.UnregisterForRemoteNotifications(); // TODO: unregister call // _pushNotificationListener.OnUnregistered(Device.iOS);