public IActionResult Index(Verify v)
        {
            string sessionId = HttpContext.Request.Cookies["sessionId"];

            if (v.VerifySession(sessionId, _db))
            {
                TempData["Alert"] = "primary|Already logged in!";
                return(Redirect("/Gallery/Index"));
            }
            else
            {
                string cartCookie = HttpContext.Request.Cookies["guestCart"];
                if (cartCookie != null)
                {
                    GuestCart guestCart = JsonSerializer.Deserialize <GuestCart>(cartCookie);
                    ViewData["CartQuantity"] = guestCart.Count();
                }
                else
                {
                    ViewData["CartQuantity"] = 0;
                }
            }
            return(View());
        }
        public IActionResult Authenticate(Hasher hasher, string username, string password, string returnUrl)
        {
            User user = _db.Users.FirstOrDefault(x => x.Username == username);

            if (user == null || hasher.GenerateHashString(password, user.Salt) != user.Password)
            {
                TempData["Alert"] = "danger|Username or password incorrect, please try again.";
                return(Redirect("Index"));
            }
            else
            {
                // Create and store session
                string guid = null;

                Session session = _db.Sessions.FirstOrDefault(session => session.UserId == user.Id);

                // Gives user the same session back if a session is already detected but updates timestamp
                if (session == null)
                {
                    guid = Guid.NewGuid().ToString();
                    _db.Sessions.Add(new Session
                    {
                        Id        = guid,
                        UserId    = user.Id,
                        TimeStamp = DateTime.Now
                    });
                }
                else
                {
                    guid = session.Id;
                    session.TimeStamp = DateTime.Now;
                }

                _db.SaveChanges();

                Response.Cookies.Append("sessionId", guid, new CookieOptions
                {
                    HttpOnly = true,
                    SameSite = SameSiteMode.Lax
                });

                TempData["Alert"] = "primary|Successfully logged in!";

                foreach (var cart in _db.Carts.Where(cart => cart.UserId == user.Id))
                {
                    _db.Carts.Remove(cart);
                }

                string cartCookie = HttpContext.Request.Cookies["guestCart"];
                if (cartCookie != null)
                {
                    // Overwrites current cart in account with guestCart if guestCart exists as per CW's specifications
                    GuestCart guestCart = JsonSerializer.Deserialize <GuestCart>(cartCookie);
                    foreach (var product in guestCart.Products)
                    {
                        _db.Carts.Add(new Cart
                        {
                            ProductId = product.ProductId,
                            UserId    = user.Id,
                            Quantity  = product.Quantity
                        });
                    }
                    HttpContext.Response.Cookies.Delete("guestCart");
                    TempData["Alert"] += $" {guestCart.Count()} item(s) from your previous cart has overwritten your account cart.";
                }
                _db.SaveChanges();
            }

            // TempData was not expiring fast enough in some use cases, this ensures removal after single usage
            if (TempData["ReturnUrl"] != null)
            {
                TempData.Remove("ReturnUrl");
            }

            if (!returnUrl.IsNullOrEmpty())
            {
                return(Redirect(returnUrl));
            }

            return(Redirect("/Gallery/Index"));
        }
        public IActionResult AddCart(int productId)
        {
            string sessionId = HttpContext.Request.Cookies["sessionId"];

            if (_v.VerifySession(sessionId, _db))
            {
                int  userid = _db.Sessions.FirstOrDefault(x => x.Id == sessionId).UserId;
                Cart cart   = _db.Carts.FirstOrDefault(x => x.UserId == userid && x.ProductId == productId);

                // Special case handling to prevent integer overflow
                if (cart == null)
                {
                    _db.Add(new Cart()
                    {
                        Quantity  = 1,
                        UserId    = userid,
                        ProductId = productId
                    });
                }
                else if (cart.Quantity < 100)
                {
                    cart.Quantity += 1;
                }
                else
                {
                    TempData["Alert"] = "warning|Cannot have more than 100 of the same product at once in cart, please contact Team 10 for bulk purchases.";
                    return(Json(new
                    {
                        success = false,
                    }));
                }

                _db.SaveChanges();

                return(Json(new
                {
                    success = true
                }));
            }
            else
            {
                string    cartCookie = HttpContext.Request.Cookies["guestCart"];
                GuestCart guestCart;
                if (cartCookie != null)
                {
                    guestCart = JsonSerializer.Deserialize <GuestCart>(cartCookie);
                }
                else
                {
                    guestCart = new GuestCart();
                    guestCart.Add(productId, _db.Products.FirstOrDefault(p => p.Id == productId));
                }

                Product product = _db.Products.FirstOrDefault(p => p.Id == productId);
                Cart    inCart  = guestCart.Find(productId);

                // Special case handling to prevent integer overflow
                if (inCart == null || inCart.Quantity < 100)
                {
                    guestCart.Add(productId, product);
                }
                else
                {
                    TempData["Alert"] = "warning|Cannot have more than 100 of the same product at once in cart, please contact Team 10 for bulk purchases.";
                    return(Json(new
                    {
                        success = false,
                    }));
                }

                HttpContext.Response.Cookies.Append("guestCart", JsonSerializer.Serialize <GuestCart>(guestCart), new CookieOptions
                {
                    HttpOnly = true,
                    SameSite = SameSiteMode.Lax
                });

                return(Json(new
                {
                    success = true
                }));
            }
        }