示例#1
0
        public IEnumerable <Item> AllItems()
        {
            using (var context = new DbContext())
            {
                var seller = _accountService.ValidateSellerSession(Request.Cookies, context);
                if (seller != null)
                {
                    var items = context.Items
                                .Where(x => !x.Hidden && x.SellerId == seller.Id)
                                .Include(item => item.Seller)
                                .OrderBy(x => x.Id)
                                .ToList();
                    return(items);
                }

                if (_accountService.ValidateAdminSession(Request.Cookies, context))
                {
                    var items = context.Items
                                .Where(x => !x.Hidden)
                                .Include(item => item.Seller)
                                .OrderBy(x => x.Id)
                                .ToList();
                    return(items);
                }

                // If the user is not a seller or admin, there is nothing to give them.
                Response.StatusCode = 403;
                return(null);
            }
        }
        public Dictionary <string, string> ChangeName([FromBody] Dictionary <string, string> request)
        {
            using (var context = new DbContext())
            {
                var obj      = new Dictionary <string, string>();
                var customer = _accountService.ValidateCustomerSession(Request.Cookies, context);
                var seller   = _accountService.ValidateSellerSession(Request.Cookies, context);
                if (customer != null)
                {
                    customer.FirstName = request["firstName"];
                    customer.LastName  = request["lastName"];
                }
                else if (seller != null)
                {
                    seller.Name = request["name"];
                }
                else
                {
                    obj["error"] = "Invalid session. Please refresh the page, and try again.";
                    return(obj);
                }

                context.SaveChanges();
                return(obj);
            }
        }
示例#3
0
        public Item CreateItem([FromBody] NewItemForm form)
        {
            form.Price = form.Price.Replace("$", "");
            using (var context = new DbContext())
            {
                var seller = _accountService.ValidateSellerSession(Request.Cookies, context);
                if (seller == null)
                {
                    Response.StatusCode = 403;
                    return(null);
                }

                var item = context.Items.Add(new Item
                {
                    Description = form.Description,
                    Name        = form.Name,
                    Price       = decimal.Parse(form.Price),
                    SellerId    = seller.Id,
                    ImageURL    = form.ImageURL,
                    Hidden      = false,
                    Purchases   = 0
                });
                context.SaveChanges();

                return(item.Entity);
            }
        }
