@strapi/admin 4.11.3 → 4.11.5

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 (115) hide show
  1. package/admin/src/components/AuthenticatedApp/index.js +2 -2
  2. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +8 -5
  3. package/admin/src/content-manager/components/Inputs/index.js +3 -47
  4. package/admin/src/content-manager/components/RelationInput/RelationInput.js +99 -178
  5. package/admin/src/content-manager/components/RelationInput/components/Option.js +17 -15
  6. package/admin/src/content-manager/components/RelationInput/components/RelationList.js +2 -2
  7. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +34 -37
  8. package/admin/src/content-manager/pages/EditSettingsView/components/ModalForm.js +0 -27
  9. package/admin/src/content-manager/pages/ListView/components/TableRows/index.js +93 -14
  10. package/admin/src/content-manager/pages/ListView/index.js +65 -47
  11. package/admin/src/content-manager/pages/ListView/utils/buildValidGetParams.js +30 -0
  12. package/admin/src/content-manager/pages/ListView/utils/index.js +1 -1
  13. package/admin/src/hooks/useAdminUsers/useAdminUsers.js +3 -3
  14. package/admin/src/hooks/useEnterprise/useEnterprise.js +4 -4
  15. package/admin/src/hooks/useSettingsMenu/index.js +35 -21
  16. package/admin/src/pages/App/index.js +0 -3
  17. package/admin/src/pages/AuthPage/components/Register/index.js +5 -1
  18. package/admin/src/pages/ProfilePage/index.js +12 -12
  19. package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +13 -11
  20. package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +15 -1
  21. package/admin/src/pages/SettingsPage/components/Tokens/TokenBox/index.js +1 -1
  22. package/admin/src/pages/SettingsPage/pages/Roles/ProtectedEditPage/index.js +4 -10
  23. package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +2 -2
  24. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/utils/makeWebhookValidationSchema.js +11 -5
  25. package/admin/src/translations/ca.json +1 -0
  26. package/admin/src/translations/en.json +4 -1
  27. package/admin/src/translations/es.json +5 -0
  28. package/admin/src/translations/fr.json +1 -0
  29. package/admin/src/translations/zh-Hans.json +1 -1
  30. package/build/2799.cf9b491f.chunk.js +1 -0
  31. package/build/539.865446c0.chunk.js +1 -0
  32. package/build/{5542.64b623c9.chunk.js → 5542.c62d0daf.chunk.js} +1 -1
  33. package/build/{5563.86f9aa9c.chunk.js → 5563.27e2de0c.chunk.js} +3 -3
  34. package/build/5932.f8be7e31.chunk.js +1 -0
  35. package/build/7259.0e25ab5d.chunk.js +1 -0
  36. package/build/{6405.27e1bee5.chunk.js → 970.89601f27.chunk.js} +2 -2
  37. package/build/{9932.7e2b71de.chunk.js → 9932.9f3790a5.chunk.js} +81 -81
  38. package/build/9944.29289a16.chunk.js +26 -0
  39. package/build/Admin-authenticatedApp.7f04c595.chunk.js +79 -0
  40. package/build/{Admin_profilePage.2131eb68.chunk.js → Admin_profilePage.0adb571e.chunk.js} +2 -2
  41. package/build/{Admin_settingsPage.4069bb8a.chunk.js → Admin_settingsPage.36152558.chunk.js} +9 -9
  42. package/build/admin-app.3ea6009c.chunk.js +61 -0
  43. package/build/{admin-edit-roles-page.2040034a.chunk.js → admin-edit-roles-page.3fdd6b9d.chunk.js} +11 -11
  44. package/build/admin-edit-users.78552758.chunk.js +10 -0
  45. package/build/admin-users.c23322fc.chunk.js +11 -0
  46. package/build/api-tokens-list-page.a103f526.chunk.js +16 -0
  47. package/build/audit-logs-settings-page.37fe915c.chunk.js +1 -0
  48. package/build/ca-json.1fed5d8b.chunk.js +1 -0
  49. package/build/content-manager.552c7418.chunk.js +1094 -0
  50. package/build/{content-type-builder-list-view.0c3ceb4e.chunk.js → content-type-builder-list-view.82cfadc0.chunk.js} +7 -7
  51. package/build/content-type-builder.238687f9.chunk.js +166 -0
  52. package/build/{email-settings-page.6b38222d.chunk.js → email-settings-page.45695daa.chunk.js} +1 -1
  53. package/build/en-json.fb9f6ddd.chunk.js +1 -0
  54. package/build/es-json.42096084.chunk.js +1 -0
  55. package/build/fr-json.69789980.chunk.js +1 -0
  56. package/build/{i18n-settings-page.ff863f20.chunk.js → i18n-settings-page.29308d0b.chunk.js} +1 -1
  57. package/build/index.html +1 -1
  58. package/build/main.3d752c03.js +2927 -0
  59. package/build/runtime~main.87232977.js +2 -0
  60. package/build/sso-settings-page.0cdb96a6.chunk.js +1 -0
  61. package/build/transfer-tokens-list-page.7237443d.chunk.js +16 -0
  62. package/build/{upload-settings.43cf16cd.chunk.js → upload-settings.cb6c14c3.chunk.js} +1 -1
  63. package/build/{upload.72f8f8fc.chunk.js → upload.7e629643.chunk.js} +2 -2
  64. package/build/users-advanced-settings-page.750b1f76.chunk.js +9 -0
  65. package/build/{users-email-settings-page.33359797.chunk.js → users-email-settings-page.e9bcd865.chunk.js} +1 -1
  66. package/build/{users-providers-settings-page.1e7a4a71.chunk.js → users-providers-settings-page.a94253e9.chunk.js} +1 -1
  67. package/build/{users-roles-settings-page.235378b6.chunk.js → users-roles-settings-page.d286426a.chunk.js} +5 -5
  68. package/build/webhook-edit-page.77ef4f1a.chunk.js +33 -0
  69. package/build/{zh-Hans-json.4cfef87d.chunk.js → zh-Hans-json.fada6f40.chunk.js} +1 -1
  70. package/ee/admin/content-manager/{components/DynamicTable/CellContent/ReviewWorkflowsStage → pages/ListView/ReviewWorkflowsColumn}/ReviewWorkflowsStageEE.js +7 -2
  71. package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/constants.js +24 -0
  72. package/ee/admin/content-manager/pages/ListView/ReviewWorkflowsColumn/index.js +1 -0
  73. package/ee/admin/hooks/useLicenseLimitNotification/index.js +17 -6
  74. package/ee/admin/hooks/useLicenseLimits/index.js +1 -32
  75. package/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js +44 -0
  76. package/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js +6 -4
  77. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +6 -4
  78. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/index.js +4 -9
  79. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/hooks/useReviewWorkflows.js +3 -5
  80. package/ee/admin/pages/SettingsPage/pages/SingleSignOn/index.js +4 -9
  81. package/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +9 -2
  82. package/ee/server/services/review-workflows/entity-service-decorator.js +20 -11
  83. package/package.json +14 -15
  84. package/server/content-types/User.js +10 -0
  85. package/server/strategies/api-token.js +9 -5
  86. package/server/strategies/data-transfer.js +9 -5
  87. package/admin/src/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -2
  88. package/admin/src/content-manager/components/RelationInput/components/Relation.js +0 -53
  89. package/admin/src/content-manager/pages/ListView/utils/buildQueryString.js +0 -36
  90. package/admin/src/content-manager/pages/ListView/utils/createPluginsFilter.js +0 -4
  91. package/admin/src/pages/App/utils/index.js +0 -3
  92. package/admin/src/pages/App/utils/unique-identifier.js +0 -12
  93. package/build/1799.84268ad3.chunk.js +0 -33
  94. package/build/5932.6a23b88c.chunk.js +0 -1
  95. package/build/7259.fb69d4bf.chunk.js +0 -1
  96. package/build/Admin-authenticatedApp.69855f1b.chunk.js +0 -79
  97. package/build/admin-app.fea867af.chunk.js +0 -61
  98. package/build/admin-edit-users.53e4290a.chunk.js +0 -10
  99. package/build/admin-users.3b12dca2.chunk.js +0 -11
  100. package/build/api-tokens-list-page.201fb67a.chunk.js +0 -16
  101. package/build/audit-logs-settings-page.b07ad202.chunk.js +0 -1
  102. package/build/ca-json.43e14418.chunk.js +0 -1
  103. package/build/content-manager.66cec770.chunk.js +0 -1094
  104. package/build/content-type-builder.e1b6d13b.chunk.js +0 -166
  105. package/build/en-json.f5fa476a.chunk.js +0 -1
  106. package/build/es-json.715b6fd8.chunk.js +0 -1
  107. package/build/fr-json.73494bf5.chunk.js +0 -1
  108. package/build/main.83edb3fc.js +0 -2926
  109. package/build/runtime~main.20c3cac6.js +0 -2
  110. package/build/sso-settings-page.35b67909.chunk.js +0 -1
  111. package/build/transfer-tokens-list-page.217573c3.chunk.js +0 -16
  112. package/build/users-advanced-settings-page.1911adf5.chunk.js +0 -9
  113. package/build/webhook-edit-page.1ee02c4b.chunk.js +0 -33
  114. package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/getTableColumn.js +0 -58
  115. package/ee/admin/content-manager/components/DynamicTable/CellContent/ReviewWorkflowsStage/index.js +0 -3
