private string GetLink(string id)
        {
            try
            {
                var    key = _configurationProvider.ReadConfigurationObject(ConfigurationConstants.AesEncryptionKey);
                byte[] keyBytes;
                if (key == null)
                {
                    var bytes = new byte[32];
                    RandomNumberGenerator.Fill(bytes);

                    _configurationProvider.AddConfigurationObject(ConfigurationConstants.AesEncryptionKey,
                                                                  AESCypher.ToString(bytes));
                    keyBytes = bytes;
                }
                else
                {
                    keyBytes = AESCypher.ToBytes(key.Value);
                }

                var(cipher, nonce, tag) = AESCypher.Encrypt(id, keyBytes);

                return($"{Request.Scheme}://{Request.Host}/" +
                       $"{ViewConstants.AccountController}/{ViewConstants.RegistrationAction}" +
                       $"?Cipher={cipher}&Tag={tag}&Nonce={nonce}");
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Failed to create invitation link.");
            }

            return(string.Empty);
        }
        public IActionResult Registration([FromQuery(Name = "Cipher")] string cipher,
                                          [FromQuery(Name = "Tag")] string tag, [FromQuery(Name = "Nonce")] string nonce)
        {
            var model = new RegistrationViewModel();

            if (!string.IsNullOrEmpty(cipher) && !string.IsNullOrEmpty(tag) && !string.IsNullOrEmpty(nonce))
            {
                var    key      = _configurationProvider.ReadConfigurationObject(ConfigurationConstants.AesEncryptionKey);
                byte[] keyBytes = AESCypher.ToBytes(key.Value);

                var result   = AESCypher.Decrypt(cipher.Replace(' ', '+'), nonce.Replace(' ', '+'), tag.Replace(' ', '+'), keyBytes);
                var ticketId = Guid.Parse(result);
                var ticket   = _ticketManager.GetTicket(ticketId);
                if (ticket == null)
                {
                    return(RedirectToAction("Index", "Error", new ErrorViewModel()
                    {
                        ErrorText = "Link already used.",
                        StatusCode = "500"
                    }));
                }

                if (ticket.ExpirationDate < DateTime.UtcNow)
                {
                    return(RedirectToAction("Index", "Error", new ErrorViewModel()
                    {
                        ErrorText = "Link expired.",
                        StatusCode = "500"
                    }));
                }

                model.ProductKey = ticket.ProductKey;
                model.Role       = ticket.Role;
                model.TicketId   = ticket.Id.ToString();
            }

            return(View(model));
        }