示例#4
0
        public Dictionary <string, dynamic> RemoveItemFromCart([FromBody] SimpleInt id)
        {
            using (var context = new DbContext())
            {
                var session = _accountService.ValidateSession(Request.Cookies, context);
                if (session == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                var itemToRemove =
                    context.CartItems.FirstOrDefault(x => x.SessionId == session.Id && x.ItemId == id.Value);
                if (itemToRemove == null)
                {
                    // Item does not exist or has already been removed
                    Response.StatusCode = 404;
                    return(null);
                }

                context.CartItems.Remove(itemToRemove);
                context.SaveChanges();
                return(GetItemsInCart());
            }
        }
示例#5
0
        public Dictionary <string, dynamic> AddItemToCart([FromBody] SimpleInt id)
        {
            using (var context = new DbContext())
            {
                var session = _accountService.ValidateSession(Request.Cookies, context);
                if (session == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                // If item does not exist, don't add it.
                if (context.Items.FirstOrDefault(x => x.Id == id.Value && !x.Hidden) == null)
                {
                    Response.StatusCode = 404; // Not found
                    return(null);
                }

                context.CartItems.Add(new CartItem
                {
                    SessionId = session.Id,
                    ItemId    = id.Value
                });

                context.SaveChanges();

                return(GetItemsInCart());
            }
        }
示例#6
0
        public void RemoveItem([FromBody] SimpleInt simpleInt)
        {
            using (var context = new DbContext())
            {
                var item = context.Items.First(x => x.Id == simpleInt.Value);
                // Check if the user is a seller.
                var seller = _accountService.ValidateSellerSession(Request.Cookies, context);
                var admin  = _accountService.ValidateAdminSession(Request.Cookies, context);
                // If user is not a seller or admin, return.
                if (seller == null && admin == false)
                {
                    Response.StatusCode = 403;
                    return;
                }

                // Do not let a seller remove the item if they are not the owner of the item.
                if (!admin && item.SellerId != seller.Id)
                {
                    Response.StatusCode = 403;
                    return;
                }

                item.Hidden = true;
                context.SaveChanges();
            }
        }
示例#7
0
        public async Task <Order> CreatePaypalOrder()
        {
            var     orderItems = new List <Item>();
            decimal totalPrice = 0;

            using (var context = new DbContext())
            {
                var customer    = _accountService.ValidateCustomerSession(Request.Cookies, context, true);
                var itemsInCart = context.CartItems
                                  .Where(x => x.SessionId == customer.Account.SessionId)
                                  .Include(x => x.Item)
                                  .Where(x => !x.Item.Hidden)
                                  .Select(cartItem => cartItem.Item).Include(x => x.Seller)
                                  .ToList();

                foreach (var item in itemsInCart)
                {
                    totalPrice += item.Price;

                    // Limit description and title size so that Paypal doesn't refuse it
                    const int maxStrSize      = 100;
                    var       itemDescription = "Sold by " + item.Seller.Name + ". " + item.Description;
                    if (itemDescription.Length > maxStrSize)
                    {
                        itemDescription = itemDescription.Substring(0, maxStrSize);
                    }
                    var itemName = item.Name;
                    if (itemName.Length > maxStrSize)
                    {
                        itemName = itemName.Substring(0, maxStrSize);
                    }

                    orderItems.Add(new Item
                    {
                        Name        = itemName,
                        Sku         = item.Id.ToString(),
                        Quantity    = 1.ToString(),
                        Category    = "PHYSICAL_GOODS",
                        Description = itemDescription,
                        Tax         = new Money
                        {
                            CurrencyCode = "AUD",
                            Value        = "0.00"
                        },
                        UnitAmount = new Money
                        {
                            CurrencyCode = "AUD",
                            Value        = item.Price.ToString(CultureInfo.InvariantCulture)
                        }
                    });
                }
            }

            // Create mostViewed for order
            var order = await _paypalService.CreateOrder(orderItems, totalPrice);

            return(order);
        }
 public void RemoveAccount()
 {
     using (var context = new DbContext())
     {
         var account = _accountService.ValidateAccountSession(Request.Cookies, context);
         context.Accounts.Remove(account);
         context.SaveChanges();
     }
 }
 public Session ValidateSession(string sessionId, string token, DbContext context)
 {
     try
     {
         return(ValidateSession(int.Parse(sessionId), token, context));
     }
     catch
     {
         return(null);
     }
 }
示例#10
0
 public IEnumerable <Item> GetItemsBoughtTogether([FromQuery] int id)
 {
     using (var context = new DbContext())
     {
         var items = context.ItemsBoughtTogether
                     .Where(x => x.ItemAId == id && x.ItemA.Hidden == false && x.ItemB.Hidden == false)
                     .OrderByDescending(x => x.Count)
                     .Take(8)
                     .Select(x => x.ItemB)
                     .ToList();
         return(items);
     }
 }
示例#11
0
 public IEnumerable <Item> TopSellingItems(int count)
 {
     using (var context = new DbContext())
     {
         var items = context.Items
                     .Where(x => !x.Hidden)
                     .Include(item => item.Seller)
                     .OrderByDescending(item => item.Purchases)
                     .Take(count)
                     .ToList();
         return(items);
     }
 }
 public Session ValidateSession(dynamic requestCookies, DbContext context)
 {
     try
     {
         var sessionId = int.Parse(requestCookies["sessionId"]);
         var token     = requestCookies["token"].ToString();
         return(ValidateSession(sessionId, token, context));
     }
     catch
     {
         return(null);
     }
 }
 public bool ValidateAdminSession(dynamic requestCookies, DbContext context)
 {
     try
     {
         var sessionId = int.Parse(requestCookies["sessionId"]);
         var accountId = int.Parse(requestCookies["accountId"]);
         var token     = requestCookies["token"].ToString();
         return(ValidateAdminSession(sessionId, accountId, token, context));
     }
     catch
     {
         return(false);
     }
 }
 public Seller ValidateSellerSession(dynamic requestCookies, DbContext context, bool includeAccountObject
                                     = false)
 {
     try
     {
         var sessionId = int.Parse(requestCookies["sessionId"]);
         var accountId = int.Parse(requestCookies["accountId"]);
         var token     = requestCookies["token"].ToString();
         return(ValidateSellerSession(sessionId, accountId, token, context, includeAccountObject));
     }
     catch
     {
         return(null);
     }
 }
示例#15
0
 public Item GetItem([FromQuery] int id)
 {
     using (var context = new DbContext())
     {
         var item = context.Items
                    .Include(x => x.Seller)
                    .First(x => x.Id == id && !x.Hidden);
         if (item.Views == null)
         {
             item.Views = 0;
         }
         item.Views++;
         context.SaveChanges();
         return(item);
     }
 }
        public IEnumerable <Seller> GetAllSellers()
        {
            using (var context = new DbContext())
            {
                if (!_accountService.ValidateAdminSession(Request.Cookies, context))
                {
                    Response.StatusCode = 403;
                    return(null);
                }

                var sellers = context.Sellers
                              .Include(seller => seller.Account)
                              .ToList();
                return(sellers);
            }
        }
        public Account ValidateCredentials(string email, string password, DbContext context)
        {
            var accountToValidate = context.Accounts.FirstOrDefault(account => account.Email == email);

            if (accountToValidate == null)
            {
                return(null);
            }

            if (ValidatePassword(password, accountToValidate))
            {
                return(accountToValidate);
            }

            return(null);
        }
示例#18
0
        public SearchItemResult SearchItems([FromQuery] string query)
        {
            // TODO: Pages
            // TODO: Separate the search phrase when adding in filters
            if (query == null)
            {
                query = "";
            }
            var searchPhrase = query.ToLower().Trim();

            // Allow for searching by id if input string is an integer
            var searchId = -1;

            if (int.TryParse(searchPhrase.Replace("id:", ""), out var result))
            {
                searchId = result;
            }

            using (var context = new DbContext())
            {
                var q = context.Items.Where(x => !x.Hidden);

                // Include seller data from start so it can be searched
                q = q.Include(item => item.Seller);

                var words = _searchService.GetWordsFromPhrase(searchPhrase);

                // This code just adds another "WHERE" query for each word in the search phrase.
                // Rider really wanted to turn this into a LINQ expression, so I just let it do that lol
                q = words.Select((t, i) => i)
                    .Aggregate(q, (current, i) => current.Where(x =>
                                                                x.Name.Contains(words[i]) ||
                                                                x.Description.Contains(words[i]) ||
                                                                x.Seller.Name.Contains(words[i]) ||
                                                                x.Id == searchId
                                                                )
                               // Prioritise name and id matches
                               .OrderBy(x => (x.Name.Contains(words[i]) ? 0 : 5) +
                                        (x.Name.StartsWith(words[i]) ? 0 : 6)
                                        + (x.Id == searchId ? 0 : 8))
                               );

                return(new SearchItemResult {
                    Items = q.ToList()
                });
            }
        }
示例#19
0
        public Dictionary <string, dynamic> GetItemsInCart()
        {
            var obj = new Dictionary <string, dynamic>();

            using (var context = new DbContext())
            {
                var session = _accountService.ValidateSession(Request.Cookies, context);
                if (session == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                var cartItems = context.CartItems
                                .Where(x => x.SessionId == session.Id)
                                .Include(x => x.Item);

                // If there are any hidden mostViewed in the cart, remove them before returning the mostViewed.
                var itemsToRemove = cartItems.Where(x => x.Item.Hidden);
                if (!itemsToRemove.IsNullOrEmpty())
                {
                    context.CartItems.RemoveRange(itemsToRemove);
                    context.SaveChanges();
                    if (itemsToRemove.Count() == 1)
                    {
                        obj["warning"] = "An item in your cart has been removed, as it is no longer available.";
                    }
                    else
                    {
                        obj["warning"] =
                            "Some mostViewed in your cart have been removed, as they are no longer available.";
                    }
                }

                var items = cartItems
                            .Select(cartItem => cartItem.Item)
                            .Where(x => !x.Hidden)
                            .Include(x => x.Seller)
                            .ToList();

                obj["mostViewed"] = items;
                return(obj);
            }
        }
        public Session ValidateSession(int sessionId, string token, DbContext context)
        {
            var session = context.Sessions.Find(sessionId);

            // If the session doesn't exist, return null.
            if (session == null)
            {
                return(null);
            }
            // If the session exists, but the provided token is wrong, return null.
            var isValid = token == session.Token;

            if (!isValid)
            {
                return(null);
            }
            // The session is valid, and the session object will be returned.
            return(session);
        }
示例#21
0
        public IEnumerable <TransactionItem> AllTransactions()
        {
            using (var context = new DbContext())
            {
                // If user is a customer, get all their transactions.
                var customer = _accountService.ValidateCustomerSession(Request.Cookies, context);
                if (customer != null)
                {
                    var items = context.TransactionItems
                                .Include(x => x.CustomerTransaction)
                                .Where(x => x.CustomerTransaction.CustomerId == customer.Id)
                                .OrderByDescending(x => x.CustomerTransaction.Date)
                                .ToList();
                    return(items);
                }

                // If user is a seller, get all their transactions.
                var seller = _accountService.ValidateSellerSession(Request.Cookies, context);
                if (seller != null)
                {
                    var items = context.TransactionItems
                                .Where(x => x.SellerSaleId == seller.Id)
                                .Include(x => x.CustomerTransaction)
                                .OrderByDescending(x => x.CustomerTransaction.Date)
                                .ToList();
                    return(items);
                }

                // If user is an admin, get everything.
                if (_accountService.ValidateAdminSession(Request.Cookies, context))
                {
                    var items = context.TransactionItems
                                .Include(x => x.CustomerTransaction)
                                .OrderByDescending(x => x.CustomerTransaction.Date)
                                .ToList();
                    return(items);
                }

                // If the user is not a seller, customer, or admin, there is nothing to give them.
                Response.StatusCode = 403;
                return(null);
            }
        }
        public Dictionary <string, string> ChangeEmail([FromBody] Dictionary <string, string> request)
        {
            using (var context = new DbContext())
            {
                var obj = new Dictionary <string, string>();
                // Validate the user's old email and password
                var account = _accountService.ValidateCredentials(request["oldEmail"], request["password"], context);
                var session = _accountService.ValidateSession(Request.Cookies, context);

                if (account == null || account.Id != session.AccountId)
                {
                    obj["error"]        = "Invalid credentials.";
                    Response.StatusCode = 403;
                    return(obj);
                }

                var newEmail = request["newEmail"];
                if (!_accountService.IsEmailValid(newEmail))
                {
                    obj["error"]        = "Invalid email.";
                    Response.StatusCode = 403;
                    return(obj);
                }

                // Set the new email
                account.Email = newEmail;

                // Set the new password hash
                var newHash = _accountService.HashPassword(request["password"], account);
                account.PasswordHash = newHash;

                // Reset session token (log user out everywhere)
                context.Sessions.Find(account.SessionId).Token = _accountService.CreateSessionToken();
                context.SaveChanges();

                // Log the user out
                ClearCookies();
                return(obj);
            }
        }
        private static bool ValidateAdminSession(int sessionId, int accountId, string token, DbContext context)
        {
            var session = ValidateAccountSession(sessionId, accountId, token, context);

            // If account not valid or not authorised, return null.
            if (session == null)
            {
                return(false);
            }
            var account = session.Account;

            // If account is not an admin, return false.
            return(account.Type == 'a');
        }
        public bool Login([FromBody] LoginForm form)
        {
            int    accountId, sessionId;
            string token;

            // Validate
            form.Email = form.Email.Trim().ToLower();

            if (form.Email.Length < 4)
            {
                return(false);
            }

            if (form.Password.Length < 8)
            {
                return(false);
            }

            using (var context = new DbContext())
            {
                var account = _accountService.ValidateCredentials(form.Email, form.Password, context);

                if (account == null)
                {
                    return(false);
                }

                accountId = account.Id;

                var session = context.Sessions.FirstOrDefault(x => x.Id == account.SessionId);
                // Generate new session and token if empty for whatever reason
                if (session == null || string.IsNullOrEmpty(session.Token))
                {
                    var newSession = context.Sessions.Add(new Session
                    {
                        Token = _accountService.CreateSessionToken()
                    });

                    // Link session to account, and account to session
                    newSession.Entity.Account = account;
                    account.Session           = newSession.Entity;

                    context.SaveChanges();
                }

                token     = account.Session.Token;
                sessionId = (int)account.SessionId;
            }

            // Clear login cookies
            ClearCookies();

            // Provide with token and id cookies
            Response.Cookies.Append("token", token, new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });
            Response.Cookies.Append("accountId", accountId.ToString(), new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });
            Response.Cookies.Append("sessionId", sessionId.ToString(), new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });

            // Account has successfully been logged into. Page should now refresh.
            return(true);
        }
        private static Session ValidateAccountSession(int sessionId, int accountId, string token, DbContext context)
        {
            var session = context.Sessions.Include(x => x.Account).FirstOrDefault(x => x.Id == sessionId);

            // If session is nonexistent, or not linked with an account, return null.
            if (session?.AccountId == null)
            {
                return(null);
            }
            // If token and account id provided do not match with the corresponding entries in the database, return null.
            var isValid = token == session.Token && session.AccountId == accountId;

            if (!isValid)
            {
                return(null);
            }

            return(session);
        }
        // If authorised, this will return an object with information about the user.
        // If more information is needed, authenticate and get the user directly.
        public Dictionary <string, dynamic> ValidateUser(int sessionId, int accountId, string token, DbContext context)
        {
            var session = ValidateAccountSession(sessionId, accountId, token, context);

            if (session == null)
            {
                return(null);
            }

            // Return either a customer or seller object, depending on what type the user is.
            // Account objects need to be stripped out for two reasons: security, and to avoid loops in the JSON.
            if (session.Account.Type == 'c')
            {
                var obj      = new Dictionary <string, dynamic>();
                var customer = context.Customers.Find(accountId);
                obj["type"]      = 'c';
                obj["id"]        = customer.Id;
                obj["firstName"] = customer.FirstName;
                obj["lastName"]  = customer.LastName;
                return(obj);
            }

            if (session.Account.Type == 's')
            {
                var obj    = new Dictionary <string, dynamic>();
                var seller = context.Sellers.Find(accountId);
                obj["type"] = 's';
                obj["id"]   = seller.Id;
                obj["name"] = seller.Name;
                return(obj);
            }

            if (session.Account.Type == 'a')
            {
                var obj     = new Dictionary <string, dynamic>();
                var account = context.Accounts.Find(accountId);
                obj["type"] = 'a';
                obj["id"]   = account.Id;
                return(obj);
            }

            return(null);
        }