@@ -19,18 +19,18 @@ const BILLING_SELF_HOSTED_URL = 'https://strapi.io/billing/request-seats';
19
19
 
20
20
  const useLicenseLimitNotification = () => {
21
21
  const { formatMessage } = useIntl();
22
- let { license } = useLicenseLimits();
22
+ let { license, isError, isLoading } = useLicenseLimits();
23
23
  const toggleNotification = useNotification();
24
24
  const { pathname } = useLocation();
25
25
 
26
+ const { enforcementUserCount, permittedSeats, licenseLimitStatus, isHostedOnStrapiCloud } =
27
+ license;
28
+
26
29
  useEffect(() => {
27
- if (!license?.data) {
30
+ if (isError || isLoading) {
28
31
  return;
29
32
  }
30
33
 
31
- const { enforcementUserCount, permittedSeats, licenseLimitStatus, isHostedOnStrapiCloud } =
32
- license?.data ?? {};
33
-
34
34
  const shouldDisplayNotification =
35
35
  !isNil(permittedSeats) &&
36
36
  !window.sessionStorage.getItem(`${STORAGE_KEY_PREFIX}-${pathname}`) &&
@@ -84,7 +84,18 @@ const useLicenseLimitNotification = () => {
84
84
  },
85
85
  });
86
86
  }
87
- }, [toggleNotification, license.data, pathname, formatMessage]);
87
+ }, [
88
+ toggleNotification,
89
+ license,
90
+ pathname,
91
+ formatMessage,
92
+ isLoading,
93
+ permittedSeats,
94
+ licenseLimitStatus,
95
+ enforcementUserCount,
96
+ isHostedOnStrapiCloud,
97
+ isError,
98
+ ]);
88
99
  };
