@strapi/strapi 4.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +144 -0
- package/bin/strapi.js +186 -0
- package/lib/Strapi.js +470 -0
- package/lib/commands/admin-reset.js +51 -0
- package/lib/commands/build.js +56 -0
- package/lib/commands/configurationDump.js +50 -0
- package/lib/commands/configurationRestore.js +169 -0
- package/lib/commands/console.js +26 -0
- package/lib/commands/develop.js +157 -0
- package/lib/commands/generate-template.js +97 -0
- package/lib/commands/install.js +48 -0
- package/lib/commands/new.js +11 -0
- package/lib/commands/start.js +8 -0
- package/lib/commands/uninstall.js +68 -0
- package/lib/commands/watchAdmin.js +45 -0
- package/lib/container.js +45 -0
- package/lib/core/app-configuration/config-loader.js +20 -0
- package/lib/core/app-configuration/index.js +75 -0
- package/lib/core/app-configuration/load-config-file.js +43 -0
- package/lib/core/app-configuration/load-functions.js +28 -0
- package/lib/core/bootstrap.js +60 -0
- package/lib/core/domain/component/index.js +24 -0
- package/lib/core/domain/component/validator.js +29 -0
- package/lib/core/domain/content-type/index.js +140 -0
- package/lib/core/domain/content-type/validator.js +64 -0
- package/lib/core/domain/module/index.js +106 -0
- package/lib/core/domain/module/validation.js +36 -0
- package/lib/core/loaders/admin.js +16 -0
- package/lib/core/loaders/apis.js +157 -0
- package/lib/core/loaders/components.js +41 -0
- package/lib/core/loaders/index.js +11 -0
- package/lib/core/loaders/middlewares.js +86 -0
- package/lib/core/loaders/plugins/get-enabled-plugins.js +100 -0
- package/lib/core/loaders/plugins/index.js +109 -0
- package/lib/core/loaders/policies.js +28 -0
- package/lib/core/loaders/src-index.js +38 -0
- package/lib/core/registries/apis.js +43 -0
- package/lib/core/registries/config.js +21 -0
- package/lib/core/registries/content-types.js +53 -0
- package/lib/core/registries/controllers.js +43 -0
- package/lib/core/registries/hooks.js +37 -0
- package/lib/core/registries/middlewares.js +30 -0
- package/lib/core/registries/modules.js +44 -0
- package/lib/core/registries/plugins.js +28 -0
- package/lib/core/registries/policies.js +38 -0
- package/lib/core/registries/services.js +58 -0
- package/lib/core/utils.js +35 -0
- package/lib/core-api/controller/collection-type.js +84 -0
- package/lib/core-api/controller/index.js +26 -0
- package/lib/core-api/controller/single-type.js +44 -0
- package/lib/core-api/controller/transform.js +97 -0
- package/lib/core-api/index.js +39 -0
- package/lib/core-api/service/collection-type.js +84 -0
- package/lib/core-api/service/index.js +55 -0
- package/lib/core-api/service/pagination.js +125 -0
- package/lib/core-api/service/single-type.js +58 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +3 -0
- package/lib/load/filepath-to-prop-path.js +22 -0
- package/lib/load/glob.js +15 -0
- package/lib/load/index.js +9 -0
- package/lib/load/load-files.js +56 -0
- package/lib/load/package-path.js +9 -0
- package/lib/middlewares/cors/index.js +66 -0
- package/lib/middlewares/error/defaults.json +5 -0
- package/lib/middlewares/error/index.js +147 -0
- package/lib/middlewares/favicon/defaults.json +7 -0
- package/lib/middlewares/favicon/index.js +31 -0
- package/lib/middlewares/gzip/defaults.json +6 -0
- package/lib/middlewares/gzip/index.js +19 -0
- package/lib/middlewares/helmet/defaults.json +18 -0
- package/lib/middlewares/helmet/index.js +9 -0
- package/lib/middlewares/index.js +120 -0
- package/lib/middlewares/ip/defaults.json +7 -0
- package/lib/middlewares/ip/index.js +25 -0
- package/lib/middlewares/logger/defaults.json +5 -0
- package/lib/middlewares/logger/index.js +37 -0
- package/lib/middlewares/parser/defaults.json +11 -0
- package/lib/middlewares/parser/index.js +75 -0
- package/lib/middlewares/poweredBy/defaults.json +5 -0
- package/lib/middlewares/poweredBy/index.js +16 -0
- package/lib/middlewares/public/assets/images/group_people_1.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_2.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_3.png +0 -0
- package/lib/middlewares/public/assets/images/logo_login.png +0 -0
- package/lib/middlewares/public/defaults.json +8 -0
- package/lib/middlewares/public/index.html +66 -0
- package/lib/middlewares/public/index.js +130 -0
- package/lib/middlewares/public/serve-static.js +23 -0
- package/lib/middlewares/responseTime/defaults.json +5 -0
- package/lib/middlewares/responseTime/index.js +25 -0
- package/lib/middlewares/responses/defaults.json +5 -0
- package/lib/middlewares/responses/index.js +19 -0
- package/lib/middlewares/router/defaults.json +7 -0
- package/lib/middlewares/router/index.js +97 -0
- package/lib/middlewares/session/defaults.json +18 -0
- package/lib/middlewares/session/index.js +140 -0
- package/lib/migrations/draft-publish.js +57 -0
- package/lib/services/auth/index.js +92 -0
- package/lib/services/core-store.js +145 -0
- package/lib/services/cron.js +54 -0
- package/lib/services/entity-service/components.js +365 -0
- package/lib/services/entity-service/index.d.ts +91 -0
- package/lib/services/entity-service/index.js +244 -0
- package/lib/services/entity-service/params.js +145 -0
- package/lib/services/entity-validator/index.js +187 -0
- package/lib/services/entity-validator/validators.js +123 -0
- package/lib/services/event-hub.js +15 -0
- package/lib/services/fs.js +58 -0
- package/lib/services/metrics/index.js +104 -0
- package/lib/services/metrics/is-truthy.js +9 -0
- package/lib/services/metrics/middleware.js +33 -0
- package/lib/services/metrics/rate-limiter.js +27 -0
- package/lib/services/metrics/sender.js +76 -0
- package/lib/services/metrics/stringify-deep.js +22 -0
- package/lib/services/server/admin-api.js +14 -0
- package/lib/services/server/api.js +32 -0
- package/lib/services/server/compose-endpoint.js +112 -0
- package/lib/services/server/content-api.js +16 -0
- package/lib/services/server/http-server.js +64 -0
- package/lib/services/server/index.js +108 -0
- package/lib/services/server/middleware.js +28 -0
- package/lib/services/server/policy.js +34 -0
- package/lib/services/server/routing.js +107 -0
- package/lib/services/utils/upload-files.js +79 -0
- package/lib/services/webhook-runner.js +155 -0
- package/lib/services/webhook-store.js +91 -0
- package/lib/services/worker-queue.js +58 -0
- package/lib/utils/addSlash.js +10 -0
- package/lib/utils/ee.js +123 -0
- package/lib/utils/get-dirs.js +15 -0
- package/lib/utils/get-prefixed-dependencies.js +7 -0
- package/lib/utils/index.js +11 -0
- package/lib/utils/is-initialized.js +23 -0
- package/lib/utils/open-browser.js +12 -0
- package/lib/utils/resources/key.pub +9 -0
- package/lib/utils/run-checks.js +22 -0
- package/lib/utils/startup-logger.js +90 -0
- package/lib/utils/success.js +31 -0
- package/lib/utils/update-notifier/index.js +97 -0
- package/lib/utils/url-from-segments.js +12 -0
- package/package.json +133 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const { toLower } = require('lodash/fp');
|
|
5
|
+
|
|
6
|
+
const createRouteScopeGenerator = namespace => route => {
|
|
7
|
+
const prefix = namespace.endsWith('::') ? namespace : `${namespace}.`;
|
|
8
|
+
|
|
9
|
+
if (typeof route.handler === 'string') {
|
|
10
|
+
const [controller, action] = route.handler.split('.');
|
|
11
|
+
|
|
12
|
+
_.defaultsDeep(route, {
|
|
13
|
+
config: {
|
|
14
|
+
auth: {
|
|
15
|
+
scope: `${prefix}${controller}.${toLower(action)}`,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
module.exports = strapi => {
|
|
23
|
+
const registerAdminRoutes = () => {
|
|
24
|
+
const generateRouteScope = createRouteScopeGenerator(`admin::`);
|
|
25
|
+
|
|
26
|
+
strapi.admin.routes.forEach(route => {
|
|
27
|
+
generateRouteScope(route);
|
|
28
|
+
route.info = { pluginName: 'admin' };
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
strapi.server.routes({
|
|
32
|
+
type: 'admin',
|
|
33
|
+
prefix: '/admin',
|
|
34
|
+
routes: strapi.admin.routes,
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const registerPluginRoutes = () => {
|
|
39
|
+
for (const pluginName in strapi.plugins) {
|
|
40
|
+
const plugin = strapi.plugins[pluginName];
|
|
41
|
+
|
|
42
|
+
const generateRouteScope = createRouteScopeGenerator(`plugin::${pluginName}`);
|
|
43
|
+
|
|
44
|
+
if (Array.isArray(plugin.routes)) {
|
|
45
|
+
plugin.routes.forEach(route => {
|
|
46
|
+
generateRouteScope(route);
|
|
47
|
+
route.info = { pluginName };
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
strapi.server.routes({
|
|
51
|
+
type: 'admin',
|
|
52
|
+
prefix: `/${pluginName}`,
|
|
53
|
+
routes: plugin.routes,
|
|
54
|
+
});
|
|
55
|
+
} else {
|
|
56
|
+
_.forEach(plugin.routes, router => {
|
|
57
|
+
router.type = router.type || 'admin';
|
|
58
|
+
router.prefix = `/${pluginName}`;
|
|
59
|
+
router.routes.forEach(route => {
|
|
60
|
+
generateRouteScope(route);
|
|
61
|
+
route.info = { pluginName };
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
strapi.server.routes(router);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const registerAPIRoutes = () => {
|
|
71
|
+
for (const apiName in strapi.api) {
|
|
72
|
+
const api = strapi.api[apiName];
|
|
73
|
+
|
|
74
|
+
const generateRouteScope = createRouteScopeGenerator(`api::${apiName}`);
|
|
75
|
+
|
|
76
|
+
_.forEach(api.routes, router => {
|
|
77
|
+
// TODO: remove once auth setup
|
|
78
|
+
// pass meta down to compose endpoint
|
|
79
|
+
router.type = 'content-api';
|
|
80
|
+
router.routes.forEach(route => {
|
|
81
|
+
generateRouteScope(route);
|
|
82
|
+
route.info = { apiName };
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return strapi.server.routes(router);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
initialize() {
|
|
92
|
+
registerAdminRoutes();
|
|
93
|
+
registerAPIRoutes();
|
|
94
|
+
registerPluginRoutes();
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"session": {
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"client": "cookie",
|
|
5
|
+
"key": "strapi.sid",
|
|
6
|
+
"prefix": "strapi:sess:",
|
|
7
|
+
"ttl": 864000000,
|
|
8
|
+
"rolling": false,
|
|
9
|
+
"secretKeys": ["mySecretKey1", "mySecretKey2"],
|
|
10
|
+
"cookie": {
|
|
11
|
+
"path": "/",
|
|
12
|
+
"httpOnly": true,
|
|
13
|
+
"maxAge": 864000000,
|
|
14
|
+
"rewrite": true,
|
|
15
|
+
"signed": false
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const _ = require('lodash');
|
|
5
|
+
const session = require('koa-session');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Session middleware
|
|
9
|
+
*/
|
|
10
|
+
module.exports = strapi => {
|
|
11
|
+
const requireStore = store => {
|
|
12
|
+
return require(path.resolve(strapi.config.appPath, 'node_modules', 'koa-' + store));
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const defineStore = session => {
|
|
16
|
+
if (_.isEmpty(_.get(session, 'client'))) {
|
|
17
|
+
return strapi.log.error(
|
|
18
|
+
'(middleware:session) please provide a valid client to store session'
|
|
19
|
+
);
|
|
20
|
+
} else if (_.isEmpty(_.get(session, 'connection'))) {
|
|
21
|
+
return strapi.log.error(
|
|
22
|
+
'(middleware:session) please provide connection for the session store'
|
|
23
|
+
);
|
|
24
|
+
} else if (!strapi.config.get(`database.connections.${session.connection}`)) {
|
|
25
|
+
return strapi.log.error(
|
|
26
|
+
'(middleware:session) please provide a valid connection for the session store'
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
session.settings = strapi.config.get(`database.connections.${session.connection}`);
|
|
31
|
+
|
|
32
|
+
// Define correct store name to avoid require to failed.
|
|
33
|
+
switch (session.client.toLowerCase()) {
|
|
34
|
+
case 'redis': {
|
|
35
|
+
const store = requireStore('redis');
|
|
36
|
+
|
|
37
|
+
session.settings.db = session.settings.database;
|
|
38
|
+
|
|
39
|
+
return store(session.settings);
|
|
40
|
+
}
|
|
41
|
+
case 'mysql': {
|
|
42
|
+
const Store = requireStore('mysql-session');
|
|
43
|
+
|
|
44
|
+
return new Store(session.settings);
|
|
45
|
+
}
|
|
46
|
+
case 'mongo': {
|
|
47
|
+
const Store = requireStore('generic-session-mongo');
|
|
48
|
+
|
|
49
|
+
session.settings.db = session.settings.database;
|
|
50
|
+
|
|
51
|
+
return new Store(session.settings);
|
|
52
|
+
}
|
|
53
|
+
case 'postgresql': {
|
|
54
|
+
const Store = requireStore('pg-session');
|
|
55
|
+
|
|
56
|
+
return new Store(session.settings, session.options);
|
|
57
|
+
}
|
|
58
|
+
case 'rethink': {
|
|
59
|
+
const Store = requireStore('generic-session-rethinkdb');
|
|
60
|
+
|
|
61
|
+
session.settings.dbName = session.settings.database;
|
|
62
|
+
session.settings.tableName = session.settings.table;
|
|
63
|
+
|
|
64
|
+
const sessionStore = new Store({
|
|
65
|
+
connection: session.settings,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Create the DB, tables and indexes to store sessions.
|
|
69
|
+
sessionStore.setup();
|
|
70
|
+
|
|
71
|
+
return sessionStore;
|
|
72
|
+
}
|
|
73
|
+
case 'sqlite': {
|
|
74
|
+
const Store = requireStore('sqlite3-session');
|
|
75
|
+
|
|
76
|
+
return new Store(session.fileName, session.options);
|
|
77
|
+
}
|
|
78
|
+
case 'sequelize': {
|
|
79
|
+
const Store = requireStore('generic-session-sequelize');
|
|
80
|
+
|
|
81
|
+
// Sequelize needs to be instantiated.
|
|
82
|
+
if (!_.isObject(strapi.sequelize)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return new Store(strapi.sequelize, session.options);
|
|
87
|
+
}
|
|
88
|
+
default: {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
initialize() {
|
|
96
|
+
strapi.server.app.keys = strapi.config.get('middleware.settings.session.secretKeys');
|
|
97
|
+
|
|
98
|
+
if (
|
|
99
|
+
_.has(strapi.config.middleware.settings.session, 'client') &&
|
|
100
|
+
_.isString(strapi.config.middleware.settings.session.client) &&
|
|
101
|
+
strapi.config.middleware.settings.session.client !== 'cookie'
|
|
102
|
+
) {
|
|
103
|
+
const store = defineStore(strapi.config.middleware.settings.session);
|
|
104
|
+
|
|
105
|
+
if (!_.isEmpty(store)) {
|
|
106
|
+
// Options object contains the defined store, the custom middlewares configurations
|
|
107
|
+
// and also the function which are located to `./config/functions/session.js`
|
|
108
|
+
const options = _.assign(
|
|
109
|
+
{
|
|
110
|
+
store,
|
|
111
|
+
},
|
|
112
|
+
strapi.config.middleware.settings.session
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
strapi.server.use(session(options, strapi.server.app));
|
|
116
|
+
strapi.server.use((ctx, next) => {
|
|
117
|
+
ctx.state = ctx.state || {};
|
|
118
|
+
ctx.state.session = ctx.session || {};
|
|
119
|
+
|
|
120
|
+
return next();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
} else if (
|
|
124
|
+
_.has(strapi.config.middleware.settings.session, 'client') &&
|
|
125
|
+
_.isString(strapi.config.middleware.settings.session.client) &&
|
|
126
|
+
strapi.config.middleware.settings.session.client === 'cookie'
|
|
127
|
+
) {
|
|
128
|
+
const options = _.assign(strapi.config.middleware.settings.session);
|
|
129
|
+
|
|
130
|
+
strapi.server.use(session(options, strapi.server.app));
|
|
131
|
+
strapi.server.use((ctx, next) => {
|
|
132
|
+
ctx.state = ctx.state || {};
|
|
133
|
+
ctx.state.session = ctx.session || {};
|
|
134
|
+
|
|
135
|
+
return next();
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
|
|
4
|
+
|
|
5
|
+
const enableDraftAndPublish = async ({ oldContentTypes, contentTypes }) => {
|
|
6
|
+
if (!oldContentTypes) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
// run the after content types migrations
|
|
10
|
+
|
|
11
|
+
for (const uid in contentTypes) {
|
|
12
|
+
if (!oldContentTypes[uid]) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const oldContentType = oldContentTypes[uid];
|
|
17
|
+
const contentType = contentTypes[uid];
|
|
18
|
+
|
|
19
|
+
// if d&p was enabled set publishedAt to eq createdAt
|
|
20
|
+
if (!hasDraftAndPublish(oldContentType) && hasDraftAndPublish(contentType)) {
|
|
21
|
+
const qb = strapi.db.queryBuilder(uid);
|
|
22
|
+
await qb
|
|
23
|
+
.update({ published_at: qb.ref('created_at') })
|
|
24
|
+
.where({ published_at: null })
|
|
25
|
+
.execute();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const disableDraftAndPublish = async ({ oldContentTypes, contentTypes }) => {
|
|
31
|
+
if (!oldContentTypes) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const uid in contentTypes) {
|
|
36
|
+
if (!oldContentTypes[uid]) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const oldContentType = oldContentTypes[uid];
|
|
41
|
+
const contentType = contentTypes[uid];
|
|
42
|
+
|
|
43
|
+
// if d&p was disabled remove unpublish content before sync
|
|
44
|
+
if (hasDraftAndPublish(oldContentType) && !hasDraftAndPublish(contentType)) {
|
|
45
|
+
await strapi.db
|
|
46
|
+
.queryBuilder(uid)
|
|
47
|
+
.delete()
|
|
48
|
+
.where({ published_at: null })
|
|
49
|
+
.execute();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
enable: enableDraftAndPublish,
|
|
56
|
+
disable: disableDraftAndPublish,
|
|
57
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { strict: assert } = require('assert');
|
|
4
|
+
const { has, prop } = require('lodash/fp');
|
|
5
|
+
|
|
6
|
+
class UnauthorizedError extends Error {}
|
|
7
|
+
class ForbiddenError extends Error {}
|
|
8
|
+
|
|
9
|
+
const INVALID_STRATEGY_MSG =
|
|
10
|
+
'Invalid auth strategy. Expecting an object with properties {name: string, authenticate: function, verify: function}';
|
|
11
|
+
|
|
12
|
+
const validStrategy = strategy => {
|
|
13
|
+
assert(has('authenticate', strategy), INVALID_STRATEGY_MSG);
|
|
14
|
+
assert(typeof strategy.authenticate === 'function', INVALID_STRATEGY_MSG);
|
|
15
|
+
|
|
16
|
+
if (has('verify', strategy)) {
|
|
17
|
+
assert(typeof strategy.verify === 'function', INVALID_STRATEGY_MSG);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const createAuthentication = () => {
|
|
22
|
+
const strategies = {};
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
errors: {
|
|
26
|
+
UnauthorizedError,
|
|
27
|
+
ForbiddenError,
|
|
28
|
+
},
|
|
29
|
+
register(type, strategy) {
|
|
30
|
+
validStrategy(strategy);
|
|
31
|
+
|
|
32
|
+
if (!strategies[type]) {
|
|
33
|
+
strategies[type] = [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
strategies[type].push(strategy);
|
|
37
|
+
|
|
38
|
+
return this;
|
|
39
|
+
},
|
|
40
|
+
async authenticate(ctx, next) {
|
|
41
|
+
const { route } = ctx.state;
|
|
42
|
+
|
|
43
|
+
// use route strategy
|
|
44
|
+
const config = prop('config.auth', route);
|
|
45
|
+
|
|
46
|
+
if (config === false) {
|
|
47
|
+
return next();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const strategiesToUse = strategies[route.info.type];
|
|
51
|
+
|
|
52
|
+
for (const strategy of strategiesToUse) {
|
|
53
|
+
const result = await strategy.authenticate(ctx);
|
|
54
|
+
|
|
55
|
+
const { authenticated = false, error = null, credentials } = result || {};
|
|
56
|
+
|
|
57
|
+
if (error !== null) {
|
|
58
|
+
return ctx.unauthorized(error);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (authenticated) {
|
|
62
|
+
ctx.state.isAuthenticated = true;
|
|
63
|
+
ctx.state.auth = {
|
|
64
|
+
strategy,
|
|
65
|
+
credentials,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return next();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return ctx.unauthorized('Missing or invalid credentials');
|
|
73
|
+
},
|
|
74
|
+
async verify(auth, config = {}) {
|
|
75
|
+
if (config === false) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!auth) {
|
|
80
|
+
throw new UnauthorizedError();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (typeof auth.strategy.verify === 'function') {
|
|
84
|
+
return auth.strategy.verify(auth, config);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
module.exports = createAuthentication;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const coreStoreModel = {
|
|
4
|
+
uid: 'strapi::core-store',
|
|
5
|
+
collectionName: 'strapi_core_store_settings',
|
|
6
|
+
attributes: {
|
|
7
|
+
key: {
|
|
8
|
+
type: 'string',
|
|
9
|
+
},
|
|
10
|
+
value: {
|
|
11
|
+
type: 'text',
|
|
12
|
+
},
|
|
13
|
+
type: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
},
|
|
16
|
+
environment: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
},
|
|
19
|
+
tag: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const createCoreStore = ({ db }) => {
|
|
26
|
+
const mergeParams = (defaultParams, params) => {
|
|
27
|
+
return {
|
|
28
|
+
...defaultParams,
|
|
29
|
+
...params,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const store = function(defaultParams = {}) {
|
|
34
|
+
return {
|
|
35
|
+
get: params => store.get(mergeParams(defaultParams, params)),
|
|
36
|
+
set: params => store.set(mergeParams(defaultParams, params)),
|
|
37
|
+
delete: params => store.delete(mergeParams(defaultParams, params)),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
Object.assign(store, {
|
|
42
|
+
/**
|
|
43
|
+
* Get value from the core store
|
|
44
|
+
* @param {Object} params
|
|
45
|
+
* @returns {*}
|
|
46
|
+
*/
|
|
47
|
+
async get(params = {}) {
|
|
48
|
+
const { key, type = 'core', environment, name, tag } = params;
|
|
49
|
+
|
|
50
|
+
const prefix = `${type}${name ? `_${name}` : ''}`;
|
|
51
|
+
|
|
52
|
+
const where = {
|
|
53
|
+
key: `${prefix}_${key}`,
|
|
54
|
+
environment: environment || null,
|
|
55
|
+
tag: tag || null,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const data = await db.query('strapi::core-store').findOne({ where });
|
|
59
|
+
|
|
60
|
+
if (!data) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
data.type === 'object' ||
|
|
66
|
+
data.type === 'array' ||
|
|
67
|
+
data.type === 'boolean' ||
|
|
68
|
+
data.type === 'string'
|
|
69
|
+
) {
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(data.value);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
return new Date(data.value);
|
|
74
|
+
}
|
|
75
|
+
} else if (data.type === 'number') {
|
|
76
|
+
return Number(data.value);
|
|
77
|
+
} else {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Set value in the core store
|
|
84
|
+
* @param {Object} params
|
|
85
|
+
* @returns {*}
|
|
86
|
+
*/
|
|
87
|
+
async set(params = {}) {
|
|
88
|
+
const { key, value, type, environment, name, tag } = params;
|
|
89
|
+
|
|
90
|
+
const prefix = `${type}${name ? `_${name}` : ''}`;
|
|
91
|
+
|
|
92
|
+
const where = {
|
|
93
|
+
key: `${prefix}_${key}`,
|
|
94
|
+
environment: environment || null,
|
|
95
|
+
tag: tag || null,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const data = await db.query('strapi::core-store').findOne({ where });
|
|
99
|
+
|
|
100
|
+
if (data) {
|
|
101
|
+
return db.query('strapi::core-store').update({
|
|
102
|
+
where: { id: data.id },
|
|
103
|
+
data: {
|
|
104
|
+
value: JSON.stringify(value) || value.toString(),
|
|
105
|
+
type: typeof value,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return db.query('strapi::core-store').create({
|
|
111
|
+
data: {
|
|
112
|
+
...where,
|
|
113
|
+
value: JSON.stringify(value) || value.toString(),
|
|
114
|
+
type: typeof value,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Deletes a value from the core store
|
|
121
|
+
* @param {Object} params
|
|
122
|
+
* @returns {*}
|
|
123
|
+
*/
|
|
124
|
+
async delete(params = {}) {
|
|
125
|
+
const { key, environment, type, name, tag } = params;
|
|
126
|
+
|
|
127
|
+
const prefix = `${type}${name ? `_${name}` : ''}`;
|
|
128
|
+
|
|
129
|
+
const where = {
|
|
130
|
+
key: `${prefix}_${key}`,
|
|
131
|
+
environment: environment || null,
|
|
132
|
+
tag: tag || null,
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
return db.query('strapi::core-store').delete({ where });
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
return store;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
module.exports = {
|
|
143
|
+
coreStoreModel,
|
|
144
|
+
createCoreStore,
|
|
145
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { Job } = require('node-schedule');
|
|
4
|
+
const { isFunction } = require('lodash/fp');
|
|
5
|
+
|
|
6
|
+
const createCronService = () => {
|
|
7
|
+
let jobsSpecs = [];
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
add(tasks = {}) {
|
|
11
|
+
for (const taskExpression in tasks) {
|
|
12
|
+
const taskValue = tasks[taskExpression];
|
|
13
|
+
|
|
14
|
+
let fn;
|
|
15
|
+
let options;
|
|
16
|
+
if (isFunction(taskValue)) {
|
|
17
|
+
fn = taskValue.bind(tasks);
|
|
18
|
+
options = taskExpression;
|
|
19
|
+
} else if (isFunction(taskValue.task)) {
|
|
20
|
+
fn = taskValue.task.bind(taskValue);
|
|
21
|
+
options = taskValue.options;
|
|
22
|
+
} else {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Could not schedule a cron job for "${taskExpression}": no function found.`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const fnWithStrapi = (...args) => fn({ strapi }, ...args);
|
|
29
|
+
|
|
30
|
+
const job = new Job(null, fnWithStrapi);
|
|
31
|
+
jobsSpecs.push({ job, options });
|
|
32
|
+
}
|
|
33
|
+
return this;
|
|
34
|
+
},
|
|
35
|
+
start() {
|
|
36
|
+
if (!strapi.config.get('server.cron.enabled')) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
jobsSpecs.forEach(({ job, options }) => job.schedule(options));
|
|
40
|
+
return this;
|
|
41
|
+
},
|
|
42
|
+
stop() {
|
|
43
|
+
jobsSpecs.forEach(({ job }) => job.cancel());
|
|
44
|
+
return this;
|
|
45
|
+
},
|
|
46
|
+
destroy() {
|
|
47
|
+
this.stop();
|
|
48
|
+
jobsSpecs = [];
|
|
49
|
+
return this;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = createCronService;
|