Repository: strapi/strapi
File: packages/core/admin/server/src/bootstrap.ts (TypeScript)

Code before:
};

/**
 * Ensures the creation of default API tokens during the app creation.
 *
 * Checks the database for existing users and API tokens:
 * - If there are no users and no API tokens, it creates two default API tokens:
 *   1. A "Read Only" API token with permissions for accessing resources.
 *   2. A "Full Access" API token with permissions for accessing and modifying resources.
 *
 * @sideEffects Creates new API tokens in the database if conditions are met.
 */

const createDefaultAPITokensIfNeeded = async () => {
  const userService = getService('user');
  const apiTokenService = getService('api-token');

  const usersCount = await userService.count();
  const apiTokenCount = await apiTokenService.count();

  if (usersCount === 0 && apiTokenCount === 0) {
    await Promise.all(
      Object.values(constants.DEFAULT_API_TOKENS).map((token) => {
        return apiTokenService.create(token);
      })
    );
  }
};

export default async ({ strapi }: { strapi: Core.Strapi }) => {
  await registerAdminConditions();
  await registerPermissionActions();
  registerModelHooks();

  const permissionService = getService('permission');
  const userService = getService('user');
  const roleService = getService('role');
  const apiTokenService = getService('api-token');
  const transferService = getService('transfer');
  const tokenService = getService('token');

  await roleService.createRolesIfNoneExist();
  await roleService.resetSuperAdminPermissions();
  await roleService.displayWarningIfNoSuperAdmin();

  await permissionService.cleanPermissionsInDatabase();

  await userService.displayWarningIfUsersDontHaveRole();

  await syncAuthSettings();
  await syncAPITokensPermissions();

Review comment (suggestion):
Does Object values do anything? Isn't DEFAULT_API_TOKENS an array already?

I'm also not sure we should Promise.all here as it means the tokens could be created in any order, so it will affect the UI

Code after:
};

/**
 * Ensures the creation of default API tokens during the app creation.
 *
 * Checks the database for existing users and API tokens:
 * - If there are no users and no API tokens, it creates two default API tokens:
 *   1. A "Read Only" API token with permissions for accessing resources.
 *   2. A "Full Access" API token with permissions for accessing and modifying resources.
 *
 * @sideEffects Creates new API tokens in the database if conditions are met.
 */

const createDefaultAPITokensIfNeeded = async () => {
  const userService = getService('user');
  const apiTokenService = getService('api-token');

  const usersCount = await userService.count();
  const apiTokenCount = await apiTokenService.count();

  if (usersCount === 0 && apiTokenCount === 0) {
    for (const token of constants.DEFAULT_API_TOKENS) {
      await apiTokenService.create(token);
    }
  }
};

export default async ({ strapi }: { strapi: Core.Strapi }) => {
  await registerAdminConditions();
  await registerPermissionActions();
  registerModelHooks();

  const permissionService = getService('permission');
  const userService = getService('user');
  const roleService = getService('role');
  const apiTokenService = getService('api-token');
  const transferService = getService('transfer');
  const tokenService = getService('token');

  await roleService.createRolesIfNoneExist();
  await roleService.resetSuperAdminPermissions();
  await roleService.displayWarningIfNoSuperAdmin();

  await permissionService.cleanPermissionsInDatabase();

  await userService.displayWarningIfUsersDontHaveRole();

  await syncAuthSettings();
  await syncAPITokensPermissions();

  await getService('metrics').sendUpdateProjectInformation(strapi);