89
100
 
90
101
  export default useLicenseLimitNotification;
@@ -1,34 +1,3 @@
1
- import { useFetchClient, useRBAC } from '@strapi/helper-plugin';
2
- import { useQuery } from 'react-query';
3
- import { useSelector } from 'react-redux';
4
-
5
- import { selectAdminPermissions } from '../../../../admin/src/pages/App/selectors';
6
-
7
- const useLicenseLimits = () => {
8
- const permissions = useSelector(selectAdminPermissions);
9
- const rbac = useRBAC(permissions.settings.users);
10
-
11
- const {
12
- isLoading: isRBACLoading,
13
- allowedActions: { canRead, canCreate, canUpdate, canDelete },
14
- } = rbac;
15
-
16
- const isRBACAllowed = canRead && canCreate && canUpdate && canDelete;
17
-
18
- const { get } = useFetchClient();
19
- const fetchLicenseLimitInfo = async () => {
20
- const {
21
- data: { data },
22
- } = await get('/admin/license-limit-information');
23
-
24
- return data;
25
- };
26
-
27
- const license = useQuery(['ee', 'license-limit-info'], fetchLicenseLimitInfo, {
28
- enabled: !isRBACLoading && isRBACAllowed,
29
- });
30
-
31
- return { license };
32
- };
1
+ import { useLicenseLimits } from './useLicenseLimits';
33
2
 
