public async Task <IActionResult> SigninAsync([FromBody] SigninBindingModel collection)
        {
            Log.Debug($"A User is trying to signing in with this data: {JsonConvert.SerializeObject(collection)}");

            if (string.IsNullOrEmpty(collection?.Username) || string.IsNullOrEmpty(collection?.Password))
            {
                return(BadRequest(_localizer[DataTransferer.DefectiveUsernameOrPassword().Message]));
            }

            var deviceHeader = GetDeviceInfosFromHeader();

            if (deviceHeader == null)
            {
                return(BadRequest(_localizer[DataTransferer.UnofficialRequest().Message]));
            }

            collection.DeviceId   = deviceHeader.DeviceId;
            collection.DeviceName = deviceHeader.DeviceName;
            collection.DeviceType = deviceHeader.DeviceType;

            try {
                var result = await _accountService.SigninAsync(collection).ConfigureAwait(true);

                switch (result.Code)
                {
                case 200:
                    return(Ok(result.Data));

                case 400:
                    return(BadRequest(result.Message));

                case 500:
                default:
                    return(Problem(result.Message));
                }
            }
            catch (Exception ex) {
                Log.Error(ex, ex.Source);
                return(Problem(_localizer[DataTransferer.SomethingWentWrong().Message]));
            }
        }
        public async Task <IActionResult> SignupAsync([FromBody] SignupBindingModel collection)
        {
            // todo: Captcha

            if (collection == null)
            {
                return(BadRequest(_localizer[DataTransferer.DefectiveEntry().Message]));
            }

            if (string.IsNullOrEmpty(collection?.Username))
            {
                return(BadRequest(_localizer[DataTransferer.DefectiveEmailOrCellPhone().Message]));
            }

            Log.Debug($"A User is trying to register with this data: {JsonConvert.SerializeObject(collection)}");
            collection.Username = collection.Username.Trim();

            try {
                if (collection.Username.IsPhoneNumber())
                {
                    collection.Phone = collection.Username;
                    if (await _accountProfileService.FirstAsync(new AccountProfileGetFirstSchema {
                        LinkedId = collection.Phone
                    }).ConfigureAwait(true) != null)
                    {
                        return(BadRequest(_localizer[DataTransferer.CellPhoneAlreadyExists().Message]));
                    }
                }
                else if (new EmailAddressAttribute().IsValid(collection.Username))
                {
                    collection.Email = collection.Username;
                    if (await _accountProfileService.FirstAsync(new AccountProfileGetFirstSchema {
                        LinkedId = collection.Email
                    }).ConfigureAwait(true) != null)
                    {
                        return(BadRequest(_localizer[DataTransferer.EmailAlreadyExists().Message]));
                    }
                }
                else
                {
                    return(BadRequest(_localizer[DataTransferer.InvalidEmailOrCellPhone().Message]));
                }

                if (string.IsNullOrEmpty(collection.Password) && string.IsNullOrEmpty(collection.ConfirmPassword))
                {
                    return(BadRequest(_localizer[DataTransferer.DefectivePassword().Message]));
                }

                if (collection.Password != collection.ConfirmPassword)
                {
                    return(BadRequest(_localizer[DataTransferer.PasswordsMissmatch().Message]));
                }

                if (string.IsNullOrEmpty(collection.DeviceId) || string.IsNullOrEmpty(collection.DeviceName))
                {
                    return(BadRequest(_localizer[DataTransferer.UnofficialRequest().Message]));
                }

                var result = await _accountService.SignupAsync(collection).ConfigureAwait(true);

                switch (result.Code)
                {
                case 200:
                    return(Ok(result.Data));

                case 400:
                    return(BadRequest(result.Message));

                case 500:
                default:
                    return(Problem(result.Message));
                }
            }
            catch (Exception ex) {
                Log.Error(ex, ex.Source);
                return(Problem(_localizer[DataTransferer.SomethingWentWrong().Message]));
            }
        }
        public async Task <IActionResult> ChangeForgotenPasswordAsync([FromBody] ChangeForgotenPasswordBindingModel collection)
        {
            Log.Debug($"ChangeForgotenPassword => {JsonConvert.SerializeObject(collection)}");

            try {
                if (string.IsNullOrEmpty(collection?.Username))
                {
                    return(BadRequest(_localizer[DataTransferer.DefectiveEmailOrCellPhone().Message]));
                }
                collection.Username = collection.Username.Trim();

                if (string.IsNullOrEmpty(collection.NewPassword) && string.IsNullOrEmpty(collection.ConfirmPassword))
                {
                    return(BadRequest(_localizer[DataTransferer.DefectivePassword().Message]));
                }

                if (collection.NewPassword != collection.ConfirmPassword)
                {
                    return(BadRequest(_localizer[DataTransferer.PasswordsMissmatch().Message]));
                }

                if (string.IsNullOrWhiteSpace(collection.Token))
                {
                    return(BadRequest(_localizer[DataTransferer.UnofficialRequest().Message]));
                }

                var query = new AccountProfileGetFirstSchema {
                    LinkedId = collection.Username
                };
                if (collection.Username.IsPhoneNumber())
                {
                    query.TypeId = AccountProfileType.Phone.ToInt();
                }
                else if (new EmailAddressAttribute().IsValid(collection.Username))
                {
                    query.TypeId = AccountProfileType.Email.ToInt();
                }
                else
                {
                    return(BadRequest(_localizer[DataTransferer.InvalidEmailOrCellPhone().Message]));
                }

                var accountProfile = await _accountProfileService.FirstAsync(query).ConfigureAwait(true);

                if (accountProfile == null)
                {
                    if (query.TypeId == AccountProfileType.Phone.ToInt())
                    {
                        return(BadRequest(_localizer[DataTransferer.PhoneNotFound().Message]));
                    }

                    if (query.TypeId == AccountProfileType.Email.ToInt())
                    {
                        return(BadRequest(_localizer[DataTransferer.EmailNotFound().Message]));
                    }
                }

                var cachedToken = _memoryCache.Get(collection.Username);
                if (cachedToken == null)
                {
                    return(BadRequest(_localizer[DataTransferer.ChangingPasswordWithoutToken().Message]));
                }

                var account = await _accountService.FirstAsync(new AccountGetFirstSchema {
                    Id = accountProfile.AccountId.Value
                }).ConfigureAwait(true);

                if (account == null)
                {
                    return(BadRequest(_localizer[DataTransferer.UserNotFound().Message]));
                }

                if (collection.Token != cachedToken.ToString())
                {
                    Log.Warning($"Account => {account}, AccountProfile => {accountProfile}, It tried to change its password with a wrong 'ForgotPasswordToken'");
                    return(BadRequest(_localizer[DataTransferer.ChangingPasswordWithWrongToken().Message]));
                }

                _memoryCache.Remove(collection.Username);

                await _accountService.UpdateAsync(new AccountUpdateSchema {
                    Id       = account.Id.Value,
                    Password = _cryptograph.RNG(collection.NewPassword)
                }).ConfigureAwait(false);

                return(Ok(_localizer[DataTransferer.PasswordChanged().Message]));
            }
            catch (Exception ex) {
                Log.Error(ex, ex.Source);
                return(Problem(_localizer[DataTransferer.SomethingWentWrong().Message]));
            }
        }