@strapi/admin 4.4.0-alpha.0 → 4.4.0-beta.1
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/StrapiApp.js +12 -4
- package/admin/src/components/Providers/index.js +10 -14
- package/admin/src/content-manager/components/DynamicTable/CellContent/RelationSingle/index.js +1 -1
- package/admin/src/content-manager/components/FieldTypeIcon/index.js +1 -31
- package/admin/src/content-manager/components/Inputs/index.js +10 -30
- package/admin/src/content-manager/components/SelectMany/index.js +3 -0
- package/admin/src/content-manager/components/SelectOne/SingleValue.js +2 -2
- package/admin/src/content-manager/components/SelectOne/index.js +3 -0
- package/admin/src/content-manager/components/SelectWrapper/Option.js +2 -2
- package/admin/src/content-manager/components/SelectWrapper/index.js +6 -0
- package/admin/src/content-manager/pages/EditSettingsView/components/FormModal.js +2 -7
- package/admin/src/content-manager/pages/EditSettingsView/index.js +1 -2
- package/admin/src/content-manager/pages/EditView/index.js +84 -91
- package/admin/src/content-manager/pages/ListSettingsView/index.js +1 -1
- package/admin/src/contexts/ApiTokenPermissions/index.js +24 -0
- package/admin/src/core/apis/index.js +0 -1
- package/admin/src/hooks/index.js +1 -0
- package/admin/src/hooks/useRegenerate/index.js +34 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js +56 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js +41 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js +72 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js +30 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +150 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ContenTypesSection/index.js +37 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js +40 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +68 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +452 -180
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js +13 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js +55 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/getDateOfExpiration.js +16 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/index.js +5 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +2 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/transformPermissionsData.js +36 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js +63 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js +1 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js +19 -0
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +3 -36
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +13 -11
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +4 -3
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/utils/tableHeaders.js +8 -8
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ProtectedEditView/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/index.js +10 -10
- package/admin/src/pages/SettingsPage/pages/Webhooks/ListView/index.js +1 -1
- package/admin/src/permissions/defaultPermissions.js +2 -6
- package/admin/src/translations/en.json +18 -0
- package/admin/src/translations/es.json +1 -1
- package/admin/src/translations/fr.json +33 -0
- package/build/1669.d1b29c28.chunk.js +1 -0
- package/build/{1856.d3da2fcd.chunk.js → 1856.47226450.chunk.js} +6 -6
- package/build/{2077.b25a0b57.chunk.js → 2077.61cebc93.chunk.js} +4 -4
- package/build/{2912.da8a70aa.chunk.js → 2912.a015078a.chunk.js} +10 -10
- package/build/4235.982b5799.chunk.js +30 -0
- package/build/{4715.3787be19.chunk.js → 4715.3f6cac0a.chunk.js} +30 -30
- package/build/{4800.d3ebc81d.chunk.js → 4800.d09f1225.chunk.js} +1 -1
- package/build/{4982.a4e36c9a.chunk.js → 4982.c6f88c5d.chunk.js} +8 -8
- package/build/611.a91aff91.chunk.js +158 -0
- package/build/7379.d246dd38.chunk.js +1 -0
- package/build/{7841.922b96eb.chunk.js → 7841.91f793dc.chunk.js} +9 -9
- package/build/{7866.22e3c9f8.chunk.js → 7866.c793a31d.chunk.js} +23 -23
- package/build/{8380.ab3939f3.chunk.js → 8380.8789ff76.chunk.js} +8 -8
- package/build/{8549.0e30f86d.chunk.js → 8549.133c4473.chunk.js} +5 -5
- package/build/{8773.4e36117f.chunk.js → 8773.eccaa5f3.chunk.js} +9 -9
- package/build/{9066.2847fdff.chunk.js → 9066.08049eb1.chunk.js} +4 -4
- package/build/{9166.280c7521.chunk.js → 9166.037339e0.chunk.js} +2 -2
- package/build/{9420.ee1ccff7.chunk.js → 9420.43a86e7c.chunk.js} +30 -30
- package/build/{Admin-authenticatedApp.aaa66872.chunk.js → Admin-authenticatedApp.3a31a087.chunk.js} +3 -3
- package/build/{Admin_homePage.118926e0.chunk.js → Admin_homePage.6d5e3236.chunk.js} +1 -1
- package/build/{Admin_marketplace.2d181ad7.chunk.js → Admin_marketplace.82c0570b.chunk.js} +1 -1
- package/build/{Admin_profilePage.8617313a.chunk.js → Admin_profilePage.83991a6c.chunk.js} +1 -1
- package/build/{Admin_settingsPage.e58753c8.chunk.js → Admin_settingsPage.fc9c607a.chunk.js} +16 -16
- package/build/admin-app.41b6472c.chunk.js +112 -0
- package/build/admin-edit-roles-page.4dd6bcb9.chunk.js +1 -0
- package/build/{admin-users.1d0aa7a0.chunk.js → admin-users.dccd5f4c.chunk.js} +2 -2
- package/build/api-tokens-create-page.29cc87b6.chunk.js +1 -0
- package/build/api-tokens-edit-page.c294a88f.chunk.js +1 -0
- package/build/api-tokens-list-page.bb36535f.chunk.js +16 -0
- package/build/content-manager.fb5ee865.chunk.js +1178 -0
- package/build/content-type-builder-list-view.8cc534e0.chunk.js +194 -0
- package/build/content-type-builder-translation-en-json.201bfb78.chunk.js +1 -0
- package/build/content-type-builder.42cecba9.chunk.js +142 -0
- package/build/{email-settings-page.818761d5.chunk.js → email-settings-page.64037147.chunk.js} +5 -5
- package/build/en-json.a9918c93.chunk.js +1 -0
- package/build/{es-json.bb1fc425.chunk.js → es-json.3a9c7c09.chunk.js} +1 -1
- package/build/fr-json.4ed1fc2c.chunk.js +1 -0
- package/build/{i18n-settings-page.bf1304b0.chunk.js → i18n-settings-page.0b73785d.chunk.js} +5 -5
- package/build/index.html +1 -1
- package/build/{main.7db3414f.js → main.cdfda31e.js} +1235 -1235
- package/build/{runtime~main.c1c5510b.js → runtime~main.fa8f8898.js} +1 -1
- package/build/sso-settings-page.9ceb0140.chunk.js +1 -0
- package/build/{upload-settings.5dfe0fe2.chunk.js → upload-settings.80ff0974.chunk.js} +7 -7
- package/build/upload-translation-ca-json.db8ed7ba.chunk.js +1 -0
- package/build/{users-advanced-settings-page.f11c8af4.chunk.js → users-advanced-settings-page.a02f4806.chunk.js} +5 -5
- package/build/{users-roles-settings-page.cafb4fe5.chunk.js → users-roles-settings-page.b33ec5e5.chunk.js} +1 -1
- package/build/{webhook-edit-page.9aba79b2.chunk.js → webhook-edit-page.9e46fc3f.chunk.js} +3 -3
- package/build/{webhook-list-page.912becb8.chunk.js → webhook-list-page.2775a683.chunk.js} +5 -5
- package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +1 -1
- package/package.json +14 -13
- package/scripts/build.js +2 -4
- package/server/bootstrap.js +19 -1
- package/server/config/admin-actions.js +20 -0
- package/server/content-types/api-token-permission.js +36 -0
- package/server/content-types/api-token.js +25 -1
- package/server/content-types/index.js +1 -0
- package/server/controllers/api-token.js +24 -1
- package/server/controllers/content-api.js +15 -0
- package/server/controllers/index.js +1 -0
- package/server/routes/api-tokens.js +11 -0
- package/server/routes/content-api.js +20 -0
- package/server/routes/index.js +2 -0
- package/server/services/api-token.js +310 -29
- package/server/services/constants.js +10 -0
- package/server/services/permission/engine.js +36 -226
- package/server/services/permission/permissions-manager/query-builers.js +3 -2
- package/server/services/permission/queries.js +1 -1
- package/server/services/permission.js +4 -1
- package/server/strategies/admin.js +7 -1
- package/server/strategies/api-token.js +71 -11
- package/server/validation/api-tokens.js +12 -2
- package/server/validation/common-functions/check-fields-are-correctly-nested.js +1 -1
- package/admin/src/core/apis/CustomFields.js +0 -80
- package/build/1669.4ce92b2f.chunk.js +0 -1
- package/build/524.2437fb56.chunk.js +0 -644
- package/build/admin-app.1f9e13f8.chunk.js +0 -112
- package/build/admin-edit-roles-page.554ba3fa.chunk.js +0 -1
- package/build/api-tokens-create-page.b4a9987d.chunk.js +0 -1
- package/build/api-tokens-edit-page.6f5b4e26.chunk.js +0 -1
- package/build/api-tokens-list-page.06938769.chunk.js +0 -15
- package/build/content-manager.86f7594d.chunk.js +0 -1178
- package/build/content-type-builder-list-view.9b874fd4.chunk.js +0 -194
- package/build/content-type-builder-translation-en-json.f985c9c4.chunk.js +0 -1
- package/build/content-type-builder.47ab07ad.chunk.js +0 -145
- package/build/en-json.1bf20384.chunk.js +0 -1
- package/build/fr-json.a3cf2e0b.chunk.js +0 -1
- package/build/sso-settings-page.445184e0.chunk.js +0 -1
- package/build/upload-translation-ca-json.00dc1f33.chunk.js +0 -1
- package/server/services/permission/engine-hooks.js +0 -82
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { transformPermissionsData } from './utils';
|
|
2
|
+
|
|
3
|
+
const init = (state, permissions = []) => {
|
|
4
|
+
return {
|
|
5
|
+
...state,
|
|
6
|
+
selectedAction: null,
|
|
7
|
+
routes: [],
|
|
8
|
+
selectedActions: [],
|
|
9
|
+
data: transformPermissionsData(permissions),
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default init;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* eslint-disable consistent-return */
|
|
2
|
+
import produce from 'immer';
|
|
3
|
+
import { pull } from 'lodash';
|
|
4
|
+
import { transformPermissionsData } from './utils';
|
|
5
|
+
|
|
6
|
+
export const initialState = {
|
|
7
|
+
data: {},
|
|
8
|
+
selectedActions: [],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const reducer = (state, action) =>
|
|
12
|
+
produce(state, (draftState) => {
|
|
13
|
+
switch (action.type) {
|
|
14
|
+
case 'ON_CHANGE': {
|
|
15
|
+
if (draftState.selectedActions.includes(action.value)) {
|
|
16
|
+
pull(draftState.selectedActions, action.value);
|
|
17
|
+
} else {
|
|
18
|
+
draftState.selectedActions.push(action.value);
|
|
19
|
+
}
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
case 'SELECT_ALL_ACTIONS': {
|
|
23
|
+
draftState.selectedActions = [...draftState.data.allActionsIds];
|
|
24
|
+
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case 'ON_CHANGE_READ_ONLY': {
|
|
28
|
+
const onlyReadOnlyActions = draftState.data.allActionsIds.filter(
|
|
29
|
+
(actionId) => actionId.includes('find') || actionId.includes('findOne')
|
|
30
|
+
);
|
|
31
|
+
draftState.selectedActions = [...onlyReadOnlyActions];
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case 'UPDATE_PERMISSIONS_LAYOUT': {
|
|
35
|
+
draftState.data = transformPermissionsData(action.value);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case 'UPDATE_ROUTES': {
|
|
39
|
+
draftState.routes = { ...action.value };
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case 'UPDATE_PERMISSIONS': {
|
|
43
|
+
draftState.selectedActions = [...action.value];
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case 'SET_SELECTED_ACTION': {
|
|
47
|
+
draftState.selectedAction = action.value;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
default:
|
|
51
|
+
return draftState;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export default reducer;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { addDays, format } from 'date-fns';
|
|
2
|
+
import * as locales from 'date-fns/locale';
|
|
3
|
+
|
|
4
|
+
const getDateOfExpiration = (createdAt, duration, language = 'en') => {
|
|
5
|
+
if (duration && typeof duration === 'number') {
|
|
6
|
+
const durationInDays = duration / 24 / 60 / 60 / 1000;
|
|
7
|
+
|
|
8
|
+
return format(addDays(new Date(createdAt), durationInDays), 'PPP', {
|
|
9
|
+
locale: locales[language],
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return 'Unlimited';
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default getDateOfExpiration;
|
|
@@ -5,9 +5,10 @@ const schema = yup.object().shape({
|
|
|
5
5
|
name: yup.string(translatedErrors.string).required(translatedErrors.required),
|
|
6
6
|
type: yup
|
|
7
7
|
.string(translatedErrors.string)
|
|
8
|
-
.oneOf(['read-only', 'full-access'])
|
|
8
|
+
.oneOf(['read-only', 'full-access', 'custom'])
|
|
9
9
|
.required(translatedErrors.required),
|
|
10
10
|
description: yup.string().nullable(),
|
|
11
|
+
lifespan: yup.number().integer().min(1).nullable().defined(translatedErrors.required),
|
|
11
12
|
});
|
|
12
13
|
|
|
13
14
|
export default schema;
|
package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/transformPermissionsData.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { flatten } from 'lodash';
|
|
2
|
+
|
|
3
|
+
const transformPermissionsData = (data) => {
|
|
4
|
+
const layout = {
|
|
5
|
+
allActionsIds: [],
|
|
6
|
+
permissions: [],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
layout.permissions = Object.keys(data).map((apiId) => ({
|
|
10
|
+
apiId,
|
|
11
|
+
label: apiId.split('::')[1],
|
|
12
|
+
controllers: flatten(
|
|
13
|
+
Object.keys(data[apiId].controllers).map((controller) => ({
|
|
14
|
+
controller,
|
|
15
|
+
actions: flatten(
|
|
16
|
+
data[apiId].controllers[controller].map((action) => {
|
|
17
|
+
const actionId = `${apiId}.${controller}.${action}`;
|
|
18
|
+
|
|
19
|
+
if (apiId.includes('api::')) {
|
|
20
|
+
layout.allActionsIds.push(actionId);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
action,
|
|
25
|
+
actionId,
|
|
26
|
+
};
|
|
27
|
+
})
|
|
28
|
+
),
|
|
29
|
+
}))
|
|
30
|
+
),
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
return layout;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default transformPermissionsData;
|
package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { Link } from '@strapi/helper-plugin';
|
|
5
|
+
import { useHistory } from 'react-router-dom';
|
|
6
|
+
import styled from 'styled-components';
|
|
7
|
+
|
|
8
|
+
const MESSAGES_MAP = {
|
|
9
|
+
edit: {
|
|
10
|
+
id: 'app.component.table.edit',
|
|
11
|
+
defaultMessage: 'Edit {target}',
|
|
12
|
+
},
|
|
13
|
+
read: {
|
|
14
|
+
id: 'app.component.table.read',
|
|
15
|
+
defaultMessage: 'Read {target}',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const LinkStyled = styled(Link)`
|
|
20
|
+
svg {
|
|
21
|
+
path {
|
|
22
|
+
fill: ${({ theme }) => theme.colors.neutral500};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:hover,
|
|
27
|
+
&:focus {
|
|
28
|
+
svg {
|
|
29
|
+
path {
|
|
30
|
+
fill: ${({ theme }) => theme.colors.neutral800};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const DefaultButton = ({ tokenName, tokenId, buttonType, children }) => {
|
|
37
|
+
const { formatMessage } = useIntl();
|
|
38
|
+
const {
|
|
39
|
+
location: { pathname },
|
|
40
|
+
} = useHistory();
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<LinkStyled
|
|
44
|
+
to={`${pathname}/${tokenId}`}
|
|
45
|
+
title={formatMessage(MESSAGES_MAP[buttonType], { target: tokenName })}
|
|
46
|
+
>
|
|
47
|
+
{children}
|
|
48
|
+
</LinkStyled>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
DefaultButton.propTypes = {
|
|
53
|
+
tokenName: PropTypes.string.isRequired,
|
|
54
|
+
tokenId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
|
55
|
+
buttonType: PropTypes.string,
|
|
56
|
+
children: PropTypes.node.isRequired,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
DefaultButton.defaultProps = {
|
|
60
|
+
buttonType: 'edit',
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default DefaultButton;
|
package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Eye from '@strapi/icons/Eye';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import DefaultButton from '../DefaultButton';
|
|
5
|
+
|
|
6
|
+
const ReadButton = ({ tokenName, tokenId }) => {
|
|
7
|
+
return (
|
|
8
|
+
<DefaultButton tokenName={tokenName} tokenId={tokenId} buttonType="read">
|
|
9
|
+
<Eye />
|
|
10
|
+
</DefaultButton>
|
|
11
|
+
);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
ReadButton.propTypes = {
|
|
15
|
+
tokenName: PropTypes.string.isRequired,
|
|
16
|
+
tokenId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default ReadButton;
|
package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js
CHANGED
|
@@ -1,46 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import Pencil from '@strapi/icons/Pencil';
|
|
3
|
-
import { useIntl } from 'react-intl';
|
|
4
3
|
import PropTypes from 'prop-types';
|
|
5
|
-
import
|
|
6
|
-
import { useHistory } from 'react-router-dom';
|
|
7
|
-
import styled from 'styled-components';
|
|
8
|
-
|
|
9
|
-
const LinkUpdate = styled(Link)`
|
|
10
|
-
svg {
|
|
11
|
-
path {
|
|
12
|
-
fill: ${({ theme }) => theme.colors.neutral500};
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
&:hover {
|
|
17
|
-
svg {
|
|
18
|
-
path {
|
|
19
|
-
fill: ${({ theme }) => theme.colors.neutral800};
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
4
|
+
import DefaultButton from '../DefaultButton';
|
|
24
5
|
|
|
25
6
|
const UpdateButton = ({ tokenName, tokenId }) => {
|
|
26
|
-
const { formatMessage } = useIntl();
|
|
27
|
-
const {
|
|
28
|
-
location: { pathname },
|
|
29
|
-
} = useHistory();
|
|
30
|
-
|
|
31
7
|
return (
|
|
32
|
-
<
|
|
33
|
-
to={`${pathname}/${tokenId}`}
|
|
34
|
-
title={formatMessage(
|
|
35
|
-
{
|
|
36
|
-
id: 'app.component.table.edit',
|
|
37
|
-
defaultMessage: 'Edit {target}',
|
|
38
|
-
},
|
|
39
|
-
{ target: `${tokenName}` }
|
|
40
|
-
)}
|
|
41
|
-
>
|
|
8
|
+
<DefaultButton tokenName={tokenName} tokenId={tokenId}>
|
|
42
9
|
<Pencil />
|
|
43
|
-
</
|
|
10
|
+
</DefaultButton>
|
|
44
11
|
);
|
|
45
12
|
};
|
|
46
13
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useIntl } from 'react-intl';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import { useHistory } from 'react-router-dom';
|
|
5
4
|
|
|
@@ -13,12 +12,11 @@ import {
|
|
|
13
12
|
pxToRem,
|
|
14
13
|
useTracking,
|
|
15
14
|
} from '@strapi/helper-plugin';
|
|
16
|
-
|
|
17
15
|
import DeleteButton from './DeleteButton';
|
|
18
16
|
import UpdateButton from './UpdateButton';
|
|
17
|
+
import ReadButton from './ReadButton';
|
|
19
18
|
|
|
20
|
-
const TableRows = ({ canDelete, canUpdate, onClickDelete, withBulkActions, rows }) => {
|
|
21
|
-
const { formatMessage } = useIntl();
|
|
19
|
+
const TableRows = ({ canDelete, canUpdate, canRead, onClickDelete, withBulkActions, rows }) => {
|
|
22
20
|
const [{ query }] = useQueryParams();
|
|
23
21
|
const [, sortOrder] = query.sort.split(':');
|
|
24
22
|
const {
|
|
@@ -59,22 +57,24 @@ const TableRows = ({ canDelete, canUpdate, onClickDelete, withBulkActions, rows
|
|
|
59
57
|
</Td>
|
|
60
58
|
<Td>
|
|
61
59
|
<Typography textColor="neutral800">
|
|
62
|
-
{
|
|
63
|
-
id: `Settings.apiTokens.types.${apiToken.type}`,
|
|
64
|
-
defaultMessage: 'Type unknown',
|
|
65
|
-
})}
|
|
60
|
+
<RelativeTime timestamp={new Date(apiToken.createdAt)} />
|
|
66
61
|
</Typography>
|
|
67
62
|
</Td>
|
|
68
63
|
<Td>
|
|
69
|
-
|
|
70
|
-
<
|
|
71
|
-
|
|
64
|
+
{apiToken.lastUsedAt && (
|
|
65
|
+
<Typography textColor="neutral800">
|
|
66
|
+
<RelativeTime timestamp={new Date(apiToken.lastUsedAt)} />
|
|
67
|
+
</Typography>
|
|
68
|
+
)}
|
|
72
69
|
</Td>
|
|
73
70
|
|
|
74
71
|
{withBulkActions && (
|
|
75
72
|
<Td>
|
|
76
73
|
<Flex justifyContent="end">
|
|
77
74
|
{canUpdate && <UpdateButton tokenName={apiToken.name} tokenId={apiToken.id} />}
|
|
75
|
+
{!canUpdate && canRead && (
|
|
76
|
+
<ReadButton tokenName={apiToken.name} tokenId={apiToken.id} />
|
|
77
|
+
)}
|
|
78
78
|
{canDelete && (
|
|
79
79
|
<DeleteButton
|
|
80
80
|
tokenName={apiToken.name}
|
|
@@ -94,6 +94,7 @@ const TableRows = ({ canDelete, canUpdate, onClickDelete, withBulkActions, rows
|
|
|
94
94
|
TableRows.defaultProps = {
|
|
95
95
|
canDelete: false,
|
|
96
96
|
canUpdate: false,
|
|
97
|
+
canRead: false,
|
|
97
98
|
onClickDelete() {},
|
|
98
99
|
rows: [],
|
|
99
100
|
withBulkActions: false,
|
|
@@ -102,6 +103,7 @@ TableRows.defaultProps = {
|
|
|
102
103
|
TableRows.propTypes = {
|
|
103
104
|
canDelete: PropTypes.bool,
|
|
104
105
|
canUpdate: PropTypes.bool,
|
|
106
|
+
canRead: PropTypes.bool,
|
|
105
107
|
onClickDelete: PropTypes.func,
|
|
106
108
|
rows: PropTypes.array,
|
|
107
109
|
withBulkActions: PropTypes.bool,
|
|
@@ -128,7 +128,7 @@ const ApiTokenListView = () => {
|
|
|
128
128
|
<LinkButton
|
|
129
129
|
data-testid="create-api-token-button"
|
|
130
130
|
startIcon={<Plus />}
|
|
131
|
-
size="
|
|
131
|
+
size="S"
|
|
132
132
|
onClick={() => trackUsage('willAddTokenFromList')}
|
|
133
133
|
to="/settings/api-tokens/create"
|
|
134
134
|
>
|
|
@@ -147,15 +147,16 @@ const ApiTokenListView = () => {
|
|
|
147
147
|
headers={headers}
|
|
148
148
|
contentType="api-tokens"
|
|
149
149
|
rows={apiTokens}
|
|
150
|
-
withBulkActions={canDelete || canUpdate}
|
|
150
|
+
withBulkActions={canDelete || canUpdate || canRead}
|
|
151
151
|
isLoading={isLoading}
|
|
152
152
|
onConfirmDelete={(id) => deleteMutation.mutateAsync(id)}
|
|
153
153
|
>
|
|
154
154
|
<TableRows
|
|
155
|
+
canRead={canRead}
|
|
155
156
|
canDelete={canDelete}
|
|
156
157
|
canUpdate={canUpdate}
|
|
157
158
|
rows={apiTokens}
|
|
158
|
-
withBulkActions={canDelete || canUpdate}
|
|
159
|
+
withBulkActions={canDelete || canUpdate || canRead}
|
|
159
160
|
/>
|
|
160
161
|
</DynamicTable>
|
|
161
162
|
)}
|
|
@@ -22,23 +22,23 @@ const tableHeaders = [
|
|
|
22
22
|
},
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
|
-
name: '
|
|
26
|
-
key: '
|
|
25
|
+
name: 'createdAt',
|
|
26
|
+
key: 'createdAt',
|
|
27
27
|
metadatas: {
|
|
28
28
|
label: {
|
|
29
|
-
id: 'Settings.apiTokens.ListView.headers.
|
|
30
|
-
defaultMessage: '
|
|
29
|
+
id: 'Settings.apiTokens.ListView.headers.createdAt',
|
|
30
|
+
defaultMessage: 'Created at',
|
|
31
31
|
},
|
|
32
32
|
sortable: false,
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
name: '
|
|
37
|
-
key: '
|
|
36
|
+
name: 'lastUsedAt',
|
|
37
|
+
key: 'lastUsedAt',
|
|
38
38
|
metadatas: {
|
|
39
39
|
label: {
|
|
40
|
-
id: 'Settings.apiTokens.ListView.headers.
|
|
41
|
-
defaultMessage: '
|
|
40
|
+
id: 'Settings.apiTokens.ListView.headers.lastUsedAt',
|
|
41
|
+
defaultMessage: 'Last used',
|
|
42
42
|
},
|
|
43
43
|
sortable: false,
|
|
44
44
|
},
|
|
@@ -5,7 +5,7 @@ import EditView from '../EditView';
|
|
|
5
5
|
|
|
6
6
|
const ProtectedApiTokenCreateView = () => {
|
|
7
7
|
return (
|
|
8
|
-
<CheckPagePermissions permissions={adminPermissions.settings['api-tokens'].
|
|
8
|
+
<CheckPagePermissions permissions={adminPermissions.settings['api-tokens'].read}>
|
|
9
9
|
<EditView />
|
|
10
10
|
</CheckPagePermissions>
|
|
11
11
|
);
|
|
@@ -102,7 +102,7 @@ const RoleListPage = () => {
|
|
|
102
102
|
<SettingsPageTitle name="Roles" />
|
|
103
103
|
<HeaderLayout
|
|
104
104
|
primaryAction={
|
|
105
|
-
<Button onClick={handleToggleModalForCreatingRole} startIcon={<Plus />} size="
|
|
105
|
+
<Button onClick={handleToggleModalForCreatingRole} startIcon={<Plus />} size="S">
|
|
106
106
|
{formatMessage({
|
|
107
107
|
id: 'Settings.roles.list.button.add',
|
|
108
108
|
defaultMessage: 'Add new role',
|
|
@@ -29,16 +29,16 @@ const StyledTable = styled.table`
|
|
|
29
29
|
const displayedData = {
|
|
30
30
|
headers: {
|
|
31
31
|
default: [
|
|
32
|
-
'Settings.webhooks.events.create',
|
|
33
|
-
'Settings.webhooks.events.update',
|
|
34
|
-
'app.utils.delete',
|
|
32
|
+
{ id: 'Settings.webhooks.events.create', defaultMessage: 'Create' },
|
|
33
|
+
{ id: 'Settings.webhooks.events.update', defaultMessage: 'Update' },
|
|
34
|
+
{ id: 'app.utils.delete', defaultMessage: 'Delete' },
|
|
35
35
|
],
|
|
36
36
|
draftAndPublish: [
|
|
37
|
-
'Settings.webhooks.events.create',
|
|
38
|
-
'Settings.webhooks.events.update',
|
|
39
|
-
'app.utils.delete',
|
|
40
|
-
'app.utils.publish',
|
|
41
|
-
'app.utils.unpublish',
|
|
37
|
+
{ id: 'Settings.webhooks.events.create', defaultMessage: 'Create' },
|
|
38
|
+
{ id: 'Settings.webhooks.events.update', defaultMessage: 'Update' },
|
|
39
|
+
{ id: 'app.utils.delete', defaultMessage: 'Delete' },
|
|
40
|
+
{ id: 'app.utils.publish', defaultMessage: 'Publish' },
|
|
41
|
+
{ id: 'app.utils.unpublish', defaultMessage: 'Unpublish' },
|
|
42
42
|
],
|
|
43
43
|
},
|
|
44
44
|
events: {
|
|
@@ -122,7 +122,7 @@ const EventInput = ({ isDraftAndPublish }) => {
|
|
|
122
122
|
})}
|
|
123
123
|
>
|
|
124
124
|
<Typography variant="sigma" textColor="neutral600">
|
|
125
|
-
{formatMessage(
|
|
125
|
+
{formatMessage(header)}
|
|
126
126
|
</Typography>
|
|
127
127
|
</td>
|
|
128
128
|
);
|
|
@@ -131,7 +131,7 @@ const EventInput = ({ isDraftAndPublish }) => {
|
|
|
131
131
|
return (
|
|
132
132
|
<td key={header}>
|
|
133
133
|
<Typography variant="sigma" textColor="neutral600">
|
|
134
|
-
{formatMessage(
|
|
134
|
+
{formatMessage(header)}
|
|
135
135
|
</Typography>
|
|
136
136
|
</td>
|
|
137
137
|
);
|
|
@@ -252,7 +252,7 @@ const ListView = () => {
|
|
|
252
252
|
primaryAction={
|
|
253
253
|
canCreate &&
|
|
254
254
|
!loadingWebhooks && (
|
|
255
|
-
<LinkButton startIcon={<Plus />} variant="default" to={`${pathname}/create`} size="
|
|
255
|
+
<LinkButton startIcon={<Plus />} variant="default" to={`${pathname}/create`} size="S">
|
|
256
256
|
{formatMessage({
|
|
257
257
|
id: 'Settings.webhooks.list.button.add',
|
|
258
258
|
defaultMessage: 'Create new webhook',
|
|
@@ -76,16 +76,12 @@ const permissions = {
|
|
|
76
76
|
update: [{ action: 'admin::webhooks.update', subject: null }],
|
|
77
77
|
},
|
|
78
78
|
'api-tokens': {
|
|
79
|
-
main: [
|
|
80
|
-
{ action: 'admin::api-tokens.create', subject: null },
|
|
81
|
-
{ action: 'admin::api-tokens.read', subject: null },
|
|
82
|
-
{ action: 'admin::api-tokens.update', subject: null },
|
|
83
|
-
{ action: 'admin::api-tokens.delete', subject: null },
|
|
84
|
-
],
|
|
79
|
+
main: [{ action: 'admin::api-tokens.access', subject: null }],
|
|
85
80
|
create: [{ action: 'admin::api-tokens.create', subject: null }],
|
|
86
81
|
delete: [{ action: 'admin::api-tokens.delete', subject: null }],
|
|
87
82
|
read: [{ action: 'admin::api-tokens.read', subject: null }],
|
|
88
83
|
update: [{ action: 'admin::api-tokens.update', subject: null }],
|
|
84
|
+
regenerate: [{ action: 'admin::api-tokens.regenerate', subject: null }],
|
|
89
85
|
},
|
|
90
86
|
},
|
|
91
87
|
};
|
|
@@ -91,10 +91,24 @@
|
|
|
91
91
|
"Settings.apiTokens.ListView.headers.description": "Description",
|
|
92
92
|
"Settings.apiTokens.ListView.headers.type": "Token type",
|
|
93
93
|
"Settings.apiTokens.ListView.headers.createdAt": "Created at",
|
|
94
|
+
"Settings.apiTokens.ListView.headers.lastUsedAt": "Last used",
|
|
94
95
|
"Settings.apiTokens.notification.copied": "Token copied to clipboard.",
|
|
95
96
|
"Settings.apiTokens.title": "API Tokens",
|
|
96
97
|
"Settings.apiTokens.types.full-access": "Full access",
|
|
97
98
|
"Settings.apiTokens.types.read-only": "Read-only",
|
|
99
|
+
"Settings.apiTokens.duration.7-days": "7 days",
|
|
100
|
+
"Settings.apiTokens.duration.30-days": "30 days",
|
|
101
|
+
"Settings.apiTokens.duration.90-days": "90 days",
|
|
102
|
+
"Settings.apiTokens.duration.unlimited": "Unlimited",
|
|
103
|
+
"Settings.apiTokens.form.duration":"Token duration",
|
|
104
|
+
"Settings.apiTokens.form.type":"Token type",
|
|
105
|
+
"Settings.apiTokens.duration.expiration-date":"Expiration date",
|
|
106
|
+
"Settings.apiTokens.createPage.permissions.title":"Permissions",
|
|
107
|
+
"Settings.apiTokens.createPage.permissions.description":"Only actions bound by a route are listed below.",
|
|
108
|
+
"Settings.apiTokens.RegenerateDialog.title": "Regenerate token",
|
|
109
|
+
"Settings.apiTokens.popUpWarning.message": "Are you sure you want to regenerate this token?",
|
|
110
|
+
"Settings.apiTokens.Button.cancel": "Cancel",
|
|
111
|
+
"Settings.apiTokens.Button.regenerate": "Regenerate",
|
|
98
112
|
"Settings.application.description": "Administration panel’s global information",
|
|
99
113
|
"Settings.application.edition-title": "current plan",
|
|
100
114
|
"Settings.application.get-help": "Get help",
|
|
@@ -416,6 +430,7 @@
|
|
|
416
430
|
"app.utils.defaultMessage": " ",
|
|
417
431
|
"app.utils.duplicate": "Duplicate",
|
|
418
432
|
"app.utils.edit": "Edit",
|
|
433
|
+
"app.utils.delete": "Delete",
|
|
419
434
|
"app.utils.errors.file-too-big.message": "The file is too big",
|
|
420
435
|
"app.utils.filter-value": "Filter value",
|
|
421
436
|
"app.utils.filters": "Filters",
|
|
@@ -757,6 +772,9 @@
|
|
|
757
772
|
"notification.success.delete": "The item has been deleted",
|
|
758
773
|
"notification.success.saved": "Saved",
|
|
759
774
|
"notification.success.title": "Success:",
|
|
775
|
+
"notification.success.tokencreated": "API Token successfully created",
|
|
776
|
+
"notification.success.tokenedited": "API Token successfully edited",
|
|
777
|
+
"notification.error.tokennamenotunique": "Name already assigned to another token",
|
|
760
778
|
"notification.version.update.message": "A new version of Strapi is available!",
|
|
761
779
|
"notification.warning.title": "Warning:",
|
|
762
780
|
"notification.warning.404": "404 - Not found",
|
|
@@ -759,7 +759,7 @@
|
|
|
759
759
|
"global.table.header.roles": "Roles",
|
|
760
760
|
"global.table.header.username": "Nombre de usuario",
|
|
761
761
|
"global.type": "Tipo",
|
|
762
|
-
"global.users": "
|
|
762
|
+
"global.users": "Usuarios",
|
|
763
763
|
"notification.warning.404": "404 - No Encontrado"
|
|
764
764
|
|
|
765
765
|
}
|
|
@@ -314,6 +314,7 @@
|
|
|
314
314
|
"app.utils.defaultMessage": " ",
|
|
315
315
|
"app.utils.duplicate": "Dupliquer",
|
|
316
316
|
"app.utils.edit": "Modifier",
|
|
317
|
+
"app.utils.delete": "Supprimer",
|
|
317
318
|
"app.utils.errors.file-too-big.message": "Le fichier est trop lourd",
|
|
318
319
|
"app.utils.filter-value": "Valeur du filtre",
|
|
319
320
|
"app.utils.filters": "Filtres",
|
|
@@ -587,6 +588,38 @@
|
|
|
587
588
|
"content-manager.success.record.save": "Sauvegardé",
|
|
588
589
|
"content-manager.success.record.unpublish": "Publication annulée",
|
|
589
590
|
"content-manager.utils.data-loaded": "{number, plural, =1 {L'entrée a été chargée} other {Les entrées on été chargées} avec succès",
|
|
591
|
+
"content-manager.apiError.This attribute must be unique": "Le champ {field} doit être unique",
|
|
592
|
+
"form.button.continue": "Continuer",
|
|
593
|
+
"global.search": "Rechercher",
|
|
594
|
+
"global.actions": "Actions",
|
|
595
|
+
"global.back": "Retour",
|
|
596
|
+
"global.cancel": "Annuler",
|
|
597
|
+
"global.change-password": "Modifier le mot de passe",
|
|
598
|
+
"global.content-manager": "Gestion du contenu",
|
|
599
|
+
"global.continue": "Continuer",
|
|
600
|
+
"global.delete": "Supprimer",
|
|
601
|
+
"global.delete-target": "Supprimer {target}",
|
|
602
|
+
"global.description": "Description",
|
|
603
|
+
"global.details": "Détails",
|
|
604
|
+
"global.disabled": "Désactivé",
|
|
605
|
+
"global.documentation": "Documentation",
|
|
606
|
+
"global.enabled": "Activé",
|
|
607
|
+
"global.finish": "Terminer",
|
|
608
|
+
"global.marketplace": "Marketplace",
|
|
609
|
+
"global.name": "Nom",
|
|
610
|
+
"global.none": "Aucun",
|
|
611
|
+
"global.password": "Mot de passe",
|
|
612
|
+
"global.plugins": "Plugins",
|
|
613
|
+
"global.profile": "Profil",
|
|
614
|
+
"global.reset-password": "Réinitialiser le mot de passe",
|
|
615
|
+
"global.roles": "Rôles",
|
|
616
|
+
"global.save": "Enregistrer",
|
|
617
|
+
"global.see-more": "Voir plus",
|
|
618
|
+
"global.select": "Sélectionner",
|
|
619
|
+
"global.select-all-entries": "Sélectionner toutes les entrées",
|
|
620
|
+
"global.settings": "Paramètres",
|
|
621
|
+
"global.type": "Type",
|
|
622
|
+
"global.users": "Utilisateurs",
|
|
590
623
|
"form.button.done": "Terminer",
|
|
591
624
|
"global.prompt.unsaved": "Êtes-vous sûr de vouloir quitter cette page? Toutes vos modifications seront perdues",
|
|
592
625
|
"notification.contentType.relations.conflict": "Le Type de Contenu à des relations qui rentrent en conflit",
|