Extending /api/auth/email-confirmation?confirmation=xxx endpoint with custom logic

System Information
  • Strapi Version: 4.12.4
  • Operating System: macOS
  • Database: MySQL
  • Node Version: v20.9.0
  • NPM Version: 10.1.0 [/details]

Hello!

I’m uncertain about the best practice to achieve my goal:

I’ve modified the file /node_modules/@strapi/plugin-users-permissions/server/controllers/auth.js. However, I’m aware that my changes will vanish when the application rebuilds.

Therefore, I intend to extend the auth.js controller.

I’ve attempted to create another file in src/extensions/users-permissions/server/controllers/auth.js with the same code but I’ve modified the emailConfirmation method a bit. Additionally, I’ve created a file in src/extensions/strapi-server.js with the following content, but nothing seems to happen:

'use strict'

module.exports = (plugin) => {
  plugin.controllers[
    'auth'
  ] = require('./users-permissions/server/controllers/auth')
  return plugin
}

What am I missing?

I would appreciate feedback, perhaps with a code example or a link to a relevant reference.

Thanks

For future reference for someone else, I was able to overwrite the emailConfirmation function and attach the user’s email to the URL. This allows me to handle it in my front-end. I hope this proves helpful to someone else as well.

Follow these steps:

I uploaded an example here.

  1. Create a file named strapi-server.js in the directory src/extensions/users-permissions/
  2. Add the following code:
const _ = require("lodash");
const utils = require("@strapi/utils");
const { getService } = require("@strapi/plugin-users-permissions/server/utils");
const {
  validateEmailConfirmationBody
} = require("@strapi/plugin-users-permissions/server/controllers/validation/auth");

const { ValidationError } = utils.errors;
const { sanitize } = utils;
const sanitizeUser = (user, ctx) => {
  const { auth } = ctx.state;
  const userSchema = strapi.getModel("plugin::users-permissions.user");

  return sanitize.contentAPI.output(user, userSchema, { auth });
};

module.exports = plugin => {
  plugin.controllers.auth.emailConfirmation = async (ctx, next, returnUser) => {
    const { confirmation: confirmationToken } = await validateEmailConfirmationBody(ctx.query);

    const userService = getService("user");
    const jwtService = getService("jwt");

    const [user] = await userService.fetchAll({
      filters: { confirmationToken }
    });

    if (!user) {
      throw new ValidationError("Invalid token");
    }

    await userService.edit(user.id, {
      confirmed: true,
      confirmationToken: null
    });

    if (returnUser) {
      ctx.send({
        jwt: jwtService.issue({ id: user.id }),
        user: await sanitizeUser(user, ctx)
      });
    } else {
      const settings = await strapi.store({ type: "plugin", name: "users-permissions", key: "advanced" }).get();

      ctx.redirect(settings.email_confirmation_redirection + "?email=" + user.email || "/");
    }
  };

  return plugin;
};