コード例 #1
0
        public async Task <ApiBaseResponse> LoginAsync(LoginRequestModel requestModel)
        {
            ApiBaseResponse apiBaseResponse = new ApiBaseResponse();
            var             user            = await _userService.FindByEmailAsync(requestModel.Email);

            if (user == null)
            {
                return(new ApiBaseResponse(System.Net.HttpStatusCode.BadRequest, ApplicationStatusCode.AnErrorHasOccured, null, "The email or password is wrong"));
            }
            if (!user.IsActive || user.IsDeleted)
            {
                return(new ApiBaseResponse(System.Net.HttpStatusCode.BadRequest, ApplicationStatusCode.AnErrorHasOccured, null, "The email or password is wrong"));
            }

            bool isVerified = PasswordHasher.Verify(user.PasswordSalt, user.PasswordHash, requestModel.Password);

            if (!isVerified)
            {
                return(new ApiBaseResponse(System.Net.HttpStatusCode.BadRequest, ApplicationStatusCode.AnErrorHasOccured, null, "The email or password is wrong"));
            }

            var token = _jwtHandler.CreateToken(user.Id.ToString());

            apiBaseResponse.Result = token;
            return(apiBaseResponse);
        }
コード例 #2
0
ファイル: UserService.cs プロジェクト: szymio11/.netCore2.0
        public async Task <TokenDto> LoginAsync(LoginDto loginDto)
        {
            if (!await _repository.ExistAsync(a => a.Email == loginDto.Email))
            {
                throw new Exception("Nie ma takiego użytkownika o tym loginie");
            }
            var users = await _repository.FindAllAsync(a => a.Email == loginDto.Email);

            var user = users.Single();

            if (user.Password != loginDto.Password)
            {
                throw new Exception("Złe Hasło!");
            }

            var token = _jwtHandler.CreateToken(user.Id, user.Email, user.Name, user.Role);

            return(new TokenDto
            {
                Token = token.Token,
                Expires = token.Expires,
                Role = user.Role,
                Email = user.Email
            });
        }
コード例 #3
0
        public async Task <JsonWebToken> CreateAccessTokenAsync(string token)
        {
            var refreshToken = await _refreshTokenRepository.GetAsync(token);

            if (refreshToken == null)
            {
                throw new ToolBoxException(Codes.RefreshTokenNotFound,
                                           "Refresh token was not found.");
            }
            //var user = await _userRepository.GetAsync(refreshToken.UserId);
            if (refreshToken.User == null || refreshToken.UserId == null || refreshToken.UserId == Guid.Empty)
            {
                throw new ToolBoxException(Codes.UserNotFound,
                                           $"User: '******' was not found.");
            }

            var claims = await _claimsProvider.GetAsync(refreshToken.User);

            var jwt = _jwtHandler.CreateToken(refreshToken.UserId.ToString(), null, claims);

            jwt.RefreshToken = refreshToken.Token;
            await _busClient.PublishAsync(new AccessTokenRefreshed(Guid.NewGuid(), refreshToken.UserId));

            // await _busClient.PublishAsync(new AccessTokenRefreshed(user.Id), CorrelationContext.Empty);

            return(jwt);
        }
コード例 #4
0
        public async Task <JsonWebToken> SignInAsync(string email, string password)
        {
            var user = await _userRepository.GetAsync(email);

            if (user == null || !user.ValidatePassword(password, _passwordHasher))
            {
                throw new ToolBoxException(Codes.InvalidCredentials,
                                           "Invalid credentials.");
            }
            var refreshToken = new RefreshToken();

            refreshToken.SetToken(user, _passwordHasher);
            var claims = await _claimsProvider.GetAsync(user);

            var jwt = _jwtHandler.CreateToken(user.Id.ToString(), null, claims);

            jwt.RefreshToken = refreshToken.Token;

            if (user.RefreshToken != null)
            {
                user.RefreshToken.Token = refreshToken.Token;
                user.RefreshToken.SetUpdatedDate();
            }
            else
            {
                await _refreshTokenRepository.AddAsync(refreshToken);

                user.RefreshToken   = refreshToken;
                user.RefreshTokenId = refreshToken.Id;
            }
            await _userRepository.UpdateAsync(user);

            return(jwt);
        }
