Merge branch 'v4/backend' into v4/graphql-schema-generation-refactor

This commit is contained in:
Convly 2021-08-24 17:58:14 +02:00
commit 466161ca70
47 changed files with 549 additions and 723 deletions

View File

@ -17,7 +17,7 @@ module.exports = strapi => ({
const loadFeaturesRoutes = () => {
for (const [feature, getFeatureRoutes] of Object.entries(routes)) {
if (features.isEnabled(feature)) {
strapi.admin.config.routes.push(...getFeatureRoutes); // TODO
strapi.admin.routes.push(...getFeatureRoutes); // TODO
}
}
};

View File

@ -0,0 +1,35 @@
'use strict';
// eslint-disable-next-line node/no-extraneous-require
const { features } = require('@strapi/strapi/lib/utils/ee');
const executeCEBootstrap = require('../../server/bootstrap');
const { getService } = require('../../server/utils');
const SSO_ACTIONS = [
{
uid: 'provider-login.read',
displayName: 'Read',
pluginName: 'admin',
section: 'settings',
category: 'single sign on',
subCategory: 'options',
},
{
uid: 'provider-login.update',
displayName: 'Update',
pluginName: 'admin',
section: 'settings',
category: 'single sign on',
subCategory: 'options',
},
];
module.exports = async () => {
const { actionProvider } = getService('permission');
if (features.isEnabled('sso')) {
await actionProvider.registerMany(SSO_ACTIONS);
}
await executeCEBootstrap();
};

View File

@ -1,24 +0,0 @@
'use strict';
module.exports = {
features: {
sso: [
{
uid: 'provider-login.read',
displayName: 'Read',
pluginName: 'admin',
section: 'settings',
category: 'single sign on',
subCategory: 'options',
},
{
uid: 'provider-login.update',
displayName: 'Update',
pluginName: 'admin',
section: 'settings',
category: 'single sign on',
subCategory: 'options',
},
],
},
};

View File

@ -1,20 +0,0 @@
'use strict';
// eslint-disable-next-line node/no-extraneous-require
const { features } = require('@strapi/strapi/lib/utils/ee');
const executeCEBootstrap = require('../../../../server/config/functions/bootstrap');
const {
features: { sso: ssoActions },
} = require('../admin-actions');
const { getService } = require('../../../../server/utils');
module.exports = async () => {
const { actionProvider } = getService('permission');
if (features.isEnabled('sso')) {
await actionProvider.registerMany(ssoActions);
}
await executeCEBootstrap();
};

View File

@ -1,8 +0,0 @@
'use strict';
module.exports = {
functions: {
bootstrap: require('./functions/bootstrap'),
},
routes: require('./routes').routes,
};

View File

@ -1,28 +0,0 @@
{
"routes": [
{
"method": "POST",
"path": "/roles",
"handler": "role.create",
"config": {
"policies": []
}
},
{
"method": "DELETE",
"path": "/roles/:id",
"handler": "role.deleteOne",
"config": {
"policies": []
}
},
{
"method": "POST",
"path": "/roles/batch-delete",
"handler": "role.deleteMany",
"config": {
"policies": []
}
}
]
}

View File

@ -2,7 +2,8 @@
module.exports = {
// TODO: update load middleware to not load the admin middleware from here
config: require('./config'),
bootstrap: require('./bootstrap'),
routes: require('./routes'),
services: require('./services'),
controllers: require('./controllers'),
};

View File

@ -0,0 +1,28 @@
'use strict';
module.exports = [
{
method: 'POST',
path: '/roles',
handler: 'role.create',
config: {
policies: [],
},
},
{
method: 'DELETE',
path: '/roles/:id',
handler: 'role.deleteOne',
config: {
policies: [],
},
},
{
method: 'POST',
path: '/roles/batch-delete',
handler: 'role.deleteMany',
config: {
policies: [],
},
},
];

View File

@ -18,7 +18,7 @@ module.exports = strapi => ({
if (isValid) {
// request is made by an admin
const admin = await strapi
.query('strapi::user')
.query('admin::user')
.findOne({ where: { id: payload.id }, populate: ['roles'] });
if (!admin || !(admin.isActive === true)) {

View File

@ -1,9 +1,9 @@
'use strict';
const { merge } = require('lodash/fp');
const { getService } = require('../../utils');
const adminActions = require('../admin-actions');
const adminConditions = require('../admin-conditions');
const { getService } = require('./utils');
const adminActions = require('./config/admin-actions');
const adminConditions = require('./config/admin-conditions');
const defaultAdminAuthSettings = {
providers: {

View File

@ -1,15 +1,10 @@
'use strict';
module.exports = {
functions: {
bootstrap: require('./functions/bootstrap'),
register: require('./functions/register'),
},
policies: {
hasPermissions: require('./policies/hasPermissions'),
isAuthenticatedAdmin: require('./policies/isAuthenticatedAdmin'),
},
routes: require('./routes').routes,
layout: require('./layout'),
...require('./settings'),
};

View File

@ -2,7 +2,7 @@
const { has, isObject } = require('lodash/fp');
const permissionModelUID = 'strapi::permission';
const permissionModelUID = 'admin::permission';
const hasAttribute = attribute => has(`attributes.${attribute}`);
const hasFieldsAttribute = hasAttribute('fields');

View File

@ -1,319 +0,0 @@
{
"routes": [
{
"method": "GET",
"path": "/plugins",
"handler": "admin.plugins",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::marketplace.read"]]
]
}
},
{
"method": "GET",
"path": "/init",
"handler": "admin.init"
},
{
"method": "GET",
"path": "/project-type",
"handler": "admin.getProjectType"
},
{
"method": "GET",
"path": "/information",
"handler": "admin.information",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
},
{
"method": "POST",
"path": "/plugins/install",
"handler": "admin.installPlugin",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::marketplace.plugins.install"]]
]
}
},
{
"method": "DELETE",
"path": "/plugins/uninstall/:plugin",
"handler": "admin.uninstallPlugin",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::marketplace.plugins.uninstall"]]
]
}
},
{
"method": "POST",
"path": "/login",
"handler": "authentication.login"
},
{
"method": "POST",
"path": "/renew-token",
"handler": "authentication.renewToken"
},
{
"method": "POST",
"path": "/register-admin",
"handler": "authentication.registerAdmin"
},
{
"method": "GET",
"path": "/registration-info",
"handler": "authentication.registrationInfo"
},
{
"method": "POST",
"path": "/register",
"handler": "authentication.register"
},
{
"method": "POST",
"path": "/forgot-password",
"handler": "authentication.forgotPassword"
},
{
"method": "POST",
"path": "/reset-password",
"handler": "authentication.resetPassword"
},
{
"method": "GET",
"path": "/webhooks",
"handler": "Webhooks.listWebhooks",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::webhooks.read"]]
]
}
},
{
"method": "POST",
"path": "/webhooks",
"handler": "Webhooks.createWebhook",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::webhooks.create"]]
]
}
},
{
"method": "GET",
"path": "/webhooks/:id",
"handler": "Webhooks.getWebhook",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::webhooks.read"]]
]
}
},
{
"method": "PUT",
"path": "/webhooks/:id",
"handler": "Webhooks.updateWebhook",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::webhooks.update"]]
]
}
},
{
"method": "DELETE",
"path": "/webhooks/:id",
"handler": "Webhooks.deleteWebhook",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::webhooks.delete"]]
]
}
},
{
"method": "POST",
"path": "/webhooks/batch-delete",
"handler": "Webhooks.deleteWebhooks",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::webhooks.delete"]]
]
}
},
{
"method": "POST",
"path": "/webhooks/:id/trigger",
"handler": "Webhooks.triggerWebhook",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/users/me",
"handler": "authenticated-user.getMe",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
},
{
"method": "PUT",
"path": "/users/me",
"handler": "authenticated-user.updateMe",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
},
{
"method": "GET",
"path": "/users/me/permissions",
"handler": "authenticated-user.getOwnPermissions",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
},
{
"method": "POST",
"path": "/users",
"handler": "user.create",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::users.create"]]
]
}
},
{
"method": "GET",
"path": "/users",
"handler": "user.find",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::users.read"]]
]
}
},
{
"method": "GET",
"path": "/users/:id",
"handler": "user.findOne",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::users.read"]]
]
}
},
{
"method": "PUT",
"path": "/users/:id",
"handler": "user.update",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::users.update"]]
]
}
},
{
"method": "DELETE",
"path": "/users/:id",
"handler": "user.deleteOne",
"config": {
"policies": [["admin::hasPermissions", ["admin::users.delete"]]]
}
},
{
"method": "POST",
"path": "/users/batch-delete",
"handler": "user.deleteMany",
"config": {
"policies": [["admin::hasPermissions", ["admin::users.delete"]]]
}
},
{
"method": "GET",
"path": "/roles/:id/permissions",
"handler": "role.getPermissions",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::roles.read"]]
]
}
},
{
"method": "PUT",
"path": "/roles/:id/permissions",
"handler": "role.updatePermissions",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::roles.update"]]
]
}
},
{
"method": "GET",
"path": "/roles/:id",
"handler": "role.findOne",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::roles.read"]]
]
}
},
{
"method": "GET",
"path": "/roles",
"handler": "role.findAll",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::roles.read"]]
]
}
},
{
"method": "PUT",
"path": "/roles/:id",
"handler": "role.update",
"config": {
"policies": [
"admin::isAuthenticatedAdmin",
["admin::hasPermissions", ["admin::roles.update"]]
]
}
},
{
"method": "GET",
"path": "/permissions",
"handler": "permission.getAll",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
},
{
"method": "POST",
"path": "/permissions/check",
"handler": "permission.check",
"config": {
"policies": ["admin::isAuthenticatedAdmin"]
}
}
]
}

