In the back-end i have a controller that receives the login data (username and password) from the front-end, validate them and then returns the result response to the front-end. Here is the controller:

```js
/* POST /api/login */
exports.Login = (req, res, next) => {
  const incomingUsername = req.body.username;
  const incomingPassword = req.body.password;

  const result = validation.ValidateLoginData(
    incomingUsername,
    incomingPassword
  );

  /* Validation fails when the validationResult === 0 */
  /* Validation succeeds when the validationResult === 1 */
  if (result.validationResult === 0) {
    res.json({ result: 0, message: result.validationMessage });
  } else if (result.validationResult === 1) {
    res.json({ result: 1, message: result.validationMessage });
  }
};

```

The `ValidateLoginData()` function contains the following steps:

1. Check if the username or password does not exist (undefined)
2. Check if the username or password is empty string
3. Check if the user is owner (Special case)
4. Check if the user exists in the database
5. Check if the password is correct

I want to keep all the validation logic in the `ValidateLoginData()` function.

Here is the first scenario:

```js
exports.ValidateLoginData = (incomingUsername, incomingPassword) => {
  /* Check if the username or password does not exist (undefined) */
  /* Check if the username or password is empty string */
  /* Check if the user is owner (Special case) */
  if (incomingUsername === undefined || incomingPassword === undefined) {
    return {
      validationResult: 0,
      validationMessage: "Undefined username or password!",
    };
  } else if (incomingUsername === "" || incomingPassword === "") {
    return {
      validationResult: 0,
      validationMessage: "Empty username or password!",
    };
  } else if (
    incomingUsername === process.env.OWNER_USERNAME &&
    incomingPassword === process.env.OWNER_PASSWORD
  ) {
    return {
      validationResult: 1,
      validationMessage:
        process.env.OWNER_USERNAME + " (Owner) Logged in sucessfully!",
    };
  }

  /* Here is want to return the result of the database query and it should be the
  user data for further validation like this */
  const user = User.findOne({
    where: {
      username: incomingUsername,
    },
  });

  if (user === null) {
    return {
      validationResult: 0,
      validationMessage: "Incorrect username!",
    };
  } else if (user.dataValues.username === incomingUsername) {
    if (user.dataValues.password === incomingPassword) {
      return {
        validationResult: 1,
        validationMessage: "You logged in successfully!",
      };
    }
  }
};

```

Second scenario:

```js
/* Or if i can place the validation inside the then() and then return
the validation result out of the ValidateLoginData function */
User.findOne({
    where: {
      username: incomingUsername,
    },
  }).then((user) => {
    if (user === null) {
      return {
        validationResult: 0,
        validationMessage: "Incorrect username!",
      };
    } else if (user.dataValues.username === incomingUsername) {
      if (user.dataValues.password === incomingPassword) {
        return {
          validationResult: 1,
          validationMessage: "You logged in successfully!",
        };
      }
    }
  });

```

Third scenario:

```js
/* Or if i can place the validation for password inside the second
then() i do not want to have nesting as it makes the code
more complicated */
  User.findOne({
    where: {
      username: incomingUsername,
    },
  })
    .then((user) => {
      if (user === null) {
        /* This returns the result outside the ValidateLoginData function */
        return {
          validationResult: 0,
          validationMessage: "Incorrect username!",
        };
      } else if (user.dataValues.username === incomingUsername) {
        /* This returns the user data to the next then() not outside the
        ValidateLoginData function */
        return user;
      }
    })
    .then((user) => {
      if (user.dataValues.password !== incomingPassword) {
        return {
          validationResult: 0,
          validationMessage: "Incorrect Password",
        };
      } else if (user.dataValues.password === incomingPassword) {
        return {
          validationResult: 1,
          validationMessage: "You logged in successfully!",
        };
      }
    });

```

The goal from this is that i want to:

1. Place all the validation logic outside the controller and in the `validateLoginData` function.
2. Return an object from the `validateLoginData` function that contains `validationResult` and `validationMessage`.
3. Avoid nesting as much as possible.