Abstraction of middleware functions

After reviewing my middleware Express functions, I realized that there is repeated code.

The first function is as follows:

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})
  }
}

The second function is:

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})
  }
}

I am now considering how to create a single abstract function like isAllowed(['admin]) for only allowing admin access, or isAllowed(['admin','recruiter']) for permitting admins and recruiters to pass through. How can I achieve this efficiently?

The issue I face currently pertains to the arguments - there are already three of them, leaving me uncertain about where to add a fourth one.

Answer №1

One way to enhance your existing functions is by incorporating higher order functions. By creating a function that takes a list of roles as input and returns another function that utilizes this list to verify if the current user is assigned to any of them, you can streamline your access control logic:

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

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

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Navigate to the end of the progress bar once finished

I have a solution that works, but it's not very aesthetically pleasing. Here is the idea: Display a progress bar before making an ajax call Move the progress bar to the end once the call is complete (or fails) Keep the progress bar at 90% if the aj ...

Rotate through different image sources using jQuery in a circular pattern

I'm working on a project where I have 3 img tags in my HTML file. My goal is to change the src of all 3 images with a button click, using an array that stores 9 different image src links. When the page initially loads, it should display the first set ...

Error in React JS: SyntaxError - "Unexpected token '?'"

Following the guidelines on this website, I successfully set up a new reactJS application, proceeded to run npm i && npm run dev and encountered the following error message: /home/www/node_modules/next/dist/cli/next-dev.js:362 showAll ...

Quarterly Date Selection Tool with jQuery

I attempted to utilize the Quarter datepicker from: http://jsfiddle.net/4mwk0d5L/1/ Every time I execute the code, I encounter this problem: Cannot set property 'qtrs' of undefined. I copied exactly what was in the jsfiddle, and included the sam ...

Switch up a JSON string using JavaScript

I received a JS string through an AJAX API call containing data like this: {"Task":"Hours per Day","Slep":22,"Work":25,"Watch TV":15,"Commute":4,"Eat":7,"Bathroom":17} My goal ...

What is the process for verifying a particular user in AngularJS?

I'm new to AngularJS and I'm a bit confused about the concepts of GET, PUT requests. I am currently working on an app where I display a list of users on one page, and on another page, I have a form with three buttons. My main focus is on the "Con ...

Creating webpages dynamically by utilizing Javascript

I need assistance with a task involving a list of elements that allows users to print only the clicked element, rather than the entire page. The elements are structured as follows: <div class="element" id="#element1">Element 1</div> <div cl ...

Express bodyParser may encounter difficulties in parsing data sent from Internet Explorer

After creating a server app with Node and Express 4, I utilized jQuery for the front-end. An Ajax call was set up to send data via POST to the server: $.ajax({ cache: false, type: 'POST', url: Config.API_ENDPOINT_REGISTRATION, ...

In what scenarios is it more suitable to utilize style over the sx prop in Material-UI?

When it comes to MUI components, the style and sx prop serve similar purposes. While the sx prop provides some shorthand syntaxes and access to the theme object, they essentially function the same way. So, when should you opt for one over the other? ...

Display a div element using AngularJS

Looking for a way to display a div using AngularJS, I came across some solutions on StackOverflow. However, implementing them did not work in my case. Here is my HTML code: <div id="myPanel" ng-controller="controllerDependance" ng-show="myvalue" clas ...

Is it possible to update the value of Select2 as you type?

In my country, the majority of people do not have a Cyrillic keyboard on their devices. To address this issue, I created a function that converts Latin characters to Cyrillic in Select2's dropdown for easier city selection. However, I noticed that the ...

Authentication for file uploads in Angular 2 using Dropzone and passportjs

I am currently working on implementing authentication for an admin user using Express, Passport, and MySQL in a specific page. The authentication process works fine, but I am facing an issue with verifying whether the user is logged in while uploading file ...

jQuery plugin that controls scrolling speed using the mousewheel

I am trying to replicate the header design of Google+ which includes a search bar that moves when scrolling. Specifically, when the user scrolls down, the search bar shifts to top:-60px and the second horizontal menu shifts from top:60px to top:0 becoming ...

Dynamic Field Validation in Angular 6: Ensuring Data Integrity for Dynamic Input Fields

After successfully implementing validation for one field in my reactive form, I encountered an issue with validating dynamically added input fields. My goal is to make both input fields required for every row. The challenge seems to be accessing the forma ...

Angular is unable to bind with 'dragula' because it does not recognize it as a valid property of 'ul'

I've been attempting to incorporate dragula into my Angular 2 application, but I'm struggling to get it functioning. This is what I have added in my app.module.ts file: import { DragulaModule, DragulaService } from 'ng2-dragula/ng2-dragula ...

Button click initiates DataTables search rather than manually entering text in the input field

I am exploring the option of relocating the search function from an input to a button for a table that has been modified using DataTables. Currently, I have a customized input that triggers this function: <script> $(document).ready(function() { ...

Creating a One-of-a-Kind Instance when Exporting a Node Module

I am currently utilizing restify to create a foundational REST API framework in node. In order to facilitate this, I have developed several helper objects that are exported and required. My challenge lies in comprehending how to properly require these obj ...

In jQuery, conditionally nest divs within another div based on a specific requirement

There is a container with multiple nested elements that need to be rearranged based on the value of their custom attribute. The goal is to reorder those elements at the end of the container if their 'data-keep-down' attribute is set to true, usin ...

Protractor - I am looking to optimize my IF ELSE statement for better dryness, if it is feasible

How can I optimize this code to follow the D.R.Y principle? If the id invite-user tag is visible in the user's profile, the user can request to play a game by clicking on it. Otherwise, a new random user will be selected until the id invite-user is di ...

Tips on obtaining a Firebase ID

Does anyone have a solution for retrieving the unique id from Firebase? I've attempted using name(), name, key, and key() without any success. Although I can view the data, I'm struggling to find a way to retrieve the id. This information is cru ...