///<inheritdoc/> public async Task <AuthenticateResult <UserDto> > AuthenticateAsync(Guid appKey, Guid appAccess, string login, string password, CancellationToken cancellationToken = default) { bool success = false; UserDto userDto = null; IDictionary <string, string> errors = new Dictionary <string, string>(); (User, Guid?)resultLogin = await _userDomain.GetByLoginAsync(appKey, appAccess, login, password, cancellationToken); User user = resultLogin.Item1; Guid?userId = resultLogin.Item2; if (user != null) { if (user.Type == UserType.User) { if (user.Credential.ChangeCredentials) { errors.Add("Authenticate", _localizer["USER_MUST_CHANGE_PASSWORD"]); } else { if (user.IsActive) { if (user.Credential.LockoutUntil.HasValue && user.Credential.LockoutUntil.Value > DateTime.UtcNow) { errors.Add("Authenticate", _localizer["USER_LOCKOUT"]); } else { success = true; userDto = user.Map(); await _userDomain.ClearLockout(user.Id, default); } } else { errors.Add("Authenticate", _localizer["USER_INACTIVE"]); } } } else { errors.Add("Authenticate", _localizer["SERVICE_NOT_AS_USER"]); } } else { if (userId.HasValue) { await _userDomain.MarkLoginFail(userId.Value, cancellationToken); } errors.Add("Authenticate", _localizer["USER_PASSWORD_FAIL"]); } return(new AuthenticateResult <UserDto>(success, userDto, errors)); }