@webiny/app-headless-cms 6.1.0 → 6.2.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.
- package/HeadlessCMS.js +5 -2
- package/HeadlessCMS.js.map +1 -1
- package/admin/components/ContentEntryForm/Header/Header.js +3 -6
- package/admin/components/ContentEntryForm/Header/Header.js.map +1 -1
- package/admin/components/ContentEntryForm/Header/RevisionSelector/RevisionSelector.js +1 -1
- package/admin/components/ContentEntryForm/Header/RevisionSelector/RevisionSelector.js.map +1 -1
- package/admin/contexts/Cms/index.js +32 -2
- package/admin/contexts/Cms/index.js.map +1 -1
- package/admin/hooks/usePermission.js +132 -125
- package/admin/hooks/usePermission.js.map +1 -1
- package/admin/plugins/apiInformation/index.js +3 -3
- package/admin/plugins/apiInformation/index.js.map +1 -1
- package/admin/plugins/apiInformation/placeholder.manage.graphql.d.ts +1 -0
- package/admin/plugins/apiInformation/placeholder.manage.graphql.js +22 -0
- package/admin/plugins/apiInformation/placeholder.manage.graphql.js.map +1 -0
- package/admin/plugins/apiInformation/placeholder.preview.graphql.d.ts +1 -0
- package/admin/plugins/apiInformation/placeholder.preview.graphql.js +19 -0
- package/admin/plugins/apiInformation/placeholder.preview.graphql.js.map +1 -0
- package/admin/plugins/apiInformation/placeholder.read.graphql.d.ts +1 -0
- package/admin/plugins/apiInformation/placeholder.read.graphql.js +20 -0
- package/admin/plugins/apiInformation/placeholder.read.graphql.js.map +1 -0
- package/admin/views/contentEntries/ContentEntriesContext.js +5 -15
- package/admin/views/contentEntries/ContentEntriesContext.js.map +1 -1
- package/admin/views/contentEntries/ContentEntriesModule.js +20 -14
- package/admin/views/contentEntries/ContentEntriesModule.js.map +1 -1
- package/admin/views/contentModels/ContentModelsDataList.js +103 -88
- package/admin/views/contentModels/ContentModelsDataList.js.map +1 -1
- package/domain/permissionsSchema.d.ts +31 -0
- package/domain/permissionsSchema.js +34 -0
- package/domain/permissionsSchema.js.map +1 -0
- package/exports/admin/cms.d.ts +3 -0
- package/exports/admin/cms.js +4 -0
- package/exports/admin/cms.js.map +1 -1
- package/features/ListCache.d.ts +29 -0
- package/features/ListCache.js +43 -0
- package/features/ListCache.js.map +1 -0
- package/features/contentEntry/events/EntryAfterCreateEvent.d.ts +10 -0
- package/features/contentEntry/events/EntryAfterCreateEvent.js +10 -0
- package/features/contentEntry/events/EntryAfterCreateEvent.js.map +1 -0
- package/features/contentEntry/events/EntryAfterDeleteEvent.d.ts +11 -0
- package/features/contentEntry/events/EntryAfterDeleteEvent.js +10 -0
- package/features/contentEntry/events/EntryAfterDeleteEvent.js.map +1 -0
- package/features/contentEntry/events/EntryAfterUpdateEvent.d.ts +10 -0
- package/features/contentEntry/events/EntryAfterUpdateEvent.js +10 -0
- package/features/contentEntry/events/EntryAfterUpdateEvent.js.map +1 -0
- package/features/contentEntry/events/abstractions.d.ts +19 -0
- package/features/contentEntry/events/abstractions.js +6 -0
- package/features/contentEntry/events/abstractions.js.map +1 -0
- package/features/contentEntry/events/index.d.ts +7 -0
- package/features/contentEntry/events/index.js +6 -0
- package/features/contentEntry/events/index.js.map +1 -0
- package/features/graphQLClient/CmsGraphQLClient.d.ts +13 -0
- package/features/graphQLClient/CmsGraphQLClient.js +21 -0
- package/features/graphQLClient/CmsGraphQLClient.js.map +1 -0
- package/features/graphQLClient/abstractions.d.ts +17 -0
- package/features/graphQLClient/abstractions.js +4 -0
- package/features/graphQLClient/abstractions.js.map +1 -0
- package/features/graphQLClient/feature.d.ts +3 -0
- package/features/graphQLClient/feature.js +16 -0
- package/features/graphQLClient/feature.js.map +1 -0
- package/features/graphQLClient/index.d.ts +1 -0
- package/features/graphQLClient/index.js +3 -0
- package/features/graphQLClient/index.js.map +1 -0
- package/features/modelGroup/abstractions.d.ts +6 -0
- package/features/modelGroup/abstractions.js +4 -0
- package/features/modelGroup/abstractions.js.map +1 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupGateway.d.ts +23 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupGateway.js +59 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupGateway.js.map +1 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupRepository.d.ts +13 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupRepository.js +19 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupRepository.js.map +1 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupUseCase.d.ts +10 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupUseCase.js +15 -0
- package/features/modelGroup/createModelGroup/CreateModelGroupUseCase.js.map +1 -0
- package/features/modelGroup/createModelGroup/abstractions.d.ts +29 -0
- package/features/modelGroup/createModelGroup/abstractions.js +15 -0
- package/features/modelGroup/createModelGroup/abstractions.js.map +1 -0
- package/features/modelGroup/createModelGroup/feature.d.ts +3 -0
- package/features/modelGroup/createModelGroup/feature.js +20 -0
- package/features/modelGroup/createModelGroup/feature.js.map +1 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupGateway.d.ts +21 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupGateway.js +41 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupGateway.js.map +1 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupRepository.d.ts +12 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupRepository.js +18 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupRepository.js.map +1 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupUseCase.d.ts +10 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupUseCase.js +15 -0
- package/features/modelGroup/deleteModelGroup/DeleteModelGroupUseCase.js.map +1 -0
- package/features/modelGroup/deleteModelGroup/abstractions.d.ts +21 -0
- package/features/modelGroup/deleteModelGroup/abstractions.js +15 -0
- package/features/modelGroup/deleteModelGroup/abstractions.js.map +1 -0
- package/features/modelGroup/deleteModelGroup/feature.d.ts +3 -0
- package/features/modelGroup/deleteModelGroup/feature.js +20 -0
- package/features/modelGroup/deleteModelGroup/feature.js.map +1 -0
- package/features/modelGroup/feature.d.ts +1 -0
- package/features/modelGroup/feature.js +21 -0
- package/features/modelGroup/feature.js.map +1 -0
- package/features/modelGroup/getModelGroup/GetModelGroupGateway.d.ts +22 -0
- package/features/modelGroup/getModelGroup/GetModelGroupGateway.js +55 -0
- package/features/modelGroup/getModelGroup/GetModelGroupGateway.js.map +1 -0
- package/features/modelGroup/getModelGroup/GetModelGroupRepository.d.ts +12 -0
- package/features/modelGroup/getModelGroup/GetModelGroupRepository.js +19 -0
- package/features/modelGroup/getModelGroup/GetModelGroupRepository.js.map +1 -0
- package/features/modelGroup/getModelGroup/GetModelGroupUseCase.d.ts +10 -0
- package/features/modelGroup/getModelGroup/GetModelGroupUseCase.js +15 -0
- package/features/modelGroup/getModelGroup/GetModelGroupUseCase.js.map +1 -0
- package/features/modelGroup/getModelGroup/abstractions.d.ts +22 -0
- package/features/modelGroup/getModelGroup/abstractions.js +15 -0
- package/features/modelGroup/getModelGroup/abstractions.js.map +1 -0
- package/features/modelGroup/getModelGroup/feature.d.ts +3 -0
- package/features/modelGroup/getModelGroup/feature.js +20 -0
- package/features/modelGroup/getModelGroup/feature.js.map +1 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsGateway.d.ts +19 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsGateway.js +56 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsGateway.js.map +1 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsRepository.d.ts +12 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsRepository.js +23 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsRepository.js.map +1 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsUseCase.d.ts +10 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsUseCase.js +15 -0
- package/features/modelGroup/listModelGroups/ListModelGroupsUseCase.js.map +1 -0
- package/features/modelGroup/listModelGroups/abstractions.d.ts +39 -0
- package/features/modelGroup/listModelGroups/abstractions.js +15 -0
- package/features/modelGroup/listModelGroups/abstractions.js.map +1 -0
- package/features/modelGroup/listModelGroups/feature.d.ts +3 -0
- package/features/modelGroup/listModelGroups/feature.js +20 -0
- package/features/modelGroup/listModelGroups/feature.js.map +1 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupGateway.d.ts +24 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupGateway.js +56 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupGateway.js.map +1 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupRepository.d.ts +13 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupRepository.js +31 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupRepository.js.map +1 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupUseCase.d.ts +10 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupUseCase.js +15 -0
- package/features/modelGroup/updateModelGroup/UpdateModelGroupUseCase.js.map +1 -0
- package/features/modelGroup/updateModelGroup/abstractions.d.ts +30 -0
- package/features/modelGroup/updateModelGroup/abstractions.js +15 -0
- package/features/modelGroup/updateModelGroup/abstractions.js.map +1 -0
- package/features/modelGroup/updateModelGroup/feature.d.ts +3 -0
- package/features/modelGroup/updateModelGroup/feature.js +20 -0
- package/features/modelGroup/updateModelGroup/feature.js.map +1 -0
- package/features/permissions/abstractions.d.ts +17 -0
- package/features/permissions/abstractions.js +5 -0
- package/features/permissions/abstractions.js.map +1 -0
- package/features/permissions/feature.d.ts +14 -0
- package/features/permissions/feature.js +6 -0
- package/features/permissions/feature.js.map +1 -0
- package/package.json +29 -30
- package/presentation/modelGroup/hooks/index.d.ts +5 -0
- package/presentation/modelGroup/hooks/index.js +7 -0
- package/presentation/modelGroup/hooks/index.js.map +1 -0
- package/presentation/modelGroup/hooks/useCreateModelGroup.d.ts +4 -0
- package/presentation/modelGroup/hooks/useCreateModelGroup.js +12 -0
- package/presentation/modelGroup/hooks/useCreateModelGroup.js.map +1 -0
- package/presentation/modelGroup/hooks/useDeleteModelGroup.d.ts +3 -0
- package/presentation/modelGroup/hooks/useDeleteModelGroup.js +12 -0
- package/presentation/modelGroup/hooks/useDeleteModelGroup.js.map +1 -0
- package/presentation/modelGroup/hooks/useGetModelGroup.d.ts +3 -0
- package/presentation/modelGroup/hooks/useGetModelGroup.js +12 -0
- package/presentation/modelGroup/hooks/useGetModelGroup.js.map +1 -0
- package/presentation/modelGroup/hooks/useListModelGroups.d.ts +3 -0
- package/presentation/modelGroup/hooks/useListModelGroups.js +16 -0
- package/presentation/modelGroup/hooks/useListModelGroups.js.map +1 -0
- package/presentation/modelGroup/hooks/useUpdateModelGroup.d.ts +4 -0
- package/presentation/modelGroup/hooks/useUpdateModelGroup.js +12 -0
- package/presentation/modelGroup/hooks/useUpdateModelGroup.js.map +1 -0
- package/admin/plugins/apiInformation/placeholder.manage.graphql +0 -18
- package/admin/plugins/apiInformation/placeholder.preview.graphql +0 -15
- package/admin/plugins/apiInformation/placeholder.read.graphql +0 -16
|
@@ -1,26 +1,108 @@
|
|
|
1
|
-
import { useCallback, useMemo } from "react";
|
|
1
|
+
import { useCallback, useContext, useMemo } from "react";
|
|
2
2
|
import { useIdentity } from "@webiny/app-admin";
|
|
3
3
|
import { makeDecoratable } from "@webiny/react-composition";
|
|
4
|
+
import { ModelContext } from "@webiny/app-headless-cms-common/ModelProvider/ModelContext.js";
|
|
5
|
+
function isModelAllowed(modelPermissions, modelId) {
|
|
6
|
+
// No model permissions in this group means all models are allowed.
|
|
7
|
+
if (!modelPermissions.length) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
for (const permission of modelPermissions) {
|
|
11
|
+
// If no models array, this permission grants access to all models.
|
|
12
|
+
if (!Array.isArray(permission.models)) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (permission.models.includes(modelId)) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
function isGroupAllowed(groupPermissions, groupId) {
|
|
22
|
+
// No group permissions in this group means all groups are allowed.
|
|
23
|
+
if (!groupPermissions.length) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
for (const permission of groupPermissions) {
|
|
27
|
+
// If no groups array, this permission grants access to all groups.
|
|
28
|
+
if (!Array.isArray(permission.groups)) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
if (permission.groups.includes(groupId)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if any _src group grants access for the given model.
|
|
39
|
+
*/
|
|
40
|
+
function hasAccessForModel({
|
|
41
|
+
permissions,
|
|
42
|
+
modelPermissions,
|
|
43
|
+
modelId,
|
|
44
|
+
check
|
|
45
|
+
}) {
|
|
46
|
+
const srcKeys = new Set();
|
|
47
|
+
for (const p of [...permissions, ...modelPermissions]) {
|
|
48
|
+
srcKeys.add(p._src);
|
|
49
|
+
}
|
|
50
|
+
for (const src of srcKeys) {
|
|
51
|
+
const srcPerms = permissions.filter(p => p._src === src);
|
|
52
|
+
const srcModelPerms = modelPermissions.filter(p => p._src === src);
|
|
53
|
+
if (!srcPerms.length) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (!srcPerms.some(check)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const modelAllowed = isModelAllowed(srcModelPerms, modelId);
|
|
60
|
+
if (!modelAllowed) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
4
67
|
export const usePermission = makeDecoratable(() => {
|
|
5
68
|
const {
|
|
6
69
|
identity
|
|
7
70
|
} = useIdentity();
|
|
71
|
+
const model = useContext(ModelContext);
|
|
72
|
+
const modelId = model?.modelId;
|
|
8
73
|
const hasFullAccess = useMemo(() => !!identity.getPermission("cms.*"), [identity]);
|
|
9
|
-
const
|
|
74
|
+
const modelPermissions = useMemo(() => identity.getPermissions("cms.contentModel") ?? [], [identity]);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check permissions with _src-based model scoping when a model context is available.
|
|
78
|
+
* When no model context exists, falls back to checking permissions without model correlation.
|
|
79
|
+
*/
|
|
80
|
+
const checkPermission = useCallback((permissionName, check) => {
|
|
10
81
|
if (hasFullAccess) {
|
|
11
82
|
return true;
|
|
12
83
|
}
|
|
13
|
-
const permissions = identity.getPermissions(permissionName)
|
|
84
|
+
const permissions = identity.getPermissions(permissionName);
|
|
14
85
|
if (!permissions.length) {
|
|
15
86
|
return false;
|
|
16
87
|
}
|
|
17
|
-
|
|
88
|
+
if (modelId) {
|
|
89
|
+
return hasAccessForModel({
|
|
90
|
+
permissions,
|
|
91
|
+
modelPermissions,
|
|
92
|
+
modelId,
|
|
93
|
+
check
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return permissions.some(check);
|
|
97
|
+
}, [identity, hasFullAccess, modelId, modelPermissions]);
|
|
98
|
+
const canRead = useCallback(permissionName => {
|
|
99
|
+
return checkPermission(permissionName, permission => {
|
|
18
100
|
if (typeof permission.rwd !== "string") {
|
|
19
101
|
return true;
|
|
20
102
|
}
|
|
21
103
|
return permission.rwd.includes("r");
|
|
22
104
|
});
|
|
23
|
-
}, [
|
|
105
|
+
}, [checkPermission]);
|
|
24
106
|
const canReadEntries = useCallback(({
|
|
25
107
|
contentModelGroup,
|
|
26
108
|
contentModel
|
|
@@ -28,79 +110,48 @@ export const usePermission = makeDecoratable(() => {
|
|
|
28
110
|
if (hasFullAccess) {
|
|
29
111
|
return true;
|
|
30
112
|
}
|
|
31
|
-
const
|
|
32
|
-
if (!
|
|
113
|
+
const entryPermissions = identity.getPermissions("cms.contentEntry") ?? [];
|
|
114
|
+
if (!entryPermissions.length) {
|
|
33
115
|
return false;
|
|
34
116
|
}
|
|
117
|
+
const groupPermissions = identity.getPermissions("cms.contentModelGroup") ?? [];
|
|
35
118
|
|
|
36
|
-
//
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
for (
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (allModelsAllowed) {
|
|
48
|
-
allowedModels = "all";
|
|
49
|
-
break;
|
|
119
|
+
// Group all permissions by _src. Permissions without _src go into an "ungrouped" bucket.
|
|
120
|
+
const srcKeys = new Set();
|
|
121
|
+
for (const p of [...entryPermissions, ...modelPermissions, ...groupPermissions]) {
|
|
122
|
+
srcKeys.add(p._src);
|
|
123
|
+
}
|
|
124
|
+
for (const src of srcKeys) {
|
|
125
|
+
const srcEntryPerms = entryPermissions.filter(p => p._src === src);
|
|
126
|
+
const srcModelPerms = modelPermissions.filter(p => p._src === src);
|
|
127
|
+
const srcGroupPerms = groupPermissions.filter(p => p._src === src);
|
|
128
|
+
if (!srcEntryPerms.length) {
|
|
129
|
+
continue;
|
|
50
130
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// "all" means user has access to all models.
|
|
61
|
-
let allowedModelGroups = [];
|
|
62
|
-
for (let i = 0; i < contentModelGroupPermissions.length; i++) {
|
|
63
|
-
const permission = contentModelGroupPermissions[i];
|
|
64
|
-
const permissionAllowedModelGroups = permission?.models;
|
|
65
|
-
// The moment we encounter a permission that gives access to all models,
|
|
66
|
-
// we can stop checking other permissions.
|
|
67
|
-
const allModelGroupsAllowed = !Array.isArray(permissionAllowedModelGroups);
|
|
68
|
-
if (allModelGroupsAllowed) {
|
|
69
|
-
allowedModelGroups = "all";
|
|
70
|
-
break;
|
|
131
|
+
const hasReadAccess = srcEntryPerms.some(p => {
|
|
132
|
+
if (typeof p.rwd !== "string") {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
return p.rwd.includes("r");
|
|
136
|
+
});
|
|
137
|
+
if (!hasReadAccess) {
|
|
138
|
+
continue;
|
|
71
139
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return allowedModelGroups.includes(contentModelGroup.id);
|
|
76
|
-
}
|
|
77
|
-
for (let i = 0; i < permissions.length; i++) {
|
|
78
|
-
const permission = permissions[i];
|
|
79
|
-
|
|
80
|
-
// If no RWD restrictions are set, we can return true.
|
|
81
|
-
if (typeof permission.rwd !== "string") {
|
|
82
|
-
return true;
|
|
140
|
+
const modelAllowed = isModelAllowed(srcModelPerms, contentModel.modelId);
|
|
141
|
+
if (!modelAllowed) {
|
|
142
|
+
continue;
|
|
83
143
|
}
|
|
84
|
-
const
|
|
85
|
-
if (
|
|
86
|
-
|
|
144
|
+
const groupAllowed = isGroupAllowed(srcGroupPerms, contentModelGroup.id);
|
|
145
|
+
if (!groupAllowed) {
|
|
146
|
+
continue;
|
|
87
147
|
}
|
|
148
|
+
return true;
|
|
88
149
|
}
|
|
89
150
|
return false;
|
|
90
|
-
}, [identity, hasFullAccess]);
|
|
151
|
+
}, [identity, hasFullAccess, modelPermissions]);
|
|
91
152
|
const canEdit = useCallback((item, permissionName) => {
|
|
92
|
-
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
const permissions = identity.getPermissions(permissionName);
|
|
96
|
-
if (!permissions.length || !identity) {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
return permissions.some(permission => {
|
|
153
|
+
return checkPermission(permissionName, permission => {
|
|
100
154
|
if (permission.own) {
|
|
101
|
-
/**
|
|
102
|
-
* There will be no "createdBy" field for a new entry therefore we enable the access.
|
|
103
|
-
*/
|
|
104
155
|
if (!item.createdBy) {
|
|
105
156
|
return true;
|
|
106
157
|
}
|
|
@@ -115,41 +166,18 @@ export const usePermission = makeDecoratable(() => {
|
|
|
115
166
|
}
|
|
116
167
|
return false;
|
|
117
168
|
});
|
|
118
|
-
}, [identity]);
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* @description This checks whether the user has the "write" access for given permission;
|
|
122
|
-
* without talking the "own" property in account.
|
|
123
|
-
* @param {string} permissionName
|
|
124
|
-
* */
|
|
169
|
+
}, [identity, checkPermission]);
|
|
125
170
|
const canCreate = useCallback(permissionName => {
|
|
126
|
-
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
const permissions = identity.getPermissions(permissionName);
|
|
130
|
-
if (!permissions.length) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
return permissions.some(permission => {
|
|
171
|
+
return checkPermission(permissionName, permission => {
|
|
134
172
|
if (typeof permission.rwd !== "string") {
|
|
135
173
|
return true;
|
|
136
174
|
}
|
|
137
175
|
return permission.rwd.includes("w");
|
|
138
176
|
});
|
|
139
|
-
}, [
|
|
177
|
+
}, [checkPermission]);
|
|
140
178
|
const canDelete = useCallback((item, permissionName) => {
|
|
141
|
-
|
|
142
|
-
return true;
|
|
143
|
-
}
|
|
144
|
-
const permissions = identity.getPermissions(permissionName);
|
|
145
|
-
if (!permissions.length) {
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
return permissions.some(permission => {
|
|
179
|
+
return checkPermission(permissionName, permission => {
|
|
149
180
|
if (permission.own) {
|
|
150
|
-
// Using optional chaining here because there might be cases where the item
|
|
151
|
-
// or its `createdBy` property is not defined. In that case, we want to
|
|
152
|
-
// return `false` and not throw an error.
|
|
153
181
|
return item?.createdBy?.id === identity.id;
|
|
154
182
|
}
|
|
155
183
|
if (typeof permission.rwd === "string") {
|
|
@@ -157,43 +185,22 @@ export const usePermission = makeDecoratable(() => {
|
|
|
157
185
|
}
|
|
158
186
|
return false;
|
|
159
187
|
});
|
|
160
|
-
}, [identity]);
|
|
188
|
+
}, [identity, checkPermission]);
|
|
161
189
|
const canDeleteEntries = useCallback(permissionName => {
|
|
162
|
-
|
|
163
|
-
return
|
|
164
|
-
}
|
|
165
|
-
const permissions = identity.getPermissions(permissionName);
|
|
166
|
-
if (!permissions.length) {
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
return permissions.some(permission => {
|
|
170
|
-
return permission.rwd?.includes("d");
|
|
190
|
+
return checkPermission(permissionName, permission => {
|
|
191
|
+
return !!permission.rwd?.includes("d");
|
|
171
192
|
});
|
|
172
|
-
}, [
|
|
193
|
+
}, [checkPermission]);
|
|
173
194
|
const canPublish = useCallback(permissionName => {
|
|
174
|
-
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
const permissions = identity.getPermissions(permissionName);
|
|
178
|
-
if (!permissions.length) {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
return permissions.some(permission => {
|
|
182
|
-
return permission.pw?.includes("p");
|
|
195
|
+
return checkPermission(permissionName, permission => {
|
|
196
|
+
return !!permission.pw?.includes("p");
|
|
183
197
|
});
|
|
184
|
-
}, [
|
|
198
|
+
}, [checkPermission]);
|
|
185
199
|
const canUnpublish = useCallback(permissionName => {
|
|
186
|
-
|
|
187
|
-
return
|
|
188
|
-
}
|
|
189
|
-
const permissions = identity.getPermissions(permissionName);
|
|
190
|
-
if (!permissions.length) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
return permissions.some(permission => {
|
|
194
|
-
return permission.pw?.includes("u");
|
|
200
|
+
return checkPermission(permissionName, permission => {
|
|
201
|
+
return !!permission.pw?.includes("u");
|
|
195
202
|
});
|
|
196
|
-
}, [
|
|
203
|
+
}, [checkPermission]);
|
|
197
204
|
const canReadContentModels = canRead("cms.contentModel");
|
|
198
205
|
const canReadContentModelGroups = canRead("cms.contentModelGroup");
|
|
199
206
|
const canCreateContentModels = canCreate("cms.contentModel");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useMemo","useIdentity","makeDecoratable","usePermission","identity","hasFullAccess","getPermission","canRead","permissionName","permissions","getPermissions","length","some","permission","rwd","includes","canReadEntries","contentModelGroup","contentModel","contentModelPermissions","allowedModels","i","permissionAllowedModels","models","allModelsAllowed","Array","isArray","modelId","contentModelGroupPermissions","allowedModelGroups","permissionAllowedModelGroups","allModelGroupsAllowed","id","rwdGivesReadAccess","canEdit","item","own","createdBy","canCreate","canDelete","canDeleteEntries","canPublish","pw","canUnpublish","canReadContentModels","canReadContentModelGroups","canCreateContentModels","canCreateContentModelGroups","canAccessManageEndpoint","undefined"],"sources":["usePermission.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { useIdentity } from \"@webiny/app-admin\";\nimport { makeDecoratable } from \"@webiny/react-composition\";\nimport type { CmsGroup, CmsIdentity, CmsModel, CmsSecurityPermission } from \"~/types.js\";\n\nexport interface CreatableItem {\n createdBy?: Pick<CmsIdentity, \"id\">;\n}\n\ninterface CanReadEntriesCallableParams {\n contentModelGroup: Pick<CmsGroup, \"id\">;\n contentModel: Pick<CmsModel, \"modelId\">;\n}\n\nexport const usePermission = makeDecoratable(() => {\n const { identity } = useIdentity();\n\n const hasFullAccess = useMemo(() => !!identity.getPermission(\"cms.*\"), [identity]);\n\n const canRead = useCallback(\n (permissionName: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const permissions =\n identity.getPermissions<CmsSecurityPermission>(permissionName) ?? [];\n\n if (!permissions.length) {\n return false;\n }\n\n return permissions.some(permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n\n return permission.rwd.includes(\"r\");\n });\n },\n [identity, hasFullAccess]\n );\n\n const canReadEntries = useCallback(\n ({ contentModelGroup, contentModel }: CanReadEntriesCallableParams): boolean => {\n if (hasFullAccess) {\n return true;\n }\n\n const permissions =\n identity.getPermissions<CmsSecurityPermission>(\"cms.contentEntry\") ?? [];\n if (!permissions.length) {\n return false;\n }\n\n // Check \"contentModel\" list.\n const contentModelPermissions = identity.getPermissions(\"cms.contentModel\");\n\n // \"all\" means user has access to all models.\n let allowedModels: \"all\" | string[] = [];\n\n for (let i = 0; i < contentModelPermissions.length; i++) {\n const permission = contentModelPermissions[i];\n const permissionAllowedModels = permission?.models;\n // The moment we encounter a permission that gives access to all models,\n // we can stop checking other permissions.\n const allModelsAllowed = !Array.isArray(permissionAllowedModels);\n if (allModelsAllowed) {\n allowedModels = \"all\";\n break;\n }\n\n allowedModels = [...allowedModels, ...permissionAllowedModels];\n }\n\n if (Array.isArray(allowedModels)) {\n return allowedModels.includes(contentModel.modelId);\n }\n\n // Check \"contentModelGroup\" list.\n const contentModelGroupPermissions = identity.getPermissions(\"cms.contentModelGroup\");\n\n // \"all\" means user has access to all models.\n let allowedModelGroups: \"all\" | string[] = [];\n\n for (let i = 0; i < contentModelGroupPermissions.length; i++) {\n const permission = contentModelGroupPermissions[i];\n const permissionAllowedModelGroups = permission?.models;\n // The moment we encounter a permission that gives access to all models,\n // we can stop checking other permissions.\n const allModelGroupsAllowed = !Array.isArray(permissionAllowedModelGroups);\n if (allModelGroupsAllowed) {\n allowedModelGroups = \"all\";\n break;\n }\n\n allowedModelGroups = [...allowedModelGroups, ...permissionAllowedModelGroups];\n }\n\n if (Array.isArray(allowedModelGroups)) {\n return allowedModelGroups.includes(contentModelGroup.id);\n }\n\n for (let i = 0; i < permissions.length; i++) {\n const permission = permissions[i];\n\n // If no RWD restrictions are set, we can return true.\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n\n const rwdGivesReadAccess = permission.rwd.includes(\"r\");\n if (rwdGivesReadAccess) {\n return true;\n }\n }\n\n return false;\n },\n [identity, hasFullAccess]\n );\n\n const canEdit = useCallback(\n (item: CreatableItem, permissionName: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n\n const permissions = identity.getPermissions<CmsSecurityPermission>(permissionName);\n\n if (!permissions.length || !identity) {\n return false;\n }\n\n return permissions.some(permission => {\n if (permission.own) {\n /**\n * There will be no \"createdBy\" field for a new entry therefore we enable the access.\n */\n if (!item.createdBy) {\n return true;\n }\n\n if (item?.createdBy?.id === identity.id) {\n return true;\n }\n }\n\n if (typeof permission.rwd === \"string\") {\n if (permission.rwd.includes(\"w\")) {\n return true;\n }\n }\n\n return false;\n });\n },\n [identity]\n );\n\n /**\n * @description This checks whether the user has the \"write\" access for given permission;\n * without talking the \"own\" property in account.\n * @param {string} permissionName\n * */\n const canCreate = useCallback(\n (permissionName: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n\n const permissions = identity.getPermissions<CmsSecurityPermission>(permissionName);\n if (!permissions.length) {\n return false;\n }\n\n return permissions.some(permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n\n return permission.rwd.includes(\"w\");\n });\n },\n [identity]\n );\n\n const canDelete = useCallback(\n (item: CreatableItem, permissionName: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n\n const permissions = identity.getPermissions<CmsSecurityPermission>(permissionName);\n\n if (!permissions.length) {\n return false;\n }\n\n return permissions.some(permission => {\n if (permission.own) {\n // Using optional chaining here because there might be cases where the item\n // or its `createdBy` property is not defined. In that case, we want to\n // return `false` and not throw an error.\n return item?.createdBy?.id === identity.id;\n }\n\n if (typeof permission.rwd === \"string\") {\n return permission.rwd.includes(\"d\");\n }\n\n return false;\n });\n },\n [identity]\n );\n\n const canDeleteEntries = useCallback(\n (permissionName: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const permissions = identity.getPermissions<CmsSecurityPermission>(permissionName);\n\n if (!permissions.length) {\n return false;\n }\n\n return permissions.some(permission => {\n return permission.rwd?.includes(\"d\");\n });\n },\n [identity, hasFullAccess]\n );\n\n const canPublish = useCallback(\n (permissionName: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const permissions = identity.getPermissions<CmsSecurityPermission>(permissionName);\n\n if (!permissions.length) {\n return false;\n }\n\n return permissions.some(permission => {\n return permission.pw?.includes(\"p\");\n });\n },\n [identity, hasFullAccess]\n );\n\n const canUnpublish = useCallback(\n (permissionName: string): boolean => {\n if (hasFullAccess) {\n return true;\n }\n const permissions = identity.getPermissions<CmsSecurityPermission>(permissionName);\n\n if (!permissions.length) {\n return false;\n }\n\n return permissions.some(permission => {\n return permission.pw?.includes(\"u\");\n });\n },\n [identity, hasFullAccess]\n );\n\n const canReadContentModels = canRead(\"cms.contentModel\");\n const canReadContentModelGroups = canRead(\"cms.contentModelGroup\");\n const canCreateContentModels = canCreate(\"cms.contentModel\");\n const canCreateContentModelGroups = canCreate(\"cms.contentModelGroup\");\n const canAccessManageEndpoint = useMemo(() => {\n return identity.getPermission(\"cms.endpoint.manage\") !== undefined;\n }, [identity]);\n\n return {\n canReadEntries,\n canEdit,\n canCreate,\n canDelete,\n canDeleteEntries,\n canPublish,\n canUnpublish,\n canReadContentModels,\n canReadContentModelGroups,\n canCreateContentModels,\n canCreateContentModelGroups,\n canAccessManageEndpoint\n };\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["useCallback","useContext","useMemo","useIdentity","makeDecoratable","ModelContext","isModelAllowed","modelPermissions","modelId","length","permission","Array","isArray","models","includes","isGroupAllowed","groupPermissions","groupId","groups","hasAccessForModel","permissions","check","srcKeys","Set","p","add","_src","src","srcPerms","filter","srcModelPerms","some","modelAllowed","usePermission","identity","model","hasFullAccess","getPermission","getPermissions","checkPermission","permissionName","canRead","rwd","canReadEntries","contentModelGroup","contentModel","entryPermissions","srcEntryPerms","srcGroupPerms","hasReadAccess","groupAllowed","id","canEdit","item","own","createdBy","canCreate","canDelete","canDeleteEntries","canPublish","pw","canUnpublish","canReadContentModels","canReadContentModelGroups","canCreateContentModels","canCreateContentModelGroups","canAccessManageEndpoint","undefined"],"sources":["usePermission.ts"],"sourcesContent":["import { useCallback, useContext, useMemo } from \"react\";\nimport { useIdentity } from \"@webiny/app-admin\";\nimport { makeDecoratable } from \"@webiny/react-composition\";\nimport { ModelContext } from \"@webiny/app-headless-cms-common/ModelProvider/ModelContext.js\";\nimport type { CmsGroup, CmsIdentity, CmsModel, CmsSecurityPermission } from \"~/types.js\";\n\nexport interface CreatableItem {\n createdBy?: Pick<CmsIdentity, \"id\">;\n}\n\ninterface CanReadEntriesCallableParams {\n contentModelGroup: Pick<CmsGroup, \"id\">;\n contentModel: Pick<CmsModel, \"modelId\">;\n}\n\nfunction isModelAllowed(modelPermissions: CmsSecurityPermission[], modelId: string): boolean {\n // No model permissions in this group means all models are allowed.\n if (!modelPermissions.length) {\n return true;\n }\n\n for (const permission of modelPermissions) {\n // If no models array, this permission grants access to all models.\n if (!Array.isArray(permission.models)) {\n return true;\n }\n\n if (permission.models.includes(modelId)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction isGroupAllowed(groupPermissions: CmsSecurityPermission[], groupId: string): boolean {\n // No group permissions in this group means all groups are allowed.\n if (!groupPermissions.length) {\n return true;\n }\n\n for (const permission of groupPermissions) {\n // If no groups array, this permission grants access to all groups.\n if (!Array.isArray(permission.groups)) {\n return true;\n }\n\n if (permission.groups.includes(groupId)) {\n return true;\n }\n }\n\n return false;\n}\n\ninterface HasAccessParams {\n permissions: CmsSecurityPermission[];\n modelPermissions: CmsSecurityPermission[];\n modelId: string;\n check: (permission: CmsSecurityPermission) => boolean;\n}\n\n/**\n * Check if any _src group grants access for the given model.\n */\nfunction hasAccessForModel({ permissions, modelPermissions, modelId, check }: HasAccessParams) {\n const srcKeys = new Set<string | undefined>();\n for (const p of [...permissions, ...modelPermissions]) {\n srcKeys.add(p._src);\n }\n\n for (const src of srcKeys) {\n const srcPerms = permissions.filter(p => p._src === src);\n const srcModelPerms = modelPermissions.filter(p => p._src === src);\n\n if (!srcPerms.length) {\n continue;\n }\n\n if (!srcPerms.some(check)) {\n continue;\n }\n\n const modelAllowed = isModelAllowed(srcModelPerms, modelId);\n if (!modelAllowed) {\n continue;\n }\n\n return true;\n }\n\n return false;\n}\n\nexport const usePermission = makeDecoratable(() => {\n const { identity } = useIdentity();\n const model = useContext(ModelContext);\n const modelId = model?.modelId;\n\n const hasFullAccess = useMemo(() => !!identity.getPermission(\"cms.*\"), [identity]);\n\n const modelPermissions = useMemo(\n () => identity.getPermissions<CmsSecurityPermission>(\"cms.contentModel\") ?? [],\n [identity]\n );\n\n /**\n * Check permissions with _src-based model scoping when a model context is available.\n * When no model context exists, falls back to checking permissions without model correlation.\n */\n const checkPermission = useCallback(\n (permissionName: string, check: (permission: CmsSecurityPermission) => boolean) => {\n if (hasFullAccess) {\n return true;\n }\n\n const permissions = identity.getPermissions<CmsSecurityPermission>(permissionName);\n if (!permissions.length) {\n return false;\n }\n\n if (modelId) {\n return hasAccessForModel({\n permissions,\n modelPermissions,\n modelId,\n check\n });\n }\n\n return permissions.some(check);\n },\n [identity, hasFullAccess, modelId, modelPermissions]\n );\n\n const canRead = useCallback(\n (permissionName: string): boolean => {\n return checkPermission(permissionName, permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"r\");\n });\n },\n [checkPermission]\n );\n\n const canReadEntries = useCallback(\n ({ contentModelGroup, contentModel }: CanReadEntriesCallableParams): boolean => {\n if (hasFullAccess) {\n return true;\n }\n\n const entryPermissions =\n identity.getPermissions<CmsSecurityPermission>(\"cms.contentEntry\") ?? [];\n if (!entryPermissions.length) {\n return false;\n }\n\n const groupPermissions =\n identity.getPermissions<CmsSecurityPermission>(\"cms.contentModelGroup\") ?? [];\n\n // Group all permissions by _src. Permissions without _src go into an \"ungrouped\" bucket.\n const srcKeys = new Set<string | undefined>();\n for (const p of [...entryPermissions, ...modelPermissions, ...groupPermissions]) {\n srcKeys.add(p._src);\n }\n\n for (const src of srcKeys) {\n const srcEntryPerms = entryPermissions.filter(p => p._src === src);\n const srcModelPerms = modelPermissions.filter(p => p._src === src);\n const srcGroupPerms = groupPermissions.filter(p => p._src === src);\n\n if (!srcEntryPerms.length) {\n continue;\n }\n\n const hasReadAccess = srcEntryPerms.some(p => {\n if (typeof p.rwd !== \"string\") {\n return true;\n }\n return p.rwd.includes(\"r\");\n });\n\n if (!hasReadAccess) {\n continue;\n }\n\n const modelAllowed = isModelAllowed(srcModelPerms, contentModel.modelId);\n if (!modelAllowed) {\n continue;\n }\n\n const groupAllowed = isGroupAllowed(srcGroupPerms, contentModelGroup.id);\n if (!groupAllowed) {\n continue;\n }\n\n return true;\n }\n\n return false;\n },\n [identity, hasFullAccess, modelPermissions]\n );\n\n const canEdit = useCallback(\n (item: CreatableItem, permissionName: string): boolean => {\n return checkPermission(permissionName, permission => {\n if (permission.own) {\n if (!item.createdBy) {\n return true;\n }\n\n if (item?.createdBy?.id === identity.id) {\n return true;\n }\n }\n\n if (typeof permission.rwd === \"string\") {\n if (permission.rwd.includes(\"w\")) {\n return true;\n }\n }\n\n return false;\n });\n },\n [identity, checkPermission]\n );\n\n const canCreate = useCallback(\n (permissionName: string): boolean => {\n return checkPermission(permissionName, permission => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n return permission.rwd.includes(\"w\");\n });\n },\n [checkPermission]\n );\n\n const canDelete = useCallback(\n (item: CreatableItem, permissionName: string): boolean => {\n return checkPermission(permissionName, permission => {\n if (permission.own) {\n return item?.createdBy?.id === identity.id;\n }\n\n if (typeof permission.rwd === \"string\") {\n return permission.rwd.includes(\"d\");\n }\n\n return false;\n });\n },\n [identity, checkPermission]\n );\n\n const canDeleteEntries = useCallback(\n (permissionName: string): boolean => {\n return checkPermission(permissionName, permission => {\n return !!permission.rwd?.includes(\"d\");\n });\n },\n [checkPermission]\n );\n\n const canPublish = useCallback(\n (permissionName: string): boolean => {\n return checkPermission(permissionName, permission => {\n return !!permission.pw?.includes(\"p\");\n });\n },\n [checkPermission]\n );\n\n const canUnpublish = useCallback(\n (permissionName: string): boolean => {\n return checkPermission(permissionName, permission => {\n return !!permission.pw?.includes(\"u\");\n });\n },\n [checkPermission]\n );\n\n const canReadContentModels = canRead(\"cms.contentModel\");\n const canReadContentModelGroups = canRead(\"cms.contentModelGroup\");\n const canCreateContentModels = canCreate(\"cms.contentModel\");\n const canCreateContentModelGroups = canCreate(\"cms.contentModelGroup\");\n const canAccessManageEndpoint = useMemo(() => {\n return identity.getPermission(\"cms.endpoint.manage\") !== undefined;\n }, [identity]);\n\n return {\n canReadEntries,\n canEdit,\n canCreate,\n canDelete,\n canDeleteEntries,\n canPublish,\n canUnpublish,\n canReadContentModels,\n canReadContentModelGroups,\n canCreateContentModels,\n canCreateContentModelGroups,\n canAccessManageEndpoint\n };\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { manageQuery } from "./placeholder.manage.graphql.js";
|
|
2
|
+
import { readQuery } from "./placeholder.read.graphql.js";
|
|
3
|
+
import { previewQuery } from "./placeholder.preview.graphql.js";
|
|
4
4
|
import { config as appConfig } from "@webiny/app/config.js";
|
|
5
5
|
const plugins = [{
|
|
6
6
|
type: "graphql-playground-tab",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["manageQuery","readQuery","previewQuery","config","appConfig","plugins","type","name","tab","identity","apiUrl","getKey","process","env","REACT_APP_API_URL","getPermission","endpoint","headers","query"],"sources":["index.tsx"],"sourcesContent":["import type { GraphQLPlaygroundTabPlugin } from \"@webiny/app-graphql-playground/types.js\";\nimport
|
|
1
|
+
{"version":3,"names":["manageQuery","readQuery","previewQuery","config","appConfig","plugins","type","name","tab","identity","apiUrl","getKey","process","env","REACT_APP_API_URL","getPermission","endpoint","headers","query"],"sources":["index.tsx"],"sourcesContent":["import type { GraphQLPlaygroundTabPlugin } from \"@webiny/app-graphql-playground/types.js\";\nimport { manageQuery } from \"./placeholder.manage.graphql.js\";\nimport { readQuery } from \"./placeholder.read.graphql.js\";\nimport { previewQuery } from \"./placeholder.preview.graphql.js\";\nimport { config as appConfig } from \"@webiny/app/config.js\";\n\nconst plugins: GraphQLPlaygroundTabPlugin[] = [\n {\n type: \"graphql-playground-tab\",\n name: \"graphql-playground-tab-manage\",\n tab({ identity }) {\n const apiUrl = appConfig.getKey(\"API_URL\", process.env.REACT_APP_API_URL);\n if (\n !identity ||\n !identity.getPermission ||\n !identity.getPermission(\"cms.endpoint.manage\")\n ) {\n return null;\n }\n\n return {\n name: \"Headless CMS - Manage API\",\n endpoint: apiUrl + \"/cms/manage\",\n headers: {},\n query: manageQuery\n };\n }\n },\n {\n type: \"graphql-playground-tab\",\n name: \"graphql-playground-tab-read\",\n tab({ identity }) {\n const apiUrl = appConfig.getKey(\"API_URL\", process.env.REACT_APP_API_URL);\n if (\n !identity ||\n !identity.getPermission ||\n !identity.getPermission(\"cms.endpoint.read\")\n ) {\n return null;\n }\n\n return {\n name: \"Headless CMS - Read API\",\n endpoint: apiUrl + \"/cms/read\",\n headers: {},\n query: readQuery\n };\n }\n },\n {\n type: \"graphql-playground-tab\",\n name: \"graphql-playground-tab-preview\",\n tab({ identity }) {\n const apiUrl = appConfig.getKey(\"API_URL\", process.env.REACT_APP_API_URL);\n if (\n !identity ||\n !identity.getPermission ||\n !identity.getPermission(\"cms.endpoint.preview\")\n ) {\n return null;\n }\n\n return {\n name: \"Headless CMS - Preview API\",\n endpoint: apiUrl + \"/cms/preview\",\n headers: {},\n query: previewQuery\n };\n }\n }\n];\n\nexport default plugins;\n"],"mappings":"AACA,SAASA,WAAW;AACpB,SAASC,SAAS;AAClB,SAASC,YAAY;AACrB,SAASC,MAAM,IAAIC,SAAS,QAAQ,uBAAuB;AAE3D,MAAMC,OAAqC,GAAG,CAC1C;EACIC,IAAI,EAAE,wBAAwB;EAC9BC,IAAI,EAAE,+BAA+B;EACrCC,GAAGA,CAAC;IAAEC;EAAS,CAAC,EAAE;IACd,MAAMC,MAAM,GAAGN,SAAS,CAACO,MAAM,CAAC,SAAS,EAAEC,OAAO,CAACC,GAAG,CAACC,iBAAiB,CAAC;IACzE,IACI,CAACL,QAAQ,IACT,CAACA,QAAQ,CAACM,aAAa,IACvB,CAACN,QAAQ,CAACM,aAAa,CAAC,qBAAqB,CAAC,EAChD;MACE,OAAO,IAAI;IACf;IAEA,OAAO;MACHR,IAAI,EAAE,2BAA2B;MACjCS,QAAQ,EAAEN,MAAM,GAAG,aAAa;MAChCO,OAAO,EAAE,CAAC,CAAC;MACXC,KAAK,EAAElB;IACX,CAAC;EACL;AACJ,CAAC,EACD;EACIM,IAAI,EAAE,wBAAwB;EAC9BC,IAAI,EAAE,6BAA6B;EACnCC,GAAGA,CAAC;IAAEC;EAAS,CAAC,EAAE;IACd,MAAMC,MAAM,GAAGN,SAAS,CAACO,MAAM,CAAC,SAAS,EAAEC,OAAO,CAACC,GAAG,CAACC,iBAAiB,CAAC;IACzE,IACI,CAACL,QAAQ,IACT,CAACA,QAAQ,CAACM,aAAa,IACvB,CAACN,QAAQ,CAACM,aAAa,CAAC,mBAAmB,CAAC,EAC9C;MACE,OAAO,IAAI;IACf;IAEA,OAAO;MACHR,IAAI,EAAE,yBAAyB;MAC/BS,QAAQ,EAAEN,MAAM,GAAG,WAAW;MAC9BO,OAAO,EAAE,CAAC,CAAC;MACXC,KAAK,EAAEjB;IACX,CAAC;EACL;AACJ,CAAC,EACD;EACIK,IAAI,EAAE,wBAAwB;EAC9BC,IAAI,EAAE,gCAAgC;EACtCC,GAAGA,CAAC;IAAEC;EAAS,CAAC,EAAE;IACd,MAAMC,MAAM,GAAGN,SAAS,CAACO,MAAM,CAAC,SAAS,EAAEC,OAAO,CAACC,GAAG,CAACC,iBAAiB,CAAC;IACzE,IACI,CAACL,QAAQ,IACT,CAACA,QAAQ,CAACM,aAAa,IACvB,CAACN,QAAQ,CAACM,aAAa,CAAC,sBAAsB,CAAC,EACjD;MACE,OAAO,IAAI;IACf;IAEA,OAAO;MACHR,IAAI,EAAE,4BAA4B;MAClCS,QAAQ,EAAEN,MAAM,GAAG,cAAc;MACjCO,OAAO,EAAE,CAAC,CAAC;MACXC,KAAK,EAAEhB;IACX,CAAC;EACL;AACJ,CAAC,CACJ;AAED,eAAeG,OAAO","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const manageQuery = "\n # Webiny Headless CMS Manage API\n #\n # This API controls all the operations within the Headless CMS module.\n # Use it to manage content, create and modify content models and more.\n # Explore the schema for details.\n #\n # Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.\n #\n # Example query - list content model groups:\n {\n listContentModelGroups {\n data {\n name\n icon\n slug\n }\n }\n }\n";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const manageQuery = /* GraphQL */`
|
|
2
|
+
# Webiny Headless CMS Manage API
|
|
3
|
+
#
|
|
4
|
+
# This API controls all the operations within the Headless CMS module.
|
|
5
|
+
# Use it to manage content, create and modify content models and more.
|
|
6
|
+
# Explore the schema for details.
|
|
7
|
+
#
|
|
8
|
+
# Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.
|
|
9
|
+
#
|
|
10
|
+
# Example query - list content model groups:
|
|
11
|
+
{
|
|
12
|
+
listContentModelGroups {
|
|
13
|
+
data {
|
|
14
|
+
name
|
|
15
|
+
icon
|
|
16
|
+
slug
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=placeholder.manage.graphql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["manageQuery"],"sources":["placeholder.manage.graphql.ts"],"sourcesContent":["export const manageQuery = /* GraphQL */ `\n # Webiny Headless CMS Manage API\n #\n # This API controls all the operations within the Headless CMS module.\n # Use it to manage content, create and modify content models and more.\n # Explore the schema for details.\n #\n # Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.\n #\n # Example query - list content model groups:\n {\n listContentModelGroups {\n data {\n name\n icon\n slug\n }\n }\n }\n`;\n"],"mappings":"AAAA,OAAO,MAAMA,WAAW,GAAG,aAAc;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const previewQuery = "\n # Webiny Headless CMS Preview API\n #\n # This is the API to use in your 3rd party apps to preview content.\n # It returns the latest content revision, regardless of whether it was published or not.\n #\n # Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.\n #\n # Example query - list content models:\n {\n listContentModels {\n data {\n name\n }\n }\n }\n";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const previewQuery = /* GraphQL */`
|
|
2
|
+
# Webiny Headless CMS Preview API
|
|
3
|
+
#
|
|
4
|
+
# This is the API to use in your 3rd party apps to preview content.
|
|
5
|
+
# It returns the latest content revision, regardless of whether it was published or not.
|
|
6
|
+
#
|
|
7
|
+
# Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.
|
|
8
|
+
#
|
|
9
|
+
# Example query - list content models:
|
|
10
|
+
{
|
|
11
|
+
listContentModels {
|
|
12
|
+
data {
|
|
13
|
+
name
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=placeholder.preview.graphql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["previewQuery"],"sources":["placeholder.preview.graphql.ts"],"sourcesContent":["export const previewQuery = /* GraphQL */ `\n # Webiny Headless CMS Preview API\n #\n # This is the API to use in your 3rd party apps to preview content.\n # It returns the latest content revision, regardless of whether it was published or not.\n #\n # Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.\n #\n # Example query - list content models:\n {\n listContentModels {\n data {\n name\n }\n }\n }\n`;\n"],"mappings":"AAAA,OAAO,MAAMA,YAAY,GAAG,aAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const readQuery = "\n # Webiny Headless CMS Read API\n #\n # This is the API to use in your 3rd party apps to read your content.\n # It returns only content that has been published.\n #\n # Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.\n #\n # Example query - list content models:\n {\n listContentModels {\n data {\n name\n modelId\n }\n }\n }\n";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const readQuery = /* GraphQL */`
|
|
2
|
+
# Webiny Headless CMS Read API
|
|
3
|
+
#
|
|
4
|
+
# This is the API to use in your 3rd party apps to read your content.
|
|
5
|
+
# It returns only content that has been published.
|
|
6
|
+
#
|
|
7
|
+
# Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.
|
|
8
|
+
#
|
|
9
|
+
# Example query - list content models:
|
|
10
|
+
{
|
|
11
|
+
listContentModels {
|
|
12
|
+
data {
|
|
13
|
+
name
|
|
14
|
+
modelId
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=placeholder.read.graphql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["readQuery"],"sources":["placeholder.read.graphql.ts"],"sourcesContent":["export const readQuery = /* GraphQL */ `\n # Webiny Headless CMS Read API\n #\n # This is the API to use in your 3rd party apps to read your content.\n # It returns only content that has been published.\n #\n # Note: to use the API outside of the playground, you will need to provide an API key via the Authorization header.\n #\n # Example query - list content models:\n {\n listContentModels {\n data {\n name\n modelId\n }\n }\n }\n`;\n"],"mappings":"AAAA,OAAO,MAAMA,SAAS,GAAG,aAAc;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { usePermission } from "../../hooks/usePermission.js";
|
|
3
3
|
export const ContentEntriesContext = /*#__PURE__*/React.createContext(undefined);
|
|
4
4
|
export const ContentEntriesProvider = ({
|
|
5
5
|
contentModel,
|
|
@@ -7,19 +7,9 @@ export const ContentEntriesProvider = ({
|
|
|
7
7
|
insideDialog
|
|
8
8
|
}) => {
|
|
9
9
|
const {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const canCreate = useMemo(() => {
|
|
14
|
-
const permission = getPermission("cms.contentEntry");
|
|
15
|
-
if (!permission) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
if (typeof permission.rwd !== "string") {
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
return permission.rwd.includes("w");
|
|
22
|
-
}, [identity]);
|
|
10
|
+
canCreate: canCreateEntries
|
|
11
|
+
} = usePermission();
|
|
12
|
+
const canCreate = canCreateEntries("cms.contentEntry");
|
|
23
13
|
const value = {
|
|
24
14
|
insideDialog,
|
|
25
15
|
contentModel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","
|
|
1
|
+
{"version":3,"names":["React","usePermission","ContentEntriesContext","createContext","undefined","ContentEntriesProvider","contentModel","children","insideDialog","canCreate","canCreateEntries","value","createElement","Provider","displayName"],"sources":["ContentEntriesContext.tsx"],"sourcesContent":["import React from \"react\";\nimport type { CmsModel } from \"~/types.js\";\nimport { usePermission } from \"~/admin/hooks/usePermission.js\";\n\nexport interface ContentEntriesContext {\n contentModel: CmsModel;\n canCreate: boolean;\n insideDialog?: boolean;\n}\n\nexport const ContentEntriesContext = React.createContext<ContentEntriesContext | undefined>(\n undefined\n);\n\nexport interface ContentEntriesContextProviderProps {\n contentModel: CmsModel;\n children: React.ReactNode;\n insideDialog?: boolean;\n}\n\nexport const ContentEntriesProvider = ({\n contentModel,\n children,\n insideDialog\n}: ContentEntriesContextProviderProps) => {\n const { canCreate: canCreateEntries } = usePermission();\n const canCreate = canCreateEntries(\"cms.contentEntry\");\n\n const value = {\n insideDialog,\n contentModel,\n canCreate\n };\n\n return (\n <ContentEntriesContext.Provider value={value}>{children}</ContentEntriesContext.Provider>\n );\n};\n\nContentEntriesProvider.displayName = \"ContentEntriesProvider\";\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAEzB,SAASC,aAAa;AAQtB,OAAO,MAAMC,qBAAqB,gBAAGF,KAAK,CAACG,aAAa,CACpDC,SACJ,CAAC;AAQD,OAAO,MAAMC,sBAAsB,GAAGA,CAAC;EACnCC,YAAY;EACZC,QAAQ;EACRC;AACgC,CAAC,KAAK;EACtC,MAAM;IAAEC,SAAS,EAAEC;EAAiB,CAAC,GAAGT,aAAa,CAAC,CAAC;EACvD,MAAMQ,SAAS,GAAGC,gBAAgB,CAAC,kBAAkB,CAAC;EAEtD,MAAMC,KAAK,GAAG;IACVH,YAAY;IACZF,YAAY;IACZG;EACJ,CAAC;EAED,oBACIT,KAAA,CAAAY,aAAA,CAACV,qBAAqB,CAACW,QAAQ;IAACF,KAAK,EAAEA;EAAM,GAAEJ,QAAyC,CAAC;AAEjG,CAAC;AAEDF,sBAAsB,CAACS,WAAW,GAAG,wBAAwB","ignoreList":[]}
|