コード例 #5
0
        public async Task SignInAsync_ShouldReturnJwtDto_WhenDataIsValid()
        {
            var user = _fixture.Build <User>()
                       .With(u => u.EmailConfirmed, true)
                       .Create();

            _userRepository.GetByUsernameAsync(user.UserName).Returns(user);

            _passwordHandler.IsValid(user.PasswordHash, "password").ReturnsForAnyArgs(true);

            _fakeUserManager.Options.SignIn.RequireConfirmedEmail = true;

            var jwtDto = _fixture.Create <JwtDto>();

            _jwtHandler.CreateToken(user.Id, user.UserName, user.UserRoles.FirstOrDefault().Role.Name.ToString())
            .Returns(jwtDto);

            var refreshToken = new RefreshToken();

            _refreshTokenFactory.Create(user.Id).Returns(refreshToken);

            var jwt = await _sut.SignInAsync(user.UserName, user.PasswordHash);

            jwt.ShouldNotBeNull();
            jwt.ShouldBeOfType(typeof(JwtDto));
            jwt.UserId.ShouldBe(jwtDto.UserId);
            jwt.Username.ShouldBe(jwtDto.Username);
            jwt.Role.ShouldBe(jwtDto.Role);
            jwt.AccessToken.ShouldBe(jwtDto.AccessToken);
            jwt.Expires.ShouldBe(jwtDto.Expires);
            jwt.RefreshToken.ShouldBe(jwtDto.RefreshToken);
        }
コード例 #6
0
        public async Task <JwtDto> SignInAsync(string username, string password)
        {
            var user = await _userRepository.GetByUsernameAsync(username);

            if (user is null)
            {
                throw new InvalidCredentialsException();
            }

            var isPasswordValid = _passwordHandler.IsValid(user.PasswordHash, password);

            if (!isPasswordValid)
            {
                throw new InvalidCredentialsException();
            }

            if (_userManager.Options.SignIn.RequireConfirmedEmail)
            {
                if (!user.EmailConfirmed)
                {
                    throw new EmailNotConfirmedException();
                }
            }

            var jwt = _jwtHandler.CreateToken(user.Id, user.UserName,
                                              user.UserRoles.Select(ur => ur.Role.Name.ToString()).FirstOrDefault());

            jwt.RefreshToken = await CreateRefreshTokenAsync(user.Id);

            return(jwt);
        }
コード例 #7
0
        public async Task <IdentityToken> SignInAsync(string email, string password)
        {
            var user = await _userRepository.GetAsync(email);

            if (user == null || !_hasher.IsValid(user, password))
            {
                throw new ServiceException("invalid_credentials", "Invalid credentials");
            }

            var jwt   = _jwtHandler.CreateToken(user.Id, user.Role);
            var token = _hasher.Create(user, user.Id.ToString("N"), "=", "+", "\\", "/");

            await _refreshTokenRepository.CreateAsync(new RefreshToken(user, token));

            user.Login();

            await _userRepository.UpdateAsync(user);


            return(new IdentityToken
            {
                AccessToken = jwt.AccessToken,
                Expires = jwt.Expires,
                RefreshToken = token,
                Role = user.Role,
                UserId = user.Id
            });
        }
コード例 #8
0
ファイル: UserService.cs プロジェクト: pawelidziak/Evento
        public async Task <TokenDto> LoginAsync(string email, string password)
        {
            var user = await _userRepository.GetAsync(email);

            if (user == null)
            {
                throw new Exception($"Invalid credentials.");
            }

            // SPRAWDZANIE HASŁA - PRYMITYWNE
            // powinno być hashowanie, metody zabezpieczające
            if (user.Password != password)
            {
                throw new Exception($"Invalid credentials.");
            }

            var jwt = _jwtHandler.CreateToken(user.Id, user.Role);

            return(new TokenDto
            {
                Token = jwt.Token,
                Expires = jwt.Expires,
                Role = user.Role
            });
        }
