Updating user (user-permissions) relation field when creating a new record from REST API

System Information
  • Strapi Version: 4.1.0
  • Operating System: Osx
  • Database: SQLite
  • Node Version: v16.8.0
  • NPM Version: 7.21.0
  • Yarn Version: 1.22.17

I created a new content type named “Report”. In this content type, I have a list of fields including 2 user-permissions relational fields called “author” and “offender”. My end goal, at least for now, is to be able to create new Reports via REST API by sending POST requests to the /api/reports endpoint.

As it stands, when a POST request is sent to this URL, a receive a 200 response back, a new record is created (as I can see in the backend) and I also receive the Report data back as a response. The issue I have, however, is that the “author” and the “offender” fields are not populated at all.

This is an example JSON body I’m sending with the POST request:

{
    "data": {
        "author": 1,
        "offender": 2,
        "type": "terms",
        "status": "pending",
        "reason": "this guy is a spammer"
    }
}

The 1 and 2 integers next to “author” and “offender” are the actual user IDs in the system.

While troubleshooting, I tried to extend the report service as explained here and could notice that the “params” received at this point, actually omit both the “author” and the “offender” fields. I can only see the rest of the data at this point. I then tried to manually force the “author” user ID in the service itself like the below and this worked without any issues:

module.exports = createCoreService("api::report.report", () => ({
  async create(params) {
    params.data.author = 1;
    const result = await super.create(params);

    return result;
  },
}));

I can’t figure out what I’m missing and I’d be grateful if someone can put me in the right direction here.

Thanks!

1 Like

Same here !

Could this be permissions related ?

To overcome this I had to use a custom middleware (I’m using GraphQL).
In this middleware, I check for permissions myself, and end up using Strapi entityService to create the entry :

await strapi.entityService.create('api::report.report', args)

Doing so, the “author” field (relation to user-permission) is correctly updated.

1 Like

You need to enable “find” permission of user under user-permissions in roles settings

Related Video

4 Likes

@blowfish - be careful - changing permissions to allow find like this will expose the data for all users to the role you are allowing this privilege - which may not be your intention.

In my case, I am trying something similar - allowing registered users to create content, as the ‘owner’. Strapi v4 doesn’t expose or populate or filter by the createdBy field - so I’ve created a related owner field - but this will only work if I make the more permissive change to the role to allow find as above.

I think the secure workaround would be something like the middleware method suggested by @Vdilly

1 Like

Thanks!, this worked for me in strapi v.4.1.12

Hi guys!

I am facing the exact same issue right now.
Figured out that I need to allow “find” for “users-permissions” on the user role.

But as @admataz stated: This is a huge security issue because it is exposing all the user data to this role.

So this is not a solution

I am wondering why this permission is needed at all?
Maybe this isnt even intended / a bug?

IMHO: Why are we forced to allow to find all users to create a relation between one (authenticated) user and another entity? :thinking: Wouldn´t it be enough to allow me permission? (which I would understand)

Right now I use this workaround which creates the relationship successful.
I think it is because it is not longer the user context but global admin role which is allowed to do everything.

const { createCoreController } = require('@strapi/strapi').factories;

module.exports = createCoreController('api::user-device-token.user-device-token', ({ strapi }) =>  ({
  async create(ctx) {
    // NOTE: For some reason "find" permission in "users-permissions" is required for user role to create the relationship...
    // Calling the default core action
    // const { data, meta } = await super.create(ctx);

    await strapi.entityService.create('api::user-device-token.user-device-token', {
      data: {
        user: ctx.state.user.id;,
        token: ctx.request.body.data.token,
      },
    });

    ctx.response.status = 200;
  },
}));

2 Likes

You need to add the publishedAt property if you want to publish the created item and make it available thru the API. If not it will be on Draft and won’t be available in any GET API.

1 Like

Thanks… had been trying this for the past 8 hours without a clue…
Now it works

Hello. Where to place the code?
I have got { data: {}, files: undefined } in console.log(ctx)
Thanks.

Hi,
I have a content type called “user-device-token”
So in my case this code is placed in a file called “user-device-token.js” in this place:
src/api/user-device-token/controllers/user-device-token.js

1 Like

I have the same issue.

It’s a huge security issue. I think that it need to fix this relation, ASAP.

Second Strapi Admin on Discord:

Derrick M :parrot: @DMehaffy - (link to message)
It’s not currently possible as it’s enforced pretty deep down, however if you do enable the find permission you can set a route policy to further restrict the access.

What is the best way to modifying the route policy or restrict the access with find() ?

1 Like

I also came here to find a proper way to unchek
Authenticated - Permissions - Users-permissions - User - find

But, by unchecking it, the related entity’s find doesn’t work with filtering relation id(user id)

Enabling find acess to Authenticated seems like a big security hole.

By the way, My IsOwner global policy version - #16 by msoler75 helped me a lot about securing user related entities.