View File

@ -5,7 +5,7 @@
*/
module.exports = {
collectionName: 'strapi_permissions',
collectionName: 'admin_permissions',
info: {
name: 'Permission',
description: '',
@ -52,7 +52,7 @@ module.exports = {
type: 'relation',
relation: 'manyToOne',
inversedBy: 'permissions',
target: 'strapi::role',
target: 'admin::role',
},
},
};

View File

@ -5,7 +5,7 @@
*/
module.exports = {
collectionName: 'strapi_roles',
collectionName: 'admin_roles',
info: {
name: 'Role',
description: '',
@ -46,14 +46,14 @@ module.exports = {
type: 'relation',
relation: 'manyToMany',
mappedBy: 'roles',
target: 'strapi::user',
target: 'admin::user',
},
permissions: {
configurable: false,
type: 'relation',
relation: 'oneToMany',
mappedBy: 'role',
target: 'strapi::permission',
target: 'admin::permission',
},
},
};

View File

@ -5,7 +5,7 @@
*/
module.exports = {
collectionName: 'strapi_users',
collectionName: 'admin_users',
info: {
name: 'User',
description: '',
@ -79,7 +79,7 @@ module.exports = {
type: 'relation',
relation: 'manyToMany',
inversedBy: 'users',
target: 'strapi::role',
target: 'admin::role',
// FIXME: Allow setting this
collectionName: 'strapi_users_roles',
},

View File

@ -1,7 +1,7 @@
'use strict';
module.exports = {
permission: require('./Permission'),
user: require('./User'),
role: require('./Role'),
permission: { schema: require('./Permission') },
user: { schema: require('./User') },
role: { schema: require('./Role') },
};

View File

@ -0,0 +1,10 @@
'use strict';
const { getService } = require('./utils');
module.exports = async () => {
const { conditionProvider, actionProvider } = getService('permission');
await conditionProvider.clear();
await actionProvider.clear();
};

View File

@ -1,18 +1,17 @@
'use strict';
const { getService } = require('./utils');
const bootstrap = require('./bootstrap');
const register = require('./register');
const destroy = require('./destroy');
module.exports = {
// TODO: update load middleware to not load the admin middleware from here
// TODO: load bootstrap / register independently
async destroy() {
const { conditionProvider, actionProvider } = getService('permission');
await conditionProvider.clear();
await actionProvider.clear();
},
register,
bootstrap,
destroy,
config: require('./config'),
routes: require('./routes'),
services: require('./services'),
controllers: require('./controllers'),
models: require('./content-types'),
contentTypes: require('./content-types'),
};

View File

@ -0,0 +1,292 @@
'use strict';
module.exports = [
{
method: 'GET',
path: '/plugins',
handler: 'admin.plugins',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::marketplace.read']],
],
},
},
{
method: 'GET',
path: '/init',
handler: 'admin.init',
},
{
method: 'GET',
path: '/project-type',
handler: 'admin.getProjectType',
},
{
method: 'GET',
path: '/information',
handler: 'admin.information',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
{
method: 'POST',
path: '/plugins/install',
handler: 'admin.installPlugin',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::marketplace.plugins.install']],
],
},
},
{
method: 'DELETE',
path: '/plugins/uninstall/:plugin',
handler: 'admin.uninstallPlugin',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::marketplace.plugins.uninstall']],
],
},
},
{
method: 'POST',
path: '/login',
handler: 'authentication.login',
},
{
method: 'POST',
path: '/renew-token',
handler: 'authentication.renewToken',
},
{
method: 'POST',
path: '/register-admin',
handler: 'authentication.registerAdmin',
},
{
method: 'GET',
path: '/registration-info',
handler: 'authentication.registrationInfo',
},
{
method: 'POST',
path: '/register',
handler: 'authentication.register',
},
{
method: 'POST',
path: '/forgot-password',
handler: 'authentication.forgotPassword',
},
{
method: 'POST',
path: '/reset-password',
handler: 'authentication.resetPassword',
},
{
method: 'GET',
path: '/webhooks',
handler: 'Webhooks.listWebhooks',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::webhooks.read']],
],
},
},
{
method: 'POST',
path: '/webhooks',
handler: 'Webhooks.createWebhook',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::webhooks.create']],
],
},
},
{
method: 'GET',
path: '/webhooks/:id',
handler: 'Webhooks.getWebhook',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::webhooks.read']],
],
},
},
{
method: 'PUT',
path: '/webhooks/:id',
handler: 'Webhooks.updateWebhook',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::webhooks.update']],
],
},
},
{
method: 'DELETE',
path: '/webhooks/:id',
handler: 'Webhooks.deleteWebhook',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::webhooks.delete']],
],
},
},
{
method: 'POST',
path: '/webhooks/batch-delete',
handler: 'Webhooks.deleteWebhooks',
config: {
policies: [
'admin::isAuthenticatedAdmin',
['admin::hasPermissions', ['admin::webhooks.delete']],
],
},
},
{
method: 'POST',
path: '/webhooks/:id/trigger',
handler: 'Webhooks.triggerWebhook',
config: {
policies: [],
},
},
{
method: 'GET',
path: '/users/me',
handler: 'authenticated-user.getMe',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
{
method: 'PUT',
path: '/users/me',
handler: 'authenticated-user.updateMe',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
{
method: 'GET',
path: '/users/me/permissions',
handler: 'authenticated-user.getOwnPermissions',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
{
method: 'POST',
path: '/users',
handler: 'user.create',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.create']]],
},
},
{
method: 'GET',
path: '/users',
handler: 'user.find',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.read']]],
},
},
{
method: 'GET',
path: '/users/:id',
handler: 'user.findOne',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.read']]],
},
},
{
method: 'PUT',
path: '/users/:id',
handler: 'user.update',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::users.update']]],
},
},
{
method: 'DELETE',
path: '/users/:id',
handler: 'user.deleteOne',
config: {
policies: [['admin::hasPermissions', ['admin::users.delete']]],
},
},
{
method: 'POST',
path: '/users/batch-delete',
handler: 'user.deleteMany',
config: {
policies: [['admin::hasPermissions', ['admin::users.delete']]],
},
},
{
method: 'GET',
path: '/roles/:id/permissions',
handler: 'role.getPermissions',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.read']]],
},
},
{
method: 'PUT',
path: '/roles/:id/permissions',
handler: 'role.updatePermissions',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.update']]],
},
},
{
method: 'GET',
path: '/roles/:id',
handler: 'role.findOne',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.read']]],
},
},
{
method: 'GET',
path: '/roles',
handler: 'role.findAll',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.read']]],
},
},
{
method: 'PUT',
path: '/roles/:id',
handler: 'role.update',
config: {
policies: ['admin::isAuthenticatedAdmin', ['admin::hasPermissions', ['admin::roles.update']]],
},
},
{
method: 'GET',
path: '/permissions',
handler: 'permission.getAll',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
{
method: 'POST',
path: '/permissions/check',
handler: 'permission.check',
config: {
policies: ['admin::isAuthenticatedAdmin'],
},
},
];