34
3
  export default useLicenseLimits;
@@ -0,0 +1,44 @@
1
+ import * as React from 'react';
2
+
3
+ import { useFetchClient, useRBAC } from '@strapi/helper-plugin';
4
+ import { useQuery } from 'react-query';
5
+ import { useSelector } from 'react-redux';
6
+
7
+ import { selectAdminPermissions } from '../../../../admin/src/pages/App/selectors';
8
+
9
+ export function useLicenseLimits() {
10
+ const permissions = useSelector(selectAdminPermissions);
11
+ const { get } = useFetchClient();
12
+ const {
13
+ isLoading: isRBACLoading,
14
+ allowedActions: { canRead, canCreate, canUpdate, canDelete },
15
+ } = useRBAC(permissions.settings.users);
16
+ const hasPermissions = canRead && canCreate && canUpdate && canDelete;
17
+
18
+ const { data, isError, isLoading } = useQuery(
19
+ ['ee', 'license-limit-info'],
20
+ async () => {
21
+ const {
22
+ data: { data },
23
+ } = await get('/admin/license-limit-information');
24
+
25
+ return data;
26
+ },
27
+ {
28
+ enabled: !isRBACLoading && hasPermissions,
29
+ }
30
+ );
31
+
32
+ const license = data ?? {};
33
+
34
+ const getFeature = React.useCallback(
35
+ (name) => {
36
+ const feature = (license?.features ?? []).find((feature) => feature.name === name);
37
+
38
+ return feature?.options ?? {};
39
+ },
40
+ [license?.features]
41
+ );
42
+
43
+ return { license, getFeature, isError, isLoading };
44
+ }
@@ -13,11 +13,13 @@ const BILLING_SELF_HOSTED_URL = 'https://strapi.io/billing/request-seats';
13
13
 
