jean d'arme
jean d'arme

Reputation: 4353

Abstracting middleware function

So I found that I have repeat code for my middleware Express functions.

First function:

const isAdmin = async (req, res, next) => {
  try {
    const requestingUser = await knex('users')
                                  .first('current_role')
                                  .where('id','=',req.user.id)

    requestingUser.current_role !== 'admin' ? res.sendStatus(403) : next()

  } catch (error) {
    res.send({error})
  }
}

Second function:

const isAdminOrRecruiter = async (req, res, next) => {
  try {
    const requestingUser = await knex('users')
                                  .first('current_role')
                                  .where('id','=',req.user.id)
    const isNotAllowed = requestingUser.current_role !== 'admin' && requestingUser.current_role !==  'recruiter'
    isNotAllowed ? res.sendStatus(403) : next()

  } catch (error) {
    res.send({error})
  }
}

My question is how can I make one abstract function like isAllowed(['admin]) so only admin can go through or isAllowed(['admin','recruiter']) so it can allow only admins and recruiters to go through?

The specific problem I have is with args - there are already three of them and not sure where to put fourth one.

Upvotes: 0

Views: 49

Answers (1)

VLAZ
VLAZ

Reputation: 29116

You could make use of higher order functions to derive your current ones. You would have a function that takes a list of roles and returns another function that uses that list of roles to check if the current user is assigned to any of them and if so allow access:

const isRole = (...roles) => async (req, res, next) => {
  try {
    const requestingUser = await knex('users')
                                  .first('current_role')
                                  .where('id','=',req.user.id)
    const isAllowed = roles.some(role => role == requestingUser.current_role);
    isAllowed ? next() : res.sendStatus(403) 

  } catch (error) {
    res.send({error})
  }
}

const isAdmin = isRole("admin");
const isAdminOrRecruiter = isRole("admin", "recruiter");

Upvotes: 1

Related Questions