View File

@ -27,7 +27,7 @@ const validatePassword = (password, hash) => bcrypt.compare(password, hash);
* @param {string} options.password
*/
const checkCredentials = async ({ email, password }) => {
const user = await strapi.query('strapi::user').findOne({ where: { email } });
const user = await strapi.query('admin::user').findOne({ where: { email } });
if (!user || !user.password) {
return [null, false, { message: 'Invalid credentials' }];
@ -52,7 +52,7 @@ const checkCredentials = async ({ email, password }) => {
* @param {string} param.email user email for which to reset the password
*/
const forgotPassword = async ({ email } = {}) => {
const user = await strapi.query('strapi::user').findOne({ where: { email, isActive: true } });
const user = await strapi.query('admin::user').findOne({ where: { email, isActive: true } });
if (!user) {
return;
@ -94,7 +94,7 @@ const forgotPassword = async ({ email } = {}) => {
*/
const resetPassword = async ({ resetPasswordToken, password } = {}) => {
const matchingUser = await strapi
.query('strapi::user')
.query('admin::user')
.findOne({ where: { resetPasswordToken, isActive: true } });
if (!matchingUser) {

View File

@ -26,7 +26,7 @@ const permissionDomain = require('../../domain/permission/index');
* @returns {Promise<array>}
*/
const deleteByRolesIds = async rolesIds => {
const permissionsToDelete = await strapi.query('strapi::permission').findMany({
const permissionsToDelete = await strapi.query('admin::permission').findMany({
select: ['id'],
where: {
role: { id: rolesIds },
@ -45,7 +45,7 @@ const deleteByRolesIds = async rolesIds => {
*/
const deleteByIds = async ids => {
for (const id of ids) {
await strapi.query('strapi::permission').delete({ where: { id } });
await strapi.query('admin::permission').delete({ where: { id } });
}
};
@ -57,7 +57,7 @@ const deleteByIds = async ids => {
const createMany = async permissions => {
const createdPermissions = [];
for (const permission of permissions) {
const newPerm = await strapi.query('strapi::permission').create({ data: permission });
const newPerm = await strapi.query('admin::permission').create({ data: permission });
createdPermissions.push(newPerm);
}
@ -72,7 +72,7 @@ const createMany = async permissions => {
*/
const update = async (params, attributes) => {
const updatedPermission = await strapi
.query('strapi::permission')
.query('admin::permission')
.update({ where: params, data: attributes });
return permissionDomain.toPermission(updatedPermission);
@ -84,7 +84,7 @@ const update = async (params, attributes) => {
* @returns {Promise<Permission[]>}
*/
const findMany = async (params = {}) => {
const rawPermissions = await strapi.query('strapi::permission').findMany(params);
const rawPermissions = await strapi.query('admin::permission').findMany(params);
return permissionDomain.toPermission(rawPermissions);
};
@ -141,13 +141,13 @@ const cleanPermissionsInDatabase = async () => {
const contentTypeService = getService('content-type');
const total = await strapi.query('strapi::permission').count();
const total = await strapi.query('admin::permission').count();
const pageCount = Math.ceil(total / pageSize);
for (let page = 0; page < pageCount; page++) {
// 1. Find invalid permissions and collect their ID to delete them later
const results = await strapi
.query('strapi::permission')
.query('admin::permission')
.findMany({ limit: pageSize, offset: page * pageSize });
const permissions = permissionDomain.toPermission(results);
@ -193,7 +193,7 @@ const ensureBoundPermissionsInDatabase = async () => {
}
const contentTypes = Object.values(strapi.contentTypes);
const editorRole = await strapi.query('strapi::role').findOne({
const editorRole = await strapi.query('admin::role').findOne({
where: { code: EDITOR_CODE },
});

View File

@ -57,7 +57,7 @@ const create = async attributes => {
code: attributes.code || autoGeneratedCode,
};
return strapi.query('strapi::role').create({ data: rolesWithCode });
return strapi.query('admin::role').create({ data: rolesWithCode });
};
/**
@ -67,7 +67,7 @@ const create = async attributes => {
* @returns {Promise<role>}
*/
const findOne = (params = {}, populate) => {
return strapi.query('strapi::role').findOne({ where: params, populate });
return strapi.query('admin::role').findOne({ where: params, populate });
};
/**
@ -77,7 +77,7 @@ const findOne = (params = {}, populate) => {
* @returns {Promise<role>}
*/
const findOneWithUsersCount = async (params = {}, populate) => {
const role = await strapi.query('strapi::role').findOne({ where: params, populate });
const role = await strapi.query('admin::role').findOne({ where: params, populate });
if (role) {
role.usersCount = await getUsersCount(role.id);
@ -93,7 +93,7 @@ const findOneWithUsersCount = async (params = {}, populate) => {
* @returns {Promise<array>}
*/
const find = (params = {}, populate) => {
return strapi.query('strapi::role').findMany({ where: params, populate });
return strapi.query('admin::role').findMany({ where: params, populate });
};
/**
@ -101,7 +101,7 @@ const find = (params = {}, populate) => {
* @returns {Promise<array>}
*/
const findAllWithUsersCount = async populate => {
const roles = await strapi.query('strapi::role').findMany({ populate });
const roles = await strapi.query('admin::role').findMany({ populate });
for (let role of roles) {
role.usersCount = await getUsersCount(role.id);
}
@ -132,7 +132,7 @@ const update = async (params, attributes) => {
}
}
return strapi.query('strapi::role').update({ where: params, data: sanitizedAttributes });
return strapi.query('admin::role').update({ where: params, data: sanitizedAttributes });
};
/**
@ -141,7 +141,7 @@ const update = async (params, attributes) => {
* @returns {Promise<boolean>}
*/
const exists = async (params = {}) => {
const count = await strapi.query('strapi::role').count({ where: params });
const count = await strapi.query('admin::role').count({ where: params });
return count > 0;
};
@ -151,7 +151,7 @@ const exists = async (params = {}) => {
* @returns {Promise<number>}
*/
const count = async (params = {}) => {
return strapi.query('strapi::role').count(params);
return strapi.query('admin::role').count(params);
};
/**
@ -186,7 +186,7 @@ const deleteByIds = async (ids = []) => {
const deletedRoles = [];
for (const id of ids) {
const deletedRole = await strapi.query('strapi::role').delete({ where: { id } });
const deletedRole = await strapi.query('admin::role').delete({ where: { id } });
if (deletedRole) {
deletedRoles.push(deletedRole);
@ -201,7 +201,7 @@ const deleteByIds = async (ids = []) => {
* @param roleId
*/
const getUsersCount = async roleId => {
return strapi.query('strapi::user').count({ where: { roles: { id: roleId } } });
return strapi.query('admin::user').count({ where: { roles: { id: roleId } } });
};
/** Returns admin role

View File

@ -37,9 +37,7 @@ const create = async attributes => {
const user = createUser(userInfo);
const createdUser = await strapi
.query('strapi::user')
.create({ data: user, populate: ['roles'] });
const createdUser = await strapi.query('admin::user').create({ data: user, populate: ['roles'] });
getService('metrics').sendDidInviteUser();
@ -82,7 +80,7 @@ const updateById = async (id, attributes) => {
if (_.has(attributes, 'password')) {
const hashedPassword = await getService('auth').hashPassword(attributes.password);
return strapi.query('strapi::user').update({
return strapi.query('admin::user').update({
where: { id },
data: {
...attributes,
@ -92,7 +90,7 @@ const updateById = async (id, attributes) => {
});
}
return strapi.query('strapi::user').update({
return strapi.query('admin::user').update({
where: { id },
data: attributes,
populate: ['roles'],
@ -139,7 +137,7 @@ const isLastSuperAdminUser = async userId => {
* @returns {Promise<boolean>}
*/
const exists = async (attributes = {}) => {
return (await strapi.query('strapi::user').count({ where: attributes })) > 0;
return (await strapi.query('admin::user').count({ where: attributes })) > 0;
};
/**
@ -148,7 +146,7 @@ const exists = async (attributes = {}) => {
* @returns {Promise<registrationInfo>} - Returns user email, firstname and lastname
*/
const findRegistrationInfo = async registrationToken => {
const user = await strapi.query('strapi::user').findOne({ where: { registrationToken } });
const user = await strapi.query('admin::user').findOne({ where: { registrationToken } });
if (!user) {
return undefined;
@ -164,7 +162,7 @@ const findRegistrationInfo = async registrationToken => {
* @param {Object} params.userInfo user info
*/
const register = async ({ registrationToken, userInfo }) => {
const matchingUser = await strapi.query('strapi::user').findOne({ where: { registrationToken } });
const matchingUser = await strapi.query('admin::user').findOne({ where: { registrationToken } });
if (!matchingUser) {
throw strapi.errors.badRequest('Invalid registration info');
@ -183,7 +181,7 @@ const register = async ({ registrationToken, userInfo }) => {
* Find one user
*/
const findOne = async (where = {}, populate = ['roles']) => {
return strapi.query('strapi::user').findOne({ where, populate });
return strapi.query('admin::user').findOne({ where, populate });
};
/** Find many users (paginated)
@ -193,7 +191,7 @@ const findOne = async (where = {}, populate = ['roles']) => {
const findPage = async (query = {}) => {
const { page = 1, pageSize = 100, populate = ['roles'] } = query;
return strapi.query('strapi::user').findPage({
return strapi.query('admin::user').findPage({
where: query.filters,
_q: query._q,
populate,
@ -208,7 +206,7 @@ const findPage = async (query = {}) => {
*/
const deleteById = async id => {
// Check at least one super admin remains
const userToDelete = await strapi.query('strapi::user').findOne({
const userToDelete = await strapi.query('admin::user').findOne({
where: { id },
populate: ['roles'],
});
@ -229,7 +227,7 @@ const deleteById = async id => {
}
}
return strapi.query('strapi::user').delete({ where: { id }, populate: ['roles'] });
return strapi.query('admin::user').delete({ where: { id }, populate: ['roles'] });
};
/** Delete a user
@ -239,7 +237,7 @@ const deleteById = async id => {
const deleteByIds = async ids => {
// Check at least one super admin remains
const superAdminRole = await getService('role').getSuperAdminWithUsersCount();
const nbOfSuperAdminToDelete = await strapi.query('strapi::user').count({
const nbOfSuperAdminToDelete = await strapi.query('admin::user').count({
where: {
id: ids,
roles: { id: superAdminRole.id },
@ -255,7 +253,7 @@ const deleteByIds = async ids => {
const deletedUsers = [];
for (const id of ids) {
const deletedUser = await strapi.query('strapi::user').delete({
const deletedUser = await strapi.query('admin::user').delete({
where: { id },
populate: ['roles'],
});
@ -270,7 +268,7 @@ const deleteByIds = async ids => {
* @returns {Promise<number>}
*/
const countUsersWithoutRole = async () => {
return strapi.query('strapi::user').count({
return strapi.query('admin::user').count({
where: {
roles: {
id: { $null: true },
@ -285,14 +283,14 @@ const countUsersWithoutRole = async () => {
* @returns {Promise<number>}
*/
const count = async (where = {}) => {
return strapi.query('strapi::user').count({ where });
return strapi.query('admin::user').count({ where });
};
/** Assign some roles to several users
* @returns {undefined}
*/
const assignARoleToAll = async roleId => {
const users = await strapi.query('strapi::user').findMany({
const users = await strapi.query('admin::user').findMany({
select: ['id'],
where: {
roles: { id: { $null: true } },
@ -301,7 +299,7 @@ const assignARoleToAll = async roleId => {
await Promise.all(
users.map(user => {
return strapi.query('strapi::user').update({
return strapi.query('admin::user').update({
where: { id: user.id },
data: { roles: [roleId] },
});

View File

@ -28,7 +28,7 @@ const findCreatorRoles = entity => {
if (has(createdByPath, entity)) {
const creatorId = prop(createdByPath, entity);
return strapi.query('strapi::role').findMany({ where: { users: { id: creatorId } } });
return strapi.query('admin::role').findMany({ where: { users: { id: creatorId } } });
}
return [];

View File

@ -36,7 +36,7 @@ const VALID_UID_TARGETS = ['string', 'text'];
const FORBIDDEN_ATTRIBUTE_NAMES = ['__component', '__contentType'];
const PREFIX = 'strapi::';
const STRAPI_USER = 'strapi::user';
const STRAPI_USER = 'admin::user';
const UPLOAD_FILE = 'plugin::upload.file';
module.exports = {

View File

@ -14,7 +14,7 @@ const loadModules = require('./core/loaders/load-modules');
const utils = require('./utils');
const bootstrap = require('./core/loaders/bootstrap');
const initializeMiddlewares = require('./middlewares');
const createStrapiFs = require('./core/fs');
const createStrapiFs = require('./services/fs');
const createEventHub = require('./services/event-hub');
const createWebhookRunner = require('./services/webhook-runner');
const { webhookModel, createWebhookStore } = require('./services/webhook-store');
@ -34,7 +34,6 @@ const modulesRegistry = require('./core/registries/modules');
const pluginsRegistry = require('./core/registries/plugins');
const createConfigProvider = require('./core/registries/config');
const loadPlugins = require('./core/load-plugins');
// const { nameToSlug } = require('../../utils/lib');
const LIFECYCLES = {
REGISTER: 'register',
@ -60,7 +59,6 @@ class Strapi {
this.app = new Koa();
this.router = new Router();
this.server = createHTTPServer(this, this.app);
this.contentTypes = {}; // to remove V3
this.fs = createStrapiFs(this);
this.eventHub = createEventHub();
this.startupLogger = createStartupLogger(this);
@ -82,6 +80,18 @@ class Strapi {
return this.container.get('services').get(uid);
}
controller(uid) {
return this.container.get('controllers').get(uid);
}
contentType(name) {
return this.container.get('content-types').get(name);
}
get contentTypes() {
return this.container.get('content-types').getAll();
}
plugin(name) {
return this.container.get('plugins').get(name);
}
@ -219,6 +229,8 @@ class Strapi {
loadAdmin() {
this.admin = require('@strapi/admin/strapi-server');
strapi.container.get('content-types').add(`admin::`, strapi.admin.contentTypes);
// TODO: rename into just admin and ./config/admin.js
const userAdminConfig = strapi.config.get('server.admin');
this.config.set('server.admin', _.merge(this.admin.config, userAdminConfig));
@ -252,7 +264,6 @@ class Strapi {
this.components = modules.components;
this.middleware = modules.middlewares;
this.hook = modules.hook;
await bootstrap(this);
@ -371,12 +382,7 @@ class Strapi {
await execLifecycle(this.config.get(configPath));
// admin
const adminFunc = _.get(this.admin.config, configPath);
return execLifecycle(adminFunc).catch(err => {
strapi.log.error(`${lifecycleName} function in admin failed`);
console.error(err);
strapi.stop();
});
await this.admin[lifecycleName]();
}
getModel(uid) {

View File

@ -16,17 +16,8 @@ const loadConfigDir = require('./config-loader');
const { version: strapiVersion } = require(path.join(__dirname, '../../../package.json'));
const CONFIG_PATHS = {
admin: 'admin',
api: 'api',
config: 'config',
controllers: 'controllers',
models: 'models',
plugins: 'plugins',
policies: 'policies',
tmp: '.tmp',
services: 'services',
static: 'public',
validators: 'validators',
views: 'views',
};
@ -48,15 +39,6 @@ const defaultConfig = {
},
settings: {},
},
hook: {
timeout: 1000,
load: {
before: ['responseTime', 'logger', 'cors', 'responses', 'gzip'],
order: [],
after: ['parser', 'router'],
},
settings: {},
},
};
module.exports = (dir, initialConfig = {}) => {
@ -80,7 +62,6 @@ module.exports = (dir, initialConfig = {}) => {
strapi: strapiVersion,
},
installedMiddlewares: getPrefixedDeps('@strapi/middleware', pkgJSON),
installedHooks: getPrefixedDeps('@strapi/hook', pkgJSON),
};
const baseConfig = omit('plugins', loadConfigDir(configDir)); // plugin config will be loaded later

View File

@ -19,11 +19,11 @@ const createContentType = (uid, definition) => {
throw new Error(`Content Type Definition is invalid for ${uid}'.\n${e.errors}`);
}
const createdContentType = cloneDeep(definition);
const { schema, actions, lifecycles } = cloneDeep(definition);
// general info
Object.assign(createdContentType.schema, {
kind: createdContentType.schema.kind || 'collectionType',
Object.assign(schema, {
kind: schema.kind || 'collectionType',
__schema__: pickSchema(definition.schema),
modelType: 'contentType',
modelName: definition.schema.info.singularName,
@ -31,27 +31,26 @@ const createContentType = (uid, definition) => {
});
if (uid.startsWith('api::')) {
Object.assign(createdContentType.schema, {
Object.assign(schema, {
uid,
apiName: uid.split('::')[1].split('.')[0],
collectionName: definition.schema.collectionName || definition.schema.info.singularName,
globalId: getGlobalId(definition.schema, definition.schema.info.singularName),
collectionName: schema.collectionName || schema.info.singularName,
globalId: getGlobalId(schema, schema.info.singularName),
});
} else if (uid.startsWith('plugin::')) {
const pluginName = uid.split('::')[1].split('.')[0];
Object.assign(createdContentType.schema, {
Object.assign(schema, {
uid,
plugin: pluginName, // TODO: to be set in load-plugins.js
collectionName:
createdContentType.schema.collectionName ||
`${pluginName}_${definition.schema.info.singularName}`.toLowerCase(),
globalId: getGlobalId(definition.schema, definition.schema.info.singularName, pluginName),
schema.collectionName || `${pluginName}_${schema.info.singularName}`.toLowerCase(),
globalId: getGlobalId(schema, schema.info.singularName, pluginName),
});
} else if (uid.startsWith('strapi::')) {
Object.assign(createdContentType.schema, {
} else if (uid.startsWith('admin::')) {
Object.assign(schema, {
uid,
plugin: 'admin',
globalId: getGlobalId(definition.schema, definition.schema.info.singularName, 'admin'),
globalId: getGlobalId(schema, schema.info.singularName, 'admin'),
});
} else {
throw new Error(
@ -59,7 +58,7 @@ const createContentType = (uid, definition) => {
);
}
Object.defineProperty(createdContentType.schema, 'privateAttributes', {
Object.defineProperty(schema, 'privateAttributes', {
get() {
// FIXME: to fix
// return strapi.getModel(model.uid).privateAttributes;
@ -68,7 +67,7 @@ const createContentType = (uid, definition) => {
});
// attributes
Object.assign(createdContentType.schema.attributes, {
Object.assign(schema.attributes, {
[CREATED_AT_ATTRIBUTE]: {
type: 'datetime',
default: () => new Date(),
@ -80,8 +79,8 @@ const createContentType = (uid, definition) => {
},
});
if (hasDraftAndPublish(createdContentType.schema)) {
createdContentType.schema.attributes[PUBLISHED_AT_ATTRIBUTE] = {
if (hasDraftAndPublish(schema)) {
schema.attributes[PUBLISHED_AT_ATTRIBUTE] = {
type: 'datetime',
configurable: false,
writable: true,
@ -89,12 +88,12 @@ const createContentType = (uid, definition) => {
};
}
const isPrivate = !_.get(createdContentType.schema, 'options.populateCreatorFields', false);
const isPrivate = !_.get(schema, 'options.populateCreatorFields', false);
createdContentType.schema.attributes[CREATED_BY_ATTRIBUTE] = {
schema.attributes[CREATED_BY_ATTRIBUTE] = {
type: 'relation',
relation: 'oneToOne',
target: 'strapi::user',
target: 'admin::user',
configurable: false,
writable: false,
visible: false,
@ -102,10 +101,10 @@ const createContentType = (uid, definition) => {
private: isPrivate,
};
createdContentType.schema.attributes[UPDATED_BY_ATTRIBUTE] = {
schema.attributes[UPDATED_BY_ATTRIBUTE] = {
type: 'relation',
relation: 'oneToOne',
target: 'strapi::user',
target: 'admin::user',
configurable: false,
writable: false,
visible: false,
@ -113,7 +112,11 @@ const createContentType = (uid, definition) => {
private: isPrivate,
};
return createdContentType;
return {
...schema,
actions: actions,
lifecycles: lifecycles,
};
};
const getGlobalId = (model, modelName, prefix) => {

View File

@ -3,9 +3,28 @@
const { keyBy, mapValues } = require('lodash');
const { yup } = require('@strapi/utils');
// To replace by directly using implemented lifecycles
const lifecycles = ['beforeCreate', 'afterCreate'];
const lifecyclesShape = mapValues(keyBy(lifecycles), () =>
const LIFECYCLES = [
'beforeCreate',
'afterCreate',
'beforeFindOne',
'afterFindOne',
'beforeFindMany',
'afterFindMany',
'beforeCount',
'afterCount',
'beforeCreateMany',
'afterCreateMany',
'beforeUpdate',
'afterUpdate',
'beforeUpdateMany',
'afterUpdateMany',
'beforeDelete',
'afterDelete',
'beforeDeleteMany',
'afterDeleteMany',
];
const lifecyclesShape = mapValues(keyBy(LIFECYCLES), () =>
yup
.mixed()
.nullable()

View File

@ -33,7 +33,7 @@ const createModule = (namespace, rawModule, strapi) => {
await rawModule.destroy(strapi);
},
load() {
strapi.container.get('content-types').add(namespace, rawModule.contentTypes);
strapi.container.get('content-types').add(namespace + '.', rawModule.contentTypes);
strapi.container.get('services').add(namespace, rawModule.services);
strapi.container.get('policies').add(namespace, rawModule.policies);
strapi.container.get('middlewares').add(namespace, rawModule.middlewares);

View File

@ -4,7 +4,6 @@ const _ = require('lodash');
const { toLower, kebabCase } = require('lodash/fp');
const { getConfigUrls } = require('@strapi/utils');
const pluralize = require('pluralize');
const { createContentType } = require('../domain/content-type');
const { createCoreApi } = require('../../core-api');
@ -30,55 +29,26 @@ const validateContentTypesUnicity = schemas => {
};
module.exports = function(strapi) {
strapi.contentTypes = {};
// validate Content-Types unicity
const allApisSchemas = Object.values(strapi.api).flatMap(api => Object.values(api.models));
validateContentTypesUnicity(allApisSchemas);
// TODO: to change with new loading system
// Register api content types
for (const apiName in strapi.api) {
const api = strapi.api[apiName];
const v4ContentTypes = _.mapValues(api.models, (model, modelName) => {
model.info.displayName = model.info.displayName || model.info.name;
model.info.singularName = model.info.singularName || modelName;
model.info.pluralName = model.info.pluralName || pluralize(modelName);
return {
schema: model,
actions: {},
lifecycles: {},
};
});
strapi.container.get('content-types').add(`api::${apiName}`, v4ContentTypes);
}
// TODO: remove v3
// Set models.
strapi.models = {};
for (const apiName in strapi.api) {
const api = strapi.api[apiName];
for (let modelName in api.models) {
let model = api.models[modelName];
const contentType = strapi.container
.get('content-types')
.get(`api::${apiName}.${model.info.singularName}`);
Object.assign(model, contentType.schema);
strapi.contentTypes[model.uid] = contentType.schema;
strapi.models[modelName] = model;
}
}
// set default services and default controllers
for (const apiName in strapi.api) {
const api = strapi.api[apiName];
for (const modelName in api.models) {
const model = api.models[modelName];
const { service, controller } = createCoreApi({ model, api, strapi });
model.info.displayName = model.info.displayName || model.info.name;
model.info.singularName = model.info.singularName || modelName;
model.info.pluralName = model.info.pluralName || pluralize(modelName);
strapi.container.get('content-types').add(`api::${apiName}.`, {
[modelName]: { schema: model, actions: model.actions, lifecycles: model.lifecycles },
});
const contentType = strapi.contentType(`api::${apiName}.${modelName}`);
const { service, controller } = createCoreApi({ model: contentType, api, strapi });
_.set(strapi.api[apiName], ['services', modelName], service);
_.set(strapi.api[apiName], ['controllers', modelName], controller);
}
@ -95,42 +65,13 @@ module.exports = function(strapi) {
return acc;
}, {});
// Set user's services.
strapi.services = Object.keys(strapi.api || []).reduce((acc, apiName) => {
strapi.container.get('services').add(`api::${apiName}`, strapi.api[apiName].services);
for (let serviceName in strapi.api[apiName].services) {
acc[serviceName] = strapi.api[apiName].services[serviceName];
}
return acc;
}, {});
// Set routes.
strapi.config.routes = Object.keys(strapi.api || []).reduce((acc, key) => {
return acc.concat(_.get(strapi.api[key], 'config.routes') || {});
}, []);
// Init admin models.
Object.keys(strapi.admin.models || []).forEach(modelName => {
let model = strapi.admin.models[modelName];
// mutate model
const ct = { schema: model, actions: {}, lifecycles: {} };
ct.schema.info.displayName = model.info.name;
ct.schema.info.singularName = modelName;
ct.schema.info.pluralName = pluralize(modelName);
const createdContentType = createContentType(`strapi::${ct.schema.info.singularName}`, ct);
Object.assign(model, createdContentType.schema);
strapi.contentTypes[model.uid] = model;
});
// TODO: delete v3 code
_.forEach(strapi.plugins, plugin => {
_.forEach(plugin.contentTypes, (ct, ctUID) => {
strapi.contentTypes[ctUID] = ct.schema;
});
_.forEach(plugin.middlewares, (middleware, middlewareUID) => {
const middlewareName = toLower(middlewareUID.split('.')[1]);
strapi.middleware[middlewareName] = middleware;

View File

@ -1,21 +0,0 @@
'use strict';
const fse = require('fs-extra');
const walk = require('./walk');
const loadFunctions = dir => {
if (!fse.existsSync(dir)) return {};
return walk(dir, { loader: loadFunction });
};
const loadFunction = file => {
try {
return require(file);
} catch (error) {
throw `Could not load function ${file}: ${error.message}`;
}
};
module.exports = loadFunctions;

View File

@ -1,36 +0,0 @@
'use strict';
const assert = require('assert');
const path = require('path');
const _ = require('lodash');
const fse = require('fs-extra');
module.exports = dir => {
if (!fse.existsSync(dir)) return {};
const root = {};
const paths = fse.readdirSync(dir, { withFileTypes: true }).filter(fd => fd.isFile());
for (let fd of paths) {
const { name } = fd;
const fullPath = dir + path.sep + name;
const ext = path.extname(name);
const key = path.basename(name, ext);
root[_.toLower(key)] = loadPolicy(fullPath);
}
return root;
};
const loadPolicy = file => {
try {
const policy = require(file);
assert(typeof policy === 'function', 'Policy must be a function.');
return policy;
} catch (error) {
throw `Could not load policy ${file}: ${error.message}`;
}
};

View File

@ -1,27 +0,0 @@
'use strict';
const assert = require('assert');
const path = require('path');
const fse = require('fs-extra');
module.exports = function walk(dir, { loader } = {}) {
assert(typeof loader === 'function', 'opts.loader must be a function');
const root = {};
const paths = fse.readdirSync(dir, { withFileTypes: true });
for (let fd of paths) {
const { name } = fd;
const fullPath = dir + path.sep + name;
if (fd.isDirectory()) {
root[name] = walk(fullPath, { loader });
} else {
const ext = path.extname(name);
const key = path.basename(name, ext);
root[key] = loader(fullPath);
}
}
return root;
};

View File

@ -22,17 +22,23 @@ const contentTypesRegistry = () => {
return contentTypes[ctUID];
},
getAll(prefix = '') {
if (!prefix) {
return contentTypes;
}
return pickBy((ct, ctUID) => ctUID.startsWith(prefix))(contentTypes);
},
add(namespace, rawContentTypes) {
validateKeySameToSingularName(rawContentTypes);
for (const rawCtName in rawContentTypes) {
const rawContentType = rawContentTypes[rawCtName];
const uid = `${namespace}.${rawContentType.schema.info.singularName}`;
const uid = `${namespace}${rawCtName}`;
if (has(uid, contentTypes)) {
throw new Error(`Content-type ${uid} has already been registered.`);
}
contentTypes[uid] = createContentType(uid, rawContentType);
contentTypes[uid] = createContentType(uid, rawContentTypes[rawCtName]);
}
},
};

View File

@ -8,13 +8,20 @@
const _ = require('lodash');
const Router = require('koa-router');
const createEndpointComposer = require('./utils/composeEndpoint');
/**
* Router hook
*/
module.exports = strapi => {
const composeEndpoint = createEndpointComposer(strapi);
const registerAdminRoutes = strapi => {
const router = new Router({ prefix: '/admin' });
strapi.admin.routes.forEach(route => {
composeEndpoint(route, { plugin: 'admin', router });
});
strapi.app.use(router.routes()).use(router.allowedMethods());
};
return {
initialize() {
_.forEach(strapi.config.routes, value => {
@ -23,16 +30,7 @@ module.exports = strapi => {
strapi.router.prefix(strapi.config.get('middleware.settings.router.prefix', ''));
if (_.has(strapi.admin, 'config.routes')) {
const router = new Router({ prefix: '/admin' });
_.get(strapi.admin, 'config.routes', []).forEach(route => {
composeEndpoint(route, { plugin: 'admin', router });
});
// Mount admin router on Strapi router
strapi.app.use(router.routes()).use(router.allowedMethods());
}
registerAdminRoutes(strapi);
if (strapi.plugins) {
// Parse each plugin's routes.

View File

@ -14,7 +14,7 @@ module.exports = async function isInitialized(strapi) {
}
// test if there is at least one admin
const anyAdministrator = await strapi.query('strapi::user').findOne({ select: ['id'] });
const anyAdministrator = await strapi.query('admin::user').findOne({ select: ['id'] });
return !isNil(anyAdministrator);
} catch (err) {

View File

@ -37,7 +37,7 @@
"cross-spawn": "^7.0.3",
"debug": "^4.1.1",
"delegates": "^1.0.0",
"dotenv": "8.2.0",
"dotenv": "10.0.0",
"execa": "^1.0.0",
"fs-extra": "^9.1.0",
"glob": "^7.1.2",

View File

@ -93,7 +93,7 @@ describe('Sanitize Entity', () => {
},
};
const models = {
const contentTypes = {
user: userModel,
article: articleModel,
userRel: userRelModel,
@ -103,7 +103,7 @@ describe('Sanitize Entity', () => {
beforeEach(() => {
global.strapi = {
getModel(name) {
return models[name];
return contentTypes[name];
},
config: {
get: jest.fn,
@ -156,7 +156,7 @@ describe('Sanitize Entity', () => {
];
test.each(tests)(`Test n°%#`, (options, expected) => {
const { user: model } = models;
const { user: model } = contentTypes;
expect(sanitizeEntity(input, { ...options, model })).toStrictEqual(expected);
});
});
@ -198,12 +198,12 @@ describe('Sanitize Entity', () => {
];
const model = {
...models.user,
...contentTypes.user,
options: {
...models.user.options,
...contentTypes.user.options,
privateAttributes: ['firstname'],
},
privateAttributes: [].concat(models.user.privateAttributes, ['firstname'], ['id']),
privateAttributes: [].concat(contentTypes.user.privateAttributes, ['firstname'], ['id']),
};
test.each(tests)(`Test n°%#`, (options, expected) => {
@ -256,14 +256,14 @@ describe('Sanitize Entity', () => {
];
test.each(tests)(`Test n°%#`, (source, options, expected) => {
const { userRel: model } = models;
const { userRel: model } = contentTypes;
expect(sanitizeEntity(source, { ...options, model })).toStrictEqual(expected);
});
});
describe('With Dynamic Zone', () => {
test('Dynamic zone null', () => {
const { userDz: model } = models;
const { userDz: model } = contentTypes;
const dataSource = { ...inputWithDz, dz: null };
const expected = _.pick(dataSource, ['id', 'firstname', 'lastname', 'dz']);
@ -272,7 +272,7 @@ describe('Sanitize Entity', () => {
});
test('Dynamic zone with a basic component', () => {
const { userDz: model } = models;
const { userDz: model } = contentTypes;
const expected = {
..._.pick(inputWithDz, ['id', 'firstname', 'lastname']),
@ -295,7 +295,7 @@ describe('Sanitize Entity', () => {
});
test(`It returns the input data as-is if it's not an object or an array`, () => {
const { user: model } = models;
const { user: model } = contentTypes;
expect(sanitizeEntity('foobar', { model })).toBe('foobar');
expect(sanitizeEntity(undefined, { model })).toBeUndefined();
expect(sanitizeEntity(null, { model })).toBeNull();
@ -309,7 +309,7 @@ describe('Sanitize Entity', () => {
_.pick(input, 'id', 'firstname', 'lastname'),
];
const { user: model } = models;
const { user: model } = contentTypes;
expect(sanitizeEntity(dataSource, { model })).toStrictEqual(expected);
});
@ -318,7 +318,7 @@ describe('Sanitize Entity', () => {
const dataSource = { ...inputWithRelation, article: null };
const expected = _.omit(dataSource, ['email', 'password']);
const { userRel: model } = models;
const { userRel: model } = contentTypes;
expect(sanitizeEntity(dataSource, { model })).toStrictEqual(expected);
});
@ -332,7 +332,7 @@ describe('Sanitize Entity', () => {
toJSON: jest.fn(() => null),
};
const { user: model } = models;
const { user: model } = contentTypes;
expect(sanitizeEntity(dataSource, { model })).toStrictEqual(
_.omit(input, ['email', 'password'])
@ -346,7 +346,7 @@ describe('Sanitize Entity', () => {
test('It should handle custom fields', () => {
const dataSource = { ...input, foo: 'bar' };
const expected = _.omit(dataSource, ['email', 'password']);
const { user: model } = models;
const { user: model } = contentTypes;
expect(sanitizeEntity(dataSource, { model })).toStrictEqual(expected);
});

View File

@ -34,13 +34,10 @@ module.exports = async () => {
if (!strapi.config.get('plugin.users-permissions.jwtSecret')) {
const jwtSecret = uuid();
strapi.config.set('plugin.users-permissions.jwtSecret', jwtSecret);
strapi.reload.isWatching = false;
if (!process.env.JWT_SECRET) {
await strapi.fs.appendFile('.env', `JWT_SECRET=${jwtSecret}\n`);
strapi.fs.appendFile('.env', `JWT_SECRET=${jwtSecret}\n`);
}
strapi.reload.isWatching = true;
}
};

View File

@ -29,7 +29,7 @@ const findEntityAndCheckPermissions = async (ability, action, model, id) => {
const pm = strapi.admin.services.permission.createPermissionsManager({ ability, action, model });
const roles = _.has(entity, `${CREATED_BY_ATTRIBUTE}.id`)
? await strapi.query('strapi::role').findMany({
? await strapi.query('admin::role').findMany({
where: {
users: { id: entity[CREATED_BY_ATTRIBUTE].id },
},

View File

@ -10,7 +10,7 @@ module.exports = {
},
initialize() {
_.forEach(strapi.admin.config.routes, value => {
_.forEach(strapi.admin.routes, value => {
if (_.get(value.config, 'policies')) {
value.config.policies.unshift('plugin::users-permissions.permissions');
}

View File

@ -8112,10 +8112,10 @@ dot-prop@^5.1.0, dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"
dotenv@8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
dotenv@10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
dotenv@8.5.1:
version "8.5.1"