Filttering by user correctly in Strapi 4.13+

System Information
  • Strapi Version: 4.15.2
  • Operating System: Alpine Linux edge
  • Database: PostgreSQL
  • Node Version: 18.18.2
  • NPM Version: 10.2.3
  • Yarn Version: 1.22.19

I have a very common scenario with a Collection type “Note” which has a text field and a relation to a User from users-permissions. The user should only be able to retrieve his own notes, and not the notes of other users, also no information about other users should be accessible.

Before Strapi 4.13, this simple trick in a controller would work:

find(ctx){
    ctx.query.filters = { ...(ctx.query.filters as any), user: ctx.state.user.id };
    return super.find(ctx);
}

As I understand, in newer versions of Strapi, filtering by the field not directly accessible by user is forbidden, and this code would produce the error “Invalid parameter user”. It would only work if explicitly checking User:find() permission, and I only want to check User:me().

What would be the correct way to implement this function in Strapi 4.13+? Should I use Entity API or DB API?

1 Like

Same issue here

The senatization is happening on the controler layer that means if you where to do this in the service instead of in the controler this should be fine.

1 Like

I managed to make it work somehow:

async find(ctx) {
    await this.validateQuery(ctx);
    let sanitizedQueryParams = await this.sanitizeQuery(ctx);
    sanitizedQueryParams.filters.$and = [...sanitizedQueryParams.filters.$and, { user: { id: ctx.state.user.id } }]
    const { results, pagination } = await strapi.service('api::yourservicename').find(sanitizedQueryParams);
    const sanitizedResults = await this.sanitizeOutput(results, ctx);
    return this.transformResponse(sanitizedResults, { pagination });
  },

You could just have done it on the service instead of the controller.
:wink:

1 Like

Hi, Does anyone know how to acheive this for media library.
Is there any way to add new key to fileinfo object in media library image upload, so that i can perform this filter?

To elaborate on Boegie19’s point; here’s the information in the docs to extend core services:

Here’s an example:

async find(params) {
    const ctx = strapi.requestContext.get();
    const { user } = ctx.state;
    
    params.filters = {
      ...params.filters,
      user: user.id
    };
    
    const { results, pagination } = await super.find(params);

    return { results, pagination };
  },