@strapi/admin 4.6.1 → 4.7.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/admin/src/assets/images/onboarding-preview.png +0 -0
  2. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +0 -2
  3. package/admin/src/hooks/useRegenerate/index.js +2 -2
  4. package/admin/src/hooks/useSettingsMenu/utils/defaultGlobalLinks.js +7 -0
  5. package/admin/src/pages/Admin/Onboarding/constants.js +46 -0
  6. package/admin/src/pages/Admin/Onboarding/index.js +161 -89
  7. package/admin/src/pages/Admin/index.js +5 -2
  8. package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components → components/Tokens}/FormHead/index.js +36 -19
  9. package/admin/src/pages/SettingsPage/components/Tokens/FormiTokenContainer/LifeSpanInput.js +96 -0
  10. package/admin/src/pages/SettingsPage/components/Tokens/LifeSpanInput/index.js +98 -0
  11. package/admin/src/pages/SettingsPage/components/Tokens/Regenerate/index.js +73 -0
  12. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DefaultButton/index.js +1 -1
  13. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DeleteButton/index.js +1 -1
  14. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/ReadButton/index.js +0 -0
  15. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/UpdateButton/index.js +0 -0
  16. package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +135 -0
  17. package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components/ContentBox → components/Tokens/TokenBox}/index.js +17 -17
  18. package/admin/src/pages/SettingsPage/components/Tokens/TokenDescription/index.js +51 -0
  19. package/admin/src/pages/SettingsPage/components/Tokens/TokenName/index.js +46 -0
  20. package/admin/src/pages/SettingsPage/components/Tokens/TokenTypeSelect/index.js +69 -0
  21. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +5 -3
  22. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +52 -142
  23. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +5 -1
  24. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +37 -14
  25. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +5 -13
  26. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/FormTransferTokenContainer/index.js +105 -0
  27. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/LoadingView/index.js +50 -0
  28. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/index.js +201 -0
  29. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/getDateOfExpiration.js +16 -0
  30. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js +4 -0
  31. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/schema.js +10 -0
  32. package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/index.js +182 -0
  33. package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/utils/tableHeaders.js +48 -0
  34. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedCreateView/index.js +14 -0
  35. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedEditView/index.js +14 -0
  36. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedListView/index.js +12 -0
  37. package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +33 -0
  38. package/admin/src/permissions/defaultPermissions.js +8 -0
  39. package/admin/src/translations/en.json +18 -1
  40. package/build/19eb2dfcf2603eb55733.png +0 -0
  41. package/build/4649.15cc0afe.chunk.js +30 -0
  42. package/build/7259.aa68d808.chunk.js +1 -0
  43. package/build/7407.883fb1f5.chunk.js +1 -0
  44. package/build/Admin-authenticatedApp.f29f6021.chunk.js +79 -0
  45. package/build/{Admin_settingsPage.d1493824.chunk.js → Admin_settingsPage.178dc6e3.chunk.js} +25 -25
  46. package/build/{admin-app.25934eaa.chunk.js → admin-app.77a50e1f.chunk.js} +19 -19
  47. package/build/{api-tokens-create-page.d248362d.chunk.js → api-tokens-create-page.0db3aec1.chunk.js} +1 -1
  48. package/build/{api-tokens-edit-page.8516fa20.chunk.js → api-tokens-edit-page.671e0e26.chunk.js} +1 -1
  49. package/build/api-tokens-list-page.7387102c.chunk.js +16 -0
  50. package/build/{content-manager.35ff9726.chunk.js → content-manager.42b24d46.chunk.js} +77 -77
  51. package/build/en-json.b0748970.chunk.js +1 -0
  52. package/build/index.html +1 -1
  53. package/build/main.1022ed01.js +4393 -0
  54. package/build/runtime~main.84941a97.js +2 -0
  55. package/build/transfer-tokens-create-page.16e23791.chunk.js +1 -0
  56. package/build/transfer-tokens-edit-page.3886c973.chunk.js +1 -0
  57. package/build/transfer-tokens-list-page.e8010a89.chunk.js +16 -0
  58. package/package.json +12 -12
  59. package/server/bootstrap.js +2 -0
  60. package/server/config/admin-actions.js +48 -0
  61. package/server/content-types/index.js +2 -0
  62. package/server/content-types/transfer-token-permission.js +36 -0
  63. package/server/content-types/transfer-token.js +66 -0
  64. package/server/controllers/api-token.js +4 -5
  65. package/server/controllers/index.js +1 -0
  66. package/server/controllers/transfer/index.js +13 -0
  67. package/server/controllers/transfer/runner.js +24 -0
  68. package/server/controllers/transfer/token.js +131 -0
  69. package/server/register.js +2 -9
  70. package/server/routes/index.js +2 -0
  71. package/server/routes/transfer.js +95 -0
  72. package/server/services/api-token.js +2 -3
  73. package/server/services/constants.js +6 -0
  74. package/server/services/index.js +1 -0
  75. package/server/services/transfer/index.js +6 -0
  76. package/server/services/transfer/permission.js +22 -0
  77. package/server/services/transfer/token.js +409 -0
  78. package/server/strategies/api-token.js +4 -2
  79. package/server/strategies/data-transfer.js +107 -0
  80. package/server/strategies/index.js +1 -0
  81. package/server/utils/index.d.ts +2 -0
  82. package/server/validation/api-tokens.js +1 -6
  83. package/server/validation/transfer/index.js +5 -0
  84. package/server/validation/transfer/token.js +34 -0
  85. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +0 -78
  86. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +0 -112
  87. package/build/4318.f96a9d4d.chunk.js +0 -30
  88. package/build/8633.00ccd382.chunk.js +0 -1
  89. package/build/Admin-authenticatedApp.ce646f66.chunk.js +0 -75
  90. package/build/api-tokens-list-page.44a79fda.chunk.js +0 -16
  91. package/build/en-json.1f137a90.chunk.js +0 -1
  92. package/build/main.7b151630.js +0 -4377
  93. package/build/runtime~main.a20d633b.js +0 -2