コード例 #9
0
        public async Task <JsonWebToken> CreateAccessTokenAsync(string token)
        {
            var refreshToken = await _refreshTokenRepository.GetAsync(token);

            if (refreshToken == null)
            {
                throw new ServiceException("refresh_token_not_found",
                                           "Refresh token was not found.");
            }
            if (refreshToken.Revoked)
            {
                throw new ServiceException("refresh_token_not_revoked",
                                           $"Refresh token: '{refreshToken.Id}' was revoked.");
            }
            var user = await _userRepository.GetAsync(refreshToken.UserId);

            if (user == null)
            {
                throw new ServiceException("user_not_found",
                                           $"User: '******' was not found.");
            }
            var jwt = _jwtHandler.CreateToken(user.Id, user.Role);

            jwt.RefreshToken = refreshToken.Token;

            return(jwt);
        }
コード例 #10
0
ファイル: ServiceUser.cs プロジェクト: adamkos93/WebShop
        public async Task <Tuple <TokenDto, int> > LoginAsync(UserDto user)
        {
            if (user.Email == null || user.Password == null)
            {
                throw new ArgumentNullException($"{nameof(user.Email)},{nameof(user.Password)}");
            }
            var domainUser = await _userRepository.GetAsync(user.Email);

            if (domainUser == null)
            {
                throw new Exception($"User with email: {user.Email} doesn't exists.");
            }
            var hash = _encrypter.GetHash(user.Password, domainUser.Salt);

            if (domainUser.Password == hash)
            {
                var jwt = _jwtHandler.CreateToken(domainUser);
                return(Tuple.Create(new TokenDto
                {
                    Token = jwt.Token,
                    Expires = jwt.Expires,
                    Role = domainUser.Role
                }, domainUser.Id));
            }
            return(Tuple.Create(new TokenDto()
            {
            }, 0));

            //jwt
            //configuration
        }
コード例 #11
0
ファイル: UserService.cs プロジェクト: osajdapawel/Better
        public async Task <TokenJwtDTO> LoginAsync(LoginModel loginData)
        {
            loginData.Email = loginData.Email.ToLower();
            if (string.IsNullOrEmpty(loginData.Email) || string.IsNullOrEmpty(loginData.Password))
            {
                throw new AppException("Email or password is incorrect");
            }

            var user = await _userRepository.GetSimpleUserAsync(loginData.Email);

            if (user == null)
            {
                throw new AppException($"User with email {loginData.Email} doesn't exist");
            }

            if (!VerifyPasswordHash(loginData.Password, user.PasswordHash, user.PasswordSalt))
            {
                throw new AppException("Email or password is incorrect");
            }

            var token = _jwtHandler.CreateToken(user);

            token.User = _mapper.Map <SimpleUserDTO>(user);

            return(token);
        }
コード例 #12
0
        public async Task <JwtDto> LoginWithFacebookAsync(string accessToken)
        {
            var validatedTokenResult = await _facebookAuthService.ValidateAccessTokenAsync(accessToken);

            if (!validatedTokenResult.FacebookTokenValidationData.IsValid)
            {
                throw new InvalidFacebookTokenException();
            }

            var userInfo = await _facebookAuthService.GetUserInfoAsync(accessToken);

            var user = await _userRepository.GetByEmailAsync(userInfo.Email);

            // if user does not exist create user and sign in
            // else user exists, just sign in
            if (user is null)
            {
                user = new User(userInfo.Email, userInfo.Email);

                await _userManager.CreateAsync(user);

                await _userManager.AddToRoleAsync(user, RoleId.User.ToString());

                await _athleteService.CreateAsync(user.Id);
            }

            var jwt = _jwtHandler.CreateToken(user.Id, user.UserName, RoleId.User.ToString());

            jwt.RefreshToken = await CreateRefreshTokenAsync(user.Id);

            return(jwt);
        }
コード例 #13
0
        public Task <JsonWebToken> SignInAsync(string email, string password)
        {
            var user = _usersRepository.GetByEmail(email);
            var jwt  = _jwtHandler.CreateToken(user.Id.ToString(), user.Role, new Dictionary <string, string>());

            return(Task.FromResult(jwt));
        }
コード例 #14
0
        public async Task <IdentityToken> CreateAccessTokenAsync(string token)
        {
            var refreshToken = await _refreshTokenRepository.GetAsync(token);

            if (refreshToken == null)
            {
                throw new ServiceException("refresh_token_not_found", $"Refresh token was not found.");
            }

            if (refreshToken.Revoked)
            {
                throw new ServiceException("refresh_token_not_revoked", $"Refresh token: '{refreshToken.Id.ToString()}' was revoked");
            }

            var user = await _userRepository.GetAsync(refreshToken.UserId);

            if (user == null)
            {
                throw new ServiceException("user_not_found", $"User: '******' was not found.");
            }

            var jwt = _jwtHandler.CreateToken(user.Id, user.Role);

            return(new IdentityToken
            {
                AccessToken = jwt.AccessToken,
                Expires = jwt.Expires,
                RefreshToken = refreshToken.Token,
                Role = user.Role,
                UserId = user.Id
            });
        }
