internal static UserAuthInfoResponse BuildUserAuthInfoResponse(this Row row)
        {
            if (row == null)
            {
                return(null);
            }

            UserAuthInfoResponse user = new UserAuthInfoResponse
            {
                Id        = row.GetValue <Guid>(UserConstant.COLUMNS_ID),
                Email     = row.GetValue <string>(UserConstant.COLUMNS_EMAIL),
                Username  = row.GetValue <string>(UserConstant.COLUMNS_USERNAME),
                FirstName = row.GetValue <string>(UserConstant.COLUMNS_FIRST_NAME),
                LastName  = row.GetValue <string>(UserConstant.COLUMNS_LAST_NAME),
                Claims    = row.GetValue <IEnumerable <string> >(UserConstant.COLUMNS_CLAIMS)
            };

            return(user);
        }
        public async Task <IActionResult> Login(LoginViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(Redirect("~/"));
            }

            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

            if (context == null)
            {
                return(View(model));
            }

            UserAuthInfoResponse user = _getUserByUsernameAndPasswordQuery.Execute(
                new GetUserAuthByUsernameAndPasswordQueryRequest
            {
                Username = model.Username,
                Password = model.Password
            });

            if (user is null)
            {
                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials"));

                ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage);

                return(View(model));
            }

            await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.Id.ToString(), user.Username));

            HashSet <System.Security.Claims.Claim> userClaimsList = new HashSet <System.Security.Claims.Claim>();

            userClaimsList.Add(new System.Security.Claims.Claim("firstname", user.FirstName));
            userClaimsList.Add(new System.Security.Claims.Claim("lastname", user.LastName));
            userClaimsList.Add(new System.Security.Claims.Claim("username", user.Username));

            if (!(user.Claims is null))
            {
                foreach (string role in user.Claims)
                {
                    userClaimsList.Add(new System.Security.Claims.Claim("role", role));
                }
            }

            await HttpContext.SignInAsync(user.Id.ToString(), user.Username, userClaimsList.ToArray());

            if (await _clientStore.IsPkceClientAsync(context.ClientId))
            {
                return(View("Redirect", model.ReturnUrl));
            }
            else if (Url.IsLocalUrl(model.ReturnUrl))
            {
                return(Redirect(model.ReturnUrl));
            }
            else if (string.IsNullOrEmpty(model.ReturnUrl))
            {
                return(Redirect("~/"));
            }

            throw new Exception("invalid return URL");
        }