@@ -7,6 +7,7 @@ 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';
10
11
 
11
12
  type S = {
12
13
  role: typeof role;
@@ -18,6 +19,7 @@ type S = {
18
19
  metrics: typeof metrics;
19
20
  'api-token': typeof apiToken;
20
21
  'project-settings': typeof projectSettings;
22
+ transfer: typeof transfer;
21
23
  };
22
24
 
23
25
  export function getService<T extends keyof S>(name: T): S[T];
@@ -10,12 +10,7 @@ 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
14
- .number()
15
- .integer()
16
- .min(1)
17
- .oneOf(Object.values(constants.API_TOKEN_LIFESPANS))
18
- .nullable(),
13
+ lifespan: yup.number().min(1).oneOf(Object.values(constants.API_TOKEN_LIFESPANS)).nullable(),
19
14
  })
20
15
  .noUnknown()
21
16
  .strict();
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ token: require('./token'),
5
+ };
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const { yup, validateYupSchema } = require('@strapi/utils');
4
+ const constants = require('../../services/constants');
5
+
6
+ const transferTokenCreationSchema = yup
7
+ .object()
8
+ .shape({
9
+ name: yup.string().min(1).required(),
10
+ description: yup.string().optional(),
11
+ permissions: yup.array().of(yup.string()).nullable(),
12
+ lifespan: yup
13
+ .number()
14
+ .min(1)
15
+ .oneOf(Object.values(constants.TRANSFER_TOKEN_LIFESPANS))
16
+ .nullable(),
17
+ })
18
+ .noUnknown()
19
+ .strict();
20
+
21
+ const transferTokenUpdateSchema = yup
22
+ .object()
23
+ .shape({
24
+ name: yup.string().min(1).notNull(),
25
+ description: yup.string().nullable(),
26
+ permissions: yup.array().of(yup.string()).nullable(),
27
+ })
28
+ .noUnknown()
29
+ .strict();
30
+
31
+ module.exports = {
32
+ validateTransferTokenCreationInput: validateYupSchema(transferTokenCreationSchema),
33
+ validateTransferTokenUpdateInput: validateYupSchema(transferTokenUpdateSchema),
34
+ };
@@ -1,78 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { ContentLayout } from '@strapi/design-system/Layout';
4
- import { Stack } from '@strapi/design-system/Stack';
5
- import HeaderContentBox from '../ContentBox';
6
- import FormApiTokenContainer from '../FormApiTokenContainer';
7
- import Permissions from '../Permissions';
8
-
9
- const FormBody = ({
10
- apiToken,
11
- errors,
12
- onChange,
13
- canEditInputs,
14
- isCreating,
15
- values,
16
- onDispatch,
17
- setHasChangedPermissions,
18
- }) => {
19
- return (
20
- <ContentLayout>
21
- <Stack spacing={6}>
22
- {Boolean(apiToken?.name) && <HeaderContentBox apiToken={apiToken?.accessKey} />}
23
- <FormApiTokenContainer
24
- errors={errors}
25
- onChange={onChange}
26
- canEditInputs={canEditInputs}
27
- isCreating={isCreating}
28
- values={values}
29
- apiToken={apiToken}
30
- onDispatch={onDispatch}
31
- setHasChangedPermissions={setHasChangedPermissions}
32
- />
33
- <Permissions
34
- disabled={
35
- !canEditInputs || values?.type === 'read-only' || values?.type === 'full-access'
36
- }
37
- />
38
- </Stack>
39
- </ContentLayout>
40
- );
41
- };
42
-
43
- FormBody.propTypes = {
44
- errors: PropTypes.shape({
45
- name: PropTypes.string,
46
- description: PropTypes.string,
47
- lifespan: PropTypes.string,
48
- type: PropTypes.string,
49
- }),
50
- apiToken: PropTypes.shape({
51
- id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
52
- type: PropTypes.string,
53
- lifespan: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
54
- name: PropTypes.string,
55
- accessKey: PropTypes.string,
56
- permissions: PropTypes.array,
57
- description: PropTypes.string,
58
- createdAt: PropTypes.string,
59
- }),
60
- onChange: PropTypes.func.isRequired,
61
- canEditInputs: PropTypes.bool.isRequired,
62
- isCreating: PropTypes.bool.isRequired,
63
- values: PropTypes.shape({
64
- name: PropTypes.string,
65
- description: PropTypes.string,
66
- lifespan: PropTypes.string,
67
- type: PropTypes.string,
68
- }).isRequired,
69
- onDispatch: PropTypes.func.isRequired,
70
- setHasChangedPermissions: PropTypes.func.isRequired,
71
- };
72
-
73
- FormBody.defaultProps = {
74
- errors: {},
75
- apiToken: {},
76
- };
77
-
78
- export default FormBody;
@@ -1,112 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useHistory } from 'react-router-dom';
4
-
5
- import { Typography } from '@strapi/design-system/Typography';
6
- import { Tbody, Tr, Td } from '@strapi/design-system/Table';
7
- import { Flex } from '@strapi/design-system/Flex';
8
- import {
9
- RelativeTime,
10
- useQueryParams,
11
- onRowClick,
12
- pxToRem,
13
- useTracking,
14
- } from '@strapi/helper-plugin';
15
- import DeleteButton from './DeleteButton';
16
- import UpdateButton from './UpdateButton';
17
- import ReadButton from './ReadButton';
18
-
19
- const TableRows = ({ canDelete, canUpdate, canRead, onClickDelete, withBulkActions, rows }) => {
20
- const [{ query }] = useQueryParams();
21
- const [, sortOrder] = query.sort.split(':');
22
- const {
23
- push,
24
- location: { pathname },
25
- } = useHistory();
26
- const { trackUsage } = useTracking();
27
-
28
- const apiTokens = rows.sort((a, b) => {
29
- const comparaison = a.name.localeCompare(b.name);
30
-
31
- return sortOrder === 'DESC' ? -comparaison : comparaison;
32
- });
33
-
34
- return (
35
- <Tbody>
36
- {apiTokens.map((apiToken) => {
37
- return (
38
- <Tr
39
- key={apiToken.id}
40
- {...onRowClick({
41
- fn() {
42
- trackUsage('willEditTokenFromList');
43
- push(`${pathname}/${apiToken.id}`);
44
- },
45
- condition: canUpdate,
46
- })}
47
- >
48
- <Td>
49
- <Typography textColor="neutral800" fontWeight="bold">
50
- {apiToken.name}
51
- </Typography>
52
- </Td>
53
- <Td maxWidth={pxToRem(250)}>
54
- <Typography textColor="neutral800" ellipsis>
55
- {apiToken.description}
56
- </Typography>
57
- </Td>
58
- <Td>
59
- <Typography textColor="neutral800">
60
- <RelativeTime timestamp={new Date(apiToken.createdAt)} />
61
- </Typography>
62
- </Td>
63
- <Td>
64
- {apiToken.lastUsedAt && (
65
- <Typography textColor="neutral800">
66
- <RelativeTime timestamp={new Date(apiToken.lastUsedAt)} />
67
- </Typography>
68
- )}
69
- </Td>
70
-
71
- {withBulkActions && (
72
- <Td>
73
- <Flex justifyContent="end">
74
- {canUpdate && <UpdateButton tokenName={apiToken.name} tokenId={apiToken.id} />}
75
- {!canUpdate && canRead && (
76
- <ReadButton tokenName={apiToken.name} tokenId={apiToken.id} />
77
- )}
78
- {canDelete && (
79
- <DeleteButton
80
- tokenName={apiToken.name}
81
- onClickDelete={() => onClickDelete(apiToken.id)}
82
- />
83
- )}
84
- </Flex>
85
- </Td>
86
- )}
87
- </Tr>
88
- );
89
- })}
90
- </Tbody>
91
- );
92
- };
93
-
94
- TableRows.defaultProps = {
95
- canDelete: false,
96
- canUpdate: false,
97
- canRead: false,
98
- onClickDelete() {},
99
- rows: [],
100
- withBulkActions: false,
101
- };
102
-
103
- TableRows.propTypes = {
104
- canDelete: PropTypes.bool,
105
- canUpdate: PropTypes.bool,
106
- canRead: PropTypes.bool,
107
- onClickDelete: PropTypes.func,
108
- rows: PropTypes.array,
109
- withBulkActions: PropTypes.bool,
110
- };
111
-
112
- export default TableRows;
@@ -1,30 +0,0 @@
1
- "use strict";(self.webpackChunk_strapi_admin=self.webpackChunk_strapi_admin||[]).push([[4318],{31625:function(ct,ge,o){o.d(ge,{Z:function(){return st}});var e=o(32735),C=o(5636),u=o(88425),w=o(27649),me=o(83281),q=o(5141),_=o(84968),fe=o(64421),ee=o(64213),ye=o(54049),Ee=(n,a,s="en")=>{if(a&&typeof a=="number"){const l=a/24/60/60/1e3;return(0,ee.format)((0,ee.addDays)(new Date(n),l),"PPP",{locale:ye[s]})}return"Unlimited"},I=o(5173),he=I.Ry().shape({name:I.Z_(u.translatedErrors.string).required(u.translatedErrors.required),type:I.Z_(u.translatedErrors.string).oneOf(["read-only","full-access","custom"]).required(u.translatedErrors.required),description:I.Z_().nullable(),lifespan:I.Rx().integer().min(0).nullable().defined(u.translatedErrors.required)}),M=o(92891),te=n=>{const a={allActionsIds:[],permissions:[]};return a.permissions=Object.keys(n).map(s=>({apiId:s,label:s.split("::")[1],controllers:(0,M.flatten)(Object.keys(n[s].controllers).map(l=>({controller:l,actions:(0,M.flatten)(n[s].controllers[l].map(i=>{const r=`${s}.${l}.${i}`;return s.includes("api::")&&a.allActionsIds.push(r),{action:i,actionId:r}}))})))})),a},ne=o(28356),ae=o(17e3),Z=o(41415),se=o(66456),Te=o(60216),t=o.n(Te);const U=({apiTokenName:n})=>{const{formatMessage:a}=(0,C.useIntl)();return(0,u.useFocusWhenNavigate)(),e.createElement(w.o,{"aria-busy":"true"},e.createElement(u.SettingsPageTitle,{name:"API Tokens"}),e.createElement(ne.T,{primaryAction:e.createElement(Z.z,{disabled:!0,startIcon:e.createElement(se.Z,null),type:"button",size:"L"},a({id:"global.save",defaultMessage:"Save"})),title:n||a({id:"Settings.apiTokens.createPage.title",defaultMessage:"Create API Token"})}),e.createElement(ae.D,null,e.createElement(u.LoadingIndicatorPage,null)))};U.defaultProps={apiTokenName:null},U.propTypes={apiTokenName:t().string};var ve=U,Ce=o(29439),k=o(27677),oe=o(44647),Ae=o(8888);const F=({onRegenerate:n,idToRegenerate:a})=>{const{formatMessage:s}=(0,C.useIntl)(),[l,i]=(0,e.useState)(!1),{regenerateData:r,isLoadingConfirmation:p}=(0,Ae.rW)(a,n),f=async()=>{r(),i(!1)};return e.createElement(e.Fragment,null,e.createElement(Z.z,{startIcon:e.createElement(oe.Z,null),type:"button",size:"S",variant:"tertiary",onClick:()=>i(!0),name:"regenerate"},s({id:"Settings.apiTokens.regenerate",defaultMessage:"Regenerate"})),e.createElement(u.ConfirmDialog,{bodyText:{id:"Settings.apiTokens.popUpWarning.message",defaultMessage:"Are you sure you want to regenerate this token?"},iconRightButton:e.createElement(oe.Z,null),isConfirmButtonLoading:p,isOpen:l,onToggleDialog:()=>i(!1),onConfirm:f,leftButtonText:{id:"Settings.apiTokens.Button.cancel",defaultMessage:"Cancel"},rightButtonText:{id:"Settings.apiTokens.Button.regenerate",defaultMessage:"Regenerate"},title:{id:"Settings.apiTokens.RegenerateDialog.title",defaultMessage:"Regenerate token"}}))};F.defaultProps={onRegenerate(){}},F.propTypes={onRegenerate:t().func,idToRegenerate:t().oneOfType([t().number,t().string]).isRequired};var ie=F;const K=({apiToken:n,setApiToken:a,canEditInputs:s,canRegenerate:l,isSubmitting:i})=>{const{formatMessage:r}=(0,C.useIntl)(),p=f=>{a({...n,accessKey:f})};return e.createElement(ne.T,{title:n?.name||r({id:"Settings.apiTokens.createPage.title",defaultMessage:"Create API Token"}),primaryAction:s?e.createElement(k.K,{horizontal:!0,spacing:2},l&&n?.id&&e.createElement(ie,{onRegenerate:p,idToRegenerate:n?.id}),e.createElement(Z.z,{disabled:i,loading:i,startIcon:e.createElement(se.Z,null),type:"submit",size:"S"},r({id:"global.save",defaultMessage:"Save"}))):l&&n?.id&&e.createElement(ie,{onRegenerate:p,idToRegenerate:n?.id}),navigationAction:e.createElement(u.Link,{startIcon:e.createElement(Ce.Z,null),to:"/settings/api-tokens"},r({id:"global.back",defaultMessage:"Back"}))})};K.propTypes={apiToken:t().shape({id:t().oneOfType([t().number,t().string]),type:t().string,lifespan:t().oneOfType([t().number,t().string]),name:t().string,accessKey:t().string,permissions:t().array,description:t().string,createdAt:t().string}),canEditInputs:t().bool.isRequired,canRegenerate:t().bool.isRequired,setApiToken:t().func.isRequired,isSubmitting:t().bool.isRequired},K.defaultProps={apiToken:void 0};var ke=K,Se=o(50563),Re=o(47765),xe=o(59087),Pe=o(11631);const W=({apiToken:n})=>{const{formatMessage:a}=(0,C.useIntl)(),s=(0,u.useNotification)(),{trackUsage:l}=(0,u.useTracking)(),i=(0,e.useRef)(l);return e.createElement(u.ContentBox,{endAction:n&&e.createElement("span",{style:{alignSelf:"start"}},e.createElement(xe.CopyToClipboard,{onCopy:()=>{i.current("didCopyTokenKey"),s({type:"success",message:{id:"Settings.apiTokens.notification.copied"}})},text:n},e.createElement(Se.h,{label:a({id:"app.component.CopyToClipboard.label",defaultMessage:"Copy to clipboard"}),noBorder:!0,icon:e.createElement(Re.Z,null),style:{padding:0,height:"1rem"}}))),title:n||a({id:"Settings.apiTokens.copy.editTitle",defaultMessage:"This token isn\u2019t accessible anymore."}),subtitle:a(n?{id:"Settings.apiTokens.copy.lastWarning",defaultMessage:"Make sure to copy this token, you won\u2019t be able to see it again!"}:{id:"Settings.apiTokens.copy.editMessage",defaultMessage:"For security reasons, you can only see your token once."}),icon:e.createElement(Pe.Z,null),iconBackground:"neutral100"})};W.defaultProps={apiToken:null},W.propTypes={apiToken:t().string};var Ie=W,S=o(72850),$=o(15335),R=o(5803),re=o(70218),x=o(84967),Me=o(10508),be=o(10369),v=o(49372);const H=({errors:n,onChange:a,canEditInputs:s,isCreating:l,values:i,apiToken:r,onDispatch:p,setHasChangedPermissions:f})=>{const{formatMessage:d}=(0,C.useIntl)(),[A]=(0,u.usePersistentState)("strapi-admin-language","en"),b=({target:{value:y}})=>{f(!1),y==="full-access"&&p({type:"SELECT_ALL_ACTIONS"}),y==="read-only"&&p({type:"ON_CHANGE_READ_ONLY"})};return e.createElement(S.x,{background:"neutral0",hasRadius:!0,shadow:"filterShadow",paddingTop:6,paddingBottom:6,paddingLeft:7,paddingRight:7},e.createElement(k.K,{spacing:4},e.createElement(v.Z,{variant:"delta",as:"h2"},d({id:"global.details",defaultMessage:"Details"})),e.createElement($.r,{gap:5},e.createElement(R.P,{key:"name",col:6,xs:12},e.createElement(be.o,{name:"name",error:n.name?d(n.name?.id?n.name:{id:n.name,defaultMessage:n.name}):null,label:d({id:"Settings.apiTokens.form.name",defaultMessage:"Name"}),onChange:a,value:i.name,disabled:!s,required:!0})),e.createElement(R.P,{key:"description",col:6,xs:12},e.createElement(Me.g,{label:d({id:"Settings.apiTokens.form.description",defaultMessage:"Description"}),name:"description",error:n.description?d(n.description?.id?n.description:{id:n.description,defaultMessage:n.description}):null,onChange:a,disabled:!s},i.description)),e.createElement(R.P,{key:"lifespan",col:6,xs:12},e.createElement(re.P,{name:"lifespan",label:d({id:"Settings.apiTokens.form.duration",defaultMessage:"Token duration"}),value:i.lifespan!==null?i.lifespan:"0",error:n.lifespan?d(n.lifespan?.id?n.lifespan:{id:n.lifespan,defaultMessage:n.lifespan}):null,onChange:y=>{a({target:{name:"lifespan",value:y}})},required:!0,disabled:!l,placeholder:"Select"},e.createElement(x.W,{value:"604800000"},d({id:"Settings.apiTokens.duration.7-days",defaultMessage:"7 days"})),e.createElement(x.W,{value:"2592000000"},d({id:"Settings.apiTokens.duration.30-days",defaultMessage:"30 days"})),e.createElement(x.W,{value:"7776000000"},d({id:"Settings.apiTokens.duration.90-days",defaultMessage:"90 days"})),e.createElement(x.W,{value:"0"},d({id:"Settings.apiTokens.duration.unlimited",defaultMessage:"Unlimited"}))),e.createElement(v.Z,{variant:"pi",textColor:"neutral600"},!l&&`${d({id:"Settings.apiTokens.duration.expiration-date",defaultMessage:"Expiration date"})}: ${Ee(r?.createdAt,parseInt(i.lifespan,10),A)}`)),e.createElement(R.P,{key:"type",col:6,xs:12},e.createElement(re.P,{name:"type",label:d({id:"Settings.apiTokens.form.type",defaultMessage:"Token type"}),value:i?.type,error:n.type?d(n.type?.id?n.type:{id:n.type,defaultMessage:n.type}):null,onChange:y=>{b({target:{value:y}}),a({target:{name:"type",value:y}})},placeholder:"Select",required:!0,disabled:!s},e.createElement(x.W,{value:"read-only"},d({id:"Settings.apiTokens.types.read-only",defaultMessage:"Read-only"})),e.createElement(x.W,{value:"full-access"},d({id:"Settings.apiTokens.types.full-access",defaultMessage:"Full access"})),e.createElement(x.W,{value:"custom"},d({id:"Settings.apiTokens.types.custom",defaultMessage:"Custom"})))))))};H.propTypes={errors:t().shape({name:t().string,description:t().string,lifespan:t().string,type:t().string}),onChange:t().func.isRequired,canEditInputs:t().bool.isRequired,values:t().shape({name:t().string,description:t().string,lifespan:t().oneOfType([t().number,t().string]),type:t().string}).isRequired,isCreating:t().bool.isRequired,apiToken:t().shape({id:t().oneOfType([t().number,t().string]),type:t().string,lifespan:t().string,name:t().string,accessKey:t().string,permissions:t().array,description:t().string,createdAt:t().string}),onDispatch:t().func.isRequired,setHasChangedPermissions:t().func.isRequired},H.defaultProps={errors:{},apiToken:{}};var Oe=H,Le=o(83828),Ne=o(61762),De=o(89966),le=o(8284),Be=o(87933),Ze=o(45112),D=o(83292);const ce=(0,e.createContext)({}),de=({children:n,...a})=>e.createElement(ce.Provider,{value:a},n),G=()=>(0,e.useContext)(ce);de.propTypes={children:t().node.isRequired};const ue=D.css`
2
- background: ${n=>n.theme.colors.primary100};
3
- svg {
4
- opacity: 1;
5
- }
6
- `;var Ue=(0,D.default)(S.x)`
7
- display: flex;
8
- justify-content: space-between;
9
- align-items: center;
10
-
11
- svg {
12
- opacity: 0;
13
- path {
14
- fill: ${n=>n.theme.colors.primary600};
15
- }
16
- }
17
-
18
- /* Show active style both on hover and when the action is selected */
19
- ${n=>n.isActive&&ue}
20
- &:hover {
21
- ${ue}
22
- }
23
- `;const Fe=D.default.div`
24
- flex: 1;
25
- align-self: center;
26
- border-top: 1px solid ${({theme:n})=>n.colors.neutral150};
27
- `,V=({controllers:n,label:a,orderNumber:s,disabled:l,onExpanded:i,indexExpandendCollapsedContent:r})=>{const{value:{onChangeSelectAll:p,onChange:f,selectedActions:d,setSelectedAction:A,selectedAction:b}}=G(),[y,B]=(0,e.useState)(!1),O=()=>{B(g=>!g),i(s)};(0,e.useEffect)(()=>{r!==null&&r!==s&&y&&B(!1)},[r,s,y]);const m=g=>g===b;return e.createElement(Le.U,{expanded:y,onToggle:O,variant:s%2?"primary":"secondary"},e.createElement(Ne.B,{title:(0,M.capitalize)(a)}),e.createElement(De.v,null,n?.map(g=>{const L=g.actions.every(E=>d.includes(E.actionId)),Q=g.actions.some(E=>d.includes(E.actionId));return e.createElement(S.x,{key:`${a}.${g?.controller}`},e.createElement(Be.k,{justifyContent:"space-between",alignItems:"center",padding:4},e.createElement(S.x,{paddingRight:4},e.createElement(v.Z,{variant:"sigma",textColor:"neutral600"},g?.controller)),e.createElement(Fe,null),e.createElement(S.x,{paddingLeft:4},e.createElement(le.X,{value:L,indeterminate:!L&&Q,onValueChange:()=>{p({target:{value:[...g.actions]}})},disabled:l},"Select all"))),e.createElement($.r,{gap:4,padding:4},g?.actions&&g?.actions.map(E=>e.createElement(R.P,{col:6,key:E.actionId},e.createElement(Ue,{isActive:m(E.actionId),padding:2,hasRadius:!0},e.createElement(le.X,{value:d.includes(E.actionId),name:E.actionId,onValueChange:()=>{f({target:{value:E.actionId}})},disabled:l},E.action),e.createElement("button",{type:"button","data-testid":"action-cog",onClick:()=>A({target:{value:E.actionId}}),style:{display:"inline-flex",alignItems:"center"}},e.createElement(Ze.Z,null)))))))})))};V.defaultProps={controllers:[],orderNumber:0,disabled:!1,onExpanded:()=>null,indexExpandendCollapsedContent:null},V.propTypes={controllers:t().array,orderNumber:t().number,label:t().string.isRequired,disabled:t().bool,onExpanded:t().func,indexExpandendCollapsedContent:t().number};var Ke=V;const z=({section:n,...a})=>{const[s,l]=(0,e.useState)(null),i=r=>l(r);return e.createElement(S.x,{padding:4,background:"neutral0"},n&&n.map((r,p)=>e.createElement(Ke,{key:r.apiId,label:r.label,controllers:r.controllers,orderNumber:p,indexExpandendCollapsedContent:s,onExpanded:i,name:r.apiId,...a})))};z.defaultProps={section:null},z.propTypes={section:t().arrayOf(t().object)};var We=z,$e=o(37213),He=o.n($e),Ge=o(15738),Ve=o.n(Ge),ze=n=>{switch(n){case"POST":return{text:"success600",border:"success200",background:"success100"};case"GET":return{text:"secondary600",border:"secondary200",background:"secondary100"};case"PUT":return{text:"warning600",border:"warning200",background:"warning100"};case"DELETE":return{text:"danger600",border:"danger200",background:"danger100"};default:return{text:"neutral600",border:"neutral200",background:"neutral100"}}};const Ye=(0,D.default)(S.x)`
28
- margin: -1px;
29
- border-radius: ${({theme:n})=>n.spaces[1]} 0 0 ${({theme:n})=>n.spaces[1]};
30
- `;function Y({route:n}){const{formatMessage:a}=(0,C.useIntl)(),{method:s,handler:l,path:i}=n,r=i?Ve()(i.split("/")):[],[p="",f=""]=l?l.split("."):[],d=ze(n.method);return e.createElement(k.K,{spacing:2},e.createElement(v.Z,{variant:"delta",as:"h3"},a({id:"Settings.apiTokens.createPage.BoundRoute.title",defaultMessage:"Bound route to"}),"\xA0",e.createElement("span",null,p),e.createElement(v.Z,{variant:"delta",textColor:"primary600"},".",f)),e.createElement(k.K,{horizontal:!0,hasRadius:!0,background:"neutral0",borderColor:"neutral200",spacing:0},e.createElement(Ye,{background:d.background,borderColor:d.border,padding:2},e.createElement(v.Z,{fontWeight:"bold",textColor:d.text},s)),e.createElement(S.x,{paddingLeft:2,paddingRight:2},He()(r,A=>e.createElement(v.Z,{key:A,textColor:A.includes(":")?"neutral600":"neutral900"},"/",A)))))}Y.defaultProps={route:{handler:"Nocontroller.error",method:"GET",path:"/there-is-no-path"}},Y.propTypes={route:t().shape({handler:t().string,method:t().string,path:t().string})};var je=Y,Qe=()=>{const{value:{selectedAction:n,routes:a}}=G(),{formatMessage:s}=(0,C.useIntl)(),l=n?.split(".")[0];return e.createElement(R.P,{col:5,background:"neutral150",paddingTop:6,paddingBottom:6,paddingLeft:7,paddingRight:7,style:{minHeight:"100%"}},n?e.createElement(k.K,{spacing:2},a[l]?.map(i=>i.config.auth?.scope?.includes(n)||i.handler===n?e.createElement(je,{key:i.handler,route:i}):null)):e.createElement(k.K,{spacing:2},e.createElement(v.Z,{variant:"delta",as:"h3"},s({id:"Settings.apiTokens.createPage.permissions.header.title",defaultMessage:"Advanced settings"})),e.createElement(v.Z,{as:"p",textColor:"neutral600"},s({id:"Settings.apiTokens.createPage.permissions.header.hint",defaultMessage:"Select the application's actions or the plugin's actions and click on the cog icon to display the bound route"}))))};const Xe=({...n})=>{const{value:{data:a}}=G(),{formatMessage:s}=(0,C.useIntl)();return e.createElement($.r,{gap:0,shadow:"filterShadow",hasRadius:!0,background:"neutral0"},e.createElement(R.P,{col:7,paddingTop:6,paddingBottom:6,paddingLeft:7,paddingRight:7},e.createElement(k.K,{spacing:2},e.createElement(v.Z,{variant:"delta",as:"h2"},s({id:"Settings.apiTokens.createPage.permissions.title",defaultMessage:"Permissions"})),e.createElement(v.Z,{as:"p",textColor:"neutral600"},s({id:"Settings.apiTokens.createPage.permissions.description",defaultMessage:"Only actions bound by a route are listed below."}))),a?.permissions&&e.createElement(We,{section:a?.permissions,...n})),e.createElement(Qe,null))};var Je=(0,e.memo)(Xe);const j=({apiToken:n,errors:a,onChange:s,canEditInputs:l,isCreating:i,values:r,onDispatch:p,setHasChangedPermissions:f})=>e.createElement(ae.D,null,e.createElement(k.K,{spacing:6},Boolean(n?.name)&&e.createElement(Ie,{apiToken:n?.accessKey}),e.createElement(Oe,{errors:a,onChange:s,canEditInputs:l,isCreating:i,values:r,apiToken:n,onDispatch:p,setHasChangedPermissions:f}),e.createElement(Je,{disabled:!l||r?.type==="read-only"||r?.type==="full-access"})));j.propTypes={errors:t().shape({name:t().string,description:t().string,lifespan:t().string,type:t().string}),apiToken:t().shape({id:t().oneOfType([t().number,t().string]),type:t().string,lifespan:t().oneOfType([t().number,t().string]),name:t().string,accessKey:t().string,permissions:t().array,description:t().string,createdAt:t().string}),onChange:t().func.isRequired,canEditInputs:t().bool.isRequired,isCreating:t().bool.isRequired,values:t().shape({name:t().string,description:t().string,lifespan:t().string,type:t().string}).isRequired,onDispatch:t().func.isRequired,setHasChangedPermissions:t().func.isRequired},j.defaultProps={errors:{},apiToken:{}};var we=j,qe=o(72041),_e=(n,a=[])=>({...n,selectedAction:null,routes:[],selectedActions:[],data:te(a)}),et=o(97889);const tt={data:{},selectedActions:[]};var nt=(n,a)=>(0,et.default)(n,s=>{switch(a.type){case"ON_CHANGE":{s.selectedActions.includes(a.value)?(0,M.pull)(s.selectedActions,a.value):s.selectedActions.push(a.value);break}case"SELECT_ALL_IN_PERMISSION":{a.value.every(i=>s.selectedActions.includes(i.actionId))?a.value.forEach(i=>{(0,M.pull)(s.selectedActions,i.actionId)}):a.value.forEach(i=>{s.selectedActions.push(i.actionId)});break}case"SELECT_ALL_ACTIONS":{s.selectedActions=[...s.data.allActionsIds];break}case"ON_CHANGE_READ_ONLY":{const l=s.data.allActionsIds.filter(i=>i.includes("find")||i.includes("findOne"));s.selectedActions=[...l];break}case"UPDATE_PERMISSIONS_LAYOUT":{s.data=te(a.value);break}case"UPDATE_ROUTES":{s.routes={...a.value};break}case"UPDATE_PERMISSIONS":{s.selectedActions=[...a.value];break}case"SET_SELECTED_ACTION":{s.selectedAction=a.value;break}default:return s}});const at="Name already taken";var st=()=>{(0,u.useFocusWhenNavigate)();const{formatMessage:n}=(0,C.useIntl)(),{lockApp:a,unlockApp:s}=(0,u.useOverlayBlocker)(),l=(0,u.useNotification)(),i=(0,q.useHistory)(),[r,p]=(0,e.useState)(i.location.state?.apiToken.accessKey?{...i.location.state.apiToken}:null),{trackUsage:f}=(0,u.useTracking)(),d=(0,e.useRef)(f),{setCurrentStep:A}=(0,u.useGuidedTour)(),{allowedActions:{canCreate:b,canUpdate:y,canRegenerate:B}}=(0,u.useRBAC)(qe.Z.settings["api-tokens"]),[O,m]=(0,e.useReducer)(nt,tt,c=>_e(c,{})),{params:{id:g}}=(0,q.useRouteMatch)("/settings/api-tokens/:id"),{get:L,post:Q,put:E}=(0,u.useFetchClient)(),T=g==="create";(0,_.useQuery)("content-api-permissions",async()=>{const[c,P]=await Promise.all(["/admin/content-api/permissions","/admin/content-api/routes"].map(async N=>{const{data:h}=await L(N);return h.data}));m({type:"UPDATE_PERMISSIONS_LAYOUT",value:c}),m({type:"UPDATE_ROUTES",value:P}),r&&(r?.type==="read-only"&&m({type:"ON_CHANGE_READ_ONLY"}),r?.type==="full-access"&&m({type:"SELECT_ALL_ACTIONS"}),r?.type==="custom"&&m({type:"UPDATE_PERMISSIONS",value:r?.permissions}))},{onError(){l({type:"warning",message:{id:"notification.error",defaultMessage:"An error occured"}})}}),(0,e.useEffect)(()=>{d.current(T?"didAddTokenFromList":"didEditTokenFromList")},[T]);const{status:ot}=(0,_.useQuery)(["api-token",g],async()=>{const{data:{data:c}}=await L(`/admin/api-tokens/${g}`);return p({...c}),c?.type==="read-only"&&m({type:"ON_CHANGE_READ_ONLY"}),c?.type==="full-access"&&m({type:"SELECT_ALL_ACTIONS"}),c?.type==="custom"&&m({type:"UPDATE_PERMISSIONS",value:c?.permissions}),c},{enabled:!T&&!r,onError(){l({type:"warning",message:{id:"notification.error",defaultMessage:"An error occured"}})}}),it=async(c,P)=>{d.current(T?"willCreateToken":"willEditToken"),a();const N=c.lifespan&&parseInt(c.lifespan,10)&&c.lifespan!=="0"?parseInt(c.lifespan,10):null;try{const{data:{data:h}}=T?await Q("/admin/api-tokens",{...c,lifespan:N,permissions:c.type==="custom"?O.selectedActions:null}):await E(`/admin/api-tokens/${g}`,{name:c.name,description:c.description,type:c.type,permissions:c.type==="custom"?O.selectedActions:null});T&&(i.replace(`/settings/api-tokens/${h.id}`,{apiToken:h}),A("apiTokens.success")),s(),p({...h}),l({type:"success",message:n(T?{id:"notification.success.tokencreated",defaultMessage:"API Token successfully created"}:{id:"notification.success.tokenedited",defaultMessage:"API Token successfully edited"})}),d.current(T?"didCreateToken":"didEditToken",{type:r.type})}catch(h){const J=(0,fe.Iz)(h.response.data);P.setErrors(J),h?.response?.data?.error?.message===at?l({type:"warning",message:h.response.data.message||"notification.error.tokennamenotunique"}):l({type:"warning",message:h?.response?.data?.message||"notification.error"}),s()}},[rt,X]=(0,e.useState)(!1),lt={...O,onChange:({target:{value:c}})=>{X(!0),m({type:"ON_CHANGE",value:c})},onChangeSelectAll:({target:{value:c}})=>{X(!0),m({type:"SELECT_ALL_IN_PERMISSION",value:c})},setSelectedAction:({target:{value:c}})=>{m({type:"SET_SELECTED_ACTION",value:c})}},pe=y&&!T||b&&T;return!T&&!r&&ot!=="success"?e.createElement(ve,{apiTokenName:r?.name}):e.createElement(de,{value:lt},e.createElement(w.o,null,e.createElement(u.SettingsPageTitle,{name:"API Tokens"}),e.createElement(me.Formik,{validationSchema:he,validateOnChange:!1,initialValues:{name:r?.name||"",description:r?.description||"",type:r?.type,lifespan:r?.lifespan?r.lifespan.toString():r?.lifespan},enableReinitialize:!0,onSubmit:(c,P)=>it(c,P)},({errors:c,handleChange:P,isSubmitting:N,values:h,setFieldValue:J})=>(rt&&h?.type!=="custom"&&J("type","custom"),e.createElement(u.Form,null,e.createElement(ke,{apiToken:r,setApiToken:p,canEditInputs:pe,canRegenerate:B,isSubmitting:N}),e.createElement(we,{apiToken:r,errors:c,onChange:P,canEditInputs:pe,isCreating:T,values:h,onDispatch:m,setHasChangedPermissions:X}))))))}}}]);