コード例 #15
0
ファイル: UserService.cs プロジェクト: StolarQQ/Shelfy_2.0
        public async Task LoginAsync(string email, string password)
        {
            var user = await _userRepository.GetByEmailAsync(email);

            if (user == null)
            {
                throw new ServiceException(ErrorCodes.InvalidCredentials, "Invalid credentials, try again.");
            }

            var hash = _encrypterService.GetHash(password, user.Salt);

            if (user.Password != hash)
            {
                throw new ServiceException(ErrorCodes.InvalidCredentials, "Invalid credentials, try again.");
            }

            var jwt = _jwtHandler.CreateToken(user.UserId, user.Role);

            var jwtDto = new TokenDto
            {
                Token   = jwt.Token,
                Role    = user.Role,
                Expires = jwt.Expires
            };

            _cache.Set(user.Email, jwtDto, TimeSpan.FromMinutes(5));
            _logger.LogInformation($"User '{user.Username}' logged in.");
        }
コード例 #16
0
        public async Task <JsonWebToken> CreateAccessTokenAsync(string token)
        {
            var refreshToken = await _refreshTokenRepository.FirstOrDefaultAsync(x => x.Token == token);

            if (refreshToken == null)
            {
                throw new AdsboardException(Codes.RefreshTokenNotFound,
                                            "Refresh token was not found.");
            }
            if (refreshToken.Revoked)
            {
                throw new AdsboardException(Codes.RefreshTokenAlreadyRevoked,
                                            $"Refresh token: '{refreshToken.Id}' was revoked.");
            }
            var identity = await _identityRepository.FirstOrDefaultAsync(x => x.Id == refreshToken.IdentityId);

            if (identity == null)
            {
                throw new AdsboardException(Codes.IdentityNotFound,
                                            $"identity: '{refreshToken.IdentityId}' was not found.");
            }
            var claims = await _claimsProvider.GetAsync(identity.Id);

            var jwt = _jwtHandler.CreateToken(identity.Id.ToString("N"), identity.Role, claims);

            jwt.RefreshToken = refreshToken.Token;
            // await _busPublisher.PublishAsync(new AccessTokenRefreshed(identity.Id), CorrelationContext.Empty);

            return(jwt);
        }
コード例 #17
0
        public async Task UseAsync_ShouldReturnJwtDto_WhenRefreshTokenExists(int id, string userName, string role)
        {
            var token        = "randomTestToken";
            var refreshToken = _fixture.Build <RefreshToken>()
                               .With(t => t.UserId, id)
                               .Create();

            var user = _fixture.Build <UserDto>()
                       .With(u => u.Id, id)
                       .With(u => u.UserName, userName)
                       .With(u => u.Role, role)
                       .Create();

            var jwtDto = _fixture.Build <JwtDto>()
                         .With(j => j.UserId, id)
                         .With(j => j.Username, userName)
                         .With(j => j.Role, role)
                         .Create();

            _refreshTokenRepository.GetAsync(token).Returns(refreshToken);

            _userService.GetAsync(id).Returns(user);

            _jwtHandler.CreateToken(id, userName, role).Returns(jwtDto);

            var jwt = await _sut.UseAsync(token);

            jwt.ShouldNotBeNull();
            jwt.UserId.ShouldBe(id);
            jwt.Username.ShouldBe(userName);
            jwt.Role.ShouldBe(role);
            await _refreshTokenRepository.Received(1).AddAsync(Arg.Any <RefreshToken>());

            await _refreshTokenRepository.Received(1).UpdateAsync(Arg.Any <RefreshToken>());
        }