示例#27
0
        public async Task <Dictionary <string, dynamic> > CapturePaypalOrder([FromQuery] string orderId)
        {
            using (var context = new DbContext())
            {
                // Refuse capture if customer is not properly authenticated
                var customer = _accountService.ValidateCustomerSession(Request.Cookies, context, true);
                if (customer == null)
                {
                    Response.StatusCode = 401; // Unauthorised
                    return(null);
                }

                // Refuse capture if

                // Capture funds through Paypal
                var order = await _paypalService.CaptureOrder(orderId);

                // Create transaction object
                var transaction = context.CustomerTransactions.Add(new CustomerTransaction
                {
                    CustomerId          = customer.Id,
                    CustomerName        = customer.FirstName + " " + customer.LastName,
                    Date                = DateTime.UtcNow.AddHours(10), // Force Sydney timezone
                    PaypalTransactionId = order.Id,
                    Total               = decimal.Parse(order.PurchaseUnits[0].AmountWithBreakdown.Value)
                });
                // Create transaction item objects
                var items        = order.PurchaseUnits[0].Items;
                var lootBoxItems = new List <int>();

                var boughtTogetherRecordsAlreadyHandledA = new HashSet <int>();
                foreach (var item in items)
                {
                    var itemId = int.Parse(item.Sku);

                    var itemEntity = context.Items
                                     .Include(x => x.Seller)
                                     .First(x => x.Id == itemId);

                    context.TransactionItems.Add(new TransactionItem
                    {
                        CustomerTransaction = transaction.Entity,
                        ItemSaleId          = itemId,
                        ItemSalePrice       = decimal.Parse(item.UnitAmount.Value),
                        ItemSaleName        = item.Name,
                        SellerSaleId        = itemEntity.SellerId,
                        SellerSaleName      = itemEntity.Seller.Name
                    });

                    // Handle bought together records and purchase count
                    if (!boughtTogetherRecordsAlreadyHandledA.Contains(itemId))
                    {
                        boughtTogetherRecordsAlreadyHandledA.Add(itemId);
                        itemEntity.Purchases++;

                        var boughtTogetherRecordsAlreadyHandledB = new HashSet <int>();
                        foreach (var itemB in items)
                        {
                            var itemBId = int.Parse(itemB.Sku);
                            // Skip if item already handled or same (means duplicate mostViewed don't impact the count)
                            if (boughtTogetherRecordsAlreadyHandledB.Contains(itemBId) || itemBId == itemId)
                            {
                                continue;
                            }

                            boughtTogetherRecordsAlreadyHandledB.Add(itemBId);

                            // Get existing bought together record
                            var boughtTogetherRecord = context.ItemsBoughtTogether
                                                       .FirstOrDefault(x => x.ItemAId == itemId && x.ItemBId == itemBId);
                            // If record doesn't exist, create it.
                            if (boughtTogetherRecord == null)
                            {
                                boughtTogetherRecord = context.ItemsBoughtTogether.Add(new ItemsBoughtTogether
                                {
                                    ItemAId = itemId,
                                    ItemBId = itemBId,
                                    Count   = 0
                                }).Entity;
                            }

                            // Increment bought together count
                            boughtTogetherRecord.Count++;
                        }
                    }


                    // If item is a loot box, also add in a random item below its price.
                    if (itemEntity.Id == 86)
                    {
                        var eligibleItems = context.Items
                                            .Include(x => x.Seller)
                                            .Where(x => !x.Hidden && x.Price < itemEntity.Price);
                        var             skip       = (int)(new Random().NextDouble() * eligibleItems.Count());
                        var             chosenItem = eligibleItems.Skip(skip).Take(1).FirstOrDefault();
                        TransactionItem transactionItem;
                        if (chosenItem == null)
                        {
                            transactionItem = context.TransactionItems.Add(new TransactionItem
                            {
                                CustomerTransaction = transaction.Entity,
                                ItemSaleId          = -1,
                                ItemSalePrice       = 0,
                                ItemSaleName        = "Empty Cardboard Box",
                                SellerSaleId        = itemEntity.SellerId,
                                SellerSaleName      = itemEntity.Seller.Name
                            }).Entity;
                        }
                        else
                        {
                            transactionItem = context.TransactionItems.Add(new TransactionItem
                            {
                                CustomerTransaction = transaction.Entity,
                                ItemSaleId          = chosenItem.Id,
                                ItemSalePrice       = 0,
                                ItemSaleName        = chosenItem.Name + " (from Loot Box)",
                                SellerSaleId        = chosenItem.SellerId,
                                SellerSaleName      = chosenItem.Seller.Name
                            }).Entity;
                        }
                        Console.WriteLine("Loot box item unlocked: " + transactionItem.ItemSaleName);
                        lootBoxItems.Add(transactionItem.ItemSaleId);
                    }
                }

                // Clear user's shopping cart
                var itemsToRemove = context.CartItems.Where(x => x.SessionId == customer.Account.SessionId);
                context.CartItems.RemoveRange(itemsToRemove);
                context.SaveChanges();

                if (lootBoxItems.IsNullOrEmpty())
                {
                    lootBoxItems = null;
                }
                return(new Dictionary <string, dynamic>
                {
                    ["order"] = order,
                    ["lootBoxItems"] = lootBoxItems
                });
            }
        }
        private static Seller ValidateSellerSession(int sessionId, int accountId, string token, DbContext
                                                    context, bool includeAccountObject = false)
        {
            var session = ValidateAccountSession(sessionId, accountId, token, context);

            // If account not valid or not authorised, return null.
            if (session == null)
            {
                return(null);
            }
            var account = session.Account;

            // If account is not a seller, return null.
            if (account.Type != 's')
            {
                return(null);
            }
            Seller seller;

            if (includeAccountObject)
            {
                seller = context.Sellers.Include(x => x.Account)
                         .FirstOrDefault(x => x.Id == account.Id);
            }
            else
            {
                seller = context.Sellers.Find(account.Id);
            }

            return(seller);
        }
        public Dictionary <string, string> StartChat([FromQuery] int?id)
        {
            var obj = new Dictionary <string, string> {
                ["error"] = "", ["otherId"] = ""
            };

            using (var context = new DbContext())
            {
                // Check if user is a customer or seller
                var customer = _accountService.ValidateCustomerSession(Request.Cookies, context, true);
                var seller   = _accountService.ValidateSellerSession(Request.Cookies, context, true);

                string userId, userName, userEmail, userRole;

                if (customer != null)
                {
                    userId    = customer.Id.ToString();
                    userName  = customer.FirstName + " " + customer.LastName;
                    userEmail = customer.Account.Email;
                    userRole  = "customer";
                }
                else if (seller != null)
                {
                    userId    = seller.Id.ToString();
                    userName  = seller.Name;
                    userEmail = seller.Account.Email;
                    userRole  = "seller";
                }
                else
                {
                    // User is not authenticated
                    Response.StatusCode = 403;
                    obj["error"]        = "Only registered customers and sellers can send and receive messages.";
                    return(obj);
                }

                obj["userId"]    = userId;
                obj["userName"]  = userName;
                obj["userEmail"] = userEmail;
                obj["userRole"]  = userRole;

                // If an id parameter is specified, try to start a new chat
                // (customers are only be able to talk to sellers, and vice versa)
                if (id != null)
                {
                    if (customer != null)
                    {
                        var other = context.Sellers.Include(x => x.Account)
                                    .FirstOrDefault(x => x.Id == id);
                        if (other != null)
                        {
                            obj["otherId"]   = other.Id.ToString();
                            obj["otherName"] = other.Name;
                        }
                    }
                    else
                    {
                        var other = context.Customers.Include(x => x.Account)
                                    .FirstOrDefault(x => x.Id == id);
                        if (other != null)
                        {
                            obj["otherId"]   = other.Id.ToString();
                            obj["otherName"] = other.FirstName;
                        }
                    }
                }

                // Generate signature
                var keyByte     = new ASCIIEncoding().GetBytes(_chatSecret);
                var userIdBytes = new ASCIIEncoding().GetBytes(userId);
                var hash        = new HMACSHA256(keyByte).ComputeHash(userIdBytes);
                // Convert to HEX (Base 16)
                obj["signature"] = string.Concat(Array.ConvertAll(hash, x => x.ToString("x2")));
            }

            return(obj);
        }
        public dynamic CreateSession()
        {
            // Don't create a new session if token and session cookies already exist.
            // (if only one of these exists, something has gone wrong and a new session will be created anyway)
            // Instead, return the data logged in user. (null if not logged in)
            if (Request.Cookies.ContainsKey("token") && Request.Cookies.ContainsKey("sessionId"))
            {
                var sessionId = int.Parse(Request.Cookies["sessionId"]);
                var token     = Request.Cookies["token"];

                if (!Request.Cookies.ContainsKey("accountId"))
                {
                    return(false);
                }

                var accountId = int.Parse(Request.Cookies["accountId"]);

                // Return the data logged in user
                var user = _accountService.ValidateUser(sessionId, accountId, token, new DbContext());
                // If user is invalid, clear cookies.
                if (user == null)
                {
                    ClearCookies();
                }
                else
                {
                    return(user);
                }
            }

            // If someone with an account id does not already have a valid session, log them out. (this shouldn't happen)
            if (Request.Cookies.ContainsKey("accountId"))
            {
                // Clear login cookies
                ClearCookies();
                return(false);
            }

            Session session;

            using (var context = new DbContext())
            {
                var newSession = context.Sessions.Add(new Session
                {
                    Token = _accountService.CreateSessionToken()
                });
                context.SaveChanges();
                session = newSession.Entity;
            }

            // Provide with token and id cookies
            Response.Cookies.Append("token", session.Token, new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });
            Response.Cookies.Append("sessionId", session.Id.ToString(), new CookieOptions
            {
                HttpOnly    = true,
                Secure      = true,
                IsEssential = true,
                Expires     = DateTimeOffset.Now.AddYears(1)
            });

            return(true);
        }