diff --git a/packages/strapi-admin/config/functions/bootstrap.js b/packages/strapi-admin/config/functions/bootstrap.js index c35d8e60ce..fd1f7c7d40 100644 --- a/packages/strapi-admin/config/functions/bootstrap.js +++ b/packages/strapi-admin/config/functions/bootstrap.js @@ -1,6 +1,30 @@ const adminActions = require('../admin-actions'); -module.exports = async () => { +const registerPermissionActions = () => { const actionProvider = strapi.admin.services.permission.provider; actionProvider.register(adminActions.actions); }; + +const cleanPermissionInDatabase = async () => { + const actionProvider = strapi.admin.services.permission.provider; + const dbPermissions = await strapi.admin.services.permission.find(); + const allActionsMap = actionProvider.getAllByMap(); + const permissionsToRemoveIds = []; + + dbPermissions.forEach(perm => { + if ( + !allActionsMap.has(perm.action) || + (allActionsMap.get(perm.action).section === 'contentTypes' && + !allActionsMap.get(perm.action).subjects.includes(perm.subject)) + ) { + permissionsToRemoveIds.push(perm.id); + } + }); + + await strapi.admin.services.permission.deleteByIds(permissionsToRemoveIds); +}; + +module.exports = async () => { + registerPermissionActions(); + await cleanPermissionInDatabase(); +}; diff --git a/packages/strapi-admin/services/action-provider.js b/packages/strapi-admin/services/action-provider.js index 32db0643f1..e5e45625c0 100644 --- a/packages/strapi-admin/services/action-provider.js +++ b/packages/strapi-admin/services/action-provider.js @@ -1,3 +1,4 @@ +const _ = require('lodash'); const { yup } = require('strapi-utils'); const { validateRegisterProviderAction } = require('../validation/action-provider'); const { getActionId, createAction } = require('../domain/action'); @@ -8,12 +9,19 @@ const actionProviderFactory = () => { return { get(uid, pluginName) { const actionId = getActionId({ pluginName, uid }); - return actions.find(p => p.actionId === actionId); + const action = actions.find(p => p.actionId === actionId); + return _.cloneDeep(action); }, getAll() { - return Array.from(actions.values()); + return _.cloneDeep(Array.from(actions.values())); + }, + getAllByMap() { + return _.cloneDeep(actions); }, register(newActions) { + if (strapi.isLoaded) { + throw new Error(`You can't register new actions outside of the bootstrap function.`); + } validateRegisterProviderAction(newActions); newActions.forEach(newAction => { const actionId = getActionId(newAction); diff --git a/packages/strapi-admin/services/permission.js b/packages/strapi-admin/services/permission.js index 1ea991c066..fb6ae7746c 100644 --- a/packages/strapi-admin/services/permission.js +++ b/packages/strapi-admin/services/permission.js @@ -5,13 +5,22 @@ const actionProvider = require('./action-provider'); /** * Delete permissions of roles in database - * @param params ids of roles + * @param rolesIds ids of roles * @returns {Promise} */ const deleteByRolesIds = rolesIds => { return strapi.query('permission', 'admin').delete({ role_in: rolesIds }); }; +/** + * Delete permissions + * @param ids ids of permissions + * @returns {Promise} + */ +const deleteByIds = ids => { + return strapi.query('permission', 'admin').delete({ id_in: ids }); +}; + /** * Find assigned permissions in the database * @param params query params to find the permissions @@ -59,6 +68,7 @@ const assign = async (roleID, permissions = []) => { module.exports = { find, deleteByRolesIds, + deleteByIds, assign, provider: actionProvider, }; diff --git a/packages/strapi/lib/Strapi.js b/packages/strapi/lib/Strapi.js index f4307c0c03..66062bb40c 100644 --- a/packages/strapi/lib/Strapi.js +++ b/packages/strapi/lib/Strapi.js @@ -372,13 +372,7 @@ class Strapi { } }; - const adminBootstrap = _.get(this.admin.config, 'functions.bootstrap'); - await execBootstrap(adminBootstrap).catch(err => { - strapi.log.error(`Bootstrap function in admin failed`); - strapi.log.error(err); - strapi.stop(); - }); - + // plugins bootstrap const pluginBoostraps = Object.keys(this.plugins).map(plugin => { return execBootstrap(_.get(this.plugins[plugin], 'config.functions.bootstrap')).catch(err => { strapi.log.error(`Bootstrap function in plugin "${plugin}" failed`); @@ -386,10 +380,18 @@ class Strapi { strapi.stop(); }); }); - await Promise.all(pluginBoostraps); - return execBootstrap(_.get(this.config, ['functions', 'bootstrap'])); + // user bootstrap + await execBootstrap(_.get(this.config, ['functions', 'bootstrap'])); + + // admin bootstrap : should always run after the others + const adminBootstrap = _.get(this.admin.config, 'functions.bootstrap'); + return execBootstrap(adminBootstrap).catch(err => { + strapi.log.error(`Bootstrap function in admin failed`); + strapi.log.error(err); + strapi.stop(); + }); } async freeze() {