Creating middleware / policy

System Information
  • Strapi Version: 4.20.0
  • Operating System: Docker
  • Database: PostGIS
  • Node Version: v20.10.0
  • NPM Version: 10.2.4
  • Yarn Version: N/A

Hi folks!

I’m trying to create a middleware and a policy for the user-permissions plugins. But I’m having problems checking whether my code is working or not. I created a middleware and a policy using the strapi CLI, but I won’t be able to make my endpoints reach them.

The policy.

I tried to create a “test-policy” policy. I run the CLI:

? Strapi Generators policy - Generate a policy for an API
? Policy name test-policy
? Where do you want to add this policy? Add policy to an existing plugin
? Which plugin is this for? users-permissions

But I think I need to register this policy, right? But where? Because this policy is not showing up when I run npm run strapi policies:list. It just shows when I generate a policy, selecting the “Add policy to root of project” option.

The CLI created the file src/plugins/users-permissions/server/policies/test-policy.ts.
But how can I implement this in my routes?
I found a tutorial saying to create the file src/extensions/users-permissions/strapi-server.js, another one saying to create the file src/plugins/users-permissions/server.js.
What is the correct directory?

I have the same questions about the middleware, I run the CLI and they created this file:
/plugins/users-permissions/server/middlewares/testing-middleware.ts.
But this doesn’t show up when I run npm run strapi middlewares:list.

My questions are more related to how I implement middlewares and policies than what I want to do with them.

These are the links that I checked trying to implement middleware and policies on users-permissions:

I managed to successfully create middleware for api/users/:id route, which is related to users-permissions plugin.

First, write your middleware logic in src/middlewares/your-custom-middleware.js:

module.exports = (config, { strapi }) => {
  return async (ctx, next) => {
    //...here
  }
}

This middleware will be global, but do not add it into config/middlewares.js array, if you need to check for things like authorization first, otherwise any unauthed request to every route will be blocked.

Then, you have to inject this middleware into users-permissions plugin in src/index.js, like shown here ← this is example that was referenced in the comment section under official Strapi tutorial on YT.

So, in there, paste “global::your-custom-middleware” and route handlers/method requests. The example is something like this:

'use strict';

module.exports = {
  register({ strapi }) {

    const userRoutes = strapi.plugins["users-permissions"].routes["content-api"].routes;
    const yourCustomMiddleware = "global::your-custom-middleware";

    // get users-permissions routes you want to attach middleware to
    const findUpdateUser = userRoutes.findIndex(
      (route) => route.handler === "user.update" && route.method === "PUT"
    );
    const findDeleteUser = userRoutes.findIndex(
      (route) => route.handler === "user.destroy" && route.method === "DELETE"
    );

    function initializeRoute(routes, index) {
      routes[index].config.middlewares = routes[index].config.middlewares || [];
      routes[index].config.policies = routes[index].config.policies || [];
    }

    // attach middleware to routes if they are present
    if (findUpdateUser) {
      initializeRoute(userRoutes, findUpdateUser);
      userRoutes[findUpdateUser].config.middlewares.push(yourCustomMiddleware);
    }
    if (findDeleteUser) {
      initializeRoute(userRoutes, findDeleteUser);
      userRoutes[findDeleteUser].config.middlewares.push(yourCustomMiddleware);
    }

    console.log(userRoutes[findUpdateUser], "userRoutes[findUpdateUser]")
    console.log(userRoutes[findDeleteUser], "userRoutes[findDeleteUser]")
  },
  bootstrap(/*{ strapi }*/) {},
};

Don’t forget to allow access to users-permissions routes in Strapi admin: Settings → Users & Permissions Plugin → Roles → Authenticated/Public → Users-permissions → User section. In there you will also find the names of the route handlers, if you click on gear icon that appears while hovering over them; they will be shown to the right of the section