Hard code the Strapi administrator

Hello :wave:
I want to run a command to auto populate the SQLITE db for local development. See it as hard coded mock data to make it easy for new developers in the team to get the project running.

I do have a way to re-create everything in the api, user and role sector, but I can’t find how to recreate the Strapi Administrator from the code and not the web interface.

This is how I create new users (works well):

await strapi.plugins["users-permissions"].services.user.add({
        ...mockUserData,
});

So far what I know about creating a administrator:

await strapi.contentTypes[strapi::user]...? //.add is not a function

Hope I’m clear enough :sweat_smile:

PD: As a double question, where can I learn more about the inner-workings of strapi for that type of mocking?

Thanks for the help!

This code will create the strapi-super-admin role as it doesn’t exist on the first run, then it will create the super-admin user. For security reasons I’ve added it only for “development” environment, to avoid cases when developers forget about this code in production.

module.exports = async () => {
  if (process.env.NODE_ENV === 'development') {
    const params = {
      username: process.env.DEV_USER || 'admin',
      password: process.env.DEV_PASS || 'admin',
      firstname: process.env.DEV_USER || 'Admin',
      lastname: process.env.DEV_USER || 'Admin',
      email: process.env.DEV_EMAIL || 'admin@test.test',
      blocked: false,
      isActive: true,
    };
    //Check if any account exists.
    const admins = await strapi.query('user', 'admin').find();

    if (admins.length === 0) {
     try {
        let tempPass = params.password;
        let verifyRole = await strapi.query('role', 'admin').findOne({ code: 'strapi-super-admin' });
        if (!verifyRole) {
        verifyRole = await strapi.query('role', 'admin').create({
          name: 'Super Admin',
          code: 'strapi-super-admin',
          description: 'Super Admins can access and manage all features and settings.',
         });
        }
        params.roles = [verifyRole.id];
        params.password = await strapi.admin.services.auth.hashPassword(params.password);
        await strapi.query('user', 'admin').create({
          ...params,
        });
        strapi.log.info('Admin account was successfully created.');
        strapi.log.info(`Email: ${params.email}`);
        strapi.log.info(`Password: ${tempPass}`);
      } catch (error) {
        strapi.log.error(`Couldn't create Admin account during bootstrap: `, error);
      }
    }
  }
};

5 Likes

Works perfect, thanks.

For anyone trying that solution, remember to call that function with an await :sweat_smile:

1 Like

Sweet, that totally works. Thanks!

1 Like

@Antoine, @jakubgs, if you usually need to use this functionality during the development process, check my new plugin strapi-plugin-boostrap-admin-user, which uses the plugin’s bootstrap.js file to create the admin user on the first run. So there is no need to hardcode all that stuff in your main bootstrap.js file.

1 Like

Why does it need to be used just only in production?

It works in production, you just have to be more careful. Is better if you create it by hand in the production environment and only use it in develelopment. That type of automation is not good in production. But it works in both

Great post, but could you update it according to Strapi v4?
Big thanks!

Here a snippet to programatically create a super admin user in Strapi v4:

const hasAdmin = await strapi.service('admin::user').exists();

if (hasAdmin) {
  return;
}

const superAdminRole = await strapi.service('admin::role').getSuperAdmin();

if (!superAdminRole) {
  return;
}

await strapi.service('admin::user').create({
  email: 'test@test.com',
  firstname: 'first name',
  lastname: 'last name',
  password: 'password',
  registrationToken: null,
  isActive: true,
  roles: superAdminRole ? [superAdminRole.id] : [],
});
1 Like

Hi,

being super newbie in strapi, where did you have to put this code? I am trying to initialize strapi automatically, and i also need to create folders before it can be used.

cheers,
Valerio

Exactly what I was looking for! Thank you!

In strapi4 you can put it in ./src/index.js

Thanks for the code. Just a small tip: You can double check ROLE info :

// Check if admin user exists
  const hasAdmin = await strapi.service("admin::user").exists();
  if (hasAdmin) {
    return;
  }

  // Check is super admin role exists
  let superAdminRole = await strapi.service("admin::role").getSuperAdmin();
  if (!superAdminRole) {
    try {
      console.log("role does not exists, creating role");
      await strapi.service("admin::role").create({
        name: "Super Admin",
        code: "strapi-super-admin",
        description:
          "Super Admins can access and manage all features and settings.",
      });
    } catch (error) {
      console.log("Could not create admin role");
      console.error(error);
    }

    superAdminRole = await strapi.service("admin::role").getSuperAdmin();
    if (!superAdminRole) {
      console.log("can't create the role. Skiping user creation");
      return;
    }
  }

  try {
    // Create admin account
    console.log("Setting up admin user...");
    await strapi.service("admin::user").create({
      ...userData,
      registrationToken: null,
      roles: superAdminRole ? [superAdminRole.id] : [],
    });
    console.info("Admin Account created");
  } catch (error) {
    console.log("Could not create admin user");
    console.error(error);
  }

With your code the user was created withou role.

your missing the declaration of userData and your admin is created as not enabled, but thanks for the info though.