コード例 #18
0
        public async Task <JsonWebToken> HandleAsync(SignInQuery query)
        {
            var user = await _userRepository.GetAsync(query.Email);

            if (user == null || !user.ValidatePassword(query.Password, _passwordHasher))
            {
                throw new DomainException(Codes.InvalidCredentials, MessagesCode.InvalidCredentials);
            }

            var rolesName = user.UserRoles != null?user.UserRoles.Select(x => x.Role.RoleName).ToList() : new List <string>();

            var refreshToken = new RefreshToken(user, _passwordHasher);

            var claim = new Dictionary <string, string>()
            {
                { CoreConstants.OnUserIdClaimType, user.Id.ToString() },
                { CoreConstants.RoleIdClaimType, string.Join(",", rolesName) }
            };

            var jwt = _jwtHandler.CreateToken(user.Id.ToString("N"), rolesName, claim);

            jwt.RefreshToken = refreshToken.Token;

            await _refreshTokenRepository.AddAsync(refreshToken);

            return(jwt);
        }
コード例 #19
0
        public async Task <LoginDTO> LoginAsync(string identity, string password)
        {
            User user = await _userRepository.GetByEmailAsync(identity);

            if (user == null)
            {
                user = await _userRepository.GetByLoginAsync(identity);

                if (user == null)
                {
                    throw new Exception("Invalid credentials.");
                }
            }

            if (user.Password != password.Hash())
            {
                throw new Exception("Invalid credentials.");
            }

            string token = _jwtHandler.CreateToken(user.Email, user.Role_name);

            return(new LoginDTO
            {
                Token = token,
                Login = user.Login,
                Email = user.Email,
                Role = user.Role_name
            });
        }
コード例 #20
0
        public async Task <JsonWebToken> CreateAccessTokenAsync(string token)
        {
            var refreshToken = await _refreshTokenRepository.GetAsync(token);

            if (refreshToken == null)
            {
                throw new MicroSException(Codes.RefreshTokenNotFound,
                                          "Refresh token was not found.");
            }
            if (refreshToken.Revoked)
            {
                throw new MicroSException(Codes.RefreshTokenAlreadyRevoked,
                                          $"Refresh token: '{refreshToken.Id}' was revoked.");
            }
            var user = await _userRepository.GetAsync(refreshToken.UserId);

            if (user == null)
            {
                throw new MicroSException(Codes.UserNotFound,
                                          $"User: '******' was not found.");
            }
            var claims = await _claimsProvider.GetAsync(user.Id);

            var jwt = _jwtHandler.CreateToken(user.Id.ToString("N"), user.Role, claims);

            jwt.RefreshToken = refreshToken.Token;
            await _busPublisher.PublishAsync(new AccessTokenRefreshed(user.Id), CorrelationContext.Empty);

            return(jwt);
        }
コード例 #21
0
        public async Task <JsonWebToken> CreateAccessTokenAsync(string token)
        {
            var refreshToken = await _refreshTokenRepository.GetAsync(token);

            if (refreshToken == null)
            {
                throw new FTException(Codes.RefreshTokenNotFound,
                                      "Refresh token was not found.");
            }
            if (refreshToken.Revoked)
            {
                throw new FTException(Codes.RefreshTokenAlreadyRevoked,
                                      $"Refresh token: '{refreshToken.Id}' was revoked.");
            }
            var user = await _userRepository.GetAsync(refreshToken.UserId);

            if (user == null)
            {
                throw new FTException(Codes.UserNotFound,
                                      $"User: '******' was not found.");
            }
            var jwt = _jwtHandler.CreateToken(user.Id.ToString("N"), user.Role);

            jwt.RefreshToken = refreshToken.Token;

            return(jwt);
        }
コード例 #22
0
ファイル: UserService.cs プロジェクト: KopczykF/Gatherer
        public async Task <TokenDto> LoginAsync(string email, string password)
        {
            var user = await _userRepository.GetAsync(email);

            if (user == null)
            {
                throw new Exception($"Invalid credentials.");
            }

            var salt = _encrypter.GetSalt(password);
            var hash = _encrypter.GetHash(password, user.Salt);

            if (user.Password != hash)
            {
                throw new Exception($"Invalid credentials.");
            }

            var jwt = _jwtHandler.CreateToken(user.Id, user.Role);

            return(new TokenDto
            {
                Token = jwt.Token,
                Expires = jwt.Expires,
                Role = user.Role
            });
        }
コード例 #23
0
        public async Task HandleAsync(Login command)
        {
            // throw new System.NotImplementedException();
            var jwt = _jwtHandler.CreateToken(command.Email);

            _cache.SetJwt(command.TokenId, jwt);
            await _userService.LoginAsync(command.Email, command.Password);
        }
