/// <summary>Creates a new User Vertex in the database.</summary>
        /// <returns>A length 1 array containing the new User Vertex.</returns>
        /// <remarks>Internal use only (not a web API). See <see cref="AuthController.Login(dynamic)"/> for use.</remarks>
        /// <param name="email">User email.</param>
        /// <param name="u">User object to create.</param>
        public async Task <IActionResult> CreateUser(string email, UserVertex u)
        {
            try {
                var result = await CreateUserVertexQuery(email, u);

                return(Ok(result));
            } catch (ArgumentException e) {
                return(BadRequest($"Malformed request: {e}"));
            } catch (ResponseException e) {
                return(BadRequest($"Error with Gremlin Query: {e}"));
            } catch (Exception e) {
                return(BadRequest($"Something went wrong: {e}"));
            }
        }
        public async Task <IActionResult> UpdateUser(string email, [FromForm] UserVertex u)
        {
            try {
                HttpContext.Request.Headers.TryGetValue("Authorization", out StringValues authorizationToken);
                AuthConnection.Instance.ValidateToken(authorizationToken);
            } catch (ArgumentException e) {
                return(BadRequest($"Malformed or missing authorization token: {e}"));
            } catch (Exception e) {
                return(Unauthorized($"Unauthenticated error: {e}"));
            }

            try {
                var result = await UpdateUserVertexQuery(email, u);

                return(Ok(result));
            } catch (ArgumentException e) {
                return(BadRequest($"Malformed request: {e}"));
            } catch (ResponseException e) {
                return(BadRequest($"Error with Gremlin Query: {e}"));
            } catch (Exception e) {
                return(BadRequest($"Something went wrong: {e}"));
            }
        }
        public async Task <IActionResult> Login(dynamic req)
        {
            JObject body = DeserializeRequest(req);

            if (!body.ContainsKey("email") || !body.ContainsKey("password"))
            {
                return(BadRequest("Request body must contain 'email' and 'password'"));
            }

            string res;

            try {
                res = await AuthConnection.Instance.LoginUser(body.GetValue("email").ToString().ToLowerInvariant(),
                                                              body.GetValue("password").ToString());
            } catch (Exception e) {
                return(BadRequest($"Something went wrong: {e}"));
            }

            // If the user exists in Azure B2C but doesn't exist in the database, create the user's profile
            // First, get the user's claims from the generated JWT
            JObject tokenObject = DeserializeRequest(res);

            if (tokenObject.ContainsKey("error"))
            {
                return(Unauthorized(tokenObject.GetValue("error_description").ToString()));
            }

            JwtSecurityToken            jwt = AuthConnection.DecodeToken(tokenObject.GetValue("access_token").ToString());
            Dictionary <string, string> claimsDictionary = AuthConnection.GetClaimsFromToken(jwt);

            try {
                // See if the user exists in the database
                string queryString = GetVertex(claimsDictionary["emails"]);
                var    result      = await DatabaseConnection.Instance.ExecuteQuery(queryString);

                // If the user exists, return Ok()
                if (result.Count > 0)
                {
                    return(Ok(res));
                }

                string firstName = claimsDictionary["given_name"];
                string lastName  = claimsDictionary["family_name"];
                string email     = claimsDictionary["emails"].ToLowerInvariant();

                // Else, create the user
                UserVertex u = new UserVertex(firstName, lastName);

                IActionResult  createUserResult = await new UsersController().CreateUser(email, u).ConfigureAwait(false);
                OkObjectResult okResult         = createUserResult as OkObjectResult;

                if (okResult.StatusCode != 200)
                {
                    return(BadRequest("Error creating new user vertex when signing in user for the first time"));
                }

                return(Ok(res));
            } catch (Exception e) {
                return(BadRequest($"Unknown error signing user for the first time: {e}"));
            }
        }