@strapi/admin 4.6.2 → 4.7.0-exp.3d6a31eb083e9d44afcf98f68c107fb7567e5720
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 +0 -2
- package/admin/src/hooks/useRegenerate/index.js +2 -2
- package/admin/src/hooks/useSettingsMenu/utils/defaultGlobalLinks.js +7 -0
- package/admin/src/pages/HomePage/CloudBox.js +83 -0
- package/admin/src/pages/HomePage/ContentBlocks.js +2 -0
- package/admin/src/pages/HomePage/assets/strapi-cloud-background.png +0 -0
- package/admin/src/pages/HomePage/assets/strapi-cloud-flags.svg +1 -0
- package/admin/src/pages/HomePage/assets/strapi-cloud-icon.svg +1 -0
- package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components → components/Tokens}/FormHead/index.js +36 -19
- package/admin/src/pages/SettingsPage/components/Tokens/FormiTokenContainer/LifeSpanInput.js +95 -0
- package/admin/src/pages/SettingsPage/components/Tokens/LifeSpanInput/index.js +97 -0
- package/admin/src/pages/SettingsPage/components/Tokens/Regenerate/index.js +73 -0
- package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DeleteButton/index.js +19 -6
- package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +145 -0
- package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components/ContentBox → components/Tokens/TokenBox}/index.js +19 -16
- package/admin/src/pages/SettingsPage/components/Tokens/TokenDescription/index.js +51 -0
- package/admin/src/pages/SettingsPage/components/Tokens/TokenName/index.js +46 -0
- package/admin/src/pages/SettingsPage/components/Tokens/TokenTypeSelect/index.js +69 -0
- package/admin/src/pages/SettingsPage/components/Tokens/constants.js +2 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +3 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +53 -150
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +5 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +46 -17
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +16 -16
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/FormTransferTokenContainer/index.js +101 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/LoadingView/index.js +48 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/index.js +219 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/getDateOfExpiration.js +16 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js +4 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/schema.js +10 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/index.js +194 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/utils/tableHeaders.js +48 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedCreateView/index.js +14 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedEditView/index.js +14 -0
- package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedListView/index.js +12 -0
- package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +33 -0
- package/admin/src/permissions/defaultPermissions.js +8 -0
- package/admin/src/translations/en.json +15 -0
- package/build/27d16aefee06412db90a.png +0 -0
- package/build/4049.16583eee.chunk.js +1 -0
- package/build/4649.b7e84a29.chunk.js +30 -0
- package/build/7259.3f04094f.chunk.js +1 -0
- package/build/{Admin-authenticatedApp.dd16edad.chunk.js → Admin-authenticatedApp.368164a1.chunk.js} +6 -6
- package/build/Admin_homePage.1f10437f.chunk.js +78 -0
- package/build/{Admin_settingsPage.3cd54156.chunk.js → Admin_settingsPage.5a329b58.chunk.js} +25 -25
- package/build/{admin-app.3a084127.chunk.js → admin-app.df9adf93.chunk.js} +26 -26
- package/build/{api-tokens-create-page.a31c7fba.chunk.js → api-tokens-create-page.4328b852.chunk.js} +1 -1
- package/build/{api-tokens-edit-page.64fef287.chunk.js → api-tokens-edit-page.bce5050f.chunk.js} +1 -1
- package/build/api-tokens-list-page.149903c8.chunk.js +16 -0
- package/build/bb3108f7fd1e6179bde1.svg +1 -0
- package/build/bb4d0d527bdfb161bc5a.svg +1 -0
- package/build/{content-manager.d04b738f.chunk.js → content-manager.6ed87531.chunk.js} +1 -1
- package/build/en-json.8e5451b1.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/{main.9c01de7f.js → main.8009bfe8.js} +1 -0
- package/build/runtime~main.725b20df.js +2 -0
- package/build/transfer-tokens-create-page.a1f14bb1.chunk.js +1 -0
- package/build/transfer-tokens-edit-page.00ee1c74.chunk.js +1 -0
- package/build/transfer-tokens-list-page.1e15926d.chunk.js +16 -0
- package/package.json +9 -9
- package/server/bootstrap.js +2 -0
- package/server/config/admin-actions.js +48 -0
- package/server/content-types/index.js +2 -0
- package/server/content-types/transfer-token-permission.js +36 -0
- package/server/content-types/transfer-token.js +66 -0
- package/server/controllers/api-token.js +4 -5
- package/server/controllers/index.js +1 -0
- package/server/controllers/transfer/index.js +13 -0
- package/server/controllers/transfer/runner.js +24 -0
- package/server/controllers/transfer/token.js +131 -0
- package/server/register.js +2 -9
- package/server/routes/index.js +2 -0
- package/server/routes/transfer.js +95 -0
- package/server/services/api-token.js +2 -3
- package/server/services/constants.js +6 -0
- package/server/services/index.js +1 -0
- package/server/services/transfer/index.js +6 -0
- package/server/services/transfer/permission.js +22 -0
- package/server/services/transfer/token.js +409 -0
- package/server/strategies/api-token.js +4 -2
- package/server/strategies/data-transfer.js +107 -0
- package/server/strategies/index.js +1 -0
- package/server/utils/index.d.ts +2 -0
- package/server/validation/api-tokens.js +1 -6
- package/server/validation/transfer/index.js +5 -0
- package/server/validation/transfer/token.js +34 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +0 -77
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +0 -110
- package/build/1341.5d48c79b.chunk.js +0 -1
- package/build/4318.9b1ac9bc.chunk.js +0 -30
- package/build/Admin_homePage.4b878f04.chunk.js +0 -72
- package/build/api-tokens-list-page.370459ba.chunk.js +0 -16
- package/build/en-json.9cada7f3.chunk.js +0 -1
- package/build/runtime~main.bb1389c9.js +0 -2
- package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DefaultButton/index.js +1 -1
- /package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/ReadButton/index.js +0 -0
- /package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/UpdateButton/index.js +0 -0
package/server/bootstrap.js
CHANGED
|
@@ -78,6 +78,7 @@ module.exports = async () => {
|
|
|
78
78
|
const userService = getService('user');
|
|
79
79
|
const roleService = getService('role');
|
|
80
80
|
const apiTokenService = getService('api-token');
|
|
81
|
+
const transferService = getService('transfer');
|
|
81
82
|
const tokenService = getService('token');
|
|
82
83
|
|
|
83
84
|
await roleService.createRolesIfNoneExist();
|
|
@@ -93,5 +94,6 @@ module.exports = async () => {
|
|
|
93
94
|
await syncAPITokensPermissions();
|
|
94
95
|
|
|
95
96
|
apiTokenService.checkSaltIsDefined();
|
|
97
|
+
transferService.token.checkSaltIsDefined();
|
|
96
98
|
tokenService.checkSecretIsDefined();
|
|
97
99
|
};
|
|
@@ -164,5 +164,53 @@ module.exports = {
|
|
|
164
164
|
section: 'settings',
|
|
165
165
|
category: 'project',
|
|
166
166
|
},
|
|
167
|
+
{
|
|
168
|
+
uid: 'transfer.tokens.access',
|
|
169
|
+
displayName: 'Access the transfer tokens settings page',
|
|
170
|
+
pluginName: 'admin',
|
|
171
|
+
section: 'settings',
|
|
172
|
+
category: 'transfer tokens',
|
|
173
|
+
subCategory: 'transfer tokens',
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
uid: 'transfer.tokens.create',
|
|
177
|
+
displayName: 'Create (generate)',
|
|
178
|
+
pluginName: 'admin',
|
|
179
|
+
section: 'settings',
|
|
180
|
+
category: 'transfer tokens',
|
|
181
|
+
subCategory: 'general',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
uid: 'transfer.tokens.read',
|
|
185
|
+
displayName: 'Read',
|
|
186
|
+
pluginName: 'admin',
|
|
187
|
+
section: 'settings',
|
|
188
|
+
category: 'transfer tokens',
|
|
189
|
+
subCategory: 'general',
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
uid: 'transfer.tokens.update',
|
|
193
|
+
displayName: 'Update',
|
|
194
|
+
pluginName: 'admin',
|
|
195
|
+
section: 'settings',
|
|
196
|
+
category: 'transfer tokens',
|
|
197
|
+
subCategory: 'general',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
uid: 'transfer.tokens.regenerate',
|
|
201
|
+
displayName: 'Regenerate',
|
|
202
|
+
pluginName: 'admin',
|
|
203
|
+
section: 'settings',
|
|
204
|
+
category: 'transfer tokens',
|
|
205
|
+
subCategory: 'general',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
uid: 'transfer.tokens.delete',
|
|
209
|
+
displayName: 'Delete (revoke)',
|
|
210
|
+
pluginName: 'admin',
|
|
211
|
+
section: 'settings',
|
|
212
|
+
category: 'transfer tokens',
|
|
213
|
+
subCategory: 'general',
|
|
214
|
+
},
|
|
167
215
|
],
|
|
168
216
|
};
|
|
@@ -6,4 +6,6 @@ module.exports = {
|
|
|
6
6
|
role: { schema: require('./Role') },
|
|
7
7
|
'api-token': { schema: require('./api-token') },
|
|
8
8
|
'api-token-permission': { schema: require('./api-token-permission') },
|
|
9
|
+
'transfer-token': { schema: require('./transfer-token') },
|
|
10
|
+
'transfer-token-permission': { schema: require('./transfer-token-permission') },
|
|
9
11
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
collectionName: 'strapi_transfer_token_permissions',
|
|
5
|
+
info: {
|
|
6
|
+
name: 'Transfer Token Permission',
|
|
7
|
+
description: '',
|
|
8
|
+
singularName: 'transfer-token-permission',
|
|
9
|
+
pluralName: 'transfer-token-permissions',
|
|
10
|
+
displayName: 'Transfer Token Permission',
|
|
11
|
+
},
|
|
12
|
+
options: {},
|
|
13
|
+
pluginOptions: {
|
|
14
|
+
'content-manager': {
|
|
15
|
+
visible: false,
|
|
16
|
+
},
|
|
17
|
+
'content-type-builder': {
|
|
18
|
+
visible: false,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
attributes: {
|
|
22
|
+
action: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
minLength: 1,
|
|
25
|
+
configurable: false,
|
|
26
|
+
required: true,
|
|
27
|
+
},
|
|
28
|
+
token: {
|
|
29
|
+
configurable: false,
|
|
30
|
+
type: 'relation',
|
|
31
|
+
relation: 'manyToOne',
|
|
32
|
+
inversedBy: 'permissions',
|
|
33
|
+
target: 'admin::transfer-token',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
collectionName: 'strapi_transfer_tokens',
|
|
5
|
+
info: {
|
|
6
|
+
name: 'Transfer Token',
|
|
7
|
+
singularName: 'transfer-token',
|
|
8
|
+
pluralName: 'transfer-tokens',
|
|
9
|
+
displayName: 'Transfer Token',
|
|
10
|
+
description: '',
|
|
11
|
+
},
|
|
12
|
+
options: {},
|
|
13
|
+
pluginOptions: {
|
|
14
|
+
'content-manager': {
|
|
15
|
+
visible: false,
|
|
16
|
+
},
|
|
17
|
+
'content-type-builder': {
|
|
18
|
+
visible: false,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
attributes: {
|
|
22
|
+
name: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
minLength: 1,
|
|
25
|
+
configurable: false,
|
|
26
|
+
required: true,
|
|
27
|
+
unique: true,
|
|
28
|
+
},
|
|
29
|
+
description: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
minLength: 1,
|
|
32
|
+
configurable: false,
|
|
33
|
+
required: false,
|
|
34
|
+
default: '',
|
|
35
|
+
},
|
|
36
|
+
accessKey: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
minLength: 1,
|
|
39
|
+
configurable: false,
|
|
40
|
+
required: true,
|
|
41
|
+
},
|
|
42
|
+
lastUsedAt: {
|
|
43
|
+
type: 'datetime',
|
|
44
|
+
configurable: false,
|
|
45
|
+
required: false,
|
|
46
|
+
},
|
|
47
|
+
permissions: {
|
|
48
|
+
type: 'relation',
|
|
49
|
+
target: 'admin::transfer-token-permission',
|
|
50
|
+
relation: 'oneToMany',
|
|
51
|
+
mappedBy: 'token',
|
|
52
|
+
configurable: false,
|
|
53
|
+
required: false,
|
|
54
|
+
},
|
|
55
|
+
expiresAt: {
|
|
56
|
+
type: 'datetime',
|
|
57
|
+
configurable: false,
|
|
58
|
+
required: false,
|
|
59
|
+
},
|
|
60
|
+
lifespan: {
|
|
61
|
+
type: 'biginteger',
|
|
62
|
+
configurable: false,
|
|
63
|
+
required: false,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { stringEquals } = require('@strapi/utils/lib');
|
|
4
4
|
const { ApplicationError } = require('@strapi/utils').errors;
|
|
5
|
-
const { trim } = require('lodash/fp');
|
|
6
|
-
const has = require('lodash/has');
|
|
5
|
+
const { trim, has } = require('lodash/fp');
|
|
7
6
|
const { getService } = require('../utils');
|
|
8
7
|
const {
|
|
9
8
|
validateApiTokenCreationInput,
|
|
@@ -93,11 +92,11 @@ module.exports = {
|
|
|
93
92
|
* - having a space at the end or start of the value.
|
|
94
93
|
* - having only spaces as value;
|
|
95
94
|
*/
|
|
96
|
-
if (has(
|
|
95
|
+
if (has('name', attributes)) {
|
|
97
96
|
attributes.name = trim(body.name);
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
if (has(
|
|
99
|
+
if (has('description', attributes) || attributes.description === null) {
|
|
101
100
|
attributes.description = trim(body.description);
|
|
102
101
|
}
|
|
103
102
|
|
|
@@ -108,7 +107,7 @@ module.exports = {
|
|
|
108
107
|
return ctx.notFound('API Token not found');
|
|
109
108
|
}
|
|
110
109
|
|
|
111
|
-
if (has(
|
|
110
|
+
if (has('name', attributes)) {
|
|
112
111
|
const nameAlreadyTaken = await apiTokenService.getByName(attributes.name);
|
|
113
112
|
|
|
114
113
|
/**
|
|
@@ -7,6 +7,7 @@ module.exports = {
|
|
|
7
7
|
authentication: require('./authentication'),
|
|
8
8
|
permission: require('./permission'),
|
|
9
9
|
role: require('./role'),
|
|
10
|
+
transfer: require('./transfer'),
|
|
10
11
|
user: require('./user'),
|
|
11
12
|
webhooks: require('./webhooks'),
|
|
12
13
|
'content-api': require('./content-api'),
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { mapKeys } = require('lodash/fp');
|
|
4
|
+
|
|
5
|
+
const runner = require('./runner');
|
|
6
|
+
const token = require('./token');
|
|
7
|
+
|
|
8
|
+
const prefixActionsName = (prefix, dict) => mapKeys((key) => `${prefix}-${key}`, dict);
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
...prefixActionsName('runner', runner),
|
|
12
|
+
...prefixActionsName('token', token),
|
|
13
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { remote } = require('@strapi/data-transfer/lib/strapi');
|
|
4
|
+
const { UnauthorizedError } = require('@strapi/utils/lib/errors');
|
|
5
|
+
|
|
6
|
+
const dataTransferAuthStrategy = require('../../strategies/data-transfer');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {import('koa').Context} ctx
|
|
10
|
+
* @param {string} [scope]
|
|
11
|
+
*/
|
|
12
|
+
const verify = async (ctx, scope) => {
|
|
13
|
+
const { auth } = ctx.state;
|
|
14
|
+
|
|
15
|
+
if (!auth) {
|
|
16
|
+
throw new UnauthorizedError();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
await dataTransferAuthStrategy.verify(auth, { scope });
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
connect: remote.handlers.createTransferHandler({ verify }),
|
|
24
|
+
};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { trim, has } = require('lodash/fp');
|
|
4
|
+
const {
|
|
5
|
+
errors: { ApplicationError },
|
|
6
|
+
stringEquals,
|
|
7
|
+
} = require('@strapi/utils');
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
token: { validateTransferTokenCreationInput, validateTransferTokenUpdateInput },
|
|
11
|
+
} = require('../../validation/transfer');
|
|
12
|
+
const { getService } = require('../../utils');
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
async list(ctx) {
|
|
16
|
+
const transferService = getService('transfer');
|
|
17
|
+
const transferTokens = await transferService.token.list();
|
|
18
|
+
|
|
19
|
+
ctx.body = { data: transferTokens };
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
async getById(ctx) {
|
|
23
|
+
const { id } = ctx.params;
|
|
24
|
+
const tokenService = getService('transfer').token;
|
|
25
|
+
|
|
26
|
+
const transferToken = await tokenService.getById(id);
|
|
27
|
+
|
|
28
|
+
if (!transferToken) {
|
|
29
|
+
ctx.notFound('Transfer token not found');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
ctx.body = { data: transferToken };
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
async create(ctx) {
|
|
37
|
+
const { body } = ctx.request;
|
|
38
|
+
const { token: tokenService } = getService('transfer');
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* We trim fields to avoid having issues with either:
|
|
42
|
+
* - having a space at the end or start of the value
|
|
43
|
+
* - having only spaces as value (so that an empty field can be caught in validation)
|
|
44
|
+
*/
|
|
45
|
+
const attributes = {
|
|
46
|
+
name: trim(body.name),
|
|
47
|
+
description: trim(body.description),
|
|
48
|
+
permissions: body.permissions,
|
|
49
|
+
lifespan: body.lifespan,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
await validateTransferTokenCreationInput(attributes);
|
|
53
|
+
|
|
54
|
+
const alreadyExists = await tokenService.exists({ name: attributes.name });
|
|
55
|
+
if (alreadyExists) {
|
|
56
|
+
throw new ApplicationError('Name already taken');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const transferTokens = await tokenService.create(attributes);
|
|
60
|
+
|
|
61
|
+
ctx.created({ data: transferTokens });
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
async update(ctx) {
|
|
65
|
+
const { body } = ctx.request;
|
|
66
|
+
const { id } = ctx.params;
|
|
67
|
+
const { token: tokenService } = getService('transfer');
|
|
68
|
+
|
|
69
|
+
const attributes = body;
|
|
70
|
+
/**
|
|
71
|
+
* We trim fields to avoid having issues with either:
|
|
72
|
+
* - having a space at the end or start of the value
|
|
73
|
+
* - having only spaces as value (so that an empty field can be caught in validation)
|
|
74
|
+
*/
|
|
75
|
+
if (has('name', attributes)) {
|
|
76
|
+
attributes.name = trim(body.name);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (has('description', attributes) || attributes.description === null) {
|
|
80
|
+
attributes.description = trim(body.description);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await validateTransferTokenUpdateInput(attributes);
|
|
84
|
+
|
|
85
|
+
const apiTokenExists = await tokenService.getById(id);
|
|
86
|
+
if (!apiTokenExists) {
|
|
87
|
+
return ctx.notFound('Transfer token not found');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (has('name', attributes)) {
|
|
91
|
+
const nameAlreadyTaken = await tokenService.getByName(attributes.name);
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* We cast the ids as string as the one coming from the ctx isn't cast
|
|
95
|
+
* as a Number in case it is supposed to be an integer. It remains
|
|
96
|
+
* as a string. This way we avoid issues with integers in the db.
|
|
97
|
+
*/
|
|
98
|
+
if (!!nameAlreadyTaken && !stringEquals(nameAlreadyTaken.id, id)) {
|
|
99
|
+
throw new ApplicationError('Name already taken');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const apiToken = await tokenService.update(id, attributes);
|
|
104
|
+
|
|
105
|
+
ctx.body = { data: apiToken };
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
async revoke(ctx) {
|
|
109
|
+
const { id } = ctx.params;
|
|
110
|
+
const { token: tokenService } = getService('transfer');
|
|
111
|
+
|
|
112
|
+
const transferToken = await tokenService.revoke(id);
|
|
113
|
+
|
|
114
|
+
ctx.deleted({ data: transferToken });
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
async regenerate(ctx) {
|
|
118
|
+
const { id } = ctx.params;
|
|
119
|
+
const { token: tokenService } = getService('transfer');
|
|
120
|
+
|
|
121
|
+
const exists = await tokenService.getById(id);
|
|
122
|
+
if (!exists) {
|
|
123
|
+
ctx.notFound('Transfer token not found');
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const accessToken = await tokenService.regenerate(id);
|
|
128
|
+
|
|
129
|
+
ctx.created({ data: accessToken });
|
|
130
|
+
},
|
|
131
|
+
};
|
package/server/register.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// const { register: registerDataTransferRoute } = require('@strapi/data-transfer/lib/strapi');
|
|
4
|
-
|
|
5
3
|
const registerAdminPanelRoute = require('./routes/serve-admin-panel');
|
|
4
|
+
|
|
6
5
|
const adminAuthStrategy = require('./strategies/admin');
|
|
6
|
+
|
|
7
7
|
const apiTokenAuthStrategy = require('./strategies/api-token');
|
|
8
8
|
|
|
9
9
|
module.exports = ({ strapi }) => {
|
|
@@ -16,11 +16,4 @@ 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
|
-
// }
|
|
26
19
|
};
|
package/server/routes/index.js
CHANGED
|
@@ -8,6 +8,7 @@ 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');
|
|
11
12
|
|
|
12
13
|
module.exports = [
|
|
13
14
|
...admin,
|
|
@@ -18,4 +19,5 @@ module.exports = [
|
|
|
18
19
|
...webhooks,
|
|
19
20
|
...apiTokens,
|
|
20
21
|
...contentApi,
|
|
22
|
+
...transfer,
|
|
21
23
|
];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const dataTransferAuthStrategy = require('../strategies/data-transfer');
|
|
4
|
+
|
|
5
|
+
module.exports = [
|
|
6
|
+
// Transfer route
|
|
7
|
+
{
|
|
8
|
+
method: 'GET',
|
|
9
|
+
path: '/transfer/runner/connect',
|
|
10
|
+
handler: 'transfer.runner-connect',
|
|
11
|
+
config: {
|
|
12
|
+
middlewares: [
|
|
13
|
+
(ctx, next) => {
|
|
14
|
+
if (process.env.STRAPI_DISABLE_REMOTE_DATA_TRANSFER === 'true') {
|
|
15
|
+
return ctx.notFound();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return next();
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
// TODO: Allow not passing any scope <> Add a way to prevent assigning one by default
|
|
22
|
+
auth: { strategies: [dataTransferAuthStrategy], scope: ['push'] },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
// Transfer Tokens
|
|
26
|
+
{
|
|
27
|
+
method: 'POST',
|
|
28
|
+
path: '/transfer/tokens',
|
|
29
|
+
handler: 'transfer.token-create',
|
|
30
|
+
config: {
|
|
31
|
+
policies: [
|
|
32
|
+
'admin::isAuthenticatedAdmin',
|
|
33
|
+
{ name: 'admin::hasPermissions', config: { actions: ['admin::transfer.tokens.create'] } },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
method: 'GET',
|
|
39
|
+
path: '/transfer/tokens',
|
|
40
|
+
handler: 'transfer.token-list',
|
|
41
|
+
config: {
|
|
42
|
+
policies: [
|
|
43
|
+
'admin::isAuthenticatedAdmin',
|
|
44
|
+
{ name: 'admin::hasPermissions', config: { actions: ['admin::transfer.tokens.read'] } },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
method: 'DELETE',
|
|
50
|
+
path: '/transfer/tokens/:id',
|
|
51
|
+
handler: 'transfer.token-revoke',
|
|
52
|
+
config: {
|
|
53
|
+
policies: [
|
|
54
|
+
'admin::isAuthenticatedAdmin',
|
|
55
|
+
{ name: 'admin::hasPermissions', config: { actions: ['admin::transfer.tokens.delete'] } },
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
method: 'GET',
|
|
61
|
+
path: '/transfer/tokens/:id',
|
|
62
|
+
handler: 'transfer.token-getById',
|
|
63
|
+
config: {
|
|
64
|
+
policies: [
|
|
65
|
+
'admin::isAuthenticatedAdmin',
|
|
66
|
+
{ name: 'admin::hasPermissions', config: { actions: ['admin::transfer.tokens.read'] } },
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
method: 'PUT',
|
|
72
|
+
path: '/transfer/tokens/:id',
|
|
73
|
+
handler: 'transfer.token-update',
|
|
74
|
+
config: {
|
|
75
|
+
policies: [
|
|
76
|
+
'admin::isAuthenticatedAdmin',
|
|
77
|
+
{ name: 'admin::hasPermissions', config: { actions: ['admin::transfer.tokens.update'] } },
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
method: 'POST',
|
|
83
|
+
path: '/transfer/tokens/:id/regenerate',
|
|
84
|
+
handler: 'transfer.token-regenerate',
|
|
85
|
+
config: {
|
|
86
|
+
policies: [
|
|
87
|
+
'admin::isAuthenticatedAdmin',
|
|
88
|
+
{
|
|
89
|
+
name: 'admin::hasPermissions',
|
|
90
|
+
config: { actions: ['admin::transfer.tokens.regenerate'] },
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
];
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
|
-
const { isNil } = require('lodash/fp');
|
|
5
|
-
const { omit, difference, isEmpty, map, isArray, uniq } = require('lodash/fp');
|
|
4
|
+
const { omit, difference, isNil, isEmpty, map, isArray, uniq } = require('lodash/fp');
|
|
6
5
|
const { ValidationError, NotFoundError } = require('@strapi/utils').errors;
|
|
7
6
|
const constants = require('./constants');
|
|
8
7
|
|
|
@@ -78,7 +77,7 @@ const assertCustomTokenPermissionsValidity = (attributes) => {
|
|
|
78
77
|
};
|
|
79
78
|
|
|
80
79
|
/**
|
|
81
|
-
* Assert that a token's
|
|
80
|
+
* Assert that a token's lifespan is valid
|
|
82
81
|
*
|
|
83
82
|
* @param {ApiToken} token
|
|
84
83
|
*/
|
package/server/services/index.js
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const permissions = require('@strapi/permissions');
|
|
4
|
+
const { providerFactory } = require('@strapi/utils');
|
|
5
|
+
|
|
6
|
+
const DEFAULT_TRANSFER_ACTIONS = ['push'];
|
|
7
|
+
|
|
8
|
+
const providers = {
|
|
9
|
+
action: providerFactory(),
|
|
10
|
+
condition: providerFactory(),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
DEFAULT_TRANSFER_ACTIONS.forEach((action) => {
|
|
14
|
+
providers.action.register(action, { action });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const engine = permissions.engine.new({ providers });
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
engine,
|
|
21
|
+
providers,
|
|
22
|
+
};
|