mirror of
https://github.com/strapi/strapi.git
synced 2025-08-31 04:03:50 +00:00
Merge pull request #10752 from strapi/v4/plugin-api/extensions
V4/plugin api/extensions
This commit is contained in:
commit
65a89df6f2
@ -2,9 +2,6 @@
|
||||
"kind": "collectionType",
|
||||
"collectionName": "countries",
|
||||
"info": {
|
||||
"displayName": "country",
|
||||
"singularName": "country",
|
||||
"pluralName": "countries",
|
||||
"name": "country",
|
||||
"description": ""
|
||||
},
|
||||
|
@ -5,9 +5,12 @@ const path = require('path');
|
||||
module.exports = ({ env }) => ({
|
||||
graphql: {
|
||||
enabled: true,
|
||||
config: require('./plugins/graphql')({ env }),
|
||||
},
|
||||
i18n: {
|
||||
config: require('./plugins/i18n')({ env }),
|
||||
config: {
|
||||
amountLimit: 50,
|
||||
depthLimit: 10,
|
||||
apolloServer: {
|
||||
tracing: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,7 +0,0 @@
|
||||
module.exports = ({ env }) => ({
|
||||
amountLimit: 50,
|
||||
depthLimit: 10,
|
||||
apolloServer: {
|
||||
tracing: true,
|
||||
},
|
||||
});
|
@ -1 +0,0 @@
|
||||
module.exports = ({ env }) => ({});
|
@ -1,8 +0,0 @@
|
||||
module.exports = {
|
||||
// provider: 'cloudinary',
|
||||
// providerOptions: {
|
||||
// cloud_name: 'cloud-name',
|
||||
// api_key: 'api-key',
|
||||
// api_secret: 'api-secret',
|
||||
// },
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
jwtSecret: process.env.JWT_SECRET || 'c4dc6f71-db45-49c6-82d0-9ca91cb93fa2',
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = (ctx, next) => {
|
||||
next();
|
||||
};
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/custom-route",
|
||||
"handler": "users-permissions.customRoute",
|
||||
"config": {
|
||||
"policies": ["plugin::users-permissions.customPolicy"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/",
|
||||
"handler": "users-permissions.index",
|
||||
"config": {
|
||||
"policies": ["plugin::users-permissions.customPolicy"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
module.exports = {
|
||||
query: `
|
||||
userCustomRoute: String
|
||||
`,
|
||||
resolver: {
|
||||
Mutation: {
|
||||
updateUser: {
|
||||
description: 'Updates a user',
|
||||
policies: ['customPolicy'],
|
||||
},
|
||||
},
|
||||
Query: {
|
||||
userCustomRoute: {
|
||||
resolver: 'plugin::users-permissions.users-permissions.customRoute',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
@ -2,7 +2,10 @@
|
||||
"collectionName": "up_roles",
|
||||
"info": {
|
||||
"name": "role",
|
||||
"description": ""
|
||||
"description": "",
|
||||
"singularName": "role",
|
||||
"pluralName": "roles",
|
||||
"displayName": "Role"
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
@ -1,8 +1,11 @@
|
||||
{
|
||||
"collectionName": "up_users",
|
||||
"info": {
|
||||
"name": "user",
|
||||
"description": ""
|
||||
"name": "User",
|
||||
"description": "",
|
||||
"singularName": "user",
|
||||
"pluralName": "users",
|
||||
"displayName": "User"
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
@ -59,7 +62,9 @@
|
||||
"configurable": false
|
||||
},
|
||||
"picture": {
|
||||
"type": "media"
|
||||
"type": "media",
|
||||
"multiple": false,
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
customRoute(ctx) {
|
||||
ctx.body = 'allRight';
|
||||
},
|
||||
};
|
@ -1,38 +0,0 @@
|
||||
module.exports = {
|
||||
layouts: {
|
||||
edit: [
|
||||
[
|
||||
{
|
||||
name: 'email',
|
||||
size: 6,
|
||||
},
|
||||
{
|
||||
name: 'username',
|
||||
size: 6,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'password',
|
||||
size: 6,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'picture',
|
||||
size: 6,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'confirmed',
|
||||
size: 4,
|
||||
},
|
||||
{
|
||||
name: 'blocked',
|
||||
size: 4,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
module.exports = plugin => {
|
||||
return plugin;
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = [];
|
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const bootstrap = require('./server/bootstrap');
|
||||
const contentTypes = require('./server/content-types');
|
||||
const policies = require('./server/policies');
|
||||
const services = require('./server/services');
|
||||
const routes = require('./server/routes');
|
||||
@ -9,11 +8,9 @@ const controllers = require('./server/controllers');
|
||||
|
||||
module.exports = () => {
|
||||
return {
|
||||
register: () => {},
|
||||
bootstrap,
|
||||
routes,
|
||||
controllers,
|
||||
contentTypes,
|
||||
policies,
|
||||
services,
|
||||
};
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
const path = require('path');
|
||||
const _ = require('lodash');
|
||||
const { capitalize } = require('lodash/fp');
|
||||
|
||||
const createSchemaHandler = require('./schema-handler');
|
||||
const createComponentBuilder = require('./component-builder');
|
||||
@ -32,17 +31,20 @@ module.exports = function createBuilder() {
|
||||
const contentType = strapi.contentTypes[key];
|
||||
|
||||
let dir;
|
||||
let filename;
|
||||
if (contentType.plugin) {
|
||||
dir = `./extensions/${contentType.plugin}/models`;
|
||||
dir = `./extensions/${contentType.plugin}/content-types/${contentType.info.singularName}`;
|
||||
filename = 'schema.json';
|
||||
} else {
|
||||
dir = `./api/${contentType.apiName}/models`;
|
||||
filename = contentType.__filename__;
|
||||
}
|
||||
|
||||
return {
|
||||
modelName: contentType.modelName,
|
||||
plugin: contentType.plugin,
|
||||
uid: contentType.uid,
|
||||
filename: capitalize(`${contentType.info.singularName}.settings.json`),
|
||||
filename,
|
||||
dir: path.join(strapi.dir, dir),
|
||||
schema: contentType.__schema__,
|
||||
};
|
||||
|
@ -103,7 +103,7 @@ class Strapi {
|
||||
|
||||
return this;
|
||||
} catch (error) {
|
||||
return this.stopWithError(error.message);
|
||||
return this.stopWithError(error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,7 +327,7 @@ class Strapi {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.config.autoReload) {
|
||||
if (this.config.get('autoReload')) {
|
||||
this.server.destroy();
|
||||
process.send('reload');
|
||||
}
|
||||
|
@ -82,12 +82,11 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
|
||||
polling,
|
||||
});
|
||||
|
||||
process.on('message', message => {
|
||||
process.on('message', async message => {
|
||||
switch (message) {
|
||||
case 'isKilled':
|
||||
strapiInstance.server.destroy(() => {
|
||||
process.send('kill');
|
||||
});
|
||||
await strapiInstance.server.destroy();
|
||||
process.send('kill');
|
||||
break;
|
||||
default:
|
||||
// Do nothing.
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { cloneDeep } = require('lodash/fp');
|
||||
const { cloneDeep, kebabCase } = require('lodash/fp');
|
||||
const _ = require('lodash');
|
||||
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
|
||||
const {
|
||||
@ -26,7 +26,7 @@ const createContentType = (uid, definition) => {
|
||||
kind: createdContentType.schema.kind || 'collectionType',
|
||||
__schema__: pickSchema(definition.schema),
|
||||
modelType: 'contentType',
|
||||
modelName: definition.schema.info.singularName,
|
||||
modelName: kebabCase(definition.schema.info.singularName),
|
||||
connection: 'default',
|
||||
});
|
||||
|
||||
|
@ -23,7 +23,7 @@ const strapiServerSchema = yup
|
||||
services: yup.object().required(),
|
||||
policies: yup.object().required(),
|
||||
middlewares: yup.object().required(), // may be removed later
|
||||
contentTypes: yup.array().required(),
|
||||
contentTypes: yup.object().required(),
|
||||
})
|
||||
.noUnknown();
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const fse = require('fs-extra');
|
||||
|
||||
/**
|
||||
@ -10,7 +11,7 @@ module.exports = strapi => {
|
||||
function normalizePath(optPath) {
|
||||
const filePath = Array.isArray(optPath) ? optPath.join('/') : optPath;
|
||||
|
||||
const normalizedPath = path.normalize(filePath).replace(/^(\/?\.\.?)+/, '');
|
||||
const normalizedPath = path.normalize(filePath).replace(/^\/?(\.\/|\.\.\/)+/, '');
|
||||
|
||||
return path.join(strapi.dir, normalizedPath);
|
||||
}
|
||||
@ -44,6 +45,14 @@ module.exports = strapi => {
|
||||
const removePath = normalizePath(optPath);
|
||||
return fse.remove(removePath);
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends a file in strapi app
|
||||
*/
|
||||
async appendFile(optPath, data) {
|
||||
const writePath = normalizePath(optPath);
|
||||
return fs.appendFileSync(writePath, data);
|
||||
},
|
||||
};
|
||||
|
||||
return strapiFS;
|
||||
|
@ -1,10 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const { join } = require('path');
|
||||
const { join, resolve } = require('path');
|
||||
const { existsSync } = require('fs');
|
||||
const { defaultsDeep, getOr } = require('lodash/fp');
|
||||
const { defaultsDeep, getOr, get } = require('lodash/fp');
|
||||
const { env } = require('@strapi/utils');
|
||||
const loadConfigFile = require('../app-configuration/load-config-file');
|
||||
const loadFiles = require('../../load/load-files');
|
||||
const getEnabledPlugins = require('./get-enabled-plugins');
|
||||
|
||||
const defaultPlugin = {
|
||||
@ -20,7 +21,33 @@ const defaultPlugin = {
|
||||
services: {},
|
||||
policies: {},
|
||||
middlewares: {},
|
||||
contentTypes: [],
|
||||
contentTypes: {},
|
||||
};
|
||||
|
||||
const applyUserExtension = async plugins => {
|
||||
const extensionsDir = resolve(strapi.dir, 'extensions');
|
||||
if (!existsSync(extensionsDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extendedSchemas = await loadFiles(extensionsDir, '**/content-types/**/schema.json');
|
||||
const strapiServers = await loadFiles(extensionsDir, '**/strapi-server.js');
|
||||
|
||||
for (const pluginName in plugins) {
|
||||
const plugin = plugins[pluginName];
|
||||
// first: load json schema
|
||||
for (const ctName in plugin.contentTypes) {
|
||||
const extendedSchema = get([pluginName, 'content-types', ctName, 'schema'], extendedSchemas);
|
||||
if (extendedSchema) {
|
||||
plugin.contentTypes[ctName].schema = extendedSchema;
|
||||
}
|
||||
}
|
||||
// second: execute strapi-server extension
|
||||
const strapiServer = get([pluginName, 'strapi-server'], strapiServers);
|
||||
if (strapiServer) {
|
||||
plugins[pluginName] = await strapiServer(plugin);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const formatContentTypes = plugins => {
|
||||
@ -34,7 +61,7 @@ const formatContentTypes = plugins => {
|
||||
}
|
||||
};
|
||||
|
||||
const formatConfig = plugins => {
|
||||
const applyUserConfig = plugins => {
|
||||
const userPluginConfigPath = join(strapi.dir, 'config', 'plugins.js');
|
||||
const userPluginsConfig = existsSync(userPluginConfigPath)
|
||||
? loadConfigFile(userPluginConfigPath)
|
||||
@ -43,13 +70,18 @@ const formatConfig = plugins => {
|
||||
for (const pluginName in plugins) {
|
||||
const plugin = plugins[pluginName];
|
||||
const userPluginConfig = getOr({}, `${pluginName}.config`, userPluginsConfig);
|
||||
const formattedConfig = defaultsDeep(plugin.config.default, userPluginConfig);
|
||||
const defaultConfig =
|
||||
typeof plugin.config.default === 'function'
|
||||
? plugin.config.default({ env })
|
||||
: plugin.config.default;
|
||||
|
||||
const config = defaultsDeep(defaultConfig, userPluginConfig);
|
||||
try {
|
||||
plugin.config.validator(formattedConfig);
|
||||
plugin.config.validator(config);
|
||||
} catch (e) {
|
||||
throw new Error(`Error regarding ${pluginName} config: ${e.message}`);
|
||||
}
|
||||
plugin.config = formattedConfig;
|
||||
plugin.config = config;
|
||||
}
|
||||
};
|
||||
|
||||
@ -59,12 +91,12 @@ const loadPlugins = async strapi => {
|
||||
|
||||
for (const pluginName in enabledPlugins) {
|
||||
const enabledPlugin = enabledPlugins[pluginName];
|
||||
const loadPluginServer = require(join(enabledPlugin.pathToPlugin, 'strapi-server.js'));
|
||||
const pluginServer = await loadPluginServer({ env });
|
||||
const pluginServer = loadConfigFile(join(enabledPlugin.pathToPlugin, 'strapi-server.js'));
|
||||
plugins[pluginName] = defaultsDeep(defaultPlugin, pluginServer);
|
||||
}
|
||||
// TODO: validate plugin format
|
||||
formatConfig(plugins);
|
||||
applyUserConfig(plugins);
|
||||
await applyUserExtension(plugins);
|
||||
formatContentTypes(plugins);
|
||||
|
||||
return plugins;
|
||||
|
@ -3,6 +3,7 @@
|
||||
const _ = require('lodash');
|
||||
const { toLower, kebabCase, camelCase } = require('lodash/fp');
|
||||
const { getConfigUrls } = require('@strapi/utils');
|
||||
const pluralize = require('pluralize');
|
||||
const { createContentType } = require('../domain/content-type');
|
||||
|
||||
const { createCoreApi } = require('../../core-api');
|
||||
@ -23,10 +24,10 @@ module.exports = function(strapi) {
|
||||
actions: {},
|
||||
lifecycles: {},
|
||||
};
|
||||
ct.schema.info = {};
|
||||
ct.schema.info.displayName = camelCase(modelName);
|
||||
|
||||
ct.schema.info.displayName = model.info.name;
|
||||
ct.schema.info.singularName = camelCase(modelName);
|
||||
ct.schema.info.pluralName = `${camelCase(modelName)}s`;
|
||||
ct.schema.info.pluralName = pluralize(camelCase(modelName));
|
||||
|
||||
const createdContentType = createContentType(
|
||||
`api::${apiName}.${kebabCase(ct.schema.info.singularName)}`,
|
||||
@ -46,19 +47,21 @@ module.exports = function(strapi) {
|
||||
}, {});
|
||||
|
||||
// Set controllers.
|
||||
strapi.controllers = Object.keys(strapi.api || []).reduce((acc, key) => {
|
||||
for (let index in strapi.api[key].controllers) {
|
||||
let controller = strapi.api[key].controllers[index];
|
||||
acc[index] = controller;
|
||||
strapi.controllers = Object.keys(strapi.api || []).reduce((acc, apiName) => {
|
||||
strapi.container.get('controllers').add(`api::${apiName}`, strapi.api[apiName].controllers);
|
||||
for (let controllerName in strapi.api[apiName].controllers) {
|
||||
let controller = strapi.api[apiName].controllers[controllerName];
|
||||
acc[controllerName] = controller;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Set services.
|
||||
strapi.services = Object.keys(strapi.api || []).reduce((acc, key) => {
|
||||
for (let index in strapi.api[key].services) {
|
||||
acc[index] = strapi.api[key].services[index];
|
||||
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;
|
||||
@ -120,6 +123,7 @@ module.exports = function(strapi) {
|
||||
_.forEach(plugin.middlewares, (middleware, middlewareUID) => {
|
||||
const middlewareName = toLower(middlewareUID.split('.')[1]);
|
||||
strapi.plugins[pluginName].middlewares[middlewareName] = middleware;
|
||||
strapi.middleware[middlewareName] = middleware;
|
||||
});
|
||||
|
||||
_.forEach(plugin.controllers, (controller, controllerUID) => {
|
||||
|
@ -19,6 +19,17 @@ const { createContentType } = require('../domain/content-type');
|
||||
// });
|
||||
// };
|
||||
|
||||
const validateKeySameToSingularName = contentTypes => {
|
||||
for (const ctName in contentTypes) {
|
||||
const contentType = contentTypes[ctName];
|
||||
if (ctName !== contentType.schema.info.singularName) {
|
||||
throw new Error(
|
||||
`The key of the content-type should be the same as its singularName. Found ${ctName} and ${contentType.schema.info.singularName}.`
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const contentTypesRegistry = () => {
|
||||
const contentTypes = {};
|
||||
|
||||
@ -30,13 +41,15 @@ const contentTypesRegistry = () => {
|
||||
return pickBy((ct, ctUID) => ctUID.startsWith(prefix))(contentTypes);
|
||||
},
|
||||
add(namespace, rawContentTypes) {
|
||||
rawContentTypes.forEach(rawContentType => {
|
||||
validateKeySameToSingularName(rawContentTypes);
|
||||
for (const rawCtName in rawContentTypes) {
|
||||
const rawContentType = rawContentTypes[rawCtName];
|
||||
const uid = `${namespace}.${rawContentType.schema.info.singularName}`;
|
||||
if (has(uid, contentTypes)) {
|
||||
throw new Error(`Content-Type ${uid} has already been registered.`);
|
||||
throw new Error(`Content-type ${uid} has already been registered.`);
|
||||
}
|
||||
contentTypes[uid] = createContentType(uid, rawContentType);
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -63,6 +63,7 @@
|
||||
"open": "8.2.1",
|
||||
"ora": "^5.4.0",
|
||||
"package-json": "6.5.0",
|
||||
"pluralize": "8.0.0",
|
||||
"qs": "^6.10.1",
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
const fileModel = require('../../models/File');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
schema: fileModel,
|
||||
},
|
||||
];
|
||||
module.exports = {
|
||||
[fileModel.info.singularName]: { schema: fileModel },
|
||||
};
|
||||
|
@ -150,7 +150,7 @@ module.exports = ({ strapi }) => ({
|
||||
},
|
||||
|
||||
async uploadFileAndPersist(fileData, { user } = {}) {
|
||||
const config = strapi.plugins.upload.config;
|
||||
const config = strapi.config.get('plugin.upload');
|
||||
|
||||
const {
|
||||
getDimensions,
|
||||
|
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const pluralize = require('pluralize');
|
||||
|
||||
const SINGLE_TYPE = 'singleType';
|
||||
const COLLECTION_TYPE = 'collectionType';
|
||||
@ -120,8 +119,8 @@ const isTypedAttribute = (attribute, type) => {
|
||||
*/
|
||||
const getContentTypeRoutePrefix = contentType => {
|
||||
return isSingleType(contentType)
|
||||
? _.kebabCase(contentType.modelName)
|
||||
: _.kebabCase(pluralize(contentType.modelName));
|
||||
? _.kebabCase(contentType.info.singularName)
|
||||
: _.kebabCase(contentType.info.pluralName);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
@ -10,6 +10,6 @@ module.exports = (/* strapi, config */) => {
|
||||
services: () => {},
|
||||
policies: {},
|
||||
middlewares: {},
|
||||
contentTypes: [],
|
||||
contentTypes: {},
|
||||
};
|
||||
};
|
||||
|
@ -2,4 +2,6 @@
|
||||
|
||||
const localeModel = require('./locale');
|
||||
|
||||
module.exports = [localeModel];
|
||||
module.exports = {
|
||||
[localeModel.schema.info.singularName]: localeModel,
|
||||
};
|
||||
|
@ -199,12 +199,21 @@ const addCreateLocalizationAction = contentType => {
|
||||
|
||||
const localizationRoute = createLocalizationRoute(contentType);
|
||||
|
||||
const coreApiControllerPath = `api.${apiName}.controllers.${modelName}.createLocalization`;
|
||||
const handler = createLocalizationHandler(contentType);
|
||||
|
||||
strapi.config.routes.push(localizationRoute);
|
||||
|
||||
_.set(strapi, coreApiControllerPath, handler);
|
||||
// TODO: to replace with:
|
||||
// strapi.controllers.extends(`api::${apiName}.${modelName}`, (contr) => ({
|
||||
// ...controller,
|
||||
// createLocalization = createLocalizationHandler(contentType),
|
||||
// }));
|
||||
// OR
|
||||
// strapi.api(apiName).controllers.extends(modelName, (contr) => ({
|
||||
// ...controller,
|
||||
// createLocalization = createLocalizationHandler(contentType),
|
||||
// }));
|
||||
|
||||
const controller = strapi.container.get('controllers').get(`api::${apiName}.${modelName}`);
|
||||
controller.createLocalization = createLocalizationHandler(contentType);
|
||||
};
|
||||
|
||||
const mergeCustomizer = (dest, src) => {
|
||||
@ -217,6 +226,7 @@ const mergeCustomizer = (dest, src) => {
|
||||
* Add a graphql schema to the plugin's global graphl schema to be processed
|
||||
* @param {object} schema
|
||||
*/
|
||||
// TODO: to replace with V4 config getter
|
||||
const addGraphqlSchema = schema => {
|
||||
_.mergeWith(strapi.plugins.i18n.config.schema.graphql, schema, mergeCustomizer);
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ describe('USERS PERMISSIONS | COMPONENTS | UserPermissions | init', () => {
|
||||
application: [{ method: 'GET', path: '/addresses' }],
|
||||
};
|
||||
|
||||
const policies = ['isauthenticated', 'ratelimit', 'custompolicy'];
|
||||
const policies = ['isAuthenticated', 'rateLimit', 'custompolicy'];
|
||||
|
||||
const expected = {
|
||||
initialData: permissions,
|
||||
|
@ -2,12 +2,12 @@ import formatPolicies from '../formatPolicies';
|
||||
|
||||
describe('USERS PERMISSIONS | utils | formatPolicies', () => {
|
||||
it('should format the policies correclty', () => {
|
||||
const policies = ['custompolicies', 'ratelimit', 'isauthenticated'];
|
||||
const policies = ['customPolicies', 'rateLimit', 'isAuthenticated'];
|
||||
|
||||
const expected = [
|
||||
{ label: 'custompolicies', value: 'custompolicies' },
|
||||
{ label: 'ratelimit', value: 'ratelimit' },
|
||||
{ label: 'isauthenticated', value: 'isauthenticated' },
|
||||
{ label: 'customPolicies', value: 'customPolicies' },
|
||||
{ label: 'rateLimit', value: 'rateLimit' },
|
||||
{ label: 'isAuthenticated', value: 'isAuthenticated' },
|
||||
];
|
||||
|
||||
expect(formatPolicies(policies)).toEqual(expected);
|
||||
|
@ -31,17 +31,14 @@ module.exports = async () => {
|
||||
await getService('users-permissions').initialize();
|
||||
|
||||
// TODO: adapt with new extension system
|
||||
if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) {
|
||||
if (!strapi.config.get('plugin.users-permissions.jwtSecret')) {
|
||||
const jwtSecret = uuid();
|
||||
_.set(strapi.plugins['users-permissions'], 'config.jwtSecret', jwtSecret);
|
||||
strapi.config.set('plugin.users-permissions.jwtSecret', jwtSecret),
|
||||
(strapi.reload.isWatching = false);
|
||||
|
||||
strapi.reload.isWatching = false;
|
||||
|
||||
await strapi.fs.writePluginFile(
|
||||
'users-permissions',
|
||||
'config/jwt.js',
|
||||
`module.exports = {\n jwtSecret: process.env.JWT_SECRET || '${jwtSecret}'\n};`
|
||||
);
|
||||
if (!process.env.JWT_SECRET) {
|
||||
await strapi.fs.appendFile('.env', `JWT_SECRET=${jwtSecret}\n`);
|
||||
}
|
||||
|
||||
strapi.reload.isWatching = true;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ module.exports = async (ctx, next) => {
|
||||
prefixKey: `${ctx.request.path}:${ctx.request.ip}`,
|
||||
message,
|
||||
},
|
||||
strapi.plugins['users-permissions'].config.ratelimit
|
||||
strapi.config.get('plugin.users-permissions.ratelimit')
|
||||
)
|
||||
)(ctx, next);
|
||||
};
|
||||
|
@ -176,7 +176,7 @@
|
||||
"path": "/connect/*",
|
||||
"handler": "auth.connect",
|
||||
"config": {
|
||||
"policies": ["plugin::users-permissions.ratelimit"],
|
||||
"policies": ["plugin::users-permissions.rateLimit"],
|
||||
"prefix": "",
|
||||
"description": "Connect a provider",
|
||||
"tag": {
|
||||
@ -190,7 +190,7 @@
|
||||
"path": "/auth/local",
|
||||
"handler": "auth.callback",
|
||||
"config": {
|
||||
"policies": ["plugin::users-permissions.ratelimit"],
|
||||
"policies": ["plugin::users-permissions.rateLimit"],
|
||||
"prefix": "",
|
||||
"description": "Login a user using the identifiers email and password",
|
||||
"tag": {
|
||||
@ -204,7 +204,7 @@
|
||||
"path": "/auth/local/register",
|
||||
"handler": "auth.register",
|
||||
"config": {
|
||||
"policies": ["plugin::users-permissions.ratelimit"],
|
||||
"policies": ["plugin::users-permissions.rateLimit"],
|
||||
"prefix": "",
|
||||
"description": "Register a new user with the default role",
|
||||
"tag": {
|
||||
@ -233,7 +233,7 @@
|
||||
"path": "/auth/forgot-password",
|
||||
"handler": "auth.forgotPassword",
|
||||
"config": {
|
||||
"policies": ["plugin::users-permissions.ratelimit"],
|
||||
"policies": ["plugin::users-permissions.rateLimit"],
|
||||
"prefix": "",
|
||||
"description": "Send the reset password email link",
|
||||
"tag": {
|
||||
@ -247,7 +247,7 @@
|
||||
"path": "/auth/reset-password",
|
||||
"handler": "auth.resetPassword",
|
||||
"config": {
|
||||
"policies": ["plugin::users-permissions.ratelimit"],
|
||||
"policies": ["plugin::users-permissions.rateLimit"],
|
||||
"prefix": "",
|
||||
"description": "Reset user password with a code (resetToken)",
|
||||
"tag": {
|
||||
|
@ -1,6 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
default: {},
|
||||
default: ({ env }) => ({
|
||||
jwtSecret: env('JWT_SECRET'),
|
||||
jwt: {
|
||||
expiresIn: '30d',
|
||||
},
|
||||
ratelimit: {
|
||||
interval: 60000,
|
||||
max: 10,
|
||||
},
|
||||
}),
|
||||
validator: () => {},
|
||||
};
|
||||
|
@ -4,14 +4,8 @@ const permissionModel = require('../../models/Permission.settings');
|
||||
const roleModel = require('../../models/Role.settings');
|
||||
const userModel = require('../../models/User.settings');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
schema: permissionModel,
|
||||
},
|
||||
{
|
||||
schema: roleModel,
|
||||
},
|
||||
{
|
||||
schema: userModel,
|
||||
},
|
||||
];
|
||||
module.exports = {
|
||||
[permissionModel.info.singularName]: { schema: permissionModel },
|
||||
[roleModel.info.singularName]: { schema: roleModel },
|
||||
[userModel.info.singularName]: { schema: userModel },
|
||||
};
|
||||
|
@ -39,27 +39,25 @@ module.exports = ({ strapi }) => ({
|
||||
},
|
||||
|
||||
issue(payload, jwtOptions = {}) {
|
||||
_.defaults(jwtOptions, strapi.plugins['users-permissions'].config.jwt);
|
||||
_.defaults(jwtOptions, strapi.config.get('plugin.users-permissions.jwt'));
|
||||
return jwt.sign(
|
||||
_.clone(payload.toJSON ? payload.toJSON() : payload),
|
||||
_.get(strapi.plugins, ['users-permissions', 'config', 'jwtSecret']),
|
||||
strapi.config.get('plugin.users-permissions.jwtSecret'),
|
||||
jwtOptions
|
||||
);
|
||||
},
|
||||
|
||||
verify(token) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
jwt.verify(
|
||||
token,
|
||||
_.get(strapi.plugins, ['users-permissions', 'config', 'jwtSecret']),
|
||||
{},
|
||||
function(err, tokenPayload = {}) {
|
||||
if (err) {
|
||||
return reject(new Error('Invalid token.'));
|
||||
}
|
||||
resolve(tokenPayload);
|
||||
jwt.verify(token, strapi.config.get('plugin.users-permissions.jwtSecret'), {}, function(
|
||||
err,
|
||||
tokenPayload = {}
|
||||
) {
|
||||
if (err) {
|
||||
return reject(new Error('Invalid token.'));
|
||||
}
|
||||
);
|
||||
resolve(tokenPayload);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -7,10 +7,11 @@ const services = require('./server/services');
|
||||
const routes = require('./server/routes');
|
||||
const controllers = require('./server/controllers');
|
||||
const middlewares = require('./server/middlewares');
|
||||
const config = require('./server/config');
|
||||
|
||||
module.exports = () => ({
|
||||
register: () => {},
|
||||
bootstrap,
|
||||
config,
|
||||
routes,
|
||||
controllers,
|
||||
middlewares,
|
||||
|
Loading…
x
Reference in New Issue
Block a user