@strapi/admin 4.7.0-beta.0 → 4.9.0-alpha.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/content-manager/components/CollectionTypeFormWrapper/index.js +6 -14
- package/admin/src/content-manager/components/DynamicTable/CellContent/RelationMultiple/index.js +1 -1
- package/admin/src/content-manager/components/DynamicZone/components/DynamicComponent.js +2 -0
- package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +39 -9
- package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/cleanData.js +9 -15
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +4 -12
- package/admin/src/content-manager/pages/EditView/DeleteLink/index.js +6 -8
- package/admin/src/content-manager/pages/ListView/index.js +6 -11
- package/admin/src/hooks/useRegenerate/index.js +2 -2
- package/admin/src/hooks/useSettingsMenu/utils/defaultGlobalLinks.js +0 -7
- package/admin/src/index.js +1 -0
- package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +15 -2
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +3 -5
- package/admin/src/pages/SettingsPage/{components/Tokens/TokenBox → pages/ApiTokens/EditView/components/ContentBox}/index.js +17 -17
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +142 -52
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +78 -0
- package/admin/src/pages/SettingsPage/{components/Tokens → pages/ApiTokens/EditView/components}/FormHead/index.js +19 -36
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +1 -5
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +14 -37
- package/admin/src/pages/SettingsPage/{components/Tokens/Table → pages/ApiTokens/ListView/DynamicTable}/DefaultButton/index.js +1 -1
- package/admin/src/pages/SettingsPage/{components/Tokens/Table → pages/ApiTokens/ListView/DynamicTable}/DeleteButton/index.js +1 -1
- package/admin/src/pages/SettingsPage/{components/Tokens/Table → pages/ApiTokens/ListView/DynamicTable}/ReadButton/index.js +0 -0
- package/admin/src/pages/SettingsPage/{components/Tokens/Table → pages/ApiTokens/ListView/DynamicTable}/UpdateButton/index.js +0 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +112 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +13 -5
- package/admin/src/pages/SettingsPage/pages/Users/components/MagicLink/MagicLinkWrapper.js +3 -20
- package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +0 -33
- package/admin/src/permissions/defaultPermissions.js +2 -23
- package/admin/src/translations/ar.json +4 -4
- package/admin/src/translations/ca.json +4 -4
- package/admin/src/translations/cs.json +4 -4
- package/admin/src/translations/de.json +4 -4
- package/admin/src/translations/dk.json +4 -4
- package/admin/src/translations/en.json +9 -17
- package/admin/src/translations/es.json +4 -4
- package/admin/src/translations/eu.json +4 -4
- package/admin/src/translations/fr.json +4 -4
- package/admin/src/translations/gu.json +4 -4
- package/admin/src/translations/he.json +4 -4
- package/admin/src/translations/hi.json +4 -4
- package/admin/src/translations/hu.json +4 -4
- package/admin/src/translations/id.json +4 -4
- package/admin/src/translations/it.json +4 -4
- package/admin/src/translations/ja.json +4 -4
- package/admin/src/translations/ko.json +4 -4
- package/admin/src/translations/ml.json +4 -4
- package/admin/src/translations/ms.json +4 -4
- package/admin/src/translations/nl.json +4 -4
- package/admin/src/translations/no.json +4 -4
- package/admin/src/translations/pl.json +4 -4
- package/admin/src/translations/pt-BR.json +4 -4
- package/admin/src/translations/pt.json +4 -4
- package/admin/src/translations/ru.json +785 -789
- package/admin/src/translations/sa.json +4 -4
- package/admin/src/translations/sk.json +4 -4
- package/admin/src/translations/sv.json +4 -4
- package/admin/src/translations/th.json +4 -4
- package/admin/src/translations/tr.json +4 -4
- package/admin/src/translations/uk.json +4 -4
- package/admin/src/translations/vi.json +4 -4
- package/admin/src/translations/zh-Hans.json +4 -4
- package/admin/src/translations/zh.json +4 -4
- package/build/1683.d59d0f23.chunk.js +268 -0
- package/build/{4855.bd092921.chunk.js → 2223.1bfea951.chunk.js} +88 -88
- package/build/2743.646a1015.chunk.js +45 -0
- package/build/3075.3ee481f1.chunk.js +108 -0
- package/build/3632.2e378cf8.chunk.js +138 -0
- package/build/4318.cd55ce02.chunk.js +30 -0
- package/build/8633.00ccd382.chunk.js +1 -0
- package/build/9707.b36ed71e.chunk.js +96 -0
- package/build/{Admin-authenticatedApp.f29f6021.chunk.js → Admin-authenticatedApp.a73577e1.chunk.js} +2 -2
- package/build/{Admin_InternalErrorPage.157152a8.chunk.js → Admin_InternalErrorPage.178ddb90.chunk.js} +1 -1
- package/build/{Admin_homePage.b1730882.chunk.js → Admin_homePage.c2f5f27d.chunk.js} +2 -2
- package/build/{Admin_marketplace.ea0316c2.chunk.js → Admin_marketplace.1df49c42.chunk.js} +1 -1
- package/build/{Admin_pluginsPage.5c24f963.chunk.js → Admin_pluginsPage.8d824408.chunk.js} +2 -2
- package/build/{Admin_profilePage.59af1978.chunk.js → Admin_profilePage.cb667bc5.chunk.js} +2 -2
- package/build/Admin_settingsPage.f90615fb.chunk.js +178 -0
- package/build/{Upload_ConfigureTheView.3f2b6e6a.chunk.js → Upload_ConfigureTheView.d306009d.chunk.js} +1 -1
- package/build/admin-app.06f07029.chunk.js +112 -0
- package/build/admin-edit-roles-page.35199b9d.chunk.js +1 -0
- package/build/admin-edit-users.9e48b00d.chunk.js +10 -0
- package/build/admin-users.cf7b4151.chunk.js +11 -0
- package/build/{api-tokens-create-page.0db3aec1.chunk.js → api-tokens-create-page.a31c7fba.chunk.js} +1 -1
- package/build/{api-tokens-edit-page.671e0e26.chunk.js → api-tokens-edit-page.64fef287.chunk.js} +1 -1
- package/build/api-tokens-list-page.e600ad3e.chunk.js +16 -0
- package/build/ar-json.39e54aba.chunk.js +1 -0
- package/build/{audit-logs-settings-page.c3dce30d.chunk.js → audit-logs-settings-page.d4da4579.chunk.js} +1 -1
- package/build/{ca-json.f6a0f472.chunk.js → ca-json.4d999055.chunk.js} +1 -1
- package/build/content-manager.255c3a59.chunk.js +1139 -0
- package/build/{content-type-builder-list-view.79e84b36.chunk.js → content-type-builder-list-view.8d7a3d68.chunk.js} +5 -5
- package/build/content-type-builder.3c8558a5.chunk.js +126 -0
- package/build/cs-json.4b44411c.chunk.js +1 -0
- package/build/{de-json.30e1f35b.chunk.js → de-json.866f8a28.chunk.js} +1 -1
- package/build/{dk-json.e6d9ffa4.chunk.js → dk-json.10f7b1d1.chunk.js} +1 -1
- package/build/email-settings-page.b19f2eb2.chunk.js +10 -0
- package/build/en-json.1997583c.chunk.js +1 -0
- package/build/es-json.ea15c957.chunk.js +1 -0
- package/build/{eu-json.fceecd8b.chunk.js → eu-json.3bc24d60.chunk.js} +1 -1
- package/build/{fr-json.78545ef8.chunk.js → fr-json.e88fbdfd.chunk.js} +1 -1
- package/build/{gu-json.676518f2.chunk.js → gu-json.94f0d242.chunk.js} +1 -1
- package/build/{he-json.ad22e8cc.chunk.js → he-json.f0de8cdb.chunk.js} +1 -1
- package/build/{hi-json.19b51c09.chunk.js → hi-json.df3a7be2.chunk.js} +1 -1
- package/build/{hu-json.f947088f.chunk.js → hu-json.680e6eef.chunk.js} +1 -1
- package/build/{i18n-settings-page.b8d8753e.chunk.js → i18n-settings-page.a6b49eac.chunk.js} +1 -1
- package/build/{id-json.504daa84.chunk.js → id-json.e0d83d41.chunk.js} +1 -1
- package/build/index.html +1 -1
- package/build/{it-json.2fd90f4d.chunk.js → it-json.8be59205.chunk.js} +1 -1
- package/build/{ja-json.c9f12d0b.chunk.js → ja-json.97ee41ba.chunk.js} +1 -1
- package/build/{ko-json.ef463065.chunk.js → ko-json.4cbbf4f2.chunk.js} +1 -1
- package/build/main.7f308c20.js +4322 -0
- package/build/{ml-json.490f666c.chunk.js → ml-json.e3747091.chunk.js} +1 -1
- package/build/ms-json.0eddffd9.chunk.js +1 -0
- package/build/{nl-json.c416295a.chunk.js → nl-json.371a15ee.chunk.js} +1 -1
- package/build/{no-json.1a2258ba.chunk.js → no-json.9b3cd181.chunk.js} +1 -1
- package/build/{pl-json.8cf0c871.chunk.js → pl-json.e535cbce.chunk.js} +1 -1
- package/build/{pt-BR-json.51fab8d0.chunk.js → pt-BR-json.e5fafa46.chunk.js} +1 -1
- package/build/pt-json.ee554a41.chunk.js +1 -0
- package/build/review-workflows-settings.7b4be1b0.chunk.js +63 -0
- package/build/{ru-json.aa5cd123.chunk.js → ru-json.866f0ff1.chunk.js} +1 -1
- package/build/runtime~main.bf374148.js +2 -0
- package/build/{sa-json.f3fa5407.chunk.js → sa-json.7efeb257.chunk.js} +1 -1
- package/build/{sk-json.9ec60d9f.chunk.js → sk-json.7bbeb0af.chunk.js} +1 -1
- package/build/{sso-settings-page.b85ad080.chunk.js → sso-settings-page.ad2143dd.chunk.js} +1 -1
- package/build/{sv-json.c6b0c237.chunk.js → sv-json.dc40951f.chunk.js} +1 -1
- package/build/{th-json.6e68155c.chunk.js → th-json.f664b96d.chunk.js} +1 -1
- package/build/{tr-json.9f41dc08.chunk.js → tr-json.b79eae31.chunk.js} +1 -1
- package/build/uk-json.b7e38370.chunk.js +1 -0
- package/build/upload-settings.eb1a7908.chunk.js +84 -0
- package/build/upload.700e2c84.chunk.js +33 -0
- package/build/{users-advanced-settings-page.fce9908e.chunk.js → users-advanced-settings-page.aae212f2.chunk.js} +1 -1
- package/build/{users-email-settings-page.343d0ad2.chunk.js → users-email-settings-page.8a9b0da1.chunk.js} +1 -1
- package/build/{users-providers-settings-page.e5a9a3f1.chunk.js → users-providers-settings-page.e6be909d.chunk.js} +10 -10
- package/build/{users-roles-settings-page.66312f31.chunk.js → users-roles-settings-page.97d06a80.chunk.js} +3 -3
- package/build/vi-json.ee4c5537.chunk.js +1 -0
- package/build/webhook-edit-page.9eb0f789.chunk.js +75 -0
- package/build/webhook-list-page.66082323.chunk.js +42 -0
- package/build/{zh-Hans-json.9c0eac99.chunk.js → zh-Hans-json.30a18940.chunk.js} +1 -1
- package/build/{zh-json.f88f563d.chunk.js → zh-json.49d84433.chunk.js} +1 -1
- package/ee/admin/hooks/useSettingsMenu/utils/customAdminLinks.js +12 -12
- package/ee/admin/hooks/useSettingsMenu/utils/customGlobalLinks.js +21 -13
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/ReviewWorkflows.js +137 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/actions/index.js +42 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/AddStage/AddStage.js +87 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/AddStage/index.js +1 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/Stage.js +90 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stage/index.js +1 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/Stages.js +77 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/components/Stages/index.js +1 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/constants.js +6 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows.js +63 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/index.js +3 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/reducer/index.js +102 -0
- package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/utils/getWorkflowValidationSchema.js +25 -0
- package/ee/admin/pages/SettingsPage/utils/customRoutes.js +16 -2
- package/ee/admin/permissions/customPermissions.js +7 -0
- package/ee/server/bootstrap.js +7 -1
- package/ee/server/config/admin-actions.js +10 -0
- package/ee/server/constants/default-stages.json +14 -0
- package/ee/server/constants/default-workflow.json +1 -0
- package/ee/server/constants/workflows.js +7 -0
- package/ee/server/content-types/index.js +9 -0
- package/ee/server/content-types/workflow/index.js +34 -0
- package/ee/server/content-types/workflow-stage/index.js +36 -0
- package/ee/server/controllers/index.js +2 -0
- package/ee/server/controllers/workflows/index.js +36 -0
- package/ee/server/controllers/workflows/stages/index.js +57 -0
- package/ee/server/index.js +1 -0
- package/ee/server/routes/index.js +87 -0
- package/ee/server/services/index.js +3 -0
- package/ee/server/services/review-workflows/review-workflows.js +54 -0
- package/ee/server/services/review-workflows/stages.js +133 -0
- package/ee/server/services/review-workflows/workflows.js +25 -0
- package/ee/server/utils/index.js +8 -0
- package/ee/server/utils/test.js +11 -0
- package/ee/server/validation/review-workflows.js +17 -0
- package/package.json +13 -13
- package/server/bootstrap.js +0 -2
- package/server/config/admin-actions.js +0 -64
- package/server/content-types/index.js +0 -2
- package/server/controllers/admin.js +0 -55
- package/server/controllers/api-token.js +5 -4
- package/server/controllers/index.js +0 -1
- package/server/register.js +9 -2
- package/server/routes/admin.js +0 -28
- package/server/routes/index.js +0 -2
- package/server/services/api-token.js +3 -2
- package/server/services/constants.js +0 -6
- package/server/services/index.js +0 -1
- package/server/strategies/api-token.js +2 -4
- package/server/strategies/index.js +0 -1
- package/server/utils/index.d.ts +0 -2
- package/server/validation/api-tokens.js +6 -1
- package/webpack.config.js +0 -3
- package/admin/src/pages/SettingsPage/components/Tokens/FormiTokenContainer/LifeSpanInput.js +0 -96
- package/admin/src/pages/SettingsPage/components/Tokens/LifeSpanInput/index.js +0 -98
- package/admin/src/pages/SettingsPage/components/Tokens/Regenerate/index.js +0 -73
- package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +0 -135
- package/admin/src/pages/SettingsPage/components/Tokens/TokenDescription/index.js +0 -51
- package/admin/src/pages/SettingsPage/components/Tokens/TokenName/index.js +0 -46
- package/admin/src/pages/SettingsPage/components/Tokens/TokenTypeSelect/index.js +0 -69
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/FormTransferTokenContainer/index.js +0 -105
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/LoadingView/index.js +0 -50
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/index.js +0 -201
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/getDateOfExpiration.js +0 -16
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js +0 -4
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/schema.js +0 -10
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/index.js +0 -182
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/utils/tableHeaders.js +0 -48
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedCreateView/index.js +0 -14
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedEditView/index.js +0 -14
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedListView/index.js +0 -12
- package/build/1683.c8aa7b7c.chunk.js +0 -268
- package/build/2743.6d1632f9.chunk.js +0 -45
- package/build/3075.dc3894fe.chunk.js +0 -108
- package/build/3632.0317b618.chunk.js +0 -138
- package/build/4649.15cc0afe.chunk.js +0 -30
- package/build/7259.aa68d808.chunk.js +0 -1
- package/build/7407.883fb1f5.chunk.js +0 -1
- package/build/9707.7290fd92.chunk.js +0 -96
- package/build/Admin_settingsPage.178dc6e3.chunk.js +0 -178
- package/build/admin-app.77a50e1f.chunk.js +0 -112
- package/build/admin-edit-roles-page.446b69dc.chunk.js +0 -1
- package/build/admin-edit-users.2ed69bfd.chunk.js +0 -10
- package/build/admin-users.fc003b10.chunk.js +0 -11
- package/build/api-tokens-list-page.7387102c.chunk.js +0 -16
- package/build/ar-json.932794f7.chunk.js +0 -1
- package/build/content-manager.42b24d46.chunk.js +0 -1139
- package/build/content-type-builder.855db321.chunk.js +0 -126
- package/build/cs-json.79879fb6.chunk.js +0 -1
- package/build/email-settings-page.d1fcc7a3.chunk.js +0 -10
- package/build/en-json.b0748970.chunk.js +0 -1
- package/build/es-json.e275481d.chunk.js +0 -1
- package/build/main.1022ed01.js +0 -4393
- package/build/ms-json.db87d8d3.chunk.js +0 -1
- package/build/pt-json.62927d1e.chunk.js +0 -1
- package/build/runtime~main.84941a97.js +0 -2
- package/build/transfer-tokens-create-page.16e23791.chunk.js +0 -1
- package/build/transfer-tokens-edit-page.3886c973.chunk.js +0 -1
- package/build/transfer-tokens-list-page.e8010a89.chunk.js +0 -16
- package/build/uk-json.b2fcd567.chunk.js +0 -1
- package/build/upload-settings.ef64bbf9.chunk.js +0 -84
- package/build/upload.c5730dfa.chunk.js +0 -33
- package/build/vi-json.f08d7d03.chunk.js +0 -1
- package/build/webhook-edit-page.73e51e64.chunk.js +0 -75
- package/build/webhook-list-page.1134f130.chunk.js +0 -42
- package/server/content-types/transfer-token-permission.js +0 -36
- package/server/content-types/transfer-token.js +0 -66
- package/server/controllers/transfer/index.js +0 -13
- package/server/controllers/transfer/runner.js +0 -24
- package/server/controllers/transfer/token.js +0 -131
- package/server/routes/transfer.js +0 -95
- package/server/services/transfer/index.js +0 -6
- package/server/services/transfer/permission.js +0 -22
- package/server/services/transfer/token.js +0 -409
- package/server/strategies/data-transfer.js +0 -107
- package/server/validation/transfer/index.js +0 -5
- package/server/validation/transfer/token.js +0 -34
|
@@ -3,11 +3,9 @@
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
5
5
|
const { map, values, sumBy, pipe, flatMap, propEq } = require('lodash/fp');
|
|
6
|
-
const execa = require('execa');
|
|
7
6
|
const _ = require('lodash');
|
|
8
7
|
const { exists } = require('fs-extra');
|
|
9
8
|
const { env } = require('@strapi/utils');
|
|
10
|
-
const { ValidationError } = require('@strapi/utils').errors;
|
|
11
9
|
const { isUsingTypeScript } = require('@strapi/typescript-utils');
|
|
12
10
|
// eslint-disable-next-line node/no-extraneous-require
|
|
13
11
|
const ee = require('@strapi/strapi/lib/utils/ee');
|
|
@@ -19,15 +17,6 @@ const {
|
|
|
19
17
|
} = require('../validation/project-settings');
|
|
20
18
|
const { getService } = require('../utils');
|
|
21
19
|
|
|
22
|
-
const PLUGIN_NAME_REGEX = /^[A-Za-z][A-Za-z0-9-_]+$/;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Validates a plugin name format
|
|
26
|
-
*/
|
|
27
|
-
const isValidPluginName = (plugin) => {
|
|
28
|
-
return _.isString(plugin) && !_.isEmpty(plugin) && PLUGIN_NAME_REGEX.test(plugin);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
20
|
/**
|
|
32
21
|
* A set of functions called "actions" for `Admin`
|
|
33
22
|
*/
|
|
@@ -146,28 +135,6 @@ module.exports = {
|
|
|
146
135
|
};
|
|
147
136
|
},
|
|
148
137
|
|
|
149
|
-
async installPlugin(ctx) {
|
|
150
|
-
try {
|
|
151
|
-
const { plugin } = ctx.request.body;
|
|
152
|
-
|
|
153
|
-
if (!isValidPluginName(plugin)) {
|
|
154
|
-
throw new ValidationError('Invalid plugin name');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
strapi.reload.isWatching = false;
|
|
158
|
-
|
|
159
|
-
strapi.log.info(`Installing ${plugin}...`);
|
|
160
|
-
await execa('npm', ['run', 'strapi', '--', 'install', plugin]);
|
|
161
|
-
|
|
162
|
-
ctx.send({ ok: true });
|
|
163
|
-
|
|
164
|
-
strapi.reload();
|
|
165
|
-
} catch (err) {
|
|
166
|
-
strapi.reload.isWatching = true;
|
|
167
|
-
throw err;
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
|
|
171
138
|
async plugins(ctx) {
|
|
172
139
|
const enabledPlugins = strapi.config.get('enabledPlugins');
|
|
173
140
|
|
|
@@ -180,26 +147,4 @@ module.exports = {
|
|
|
180
147
|
|
|
181
148
|
ctx.send({ plugins });
|
|
182
149
|
},
|
|
183
|
-
|
|
184
|
-
async uninstallPlugin(ctx) {
|
|
185
|
-
try {
|
|
186
|
-
const { plugin } = ctx.params;
|
|
187
|
-
|
|
188
|
-
if (!isValidPluginName(plugin)) {
|
|
189
|
-
throw new ValidationError('Invalid plugin name');
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
strapi.reload.isWatching = false;
|
|
193
|
-
|
|
194
|
-
strapi.log.info(`Uninstalling ${plugin}...`);
|
|
195
|
-
await execa('npm', ['run', 'strapi', '--', 'uninstall', plugin, '-d']);
|
|
196
|
-
|
|
197
|
-
ctx.send({ ok: true });
|
|
198
|
-
|
|
199
|
-
strapi.reload();
|
|
200
|
-
} catch (err) {
|
|
201
|
-
strapi.reload.isWatching = true;
|
|
202
|
-
throw err;
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
150
|
};
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { stringEquals } = require('@strapi/utils/lib');
|
|
4
4
|
const { ApplicationError } = require('@strapi/utils').errors;
|
|
5
|
-
const { trim
|
|
5
|
+
const { trim } = require('lodash/fp');
|
|
6
|
+
const has = require('lodash/has');
|
|
6
7
|
const { getService } = require('../utils');
|
|
7
8
|
const {
|
|
8
9
|
validateApiTokenCreationInput,
|
|
@@ -92,11 +93,11 @@ module.exports = {
|
|
|
92
93
|
* - having a space at the end or start of the value.
|
|
93
94
|
* - having only spaces as value;
|
|
94
95
|
*/
|
|
95
|
-
if (has('name'
|
|
96
|
+
if (has(attributes, 'name')) {
|
|
96
97
|
attributes.name = trim(body.name);
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
if (has('description'
|
|
100
|
+
if (has(attributes, 'description') || attributes.description === null) {
|
|
100
101
|
attributes.description = trim(body.description);
|
|
101
102
|
}
|
|
102
103
|
|
|
@@ -107,7 +108,7 @@ module.exports = {
|
|
|
107
108
|
return ctx.notFound('API Token not found');
|
|
108
109
|
}
|
|
109
110
|
|
|
110
|
-
if (has('name'
|
|
111
|
+
if (has(attributes, 'name')) {
|
|
111
112
|
const nameAlreadyTaken = await apiTokenService.getByName(attributes.name);
|
|
112
113
|
|
|
113
114
|
/**
|
|
@@ -7,7 +7,6 @@ module.exports = {
|
|
|
7
7
|
authentication: require('./authentication'),
|
|
8
8
|
permission: require('./permission'),
|
|
9
9
|
role: require('./role'),
|
|
10
|
-
transfer: require('./transfer'),
|
|
11
10
|
user: require('./user'),
|
|
12
11
|
webhooks: require('./webhooks'),
|
|
13
12
|
'content-api': require('./content-api'),
|
package/server/register.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
// const { register: registerDataTransferRoute } = require('@strapi/data-transfer/lib/strapi');
|
|
4
4
|
|
|
5
|
+
const registerAdminPanelRoute = require('./routes/serve-admin-panel');
|
|
5
6
|
const adminAuthStrategy = require('./strategies/admin');
|
|
6
|
-
|
|
7
7
|
const apiTokenAuthStrategy = require('./strategies/api-token');
|
|
8
8
|
|
|
9
9
|
module.exports = ({ strapi }) => {
|
|
@@ -16,4 +16,11 @@ module.exports = ({ strapi }) => {
|
|
|
16
16
|
if (strapi.config.serveAdminPanel) {
|
|
17
17
|
registerAdminPanelRoute({ strapi });
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
// if (
|
|
21
|
+
// process.env.STRAPI_EXPERIMENTAL === 'true' &&
|
|
22
|
+
// process.env.STRAPI_DISABLE_REMOTE_DATA_TRANSFER !== 'true'
|
|
23
|
+
// ) {
|
|
24
|
+
// registerDataTransferRoute(strapi);
|
|
25
|
+
// }
|
|
19
26
|
};
|
package/server/routes/admin.js
CHANGED
|
@@ -68,32 +68,4 @@ module.exports = [
|
|
|
68
68
|
],
|
|
69
69
|
},
|
|
70
70
|
},
|
|
71
|
-
{
|
|
72
|
-
method: 'POST',
|
|
73
|
-
path: '/plugins/install',
|
|
74
|
-
handler: 'admin.installPlugin',
|
|
75
|
-
config: {
|
|
76
|
-
policies: [
|
|
77
|
-
'admin::isAuthenticatedAdmin',
|
|
78
|
-
{
|
|
79
|
-
name: 'admin::hasPermissions',
|
|
80
|
-
config: { actions: ['admin::marketplace.plugins.install'] },
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
method: 'DELETE',
|
|
87
|
-
path: '/plugins/uninstall/:plugin',
|
|
88
|
-
handler: 'admin.uninstallPlugin',
|
|
89
|
-
config: {
|
|
90
|
-
policies: [
|
|
91
|
-
'admin::isAuthenticatedAdmin',
|
|
92
|
-
{
|
|
93
|
-
name: 'admin::hasPermissions',
|
|
94
|
-
config: { actions: ['admin::marketplace.plugins.uninstall'] },
|
|
95
|
-
},
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
71
|
];
|
package/server/routes/index.js
CHANGED
|
@@ -8,7 +8,6 @@ const roles = require('./roles');
|
|
|
8
8
|
const webhooks = require('./webhooks');
|
|
9
9
|
const apiTokens = require('./api-tokens');
|
|
10
10
|
const contentApi = require('./content-api');
|
|
11
|
-
const transfer = require('./transfer');
|
|
12
11
|
|
|
13
12
|
module.exports = [
|
|
14
13
|
...admin,
|
|
@@ -19,5 +18,4 @@ module.exports = [
|
|
|
19
18
|
...webhooks,
|
|
20
19
|
...apiTokens,
|
|
21
20
|
...contentApi,
|
|
22
|
-
...transfer,
|
|
23
21
|
];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
|
-
const {
|
|
4
|
+
const { isNil } = require('lodash/fp');
|
|
5
|
+
const { omit, difference, isEmpty, map, isArray, uniq } = require('lodash/fp');
|
|
5
6
|
const { ValidationError, NotFoundError } = require('@strapi/utils').errors;
|
|
6
7
|
const constants = require('./constants');
|
|
7
8
|
|
|
@@ -77,7 +78,7 @@ const assertCustomTokenPermissionsValidity = (attributes) => {
|
|
|
77
78
|
};
|
|
78
79
|
|
|
79
80
|
/**
|
|
80
|
-
* Assert that a token's
|
|
81
|
+
* Assert that a token's permissions attribute is valid for its type
|
|
81
82
|
*
|
|
82
83
|
* @param {ApiToken} token
|
|
83
84
|
*/
|
package/server/services/index.js
CHANGED
|
@@ -24,8 +24,7 @@ const extractToken = (ctx) => {
|
|
|
24
24
|
/**
|
|
25
25
|
* Authenticate the validity of the token
|
|
26
26
|
*
|
|
27
|
-
* @type {import('.').AuthenticateFunction}
|
|
28
|
-
*/
|
|
27
|
+
* @type {import('.').AuthenticateFunction} */
|
|
29
28
|
const authenticate = async (ctx) => {
|
|
30
29
|
const apiTokenService = getService('api-token');
|
|
31
30
|
const token = extractToken(ctx);
|
|
@@ -73,8 +72,7 @@ const authenticate = async (ctx) => {
|
|
|
73
72
|
/**
|
|
74
73
|
* Verify the token has the required abilities for the requested scope
|
|
75
74
|
*
|
|
76
|
-
* @type {import('.').VerifyFunction}
|
|
77
|
-
*/
|
|
75
|
+
* @type {import('.').VerifyFunction} */
|
|
78
76
|
const verify = (auth, config) => {
|
|
79
77
|
const { credentials: apiToken, ability } = auth;
|
|
80
78
|
|
package/server/utils/index.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ import * as token from '../services/token';
|
|
|
7
7
|
import * as auth from '../services/auth';
|
|
8
8
|
import * as apiToken from '../services/api-token';
|
|
9
9
|
import * as projectSettings from '../services/project-settings';
|
|
10
|
-
import * as transfer from '../services/transfer';
|
|
11
10
|
|
|
12
11
|
type S = {
|
|
13
12
|
role: typeof role;
|
|
@@ -19,7 +18,6 @@ type S = {
|
|
|
19
18
|
metrics: typeof metrics;
|
|
20
19
|
'api-token': typeof apiToken;
|
|
21
20
|
'project-settings': typeof projectSettings;
|
|
22
|
-
transfer: typeof transfer;
|
|
23
21
|
};
|
|
24
22
|
|
|
25
23
|
export function getService<T extends keyof S>(name: T): S[T];
|
|
@@ -10,7 +10,12 @@ const apiTokenCreationSchema = yup
|
|
|
10
10
|
description: yup.string().optional(),
|
|
11
11
|
type: yup.string().oneOf(Object.values(constants.API_TOKEN_TYPE)).required(),
|
|
12
12
|
permissions: yup.array().of(yup.string()).nullable(),
|
|
13
|
-
lifespan: yup
|
|
13
|
+
lifespan: yup
|
|
14
|
+
.number()
|
|
15
|
+
.integer()
|
|
16
|
+
.min(1)
|
|
17
|
+
.oneOf(Object.values(constants.API_TOKEN_LIFESPANS))
|
|
18
|
+
.nullable(),
|
|
14
19
|
})
|
|
15
20
|
.noUnknown()
|
|
16
21
|
.strict();
|
package/webpack.config.js
CHANGED
|
@@ -8,7 +8,6 @@ const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
|
|
|
8
8
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
9
9
|
const { ESBuildMinifyPlugin } = require('esbuild-loader');
|
|
10
10
|
const WebpackBar = require('webpackbar');
|
|
11
|
-
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
|
|
12
11
|
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
|
13
12
|
const browserslistToEsbuild = require('browserslist-to-esbuild');
|
|
14
13
|
|
|
@@ -232,8 +231,6 @@ module.exports = ({
|
|
|
232
231
|
}),
|
|
233
232
|
new webpack.DefinePlugin(envVariables),
|
|
234
233
|
|
|
235
|
-
new NodePolyfillPlugin(),
|
|
236
|
-
|
|
237
234
|
new ForkTsCheckerPlugin({
|
|
238
235
|
typescript: {
|
|
239
236
|
configFile: tsConfigFilePath,
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { useIntl } from 'react-intl';
|
|
4
|
-
import { usePersistentState } from '@strapi/helper-plugin';
|
|
5
|
-
import { Select, Option } from '@strapi/design-system/Select';
|
|
6
|
-
import { Typography } from '@strapi/design-system/Typography';
|
|
7
|
-
import { getDateOfExpiration } from '../../../pages/ApiTokens/EditView/utils';
|
|
8
|
-
|
|
9
|
-
const LifeSpanInput = ({ token, errors, values, onChange, disabled }) => {
|
|
10
|
-
const { formatMessage } = useIntl();
|
|
11
|
-
const [lang] = usePersistentState('strapi-admin-language', 'en');
|
|
12
|
-
|
|
13
|
-
return (
|
|
14
|
-
<>
|
|
15
|
-
<Select
|
|
16
|
-
name="lifespan"
|
|
17
|
-
label={formatMessage({
|
|
18
|
-
id: 'Settings.apiTokens.form.duration',
|
|
19
|
-
defaultMessage: 'Token duration',
|
|
20
|
-
})}
|
|
21
|
-
value={values.lifespan !== null ? values.lifespan : '0'}
|
|
22
|
-
error={
|
|
23
|
-
errors.lifespan
|
|
24
|
-
? formatMessage(
|
|
25
|
-
errors.lifespan?.id
|
|
26
|
-
? errors.lifespan
|
|
27
|
-
: { id: errors.lifespan, defaultMessage: errors.lifespan }
|
|
28
|
-
)
|
|
29
|
-
: null
|
|
30
|
-
}
|
|
31
|
-
onChange={(value) => {
|
|
32
|
-
onChange({ target: { name: 'lifespan', value } });
|
|
33
|
-
}}
|
|
34
|
-
required
|
|
35
|
-
disabled={disabled}
|
|
36
|
-
placeholder="Select"
|
|
37
|
-
>
|
|
38
|
-
<Option value="604800000">
|
|
39
|
-
{formatMessage({
|
|
40
|
-
id: 'Settings.apiTokens.duration.7-days',
|
|
41
|
-
defaultMessage: '7 days',
|
|
42
|
-
})}
|
|
43
|
-
</Option>
|
|
44
|
-
<Option value="2592000000">
|
|
45
|
-
{formatMessage({
|
|
46
|
-
id: 'Settings.apiTokens.duration.30-days',
|
|
47
|
-
defaultMessage: '30 days',
|
|
48
|
-
})}
|
|
49
|
-
</Option>
|
|
50
|
-
<Option value="7776000000">
|
|
51
|
-
{formatMessage({
|
|
52
|
-
id: 'Settings.apiTokens.duration.90-days',
|
|
53
|
-
defaultMessage: '90 days',
|
|
54
|
-
})}
|
|
55
|
-
</Option>
|
|
56
|
-
<Option value="0">
|
|
57
|
-
{formatMessage({
|
|
58
|
-
id: 'Settings.apiTokens.duration.unlimited',
|
|
59
|
-
defaultMessage: 'Unlimited',
|
|
60
|
-
})}
|
|
61
|
-
</Option>
|
|
62
|
-
</Select>
|
|
63
|
-
<Typography variant="pi" textColor="neutral600">
|
|
64
|
-
{disabled &&
|
|
65
|
-
`${formatMessage({
|
|
66
|
-
id: 'Settings.apiTokens.duration.expiration-date',
|
|
67
|
-
defaultMessage: 'Expiration date',
|
|
68
|
-
})}: ${getDateOfExpiration(token?.createdAt, parseInt(values.lifespan, 10, lang))}`}
|
|
69
|
-
</Typography>
|
|
70
|
-
</>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
LifeSpanInput.propTypes = {
|
|
75
|
-
errors: PropTypes.string,
|
|
76
|
-
onChange: PropTypes.func.isRequired,
|
|
77
|
-
values: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
|
|
78
|
-
disabled: PropTypes.bool.isRequired,
|
|
79
|
-
token: PropTypes.shape({
|
|
80
|
-
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
81
|
-
type: PropTypes.string,
|
|
82
|
-
lifespan: PropTypes.string,
|
|
83
|
-
name: PropTypes.string,
|
|
84
|
-
accessKey: PropTypes.string,
|
|
85
|
-
permissions: PropTypes.array,
|
|
86
|
-
description: PropTypes.string,
|
|
87
|
-
createdAt: PropTypes.string,
|
|
88
|
-
}),
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
LifeSpanInput.defaultProps = {
|
|
92
|
-
errors: {},
|
|
93
|
-
token: {},
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
export default LifeSpanInput;
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { useIntl } from 'react-intl';
|
|
4
|
-
import { Select, Option } from '@strapi/design-system/Select';
|
|
5
|
-
import { Typography } from '@strapi/design-system/Typography';
|
|
6
|
-
import { getDateOfExpiration } from '../../../pages/ApiTokens/EditView/utils';
|
|
7
|
-
|
|
8
|
-
const LifeSpanInput = ({ token, errors, values, onChange, isCreating }) => {
|
|
9
|
-
const { formatMessage } = useIntl();
|
|
10
|
-
|
|
11
|
-
return (
|
|
12
|
-
<>
|
|
13
|
-
<Select
|
|
14
|
-
name="lifespan"
|
|
15
|
-
label={formatMessage({
|
|
16
|
-
id: 'Settings.apiTokens.form.duration',
|
|
17
|
-
defaultMessage: 'Token duration',
|
|
18
|
-
})}
|
|
19
|
-
value={values.lifespan !== null ? values.lifespan : '0'}
|
|
20
|
-
error={
|
|
21
|
-
errors.lifespan
|
|
22
|
-
? formatMessage(
|
|
23
|
-
errors.lifespan?.id
|
|
24
|
-
? errors.lifespan
|
|
25
|
-
: { id: errors.lifespan, defaultMessage: errors.lifespan }
|
|
26
|
-
)
|
|
27
|
-
: null
|
|
28
|
-
}
|
|
29
|
-
onChange={(value) => {
|
|
30
|
-
onChange({ target: { name: 'lifespan', value } });
|
|
31
|
-
}}
|
|
32
|
-
required
|
|
33
|
-
disabled={!isCreating}
|
|
34
|
-
placeholder="Select"
|
|
35
|
-
>
|
|
36
|
-
<Option value="604800000">
|
|
37
|
-
{formatMessage({
|
|
38
|
-
id: 'Settings.tokens.duration.7-days',
|
|
39
|
-
defaultMessage: '7 days',
|
|
40
|
-
})}
|
|
41
|
-
</Option>
|
|
42
|
-
<Option value="2592000000">
|
|
43
|
-
{formatMessage({
|
|
44
|
-
id: 'Settings.tokens.duration.30-days',
|
|
45
|
-
defaultMessage: '30 days',
|
|
46
|
-
})}
|
|
47
|
-
</Option>
|
|
48
|
-
<Option value="7776000000">
|
|
49
|
-
{formatMessage({
|
|
50
|
-
id: 'Settings.tokens.duration.90-days',
|
|
51
|
-
defaultMessage: '90 days',
|
|
52
|
-
})}
|
|
53
|
-
</Option>
|
|
54
|
-
<Option value="0">
|
|
55
|
-
{formatMessage({
|
|
56
|
-
id: 'Settings.tokens.duration.unlimited',
|
|
57
|
-
defaultMessage: 'Unlimited',
|
|
58
|
-
})}
|
|
59
|
-
</Option>
|
|
60
|
-
</Select>
|
|
61
|
-
<Typography variant="pi" textColor="neutral600">
|
|
62
|
-
{!isCreating &&
|
|
63
|
-
`${formatMessage({
|
|
64
|
-
id: 'Settings.tokens.duration.expiration-date',
|
|
65
|
-
defaultMessage: 'Expiration date',
|
|
66
|
-
})}: ${getDateOfExpiration(token?.createdAt, parseInt(values.lifespan, 10))}`}
|
|
67
|
-
</Typography>
|
|
68
|
-
</>
|
|
69
|
-
);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
LifeSpanInput.propTypes = {
|
|
73
|
-
errors: PropTypes.shape({
|
|
74
|
-
lifespan: PropTypes.string,
|
|
75
|
-
}),
|
|
76
|
-
onChange: PropTypes.func.isRequired,
|
|
77
|
-
values: PropTypes.shape({
|
|
78
|
-
lifespan: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
79
|
-
}).isRequired,
|
|
80
|
-
isCreating: PropTypes.bool.isRequired,
|
|
81
|
-
token: PropTypes.shape({
|
|
82
|
-
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
83
|
-
type: PropTypes.string,
|
|
84
|
-
lifespan: PropTypes.string,
|
|
85
|
-
name: PropTypes.string,
|
|
86
|
-
accessKey: PropTypes.string,
|
|
87
|
-
permissions: PropTypes.array,
|
|
88
|
-
description: PropTypes.string,
|
|
89
|
-
createdAt: PropTypes.string,
|
|
90
|
-
}),
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
LifeSpanInput.defaultProps = {
|
|
94
|
-
errors: {},
|
|
95
|
-
token: {},
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export default LifeSpanInput;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { useIntl } from 'react-intl';
|
|
4
|
-
import { Button } from '@strapi/design-system/Button';
|
|
5
|
-
import Refresh from '@strapi/icons/Refresh';
|
|
6
|
-
import { ConfirmDialog } from '@strapi/helper-plugin';
|
|
7
|
-
import { useRegenerate } from '../../../../../hooks';
|
|
8
|
-
|
|
9
|
-
export const Regenerate = ({ onRegenerate, idToRegenerate, backUrl }) => {
|
|
10
|
-
const { formatMessage } = useIntl();
|
|
11
|
-
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
|
|
12
|
-
const { regenerateData, isLoadingConfirmation } = useRegenerate(
|
|
13
|
-
backUrl,
|
|
14
|
-
idToRegenerate,
|
|
15
|
-
onRegenerate
|
|
16
|
-
);
|
|
17
|
-
const handleConfirmRegeneration = async () => {
|
|
18
|
-
regenerateData();
|
|
19
|
-
setShowConfirmDialog(false);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<>
|
|
24
|
-
<Button
|
|
25
|
-
startIcon={<Refresh />}
|
|
26
|
-
type="button"
|
|
27
|
-
size="S"
|
|
28
|
-
variant="tertiary"
|
|
29
|
-
onClick={() => setShowConfirmDialog(true)}
|
|
30
|
-
name="regenerate"
|
|
31
|
-
>
|
|
32
|
-
{formatMessage({
|
|
33
|
-
id: 'Settings.apiTokens.regenerate',
|
|
34
|
-
defaultMessage: 'Regenerate',
|
|
35
|
-
})}
|
|
36
|
-
</Button>
|
|
37
|
-
|
|
38
|
-
<ConfirmDialog
|
|
39
|
-
bodyText={{
|
|
40
|
-
id: 'Settings.apiTokens.popUpWarning.message',
|
|
41
|
-
defaultMessage: 'Are you sure you want to regenerate this token?',
|
|
42
|
-
}}
|
|
43
|
-
iconRightButton={<Refresh />}
|
|
44
|
-
isConfirmButtonLoading={isLoadingConfirmation}
|
|
45
|
-
isOpen={showConfirmDialog}
|
|
46
|
-
onToggleDialog={() => setShowConfirmDialog(false)}
|
|
47
|
-
onConfirm={handleConfirmRegeneration}
|
|
48
|
-
leftButtonText={{
|
|
49
|
-
id: 'Settings.apiTokens.Button.cancel',
|
|
50
|
-
defaultMessage: 'Cancel',
|
|
51
|
-
}}
|
|
52
|
-
rightButtonText={{
|
|
53
|
-
id: 'Settings.apiTokens.Button.regenerate',
|
|
54
|
-
defaultMessage: 'Regenerate',
|
|
55
|
-
}}
|
|
56
|
-
title={{
|
|
57
|
-
id: 'Settings.apiTokens.RegenerateDialog.title',
|
|
58
|
-
defaultMessage: 'Regenerate token',
|
|
59
|
-
}}
|
|
60
|
-
/>
|
|
61
|
-
</>
|
|
62
|
-
);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
Regenerate.defaultProps = { onRegenerate() {} };
|
|
66
|
-
|
|
67
|
-
Regenerate.propTypes = {
|
|
68
|
-
onRegenerate: PropTypes.func,
|
|
69
|
-
idToRegenerate: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
|
|
70
|
-
backUrl: PropTypes.string.isRequired,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export default Regenerate;
|