private async Task <IUserAuthenticationCode> AcknowledgeAcknowledgeCodeAsync(ISessionIdentity identity, IAcknowledgeUserAuthenticationCodeRequest request)
        {
            if (identity.IdentityType != IdentityType.Bot)
            {
                throw new HttpStatusException($"NotBot:Identity{identity.IdentityType}")
                      {
                          Status = StatusCode.Unauthorized
                      }
            }
            ;
            if (string.IsNullOrEmpty(request.Code))
            {
                throw new HttpStatusException("Empty:AcknowledgeUserAuthenticationCodeRequest.Code")
                      {
                          Status = StatusCode.BadRequest
                      }
            }
            ;

            var table = tableClient.GetTableReference(AcknowledgeCodeTableName);

            var statusResult = await table.RetrieveAsync <AcknowledgeCodeStatusEntity>(request.Code, 0L.ToString("X16"));

            if (statusResult.HttpStatusCode == 404)
            {
                throw new HttpStatusException("EntityNotFound:AcknowledgeCodeStatus", statusResult.HttpStatusCode)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (statusResult.HttpStatusCode >= 400)
            {
                throw new HttpStatusException("EntityErrorRetrieve:AcknowledgeCodeStatus", statusResult.HttpStatusCode);
            }

            var now      = DateTime.UtcNow;
            var nowTicks = now.Ticks;

            var statusEntity = statusResult.Entity;

            if (statusEntity.AvailableAfter < nowTicks)
            {
                throw new HttpStatusException("Expired:AcknowledgeCodeStatus")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            var rowKey = statusEntity.CurrentRowKey;

            var codeResult = await table.RetrieveAsync <AcknowledgeCodeEntity>(request.Code, rowKey);

            if (codeResult.HttpStatusCode >= 400)
            {
                throw new HttpStatusException("EntityErrorRetrieve:AcknowledgeCode", codeResult.HttpStatusCode);
            }

            var codeEntity = codeResult.Entity;

            if (codeEntity.ExpireIn < nowTicks)
            {
                throw new HttpStatusException("Expired:AcknowledgeCode")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (codeEntity.Status != (int)StatusCode.Pending)
            {
                throw new HttpStatusException("EntityErrorStatus:AcknowledgeCode", codeEntity.Status)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (!string.IsNullOrEmpty(codeEntity.TargetUser) && string.Compare(codeEntity.TargetUser, request.AcknowledgeUser, true) != 0)
            {
                throw new HttpStatusException($"NotMatch:AcknowledgeUserAuthenticationCodeRequest.AcknowledgeUser({codeEntity.TargetUser}, {request.AcknowledgeUser})")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            codeEntity.AckBy  = request.AcknowledgeUser;
            codeEntity.Ackime = nowTicks;
            codeEntity.AckVia = identity.Name;
            codeEntity.Status = (int)StatusCode.Confirmed;

            var result = await table.MergeAsync(codeEntity);

            if (result >= 400)
            {
                throw new HttpStatusException("EntityErrorUpdate:AcknowledgeCode", result);
            }

            return(new UserAuthenticationCode
            {
                Code = codeEntity.PartitionKey,
                ExpireIn = codeEntity.ExpireIn,
                TargetUser = codeEntity.AckBy
            });
        }
        private async Task <IUserAuthenticationCode> AcknowledgeDirectLoginCodeAsync(ISessionIdentity identity, IAcknowledgeUserAuthenticationCodeRequest request)
        {
            if (identity.IdentityType != IdentityType.App)
            {
                throw new HttpStatusException($"NotApp:Identity({identity.IdentityType})")
                      {
                          Status = StatusCode.Unauthorized
                      }
            }
            ;
            if (string.IsNullOrEmpty(request.Code) || request.Code.Length != 40)
            {
                throw new HttpStatusException($"Invalid:AcknowledgeUserAuthenticationCodeRequest.Code({request.Code})")
                      {
                          Status = StatusCode.BadRequest
                      }
            }
            ;

            var table = tableClient.GetTableReference(DirectLoginCodeTableName);

            var now      = DateTime.UtcNow;
            var nowTicks = now.Ticks;

            var result = await table.RetrieveAsync <DirectLoginCodeEntity>(request.Code.Substring(0, 8), request.Code);

            if (result.HttpStatusCode == 404)
            {
                throw new HttpStatusException("EntityNotFound:DirectLoginCode", result.HttpStatusCode)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (result.HttpStatusCode >= 400)
            {
                throw new HttpStatusException("EntityErrorRetrieve:DirectLoginCode", result.HttpStatusCode);
            }

            var codeEntity = result.Entity;

            if (codeEntity.ExpireIn < nowTicks)
            {
                throw new HttpStatusException("Expired:DirectLoginCode")
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;
            if (codeEntity.Status != (int)StatusCode.Pending)
            {
                throw new HttpStatusException($"EntityErrorStatus:DirectLoginCode(Status={codeEntity.Status})", codeEntity.Status)
                      {
                          Status = StatusCode.NotFound
                      }
            }
            ;

            codeEntity.AckDeviceId  = identity.ClientDeviceId;
            codeEntity.AckSessionId = identity.ClientSessionId;
            codeEntity.AckTime      = nowTicks;
            codeEntity.Status       = (int)StatusCode.Confirmed;

            var mergeResult = await table.MergeAsync(codeEntity);

            if (mergeResult >= 400)
            {
                throw new HttpStatusException("EntityErrorUpdate:DirectLoginCode", mergeResult);
            }

            return(new UserAuthenticationCode
            {
                Code = codeEntity.RowKey,
                ExpireIn = codeEntity.ExpireIn,
                TargetUser = codeEntity.TargetUser
            });
        }
        public async Task <IUserAuthenticationCode> AcknowledgeCodeAsync(ISessionIdentity identity, IAcknowledgeUserAuthenticationCodeRequest request)
        {
            if (identity == null || !identity.IsAuthenticated)
            {
                throw new HttpStatusException("Unauthorized:Identity")
                      {
                          Status = StatusCode.Unauthorized
                      }
            }
            ;

            if (request.CodeType == UserAuthenticationCodeType.AcknowledgeCode)
            {
                return(await AcknowledgeAcknowledgeCodeAsync(identity, request));
            }
            else if (request.CodeType == UserAuthenticationCodeType.DirectLoginCode)
            {
                return(await AcknowledgeDirectLoginCodeAsync(identity, request));
            }
            else
            {
                throw new HttpStatusException($"Unknown:AcknowledgeUserAuthenticationCodeRequest.CodeType({request.CodeType})")
                      {
                          Status = StatusCode.BadRequest
                      };
            }
        }