How can I create user lifecycle hooks in v4?

I figured out a workaround for now, turns out I was using the incorrect model name, so the db lifecycle hook does work for the user model (docs)

In src/index.js, this is my code, I wanted to send a confirmation email after user create:

'use strict';

module.exports = {
  /**
   * An asynchronous register function that runs before
   * your application is initialized.
   *
   * This gives you an opportunity to extend code.
   */
  register(/*{ strapi }*/) {},

  /**
   * An asynchronous bootstrap function that runs before
   * your application gets started.
   *
   * This gives you an opportunity to set up your data model,
   * run jobs, or perform some special logic.
   */
  async bootstrap({ strapi }) {
    strapi.db.lifecycles.subscribe({
      models: ['plugin::users-permissions.user'],

      async afterCreate(event) {
        await strapi.service('plugin::users-permissions.user').sendConfirmationEmail(
          event.result
        );
      },
    });
  },
};

This solution doesn’t work as well for beforeCreate, as this hook is before the entity is created in the database, whereas you might want logic to run before any of the user-permissions plugin code.

To get around this, I modified the create controller by using the strapi plugin extension.

Here’s the code in this file: src/extensions/user-permissions/strapi-server.js. This is defaulting the user’s username and password so they don’t have to be filled in from the admin front end

const crypto = require('crypto');

module.exports = (plugin) => {
  const userCreate = plugin.controllers.contentmanageruser.create;

  plugin.controllers.contentmanageruser.create = async (ctx) => {
    ctx.request.body.username = ctx.request.body.email;
    ctx.request.body.password = crypto.randomBytes(64).toString('hex');
    ctx.request.body.confirmed = false;

    await userCreate(ctx);
  };

  return plugin;
};
5 Likes