14
14
  const AdminSeatInfo = () => {
15
15
  const { formatMessage } = useIntl();
16
- const { license } = useLicenseLimits();
17
- const { licenseLimitStatus, enforcementUserCount, permittedSeats, isHostedOnStrapiCloud } =
18
- license?.data ?? {};
16
+ const {
17
+ license: { licenseLimitStatus, enforcementUserCount, permittedSeats, isHostedOnStrapiCloud },
18
+ isError,
19
+ isLoading,
20
+ } = useLicenseLimits();
19
21
 
20
- if (!permittedSeats) {
22
+ if (isError || isLoading || !permittedSeats) {
21
23
  return null;
22
24
  }
23
25
 
@@ -1,4 +1,4 @@
1
- import { useFetchClient, useNotification } from '@strapi/helper-plugin';
1
+ import { useFetchClient, useNotification, useQueryParams } from '@strapi/helper-plugin';
2
2
  import { useQuery } from 'react-query';
3
3
  import { useLocation } from 'react-router-dom';
4
4
 
@@ -8,6 +8,7 @@ const useAuditLogsData = ({ canReadAuditLogs, canReadUsers }) => {
8
8
  const { get } = useFetchClient();
9
9
  const { search } = useLocation();
10
10
  const toggleNotification = useNotification();
11
+ const [{ query }] = useQueryParams();
11
12
 
12
13
  const queryOptions = {
13
14
  keepPreviousData: true,
@@ -35,9 +36,10 @@ const useAuditLogsData = ({ canReadAuditLogs, canReadUsers }) => {
35
36
  isError: isAuditLogsError,
36
37
  } = useQuery(
37
38
  ['auditLogs', search],
38
- async ({ queryKey }) => {
39
- const search = queryKey[1];
40
- const { data } = await get(`/admin/audit-logs${search}`);
39
+ async () => {
40
+ const { data } = await get(`/admin/audit-logs`, {
41
+ params: query,
42
+ });
41
43
 
42
44
  return data;
43
45
  },
@@ -33,17 +33,12 @@ const ListView = () => {
33
33
  const { formatMessage } = useIntl();
34
34
  const permissions = useSelector(selectAdminPermissions);
35
35
 
36
- // TODO: this is necessary because otherwise we run into an
37
- // infinite rendering loop
38
- const permissionsMemoized = React.useMemo(() => {
39
- return {
40
- ...permissions.settings.auditLogs,
41
- readUsers: permissions.settings.users.read,
42
- };
43
- }, [permissions.settings.auditLogs, permissions.settings.users.read]);
44
36
  const {
45
37
  allowedActions: { canRead: canReadAuditLogs, canReadUsers },
46
- } = useRBAC(permissionsMemoized);
38
+ } = useRBAC({
39
+ ...permissions.settings.auditLogs,
40
+ readUsers: permissions.settings.users.read,
41
+ });
47
42
 
48
43
  const [{ query }, setQuery] = useQueryParams();
49
44
  const { auditLogs, users, isLoading, hasError } = useAuditLogsData({
@@ -1,5 +1,4 @@
1
1
  import { useFetchClient } from '@strapi/helper-plugin';
2
- import { stringify } from 'qs';
3
2
  import { useQuery } from 'react-query';
4
3
 
5
4
  export function useReviewWorkflows(params = {}) {
@@ -9,7 +8,6 @@ export function useReviewWorkflows(params = {}) {
9
8
  };
10
9
 
11
10
  const { get } = useFetchClient();
12
- const queryString = stringify({ ...defaultQueryParams, ...queryParams }, { encode: false });
13
11
 
14
12
  const { data, isLoading, status, refetch } = useQuery(
15
13
  ['review-workflows', 'workflows', id],
@@ -17,9 +15,9 @@ export function useReviewWorkflows(params = {}) {
17
15
  try {
18
16
  const {
19
17
  data: { data },
20
- } = await get(
21
- `/admin/review-workflows/workflows/${id}${queryString ? `?${queryString}` : ''}`
22
- );
18
+ } = await get(`/admin/review-workflows/workflows/${id}`, {
19
+ params: { ...defaultQueryParams, ...queryParams },
20
+ });
23
21
 
24
22
  return data;
25
23
  } catch (err) {
@@ -38,18 +38,13 @@ export const SingleSignOn = () => {
38
38
  const { formatMessage } = useIntl();
39
39
  const permissions = useSelector(selectAdminPermissions);
40
40
 
41
- // TODO: this is necessary because otherwise we run into an
42
- // infinite rendering loop
43
- const permissionsMemoized = React.useMemo(() => {
44
- return {
45
- ...permissions.settings.sso,
46
- readRoles: permissions.settings.roles.read,
47
- };
48
- }, [permissions.settings.roles.read, permissions.settings.sso]);
49
41
  const {
50
42
  isLoading: isLoadingForPermissions,
51
43
  allowedActions: { canUpdate, canReadRoles },
52
- } = useRBAC(permissionsMemoized);
44
+ } = useRBAC({
45
+ ...permissions.settings.sso,
46
+ readRoles: permissions.settings.roles.read,
47
+ });
53
48
 
54
49
  const [
55
50
  { formErrors, initialData, isLoading, modifiedData, showHeaderButtonLoader },
@@ -10,8 +10,15 @@ import { useLicenseLimits } from '../../../../../../hooks';
10
10
 
11
11
  const CreateAction = ({ onClick }) => {
12
12
  const { formatMessage } = useIntl();
13
- const { license } = useLicenseLimits();
14
- const { permittedSeats, shouldStopCreate } = license?.data ?? {};
13
+ const {
14
+ license: { permittedSeats, shouldStopCreate },
15
+ isError,
16
+ isLoading,
17
+ } = useLicenseLimits();
18
+
19
+ if (isError || isLoading) {
20
+ return null;
21
+ }
15
22
 
16
23
  return (
17
24
  <Flex gap={2}>
@@ -69,22 +69,31 @@ const decorator = (service) => ({
69
69
  const previousStage = await getEntityStage(uid, entityId);
70
70
 
71
71
  const updatedEntity = await service.update.call(this, uid, entityId, { ...opts, data });
72
- if (
73
- previousStage?.workflow?.id &&
74
- previousStage?.id &&
75
- previousStage.id !== data[ENTITY_STAGE_ATTRIBUTE]
76
- ) {
77
- const webhookPayload = {
78
- entityId,
72
+ const updatedStage = updatedEntity[ENTITY_STAGE_ATTRIBUTE];
73
+
74
+ if (previousStage?.id && previousStage.id !== updatedStage.id) {
75
+ const model = strapi.getModel(uid);
76
+
77
+ strapi.eventHub.emit(WORKFLOW_UPDATE_STAGE, {
78
+ model: model.modelName,
79
+ uid: model.uid,
80
+ entity: {
81
+ id: entityId,
82
+ },
79
83
  workflow: {
80
84
  id: previousStage.workflow.id,
81
85
  stages: {
82
- from: previousStage.id,
83
- to: data[ENTITY_STAGE_ATTRIBUTE],
86
+ from: {
87
+ id: previousStage.id,
88
+ name: previousStage.name,
89
+ },
90
+ to: {
91
+ id: updatedStage.id,
92
+ name: updatedStage.name,
93
+ },
84
94
  },
85
95
  },
86
- };
87
- await strapi.entityService.emitEvent(uid, WORKFLOW_UPDATE_STAGE, webhookPayload);
96
+ });
88
97
  }
89
98
 
90
99
  return updatedEntity;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/admin",
3
- "version": "4.11.3",
3
+ "version": "4.11.5",
4
4
  "description": "Strapi Admin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,17 +46,16 @@
46
46
  "@babel/preset-react": "^7.18.6",
47
47
  "@babel/runtime": "^7.20.13",
48
48
  "@casl/ability": "^5.4.3",
49
- "@fingerprintjs/fingerprintjs": "3.4.1",
50
49
  "@pmmmwh/react-refresh-webpack-plugin": "0.5.10",
51
- "@strapi/babel-plugin-switch-ee-ce": "4.11.3",
52
- "@strapi/data-transfer": "4.11.3",
53
- "@strapi/design-system": "1.8.0",
54
- "@strapi/helper-plugin": "4.11.3",
55
- "@strapi/icons": "1.8.0",
56
- "@strapi/permissions": "4.11.3",
57
- "@strapi/provider-audit-logs-local": "4.11.3",
58
- "@strapi/typescript-utils": "4.11.3",
59
- "@strapi/utils": "4.11.3",
50
+ "@strapi/babel-plugin-switch-ee-ce": "4.11.5",
51
+ "@strapi/data-transfer": "4.11.5",
52
+ "@strapi/design-system": "1.8.1",
53
+ "@strapi/helper-plugin": "4.11.5",
54
+ "@strapi/icons": "1.8.1",
55
+ "@strapi/permissions": "4.11.5",
56
+ "@strapi/provider-audit-logs-local": "4.11.5",
57
+ "@strapi/typescript-utils": "4.11.5",
58
+ "@strapi/utils": "4.11.5",
60
59
  "axios": "1.4.0",
61
60
  "babel-loader": "^9.1.2",
62
61
  "babel-plugin-styled-components": "2.1.1",
@@ -117,7 +116,7 @@
117
116
  "react-intl": "6.4.1",
118
117
  "react-is": "^18.2.0",
119
118
  "react-query": "3.39.3",
120
- "react-redux": "8.0.5",
119
+ "react-redux": "8.1.1",
121
120
  "react-refresh": "0.14.0",
122
121
  "react-router-dom": "5.3.4",
123
122
  "react-select": "5.7.0",
@@ -131,7 +130,7 @@
131
130
  "style-loader": "3.3.1",
132
131
  "styled-components": "5.3.3",
133
132
  "typescript": "5.1.3",
134
- "webpack": "^5.86.0",
133
+ "webpack": "^5.88.1",
135
134
  "webpack-cli": "^5.1.0",
136
135
  "webpack-dev-server": "^4.15.0",
137
136
  "webpackbar": "^5.0.2",
@@ -145,7 +144,7 @@
145
144
  "glob": "8.0.3",
146
145
  "msw": "1.2.1",
147
146
  "speed-measure-webpack-plugin": "1.5.0",
148
- "webpack-bundle-analyzer": "^4.8.0"
147
+ "webpack-bundle-analyzer": "^4.9.0"
149
148
  },
150
149
  "peerDependencies": {
151
150
  "@strapi/strapi": "^4.3.4"
@@ -163,5 +162,5 @@
163
162
  }
164
163
  }
165
164
  },
166
- "gitHead": "aac28413ada24fb8fff55c2908343cc3b8a2a3e0"
165
+ "gitHead": "7bdef3d27843c78666c85f30dc2f1bcf4d6b805e"
167
166
  }
@@ -99,4 +99,14 @@ module.exports = {
99
99
  searchable: false,
100
100
  },
101
101
  },
102
+ config: {
103
+ attributes: {
104
+ resetPasswordToken: {
105
+ hidden: true,
106
+ },
107
+ registrationToken: {
108
+ hidden: true,
109
+ },
110
+ },
111
+ },
102
112
  };
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const { castArray, isNil } = require('lodash/fp');
4
+ const { differenceInHours, parseISO } = require('date-fns');
4
5
  const { UnauthorizedError, ForbiddenError } = require('@strapi/utils').errors;
5
6
  const constants = require('../services/constants');
6
7
  const { getService } = require('../utils');
@@ -53,11 +54,14 @@ const authenticate = async (ctx) => {
53
54
  }
54
55
  }
55
56
 
56
- // update lastUsedAt
57
- await strapi.query('admin::api-token').update({
58
- where: { id: apiToken.id },
59
- data: { lastUsedAt: currentDate },
60
- });
57
+ // update lastUsedAt if the token has not been used in the last hour
58
+ const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(apiToken.lastUsedAt));
59
+ if (hoursSinceLastUsed >= 1) {
60
+ await strapi.query('admin::api-token').update({
61
+ where: { id: apiToken.id },
62
+ data: { lastUsedAt: currentDate },
63
+ });
64
+ }
61
65
 
62
66
  if (apiToken.type === constants.API_TOKEN_TYPE.CUSTOM) {
63
67
  const ability = await strapi.contentAPI.permissions.engine.generateAbility(
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ const { differenceInHours, parseISO } = require('date-fns');
3
4
  const {
4
5
  errors: { UnauthorizedError, ForbiddenError },
5
6
  } = require('@strapi/utils');
@@ -52,11 +53,14 @@ const authenticate = async (ctx) => {
52
53
  }
53
54
  }
54
55
 
55
- // Update token metadata
56
- await strapi.query('admin::transfer-token').update({
57
- where: { id: transferToken.id },
58
- data: { lastUsedAt: currentDate },
59
- });
56
+ // Update token metadata if the token has not been used in the last hour
57
+ const hoursSinceLastUsed = differenceInHours(currentDate, parseISO(transferToken.lastUsedAt));
58
+ if (hoursSinceLastUsed >= 1) {
59
+ await strapi.query('admin::api-token').update({
60
+ where: { id: transferToken.id },
61
+ data: { lastUsedAt: currentDate },
62
+ });
63
+ }
60
64
 
61
65
  // Generate an ability based on the token permissions
62
66
  const ability = await getService('transfer').permission.engine.generateAbility(
@@ -1,2 +0,0 @@
1
- // Overwritten in EE
2
- export default () => null;
@@ -1,53 +0,0 @@
1
- import React from 'react';
2
-
3
- import { Flex } from '@strapi/design-system';
4
- import PropTypes from 'prop-types';
5
-
6
- export const Relation = ({
7
- children,
8
- loadMore,
9
- search,
10
- totalNumberOfRelations,
11
- size,
12
- ...props
13
- }) => {
14
- return (
15
- <>
16
- <Flex
17
- paddingBottom={totalNumberOfRelations > 0 ? 3 : 0}
18
- gap={2}
19
- justifyContent="space-between"
20
- alignItems="end"
21
- wrap="wrap"
22
- >
23
- <Flex
24
- direction="column"
25
- alignItems="stretch"
26
- basis={size <= 6 ? '100%' : '70%'}
27
- gap={1}
28
- {...props}
29
- >
30
- {search}
31
- </Flex>
32
-
33
- {loadMore}
34
- </Flex>
35
-
36
- {children}
37
- </>
38
- );
39
- };
40
-
41
- Relation.defaultProps = {
42
- search: undefined,
43
- loadMore: undefined,
44
- totalNumberOfRelations: 0,
45
- };
46
-
47
- Relation.propTypes = {
48
- children: PropTypes.node.isRequired,
49
- search: PropTypes.node,
50
- loadMore: PropTypes.node,
51
- size: PropTypes.number.isRequired,
52
- totalNumberOfRelations: PropTypes.number,
53
- };
@@ -1,36 +0,0 @@
1
- import set from 'lodash/set';
2
- import { stringify } from 'qs';
3
-
4
- import createPluginsFilter from './createPluginsFilter';
5
-
6
- /**
7
- * Creates a valid query string from an object of queryParams
8
- * This includes:
9
- * - a filters clause
10
- * - plugin options
11
- */
12
- const buildQueryString = (queryParams = {}) => {
13
- /**
14
- * Extracting pluginOptions from the query since we don't want them to be part
15
- * of the url
16
- */
17
- const {
18
- plugins: _,
19
- _q: query,
20
- ...otherQueryParams
21
- } = {
22
- ...queryParams,
23
- ...createPluginsFilter(queryParams.plugins),
24
- };
25
-
26
- if (query) {
27
- set(otherQueryParams, `_q`, encodeURIComponent(query));
28
- }
29
-
30
- return `${stringify(otherQueryParams, {
31
- encode: false,
32
- addQueryPrefix: true,
33
- })}`;
34
- };
35
-
36
- export default buildQueryString;
@@ -1,4 +0,0 @@
1
- const createPluginsFilter = (obj) =>
2
- Object.values(obj || {}).reduce((acc, current) => Object.assign(acc, current), {});
3
-
4
- export default createPluginsFilter;
@@ -1,3 +0,0 @@
1
- /* eslint-disable import/prefer-default-export */
2
-
3
- export { default as getUID } from './unique-identifier';
@@ -1,12 +0,0 @@
1
- import FingerprintJS from '@fingerprintjs/fingerprintjs';
2
-
3
- const getUniqueIdentifier = async () => {
4
- const fp = await FingerprintJS.load();
5
- const result = await fp.get();
6
-
7
- const deviceId = `web-fingerprint-${result.visitorId}`;
8
-
9
- return deviceId;
10
- };
11
-
12
- export default getUniqueIdentifier;