V4.0.0 Sanitize user data

System Information
  • strapi version: 4.0.0
  • OS: Ubuntu 20.04.3 lts
  • DB: Sqlite
  • Node v 16.1.0
  • npm v 7.11.2
  • yarn: 1.17.3

Hi guys,

I’m trying to enrich the data of a user with additional information. For this I have created a custom controller in which I get the user. Now I’ve noticed two weirdnesses:

  1. When I started my project I was using Strapi v3 where I could get the user from ctx.state.user in my custom route, when the user had a JWT present. This, however didn’t seem to work in v4 which is why I made a workaround like this:
module.exports = {
  currentUser: async (ctx, next) => {
    const {id, isAdmin = false} = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx);
    let user = await strapi.plugins['users-permissions'].services.user.fetchAuthenticatedUser(id);
    return user;
  }
}

Which got me the user. First of all, is this the right way to do this? My guess is it’s not, but I was unable to find an alternative solution as the jwt.getToken() only returned the userId.

Secondly, and more importantly, when I’m querying for the user in the way described above, how does sanitization work in v4? v3 offered the sanitizeEntity() -function, which in v4 seems to have gone. Someone on stackoverflow suggested using sanitizeOutput(user, ctx) but I can’t seem to find this function anywhere in the strapi source, i.e. I can’t require it and when I just use it as described above, my server dies with a sanitizeOutput is not defined- exception.

Any help would be very much appreciated.

Greetings,
derelektrischemoench

Hi @derelektrischemoench,

I got the same issue as you, with the same research.
Did you found a solution at the end ? :slight_smile:

Hi @JustJerem unfortunately not I did some digging into the source but my js knowledge is only average and I couldn’t figure out what is happening there. I’m surprised that no one else faces that issue, since my guess would be that this should be an issue that more users would face. Sorry I can’t help you out there. Maybe someone else will find a solution eventually.

I just found :

**const { sanitizeEntity } = require("strapi-utils/lib");**

module.exports = (plugin) => {

  plugin.controllers.user.deleteMe = async (ctx) => {
    const entity = await strapi.entityService.delete('plugin::users-permissions.user', user.id)
    var result = **sanitizeEntity(entity, { model: strapi.getModel('plugin::users-permissions.user') })**
    return result
  };
//...
};

Like this, it’s working for me. And also, don’t forget to declare privateAttributes in your schema.

2 Likes

You sir, are a lifesaver. Thanks so much for this, I’ve been trying quite some time to find a solution to this, but I’m not exactly what you would consider a good coder.
I wish you a nice weekend and great success with whatever it is you’re working on.

I got the same issue as you, but this solution does not work on Strapi 4.0.5.
My server dies with Cannot find module 'strapi-utils/lib’

The following code is working fine with Strapi v4.0.5:

async findOne(ctx) 
{
	const { id } = ctx.params;
	const { query } = ctx;
	const entity = await strapi.service('api::customer.customer').findOne(id, query);
	const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
	return this.transformResponse(sanitizedEntity);
}
1 Like

v.4.15.0

"use strict";
const utils = require("@strapi/utils");
const { santize } = utils;

const { ForbiddenError } = utils.errors;

/**
 *  project controller
 */

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

module.exports = createCoreController("api::project.project", ({ strapi }) => ({
  async find(ctx) {
    const { user } = ctx.state;
    const { auth } = ctx.state;
    if (!user) throw new ForbiddenError("You are not authorized");

    const entities = await strapi
      .service("api::project.project")
      .myCustomEntityService(user);

    return await Promise.all(
      entities.map(async (entity) => ({
        ...entity,
        owner: await utils.sanitize.contentAPI.output(
          entity.owner,
          strapi.getModel("plugin::users-permissions.user"),
          { auth }
        ),
      }))
    );
  },
}));
1 Like

thanks mate!