private bool SendNotification(string deviceToken, LoginNotificationModel model)
        {
            // Configuration(NOTE: .pfx can also be used here)
            var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox,
                                               _apnsConfiguration.Value.CertificatePath,
                                               _apnsConfiguration.Value.CertificatePassword);

            // Create a new broker
            var apnsBroker = new ApnsServiceBroker(config);

            // Wire up events
            apnsBroker.OnNotificationFailed += (notification, aggregateEx) => {
                aggregateEx.Handle(ex => {
                    // See what kind of exception it was to further diagnose
                    if (ex is ApnsNotificationException notificationException)
                    {
                        // Deal with the failed notification
                        var apnsNotification = notificationException.Notification;
                        var statusCode       = notificationException.ErrorStatusCode;

                        Console.WriteLine($"Apple Notification Failed: ID={apnsNotification.Identifier}, Code={statusCode}");
                    }
                    else
                    {
                        // Inner exception might hold more useful information like an ApnsConnectionException
                        Console.WriteLine($"Apple Notification Failed for some unknown reason : {ex.InnerException}");
                    }

                    // Mark it as handled
                    return(true);
                });
            };

            apnsBroker.OnNotificationSucceeded += (notification) => {
                Console.WriteLine("Apple Notification Sent!");
            };

            // Start the broker
            apnsBroker.Start();
            var json = model.ToAPNSNotification();
            var test = JObject.Parse("{\"aps\":{ \"alert\":\"Authentication Request\" },\"ApplicationName\":\"Sample .Net App\",\"UserName\": \"[email protected]\",\"ClientIp\": \"192.168.1.10\",\"GeoLocation\": \"Harrisonburg, VA, USA\",\"TransactionId\": \"ea690fa5-8454-4909-902f-3f1b69db9119\",\"Timestamp\": 1577515106.505353}");

            apnsBroker.QueueNotification(new ApnsNotification
            {
                DeviceToken = deviceToken,
                Payload     = json
                              //Payload = JObject.Parse("{\"aps\":{ \"alert\":\"Authentication Request\" },\"ApplicationName\":\"Sample .Net App\",\"UserName\": \"[email protected]\",\"ClientIp\": \"192.168.1.10\",\"GeoLocation\": \"Harrisonburg, VA, USA\",\"TransactionId\": \"ea690fa5-8454-4909-902f-3f1b69db9119\",\"Timestamp\": 1577515106.505353}")
            });

            // Stop the broker, wait for it to finish
            // This isn't done after every message, but after you're
            // done with the broker
            apnsBroker.Stop();
            return(false);
        }
        public async Task <IActionResult> LoginAttempt([FromBody] AddTransactionModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            var application = await _dbContext.Applications.FindAsync(model.ApplicationId);

            if (application == null)
            {
                return(NotFound());
            }

            var signature         = model.CalculateSignature(application.Key);
            var providedSignature = Convert.FromBase64String(model.Signature);

            if (!signature.SequenceEqual(providedSignature))
            {
                return(BadRequest());
            }

            var transactionId = Guid.NewGuid();
            var transaction   = new TransactionModel
            {
                Id            = transactionId,
                UserId        = application.UserId,
                ApplicationId = application.Id,
                ClientIP      = model.ClientIP,
                GeoLocation   = model.GeoLocation,
                Signature     = model.Signature,
                UserName      = model.UserName
            };
            await _dbContext.AddAsync(transaction);

            var result = await _dbContext.SaveChangesAsync();

            if (result != 1)
            {
                return(StatusCode(500));
            }

            // Retrieve user by username in order to get user's device
            var user = await _userManager.FindByNameAsync(model.UserName);

            if (user == null)
            {
                return(BadRequest("No matching user found."));
            }
            var device = _dbContext.Devices.FirstOrDefault(x => x.UserId == user.Id);

            if (device == null)
            {
                return(BadRequest("No device found for user."));
            }

            //TODO: Implement geolocation of IP
            var notification = new LoginNotificationModel
            {
                TransactionId   = transaction.Id,
                ApplicationName = application.Name,
                UserName        = transaction.UserName,
                ClientIP        = transaction.ClientIP,
                GeoLocation     = "Not yet implemented",
                TimeStamp       = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds()
            };

            SendNotification(device.DeviceToken, notification);

            return(Ok(transactionId));
        }