コード例 #24
0
        public async Task <IActionResult> Login([FromBody] LoginModel login)
        {
            var user = await _identityService.Login(login.Login, login.Password);

            var token = _jwtHandler.CreateToken(user.UserId);

            return(Ok(token));
        }
コード例 #25
0
        public IHttpActionResult Login([FromBody] UserModel login)
        {
            var user  = userRepository.Login(login.Login, login.Password);
            var token = jwtHandler.CreateToken(user.ID, user.Role);

            token.User = user;
            return(Ok(token));
        }
コード例 #26
0
ファイル: LoginHandler.cs プロジェクト: konraddabrowski/Cvtex
 public async Task HandleAsync(Login command)
 => await _handler
 .Run(async() => await _userService.LoginAsync(command.Email, command.Password))
 .Next().Run(async() => {
     var user = await _userService.GetAsync(command.Email);
     var jwt  = _jwtHandler.CreateToken(user.Id, user.Role);
     _memoryCache.SetJwt(command.TokenId, jwt);
 })
 .ExecuteAsync();
コード例 #27
0
        public async Task <UserLoginData> LoginAsync(LoginUserCommand command)
        {
            var user = await _userRepository.GetWithGroupTeamsAndStudents(command.Email);

            if (user == null)
            {
                throw new AppException("Wrong email or password.", AppErrorCode.VALIDATION_ERROR);
            }

            string generatedHash = _encrypter.GetHash(command.Password, user.Salt);

            if (user.PasswordHash != generatedHash)
            {
                throw new AppException("Wrong email or password.", AppErrorCode.VALIDATION_ERROR);
            }

            JwtDto token    = _jwtHandler.CreateToken(user.Id, user.Role);
            var    userData = new UserLoginData
            {
                Token = token,
                User  = new LoginUser
                {
                    FirstName = user.FirstName,
                    LastName  = user.LastName,
                    Email     = user.Email,
                    Groups    = user.Groups.Select(g => new LoginGroupDto
                    {
                        Id        = g.Id,
                        UserRoles = new List <RoleDto>(),
                        Name      = g.Name,
                        Teams     = g.Teams.Select(t => t.Name).ToList(),
                        UserTeams = g.Teams.Where(t =>
                                                  t.Students.Any(s => s.Id == user.Id))
                                    .Select(t => t.Name).ToList()
                    }).ToList()
                }
            };

            for (int i = 0; i < user.Groups.Count(); i++)
            {
                if (user.Groups.ElementAt(i).Students.Any(s => s.Id == user.Id))
                {
                    userData.User.Groups.ElementAt(i).UserRoles.Add(RoleDto.Student);
                }
                if (user.Groups.ElementAt(i).Moderators.Any(s => s.Id == user.Id))
                {
                    userData.User.Groups.ElementAt(i).UserRoles.Add(RoleDto.Moderator);
                }
                if (user.Groups.ElementAt(i).Administrators.Any(s => s.Id == user.Id))
                {
                    userData.User.Groups.ElementAt(i).UserRoles.Add(RoleDto.Administrator);
                }
            }

            return(userData);
        }
コード例 #28
0
        public async Task HandleAsync(LogIn command)
        {
            await userService.LoginAsync(command.Email, command.Password);

            var user = await userService.GetAsync(command.Email);

            var token = jwtHandler.CreateToken(user.Id, user.Role);

            cache.SetJwt(command.TokenId, token);
        }
コード例 #29
0
ファイル: LoginHandler.cs プロジェクト: beniovski/Passenger
        public async Task HandleAsync(Login command)
        {
            await _userService.LoginAsync(command.Email, command.Password);

            var user = await _userService.GetAsync(command.Email);

            var jwt = _jwtHandler.CreateToken(command.Email, "rola");

            _cache.SetJwt(command.tokenId, jwt);
        }
コード例 #30
0
        public async Task HandleAsync(Login command)
        {
            await _userService.Login(command.Email, command.Password);

            var user = await _userService.Get(command.Email);

            var jwt = _jwtHandler.CreateToken(user.Id, "user");

            _cache.Set(command.TokenId, jwt, TimeSpan.FromSeconds(5));
        }