@strapi/plugin-documentation 4.0.0-next.6 → 4.0.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/admin/src/components/FieldActionWrapper/index.js +14 -0
- package/admin/src/components/PluginIcon/index.js +12 -0
- package/admin/src/index.js +27 -12
- package/admin/src/pages/PluginPage/index.js +199 -0
- package/admin/src/pages/PluginPage/tests/index.test.js +873 -0
- package/admin/src/pages/PluginPage/tests/server.js +23 -0
- package/admin/src/pages/SettingsPage/index.js +181 -0
- package/admin/src/pages/SettingsPage/tests/index.test.js +612 -0
- package/admin/src/pages/SettingsPage/tests/server.js +18 -0
- package/admin/src/pages/{HomePage/utils → utils}/api.js +5 -4
- package/admin/src/pages/{HomePage/utils → utils}/schema.js +0 -0
- package/admin/src/pages/utils/useReactQuery.js +46 -0
- package/admin/src/permissions.js +7 -7
- package/admin/src/translations/ar.json +0 -3
- package/admin/src/translations/cs.json +0 -3
- package/admin/src/translations/de.json +0 -3
- package/admin/src/translations/en.json +14 -3
- package/admin/src/translations/es.json +0 -3
- package/admin/src/translations/fr.json +0 -3
- package/admin/src/translations/id.json +0 -3
- package/admin/src/translations/it.json +0 -3
- package/admin/src/translations/ko.json +0 -3
- package/admin/src/translations/ms.json +0 -3
- package/admin/src/translations/nl.json +0 -3
- package/admin/src/translations/pl.json +0 -3
- package/admin/src/translations/pt-BR.json +0 -3
- package/admin/src/translations/pt.json +0 -3
- package/admin/src/translations/ru.json +0 -3
- package/admin/src/translations/sk.json +0 -3
- package/admin/src/translations/th.json +0 -3
- package/admin/src/translations/tr.json +0 -3
- package/admin/src/translations/uk.json +0 -3
- package/admin/src/translations/vi.json +0 -3
- package/admin/src/translations/zh-Hans.json +3 -6
- package/admin/src/translations/zh.json +0 -3
- package/package.json +32 -45
- package/server/bootstrap.js +56 -0
- package/server/config/default-config.js +45 -0
- package/server/config/index.js +16 -0
- package/server/controllers/documentation.js +240 -0
- package/server/controllers/index.js +7 -0
- package/server/index.js +17 -0
- package/server/middlewares/documentation.js +30 -0
- package/server/middlewares/index.js +7 -0
- package/server/middlewares/restrict-access.js +24 -0
- package/{public → server/public}/index.html +0 -0
- package/{public → server/public}/login.html +0 -0
- package/server/register.js +11 -0
- package/server/routes/index.js +83 -0
- package/server/services/documentation.js +155 -0
- package/server/services/index.js +7 -0
- package/{services → server/services}/utils/components.json +0 -0
- package/{services → server/services}/utils/parametersOptions.json +0 -0
- package/{services → server/services}/utils/unknownComponent.json +0 -0
- package/server/utils/builders/build-api-endpoint-path.js +174 -0
- package/server/utils/builders/build-api-requests.js +41 -0
- package/server/utils/builders/build-api-responses.js +108 -0
- package/server/utils/builders/index.js +11 -0
- package/server/utils/clean-schema-attributes.js +205 -0
- package/server/utils/error-response.js +22 -0
- package/server/utils/get-schema-data.js +32 -0
- package/server/utils/query-params.js +84 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +3 -0
- package/admin/src/assets/images/logo.svg +0 -1
- package/admin/src/components/Block/components.js +0 -26
- package/admin/src/components/Block/index.js +0 -39
- package/admin/src/components/Copy/index.js +0 -36
- package/admin/src/components/Header/index.js +0 -72
- package/admin/src/components/Row/ButtonContainer.js +0 -67
- package/admin/src/components/Row/components.js +0 -83
- package/admin/src/components/Row/index.js +0 -51
- package/admin/src/pages/App/index.js +0 -21
- package/admin/src/pages/HomePage/components.js +0 -59
- package/admin/src/pages/HomePage/index.js +0 -168
- package/admin/src/pages/HomePage/useHomePage.js +0 -56
- package/config/functions/bootstrap.js +0 -142
- package/config/policies/index.js +0 -33
- package/config/routes.json +0 -74
- package/config/settings.json +0 -46
- package/controllers/Documentation.js +0 -302
- package/middlewares/documentation/defaults.json +0 -5
- package/middlewares/documentation/index.js +0 -59
- package/services/Documentation.js +0 -1863
- package/services/utils/forms.json +0 -29
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-unreachable */
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const _ = require('lodash');
|
|
7
|
-
|
|
8
|
-
// Add permissions
|
|
9
|
-
const RBAC_ACTIONS = [
|
|
10
|
-
{
|
|
11
|
-
section: 'plugins',
|
|
12
|
-
displayName: 'Access the Documentation',
|
|
13
|
-
uid: 'read',
|
|
14
|
-
pluginName: 'documentation',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
section: 'plugins',
|
|
18
|
-
displayName: 'Update and delete',
|
|
19
|
-
uid: 'settings.update',
|
|
20
|
-
subCategory: 'settings',
|
|
21
|
-
pluginName: 'documentation',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
section: 'plugins',
|
|
25
|
-
displayName: 'Regenerate',
|
|
26
|
-
uid: 'settings.regenerate',
|
|
27
|
-
subCategory: 'settings',
|
|
28
|
-
pluginName: 'documentation',
|
|
29
|
-
},
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
module.exports = async () => {
|
|
33
|
-
await strapi.admin.services.permission.actionProvider.registerMany(RBAC_ACTIONS);
|
|
34
|
-
|
|
35
|
-
return;
|
|
36
|
-
|
|
37
|
-
// Check if the plugin users-permissions is installed because the documentation needs it
|
|
38
|
-
if (Object.keys(strapi.plugins).indexOf('users-permissions') === -1) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
'In order to make the documentation plugin works the users-permissions one is required'
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const pluginStore = strapi.store({
|
|
45
|
-
environment: '',
|
|
46
|
-
type: 'plugin',
|
|
47
|
-
name: 'documentation',
|
|
48
|
-
});
|
|
49
|
-
const restrictedAccess = await pluginStore.get({ key: 'config' });
|
|
50
|
-
|
|
51
|
-
if (!restrictedAccess) {
|
|
52
|
-
pluginStore.set({ key: 'config', value: { restrictedAccess: false } });
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
let shouldUpdateFullDoc = false;
|
|
56
|
-
const services = strapi.plugins['documentation'].services.documentation;
|
|
57
|
-
// Generate plugins' documentation
|
|
58
|
-
const pluginsWithDocumentationNeeded = services.getPluginsWithDocumentationNeeded();
|
|
59
|
-
|
|
60
|
-
pluginsWithDocumentationNeeded.forEach(plugin => {
|
|
61
|
-
const isDocExisting = services.checkIfPluginDocumentationFolderExists(plugin);
|
|
62
|
-
|
|
63
|
-
if (!isDocExisting) {
|
|
64
|
-
services.createDocumentationDirectory(services.getPluginDocumentationPath(plugin));
|
|
65
|
-
// create the overrides directory
|
|
66
|
-
services.createDocumentationDirectory(services.getPluginOverrideDocumentationPath(plugin));
|
|
67
|
-
services.createPluginDocumentationFile(plugin);
|
|
68
|
-
shouldUpdateFullDoc = true;
|
|
69
|
-
} else {
|
|
70
|
-
const needToUpdatePluginDoc = services.checkIfPluginDocNeedsUpdate(plugin);
|
|
71
|
-
|
|
72
|
-
if (needToUpdatePluginDoc) {
|
|
73
|
-
services.createPluginDocumentationFile(plugin);
|
|
74
|
-
shouldUpdateFullDoc = true;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Retrieve all the apis from the apis directory
|
|
80
|
-
const apis = services.getApis();
|
|
81
|
-
// Generate APIS' documentation
|
|
82
|
-
apis.forEach(api => {
|
|
83
|
-
const isDocExisting = services.checkIfDocumentationFolderExists(api);
|
|
84
|
-
|
|
85
|
-
if (!isDocExisting) {
|
|
86
|
-
// If the documentation directory doesn't exist create it
|
|
87
|
-
services.createDocumentationDirectory(services.getDocumentationPath(api));
|
|
88
|
-
// Create the overrides directory
|
|
89
|
-
services.createDocumentationDirectory(services.getDocumentationOverridesPath(api));
|
|
90
|
-
// Create the documentation files per version
|
|
91
|
-
services.createDocumentationFile(api); // Then create the {api}.json documentation file
|
|
92
|
-
shouldUpdateFullDoc = true;
|
|
93
|
-
} else {
|
|
94
|
-
const needToUpdateAPIDoc = services.checkIfAPIDocNeedsUpdate(api);
|
|
95
|
-
|
|
96
|
-
if (needToUpdateAPIDoc) {
|
|
97
|
-
services.createDocumentationFile(api);
|
|
98
|
-
shouldUpdateFullDoc = true;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const fullDoc = services.generateFullDoc();
|
|
104
|
-
// Verify that the correct documentation folder exists in the documentation plugin
|
|
105
|
-
const isMergedDocumentationExists = services.checkIfMergedDocumentationFolderExists();
|
|
106
|
-
const documentationPath = services.getMergedDocumentationPath();
|
|
107
|
-
|
|
108
|
-
if (isMergedDocumentationExists) {
|
|
109
|
-
/**
|
|
110
|
-
* Retrieve all tags from the documentation and join them
|
|
111
|
-
* @param {Object} documentation
|
|
112
|
-
* @returns {String}
|
|
113
|
-
*/
|
|
114
|
-
const getDocTagsToString = documentation => {
|
|
115
|
-
return _.get(documentation, 'tags', [])
|
|
116
|
-
.map(tag => {
|
|
117
|
-
return tag.name.toLowerCase();
|
|
118
|
-
})
|
|
119
|
-
.sort((a, b) => a - b)
|
|
120
|
-
.join('.');
|
|
121
|
-
};
|
|
122
|
-
const oldDoc = require(path.resolve(documentationPath, 'full_documentation.json'));
|
|
123
|
-
const oldDocTags = getDocTagsToString(oldDoc);
|
|
124
|
-
const currentDocTags = getDocTagsToString(fullDoc);
|
|
125
|
-
|
|
126
|
-
// If the tags are different (an api has been deleted) we need to rebuild the documentation
|
|
127
|
-
if (oldDocTags !== currentDocTags) {
|
|
128
|
-
shouldUpdateFullDoc = true;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (!isMergedDocumentationExists || shouldUpdateFullDoc) {
|
|
133
|
-
// Create the folder
|
|
134
|
-
services.createDocumentationDirectory(documentationPath);
|
|
135
|
-
// Write the file
|
|
136
|
-
fs.writeFileSync(
|
|
137
|
-
path.resolve(documentationPath, 'full_documentation.json'),
|
|
138
|
-
JSON.stringify(fullDoc, null, 2),
|
|
139
|
-
'utf8'
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
};
|
package/config/policies/index.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = async (ctx, next) => {
|
|
4
|
-
const pluginStore = strapi.store({
|
|
5
|
-
environment: '',
|
|
6
|
-
type: 'plugin',
|
|
7
|
-
name: 'documentation',
|
|
8
|
-
});
|
|
9
|
-
const config = await pluginStore.get({ key: 'config' });
|
|
10
|
-
|
|
11
|
-
if (!config.restrictedAccess) {
|
|
12
|
-
return await next();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (!ctx.session.documentation) {
|
|
16
|
-
const querystring = ctx.querystring ? `?${ctx.querystring}` : '';
|
|
17
|
-
|
|
18
|
-
return ctx.redirect(
|
|
19
|
-
`${strapi.config.server.url}${strapi.plugins.documentation.config['x-strapi-config'].path}/login${querystring}`
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
const isValid = await strapi.plugins['users-permissions'].services.user.validatePassword(
|
|
23
|
-
ctx.session.documentation,
|
|
24
|
-
config.password
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
if (!isValid) {
|
|
28
|
-
ctx.session.documentation = null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Execute the action.
|
|
32
|
-
await next();
|
|
33
|
-
};
|
package/config/routes.json
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"routes": [
|
|
3
|
-
{
|
|
4
|
-
"method": "GET",
|
|
5
|
-
"path": "/",
|
|
6
|
-
"handler": "Documentation.index",
|
|
7
|
-
"config": {
|
|
8
|
-
"policies": [
|
|
9
|
-
"plugins::documentation.index",
|
|
10
|
-
["admin::hasPermissions", ["plugins::documentation.read"]]
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"method": "GET",
|
|
16
|
-
"path": "/v:major(\\d+).:minor(\\d+).:patch(\\d+)",
|
|
17
|
-
"handler": "Documentation.index",
|
|
18
|
-
"config": {
|
|
19
|
-
"policies": [
|
|
20
|
-
"plugins::documentation.index",
|
|
21
|
-
["admin::hasPermissions", ["plugins::documentation.read"]]
|
|
22
|
-
]
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"method": "GET",
|
|
27
|
-
"path": "/login",
|
|
28
|
-
"handler": "Documentation.loginView",
|
|
29
|
-
"config": {
|
|
30
|
-
"policies": [["admin::hasPermissions", ["plugins::documentation.read"]]]
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
"method": "POST",
|
|
35
|
-
"path": "/login",
|
|
36
|
-
"handler": "Documentation.login",
|
|
37
|
-
"config": {
|
|
38
|
-
"policies": [["admin::hasPermissions", ["plugins::documentation.read"]]]
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"method": "GET",
|
|
43
|
-
"path": "/getInfos",
|
|
44
|
-
"handler": "Documentation.getInfos",
|
|
45
|
-
"config": {
|
|
46
|
-
"policies": [["admin::hasPermissions", ["plugins::documentation.read"]]]
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"method": "POST",
|
|
51
|
-
"path": "/regenerateDoc",
|
|
52
|
-
"handler": "Documentation.regenerateDoc",
|
|
53
|
-
"config": {
|
|
54
|
-
"policies": [["admin::hasPermissions", ["plugins::documentation.settings.regenerate"]]]
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"method": "PUT",
|
|
59
|
-
"path": "/updateSettings",
|
|
60
|
-
"handler": "Documentation.updateSettings",
|
|
61
|
-
"config": {
|
|
62
|
-
"policies": [["admin::hasPermissions", ["plugins::documentation.settings.update"]]]
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"method": "DELETE",
|
|
67
|
-
"path": "/deleteDoc/:version",
|
|
68
|
-
"handler": "Documentation.deleteDoc",
|
|
69
|
-
"config": {
|
|
70
|
-
"policies": []
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
}
|
package/config/settings.json
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"openapi": "3.0.0",
|
|
3
|
-
"info": {
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"title": "DOCUMENTATION",
|
|
6
|
-
"description": "",
|
|
7
|
-
"termsOfService": "YOUR_TERMS_OF_SERVICE_URL",
|
|
8
|
-
"contact": {
|
|
9
|
-
"name": "TEAM",
|
|
10
|
-
"email": "contact-email@something.io",
|
|
11
|
-
"url": "mywebsite.io"
|
|
12
|
-
},
|
|
13
|
-
"license": {
|
|
14
|
-
"name": "Apache 2.0",
|
|
15
|
-
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
"x-strapi-config": {
|
|
19
|
-
"path": "/documentation",
|
|
20
|
-
"showGeneratedFiles": true,
|
|
21
|
-
"generateDefaultResponse": true
|
|
22
|
-
},
|
|
23
|
-
"servers": [
|
|
24
|
-
{
|
|
25
|
-
"url": "http://localhost:1337",
|
|
26
|
-
"description": "Development server"
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"url": "YOUR_STAGING_SERVER",
|
|
30
|
-
"description": "Staging server"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"url": "YOUR_PRODUCTION_SERVER",
|
|
34
|
-
"description": "Production server"
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
"externalDocs": {
|
|
38
|
-
"description": "Find out more",
|
|
39
|
-
"url": "https://strapi.io/documentation/developer-docs/latest/getting-started/introduction.html"
|
|
40
|
-
},
|
|
41
|
-
"security": [
|
|
42
|
-
{
|
|
43
|
-
"bearerAuth": []
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
}
|
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Documentation.js controller
|
|
5
|
-
*
|
|
6
|
-
* @description: A set of functions called "actions" of the `documentation` plugin.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
// Core dependencies.
|
|
10
|
-
const path = require('path');
|
|
11
|
-
|
|
12
|
-
// Public dependencies.
|
|
13
|
-
const fs = require('fs-extra');
|
|
14
|
-
const cheerio = require('cheerio');
|
|
15
|
-
const _ = require('lodash');
|
|
16
|
-
const koaStatic = require('koa-static');
|
|
17
|
-
|
|
18
|
-
module.exports = {
|
|
19
|
-
getInfos: async ctx => {
|
|
20
|
-
try {
|
|
21
|
-
const service = strapi.plugins.documentation.services.documentation;
|
|
22
|
-
const docVersions = service.retrieveDocumentationVersions();
|
|
23
|
-
const form = await service.retrieveFrontForm();
|
|
24
|
-
|
|
25
|
-
ctx.send({
|
|
26
|
-
docVersions,
|
|
27
|
-
currentVersion: service.getDocumentationVersion(),
|
|
28
|
-
prefix: strapi.plugins.documentation.config['x-strapi-config'].path,
|
|
29
|
-
form,
|
|
30
|
-
});
|
|
31
|
-
} catch (err) {
|
|
32
|
-
ctx.badRequest(null, err.message);
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
async index(ctx, next) {
|
|
37
|
-
try {
|
|
38
|
-
/**
|
|
39
|
-
* We don't expose the specs using koa-static or something else due to security reasons.
|
|
40
|
-
* That's why, we need to read the file localy and send the specs through it when we serve the Swagger UI.
|
|
41
|
-
*/
|
|
42
|
-
const { major, minor, patch } = ctx.params;
|
|
43
|
-
const version =
|
|
44
|
-
major && minor && patch
|
|
45
|
-
? `${major}.${minor}.${patch}`
|
|
46
|
-
: strapi.plugins.documentation.config.info.version;
|
|
47
|
-
const openAPISpecsPath = path.join(
|
|
48
|
-
strapi.config.appPath,
|
|
49
|
-
'extensions',
|
|
50
|
-
'documentation',
|
|
51
|
-
'documentation',
|
|
52
|
-
version,
|
|
53
|
-
'full_documentation.json'
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
const documentation = fs.readFileSync(openAPISpecsPath, 'utf8');
|
|
58
|
-
const layout = fs.readFileSync(
|
|
59
|
-
path.resolve(__dirname, '..', 'public', 'index.html'),
|
|
60
|
-
'utf8'
|
|
61
|
-
);
|
|
62
|
-
const filledLayout = _.template(layout)({
|
|
63
|
-
backendUrl: strapi.config.server.url,
|
|
64
|
-
spec: JSON.stringify(JSON.parse(documentation)),
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
const layoutPath = path.resolve(
|
|
69
|
-
strapi.config.appPath,
|
|
70
|
-
'extensions',
|
|
71
|
-
'documentation',
|
|
72
|
-
'public',
|
|
73
|
-
'index.html'
|
|
74
|
-
);
|
|
75
|
-
await fs.ensureFile(layoutPath);
|
|
76
|
-
await fs.writeFile(layoutPath, filledLayout);
|
|
77
|
-
|
|
78
|
-
// Serve the file.
|
|
79
|
-
ctx.url = path.basename(`${ctx.url}/index.html`);
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
const staticFolder = path.resolve(
|
|
83
|
-
strapi.config.appPath,
|
|
84
|
-
'extensions',
|
|
85
|
-
'documentation',
|
|
86
|
-
'public'
|
|
87
|
-
);
|
|
88
|
-
return await koaStatic(staticFolder)(ctx, next);
|
|
89
|
-
} catch (e) {
|
|
90
|
-
strapi.log.error(e);
|
|
91
|
-
}
|
|
92
|
-
} catch (e) {
|
|
93
|
-
strapi.log.error(e);
|
|
94
|
-
}
|
|
95
|
-
} catch (e) {
|
|
96
|
-
strapi.log.error(e);
|
|
97
|
-
}
|
|
98
|
-
} catch (e) {
|
|
99
|
-
strapi.log.error(e);
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
async loginView(ctx, next) {
|
|
104
|
-
const { error } = ctx.query;
|
|
105
|
-
|
|
106
|
-
try {
|
|
107
|
-
const layout = fs.readFileSync(path.join(__dirname, '..', 'public', 'login.html'));
|
|
108
|
-
const filledLayout = _.template(layout)({
|
|
109
|
-
actionUrl: `${strapi.config.server.url}${strapi.plugins.documentation.config['x-strapi-config'].path}/login`,
|
|
110
|
-
});
|
|
111
|
-
const $ = cheerio.load(filledLayout);
|
|
112
|
-
|
|
113
|
-
$('.error').text(_.isEmpty(error) ? '' : 'Wrong password...');
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
const layoutPath = path.resolve(
|
|
117
|
-
strapi.config.appPath,
|
|
118
|
-
'extensions',
|
|
119
|
-
'documentation',
|
|
120
|
-
'public',
|
|
121
|
-
'login.html'
|
|
122
|
-
);
|
|
123
|
-
await fs.ensureFile(layoutPath);
|
|
124
|
-
await fs.writeFile(layoutPath, $.html());
|
|
125
|
-
|
|
126
|
-
ctx.url = path.basename(`${ctx.url}/login.html`);
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
const staticFolder = path.resolve(
|
|
130
|
-
strapi.config.appPath,
|
|
131
|
-
'extensions',
|
|
132
|
-
'documentation',
|
|
133
|
-
'public'
|
|
134
|
-
);
|
|
135
|
-
return await koaStatic(staticFolder)(ctx, next);
|
|
136
|
-
} catch (e) {
|
|
137
|
-
strapi.log.error(e);
|
|
138
|
-
}
|
|
139
|
-
} catch (e) {
|
|
140
|
-
strapi.log.error(e);
|
|
141
|
-
}
|
|
142
|
-
} catch (e) {
|
|
143
|
-
strapi.log.error(e);
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
async login(ctx) {
|
|
148
|
-
const {
|
|
149
|
-
body: { password },
|
|
150
|
-
} = ctx.request;
|
|
151
|
-
|
|
152
|
-
const { password: storedPassword } = await strapi
|
|
153
|
-
.store({
|
|
154
|
-
environment: '',
|
|
155
|
-
type: 'plugin',
|
|
156
|
-
name: 'documentation',
|
|
157
|
-
key: 'config',
|
|
158
|
-
})
|
|
159
|
-
.get();
|
|
160
|
-
|
|
161
|
-
const isValid = await strapi.plugins['users-permissions'].services.user.validatePassword(
|
|
162
|
-
password,
|
|
163
|
-
storedPassword
|
|
164
|
-
);
|
|
165
|
-
let querystring = '?error=password';
|
|
166
|
-
|
|
167
|
-
if (isValid) {
|
|
168
|
-
ctx.session.documentation = password;
|
|
169
|
-
querystring = '';
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
ctx.redirect(
|
|
173
|
-
`${strapi.config.server.url}${strapi.plugins.documentation.config['x-strapi-config'].path}${querystring}`
|
|
174
|
-
);
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
regenerateDoc: async ctx => {
|
|
178
|
-
const service = strapi.plugins.documentation.services.documentation;
|
|
179
|
-
const documentationVersions = service.retrieveDocumentationVersions().map(el => el.version);
|
|
180
|
-
const {
|
|
181
|
-
request: {
|
|
182
|
-
body: { version },
|
|
183
|
-
admin,
|
|
184
|
-
},
|
|
185
|
-
} = ctx;
|
|
186
|
-
|
|
187
|
-
if (_.isEmpty(version)) {
|
|
188
|
-
return ctx.badRequest(
|
|
189
|
-
null,
|
|
190
|
-
admin ? 'documentation.error.noVersion' : 'Please provide a version.'
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (!documentationVersions.includes(version)) {
|
|
195
|
-
return ctx.badRequest(
|
|
196
|
-
null,
|
|
197
|
-
admin
|
|
198
|
-
? 'documentation.error.regenerateDoc.versionMissing'
|
|
199
|
-
: 'The version you are trying to generate does not exist.'
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
strapi.reload.isWatching = false;
|
|
205
|
-
const fullDoc = service.generateFullDoc(version);
|
|
206
|
-
const documentationPath = service.getMergedDocumentationPath(version);
|
|
207
|
-
// Write the file
|
|
208
|
-
fs.writeFileSync(
|
|
209
|
-
path.resolve(documentationPath, 'full_documentation.json'),
|
|
210
|
-
JSON.stringify(fullDoc, null, 2),
|
|
211
|
-
'utf8'
|
|
212
|
-
);
|
|
213
|
-
ctx.send({ ok: true });
|
|
214
|
-
} catch (err) {
|
|
215
|
-
ctx.badRequest(null, admin ? 'documentation.error.regenerateDoc' : 'An error occured');
|
|
216
|
-
} finally {
|
|
217
|
-
strapi.reload.isWatching = true;
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
deleteDoc: async ctx => {
|
|
222
|
-
strapi.reload.isWatching = false;
|
|
223
|
-
const service = strapi.plugins.documentation.services.documentation;
|
|
224
|
-
const documentationVersions = service.retrieveDocumentationVersions().map(el => el.version);
|
|
225
|
-
|
|
226
|
-
const {
|
|
227
|
-
params: { version },
|
|
228
|
-
request: { admin },
|
|
229
|
-
} = ctx;
|
|
230
|
-
|
|
231
|
-
if (_.isEmpty(version)) {
|
|
232
|
-
return ctx.badRequest(
|
|
233
|
-
null,
|
|
234
|
-
admin ? 'documentation.error.noVersion' : 'Please provide a version.'
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (!documentationVersions.includes(version)) {
|
|
239
|
-
return ctx.badRequest(
|
|
240
|
-
null,
|
|
241
|
-
admin
|
|
242
|
-
? 'documentation.error.deleteDoc.versionMissing'
|
|
243
|
-
: 'The version you are trying to delete does not exist.'
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
try {
|
|
248
|
-
await service.deleteDocumentation(version);
|
|
249
|
-
ctx.send({ ok: true });
|
|
250
|
-
} catch (err) {
|
|
251
|
-
ctx.badRequest(null, admin ? 'notification.error' : err.message);
|
|
252
|
-
} finally {
|
|
253
|
-
strapi.reload.isWatching = true;
|
|
254
|
-
}
|
|
255
|
-
},
|
|
256
|
-
|
|
257
|
-
updateSettings: async ctx => {
|
|
258
|
-
const {
|
|
259
|
-
admin,
|
|
260
|
-
body: { restrictedAccess, password },
|
|
261
|
-
} = ctx.request;
|
|
262
|
-
const usersPermService = strapi.plugins['users-permissions'].services;
|
|
263
|
-
const pluginStore = strapi.store({
|
|
264
|
-
environment: '',
|
|
265
|
-
type: 'plugin',
|
|
266
|
-
name: 'documentation',
|
|
267
|
-
});
|
|
268
|
-
const prevConfig = await pluginStore.get({ key: 'config' });
|
|
269
|
-
|
|
270
|
-
if (restrictedAccess && _.isEmpty(password)) {
|
|
271
|
-
return ctx.badRequest(
|
|
272
|
-
null,
|
|
273
|
-
admin ? 'users-permissions.Auth.form.error.password.provide' : 'Please provide a password'
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const isNewPassword = !_.isEmpty(password) && password !== prevConfig.password;
|
|
278
|
-
|
|
279
|
-
if (isNewPassword && usersPermService.user.isHashed(password)) {
|
|
280
|
-
// Throw an error if the password selected by the user
|
|
281
|
-
// contains more than two times the symbol '$'.
|
|
282
|
-
return ctx.badRequest(
|
|
283
|
-
null,
|
|
284
|
-
admin
|
|
285
|
-
? 'users-permissions.Auth.form.error.password.format'
|
|
286
|
-
: 'our password cannot contain more than three times the symbol `$`.'
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
if (isNewPassword) {
|
|
291
|
-
prevConfig.password = await usersPermService.user.hashPassword({
|
|
292
|
-
password,
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
_.set(prevConfig, 'restrictedAccess', restrictedAccess);
|
|
297
|
-
|
|
298
|
-
await pluginStore.set({ key: 'config', value: prevConfig });
|
|
299
|
-
|
|
300
|
-
return ctx.send({ ok: true });
|
|
301
|
-
},
|
|
302
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Module dependencies
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Public node modules.
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const _ = require('lodash');
|
|
10
|
-
const swaggerUi = require('swagger-ui-dist');
|
|
11
|
-
const koaStatic = require('koa-static');
|
|
12
|
-
|
|
13
|
-
// Variables.
|
|
14
|
-
const initialRoutes = [];
|
|
15
|
-
|
|
16
|
-
module.exports = strapi => {
|
|
17
|
-
return {
|
|
18
|
-
beforeInitialize() {
|
|
19
|
-
strapi.config.middleware.load.before.push('documentation');
|
|
20
|
-
|
|
21
|
-
initialRoutes.push(..._.cloneDeep(strapi.plugins.documentation.config.routes));
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
initialize() {
|
|
25
|
-
// Find the plugins routes.
|
|
26
|
-
strapi.plugins.documentation.config.routes = strapi.plugins.documentation.config.routes.map(
|
|
27
|
-
(route, index) => {
|
|
28
|
-
if (route.handler === 'Documentation.getInfos') {
|
|
29
|
-
return route;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (route.handler === 'Documentation.index' || route.path === '/login') {
|
|
33
|
-
route.config.policies = initialRoutes[index].config.policies;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Set prefix to empty to be able to customise it.
|
|
37
|
-
if (_.get(strapi.plugins, ['documentation', 'config', 'x-strapi-config', 'path'])) {
|
|
38
|
-
route.config.prefix = '';
|
|
39
|
-
route.path = `/${strapi.plugins.documentation.config['x-strapi-config'].path}${route.path}`.replace(
|
|
40
|
-
'//',
|
|
41
|
-
'/'
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return route;
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
strapi.router.get('/plugins/documentation/*', async (ctx, next) => {
|
|
50
|
-
ctx.url = path.basename(ctx.url);
|
|
51
|
-
|
|
52
|
-
return await koaStatic(swaggerUi.getAbsoluteFSPath(), {
|
|
53
|
-
maxage: strapi.config.middleware.settings.public.maxAge,
|
|
54
|
-
defer: true,
|
|
55
|
-
})(ctx, next);
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
};
|