/// <exclude/>
        public static async Task <bool> RegisterDataKeyForDevice(this IAuthentication auth, DeviceInfo device)
        {
            var publicKeyBytes   = device.DevicePublicKey.ToByteArray();
            var publicKey        = CryptoUtils.LoadPublicEcKey(publicKeyBytes);
            var encryptedDataKey = CryptoUtils.EncryptEc(auth.AuthContext.DataKey, publicKey);
            var request          = new RegisterDeviceDataKeyRequest
            {
                EncryptedDeviceToken   = device.EncryptedDeviceToken,
                EncryptedDeviceDataKey = ByteString.CopyFrom(encryptedDataKey),
            };

            try
            {
                await auth.ExecuteAuthRest("authentication/register_encrypted_data_key_for_device", request);

                return(true);
            }
            catch (KeeperApiException kae)
            {
                if (kae.Code == "device_data_key_exists")
                {
                    return(false);
                }
                throw;
            }
        }
        /// <exclude/>
        public static async Task <AccountSummaryElements> LoadAccountSummary(this IAuthentication auth)
        {
            var rq = new AccountSummaryRequest
            {
                SummaryVersion = 1
            };

            return(await auth.ExecuteAuthRest <AccountSummaryRequest, AccountSummaryElements>("login/account_summary", rq));
        }
 /// <exclude/>
 public static async Task SetSessionParameter(this IAuthentication auth, string name, string value)
 {
     await auth.ExecuteAuthRest("setting/set_user_setting",
                                new UserSettingRequest
     {
         Setting = name,
         Value   = value
     });
 }
        internal void SetKeepAliveTimer(int timeoutInMinutes, IAuthentication auth)
        {
            _timer?.Dispose();
            _timer = null;
            if (auth == null)
            {
                return;
            }

            ResetKeepAliveTimer();
            var timeout = TimeSpan.FromMinutes(timeoutInMinutes - (timeoutInMinutes > 1 ? 1 : 0));

            _timer = new Timer(async(_) =>
            {
                var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000;
                if (_lastRequestTime + timeout.TotalSeconds / 2 > now)
                {
                    return;
                }
                try
                {
                    await auth.ExecuteAuthRest("keep_alive", null);
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    _timer.Dispose();
                    _timer = null;
                }

                _lastRequestTime = now;
            },
                               null,
                               (long)timeout.TotalMilliseconds / 2,
                               (long)timeout.TotalMilliseconds / 2);
        }
        public static async Task ExecuteDeviceApprove(IAuthentication auth, IList <string> messages)
        {
            var keysRq = new EnterpriseDataCommand
            {
                include = new[] { "devices_request_for_admin_approval" }
            };
            var rs = await auth.ExecuteAuthCommand <EnterpriseDataCommand, EnterpriseDataResponse>(keysRq);

            if ((rs.DeviceRequestForApproval?.Count ?? 0) == 0)
            {
                return;
            }

            var userDataKeys = new Dictionary <long, byte[]>();

            foreach (var drq in rs.DeviceRequestForApproval)
            {
                if (!userDataKeys.ContainsKey(drq.EnterpriseUserId))
                {
                    userDataKeys[drq.EnterpriseUserId] = null;
                }
            }

            var dataKeyRq = new UserDataKeyRequest();

            dataKeyRq.EnterpriseUserId.AddRange(userDataKeys.Keys);
            var dataKeyRs = await auth.ExecuteAuthRest <UserDataKeyRequest, EnterpriseUserDataKeys>("enterprise/get_enterprise_user_data_key", dataKeyRq);

            foreach (var key in dataKeyRs.Keys)
            {
                if (key.UserEncryptedDataKey.IsEmpty)
                {
                    continue;
                }
                if (key.KeyTypeId != 2)
                {
                    continue;
                }
                try
                {
                    var userDataKey = CryptoUtils.DecryptEc(key.UserEncryptedDataKey.ToByteArray(), _enterprisePrivateKey);
                    userDataKeys[key.EnterpriseUserId] = userDataKey;
                }
                catch (Exception e)
                {
                    messages.Add($"Data key decrypt error: {e.Message}");
                }
            }

            var approveDevicesRq = new ApproveUserDevicesRequest();

            foreach (var drq in rs.DeviceRequestForApproval)
            {
                if (!userDataKeys.ContainsKey(drq.EnterpriseUserId) || userDataKeys[drq.EnterpriseUserId] == null)
                {
                    continue;
                }

                var dataKey         = userDataKeys[drq.EnterpriseUserId];
                var devicePublicKey = CryptoUtils.LoadPublicEcKey(drq.DevicePublicKey.Base64UrlDecode());
                var encDataKey      = CryptoUtils.EncryptEc(dataKey, devicePublicKey);
                var approveRq       = new ApproveUserDeviceRequest
                {
                    EnterpriseUserId       = drq.EnterpriseUserId,
                    EncryptedDeviceToken   = ByteString.CopyFrom(drq.EncryptedDeviceToken.Base64UrlDecode()),
                    EncryptedDeviceDataKey = ByteString.CopyFrom(encDataKey),
                    DenyApproval           = false,
                };
                approveDevicesRq.DeviceRequests.Add(approveRq);
            }

            if (approveDevicesRq.DeviceRequests.Count == 0)
            {
                return;
            }

            var approveRs = await auth.ExecuteAuthRest <ApproveUserDevicesRequest, ApproveUserDevicesResponse>("enterprise/approve_user_devices", approveDevicesRq);

            foreach (var deviceRs in approveRs.DeviceResponses)
            {
                var message = $"Approve device for {deviceRs.EnterpriseUserId} {(deviceRs.Failed ? "failed" : "succeeded")}";
                Debug.WriteLine(message);
                messages.Add(message);
            }
        }
 /// <summary>
 /// Executes Protobuf authenticated request.
 /// </summary>
 /// <typeparam name="TC">Protobuf authenticated request type.</typeparam>
 /// <typeparam name="TR">Protobuf response type.</typeparam>
 /// <param name="auth">The authenticated connection.</param>
 /// <param name="endpoint">URL path for request.</param>
 /// <param name="request"></param>
 /// <returns>Task returning Protobuf response.</returns>
 /// <seealso cref="IAuthentication.ExecuteAuthRest"/>
 /// <seealso cref="IKeeperEndpoint.ExecuteRest"/>
 public static async Task <TR> ExecuteAuthRest <TC, TR>(this IAuthentication auth, string endpoint, TC request)
     where TC : IMessage
     where TR : IMessage
 {
     return((TR)await auth.ExecuteAuthRest(endpoint, request, typeof(TR)));
 }