@strapi/content-manager 5.0.0-rc.1 → 5.0.0-rc.11
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/dist/_chunks/{ComponentConfigurationPage-D8RyVgJC.js → ComponentConfigurationPage-D_M8iBw5.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-D8RyVgJC.js.map → ComponentConfigurationPage-D_M8iBw5.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DLuACgva.mjs → ComponentConfigurationPage-qemkOlnj.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DLuACgva.mjs.map → ComponentConfigurationPage-qemkOlnj.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-fOm5AebB.js → EditConfigurationPage-BePwPuHy.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-fOm5AebB.js.map → EditConfigurationPage-BePwPuHy.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CuCAsHWR.mjs → EditConfigurationPage-CjUrEewK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-CuCAsHWR.mjs.map → EditConfigurationPage-CjUrEewK.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-Or0fpTwh.js → EditViewPage-B-RJeiJD.js} +19 -8
- package/dist/_chunks/EditViewPage-B-RJeiJD.js.map +1 -0
- package/dist/_chunks/{EditViewPage-BqDlT9w0.mjs → EditViewPage-De8GyU8P.mjs} +19 -8
- package/dist/_chunks/EditViewPage-De8GyU8P.mjs.map +1 -0
- package/dist/_chunks/{Field-Bix2HU_O.js → Field-dq8Tg1M_.js} +99 -33
- package/dist/_chunks/Field-dq8Tg1M_.js.map +1 -0
- package/dist/_chunks/{Field-OfBJ6x59.mjs → Field-pb2o8uBe.mjs} +101 -35
- package/dist/_chunks/Field-pb2o8uBe.mjs.map +1 -0
- package/dist/_chunks/{Form-Bv5ABnqE.js → Form-DGIf4jQU.js} +22 -11
- package/dist/_chunks/Form-DGIf4jQU.js.map +1 -0
- package/dist/_chunks/{Form-DyMXqj_v.mjs → Form-DJn0Dxha.mjs} +22 -11
- package/dist/_chunks/Form-DJn0Dxha.mjs.map +1 -0
- package/dist/_chunks/{History-rvLnluF0.mjs → History-BowL3JKP.mjs} +4 -4
- package/dist/_chunks/{History-rvLnluF0.mjs.map → History-BowL3JKP.mjs.map} +1 -1
- package/dist/_chunks/{History-fnln26gA.js → History-Dh2NEHnR.js} +4 -4
- package/dist/_chunks/{History-fnln26gA.js.map → History-Dh2NEHnR.js.map} +1 -1
- package/dist/_chunks/{ListConfigurationPage-DdKfJRdq.mjs → ListConfigurationPage-BpVOB-hn.mjs} +14 -4
- package/dist/_chunks/ListConfigurationPage-BpVOB-hn.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-BtCBP_L_.js → ListConfigurationPage-BxYCWz9e.js} +14 -4
- package/dist/_chunks/ListConfigurationPage-BxYCWz9e.js.map +1 -0
- package/dist/_chunks/{ListViewPage-CGZWD2qn.js → ListViewPage-4XsciqHZ.js} +9 -4
- package/dist/_chunks/ListViewPage-4XsciqHZ.js.map +1 -0
- package/dist/_chunks/{ListViewPage-B8cPO1bK.mjs → ListViewPage-CXFUjZQC.mjs} +10 -5
- package/dist/_chunks/ListViewPage-CXFUjZQC.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-oJxX0WCQ.js → NoContentTypePage-C8OpoHeU.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-oJxX0WCQ.js.map → NoContentTypePage-C8OpoHeU.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CVqYTeML.mjs → NoContentTypePage-DuhOTp3x.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CVqYTeML.mjs.map → NoContentTypePage-DuhOTp3x.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-mlXqh8p6.mjs → NoPermissionsPage-DVz3mzDz.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-mlXqh8p6.mjs.map → NoPermissionsPage-DVz3mzDz.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BB11jqM_.js → NoPermissionsPage-y_r7DVA2.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BB11jqM_.js.map → NoPermissionsPage-y_r7DVA2.js.map} +1 -1
- package/dist/_chunks/{Relations-DWscdjKO.mjs → Relations-CVNLrn1Y.mjs} +4 -4
- package/dist/_chunks/{Relations-DWscdjKO.mjs.map → Relations-CVNLrn1Y.mjs.map} +1 -1
- package/dist/_chunks/{Relations-6xIumgbN.js → Relations-DPFCAa7b.js} +4 -4
- package/dist/_chunks/{Relations-6xIumgbN.js.map → Relations-DPFCAa7b.js.map} +1 -1
- package/dist/_chunks/{index-BzUwgKUj.js → index-C3fJE-1-.js} +140 -71
- package/dist/_chunks/index-C3fJE-1-.js.map +1 -0
- package/dist/_chunks/{index-JSJrqmB9.mjs → index-DiMrfcfy.mjs} +158 -89
- package/dist/_chunks/index-DiMrfcfy.mjs.map +1 -0
- package/dist/_chunks/{layout-U4xJd8Oi.js → layout-C788OmNr.js} +19 -7
- package/dist/_chunks/layout-C788OmNr.js.map +1 -0
- package/dist/_chunks/{layout-Dewoec1b.mjs → layout-ls3gxfpH.mjs} +20 -8
- package/dist/_chunks/layout-ls3gxfpH.mjs.map +1 -0
- package/dist/_chunks/{relations-DMxeUp5V.mjs → relations-CLcOmGO0.mjs} +2 -2
- package/dist/_chunks/{relations-DMxeUp5V.mjs.map → relations-CLcOmGO0.mjs.map} +1 -1
- package/dist/_chunks/{relations-BifGhhuo.js → relations-DYeotliT.js} +2 -2
- package/dist/_chunks/{relations-BifGhhuo.js.map → relations-DYeotliT.js.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +4 -4
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +10 -22
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +16 -16
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +155 -103
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +156 -104
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +1 -1
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/_chunks/EditViewPage-BqDlT9w0.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-Or0fpTwh.js.map +0 -1
- package/dist/_chunks/Field-Bix2HU_O.js.map +0 -1
- package/dist/_chunks/Field-OfBJ6x59.mjs.map +0 -1
- package/dist/_chunks/Form-Bv5ABnqE.js.map +0 -1
- package/dist/_chunks/Form-DyMXqj_v.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-BtCBP_L_.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DdKfJRdq.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-B8cPO1bK.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-CGZWD2qn.js.map +0 -1
- package/dist/_chunks/index-BzUwgKUj.js.map +0 -1
- package/dist/_chunks/index-JSJrqmB9.mjs.map +0 -1
- package/dist/_chunks/layout-Dewoec1b.mjs.map +0 -1
- package/dist/_chunks/layout-U4xJd8Oi.js.map +0 -1
package/dist/server/index.js
CHANGED
@@ -226,9 +226,10 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
226
226
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
227
227
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
228
228
|
};
|
229
|
-
const getDeepPopulate2 = (uid2) => {
|
229
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
230
230
|
const model = strapi2.getModel(uid2);
|
231
231
|
const attributes = Object.entries(model.attributes);
|
232
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
232
233
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
233
234
|
switch (attribute.type) {
|
234
235
|
case "relation": {
|
@@ -238,12 +239,12 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
238
239
|
}
|
239
240
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
240
241
|
if (isVisible2) {
|
241
|
-
acc[attributeName] = {
|
242
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
242
243
|
}
|
243
244
|
break;
|
244
245
|
}
|
245
246
|
case "media": {
|
246
|
-
acc[attributeName] = {
|
247
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
247
248
|
break;
|
248
249
|
}
|
249
250
|
case "component": {
|
@@ -494,6 +495,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
494
495
|
}
|
495
496
|
};
|
496
497
|
};
|
498
|
+
const shouldCreateHistoryVersion = (context) => {
|
499
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
500
|
+
return false;
|
501
|
+
}
|
502
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
503
|
+
return false;
|
504
|
+
}
|
505
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
506
|
+
return false;
|
507
|
+
}
|
508
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
509
|
+
return false;
|
510
|
+
}
|
511
|
+
return true;
|
512
|
+
};
|
513
|
+
const getSchemas = (uid2) => {
|
514
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
515
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
516
|
+
(currentComponentSchemas, key) => {
|
517
|
+
const fieldSchema = attributesSchema[key];
|
518
|
+
if (fieldSchema.type === "component") {
|
519
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
520
|
+
return {
|
521
|
+
...currentComponentSchemas,
|
522
|
+
[fieldSchema.component]: componentSchema
|
523
|
+
};
|
524
|
+
}
|
525
|
+
return currentComponentSchemas;
|
526
|
+
},
|
527
|
+
{}
|
528
|
+
);
|
529
|
+
return {
|
530
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
531
|
+
componentsSchemas
|
532
|
+
};
|
533
|
+
};
|
497
534
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
498
535
|
const state = {
|
499
536
|
deleteExpiredJob: null,
|
@@ -506,63 +543,43 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
506
543
|
return;
|
507
544
|
}
|
508
545
|
strapi2.documents.use(async (context, next) => {
|
509
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
510
|
-
return next();
|
511
|
-
}
|
512
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
513
|
-
return next();
|
514
|
-
}
|
515
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
516
|
-
return next();
|
517
|
-
}
|
518
|
-
const contentTypeUid = context.contentType.uid;
|
519
|
-
if (!contentTypeUid.startsWith("api::")) {
|
520
|
-
return next();
|
521
|
-
}
|
522
546
|
const result = await next();
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
547
|
+
if (!shouldCreateHistoryVersion(context)) {
|
548
|
+
return result;
|
549
|
+
}
|
550
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
527
551
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
528
|
-
const
|
529
|
-
if (
|
530
|
-
|
531
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
532
|
-
);
|
533
|
-
return next();
|
552
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
553
|
+
if (!locales.length) {
|
554
|
+
return result;
|
534
555
|
}
|
535
|
-
const
|
536
|
-
|
537
|
-
|
538
|
-
|
556
|
+
const uid2 = context.contentType.uid;
|
557
|
+
const schemas = getSchemas(uid2);
|
558
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
559
|
+
where: {
|
560
|
+
documentId,
|
561
|
+
locale: { $in: locales },
|
562
|
+
publishedAt: null
|
563
|
+
},
|
564
|
+
populate: serviceUtils.getDeepPopulate(
|
565
|
+
uid2,
|
566
|
+
true
|
567
|
+
/* use database syntax */
|
568
|
+
)
|
539
569
|
});
|
540
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
541
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
542
|
-
const componentsSchemas = Object.keys(
|
543
|
-
attributesSchema
|
544
|
-
).reduce((currentComponentSchemas, key) => {
|
545
|
-
const fieldSchema = attributesSchema[key];
|
546
|
-
if (fieldSchema.type === "component") {
|
547
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
548
|
-
return {
|
549
|
-
...currentComponentSchemas,
|
550
|
-
[fieldSchema.component]: componentSchema
|
551
|
-
};
|
552
|
-
}
|
553
|
-
return currentComponentSchemas;
|
554
|
-
}, {});
|
555
570
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
556
|
-
onCommit(() => {
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
571
|
+
onCommit(async () => {
|
572
|
+
for (const entry of localeEntries) {
|
573
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
574
|
+
await getService(strapi2, "history").createVersion({
|
575
|
+
contentType: uid2,
|
576
|
+
data: fp.omit(FIELDS_TO_IGNORE, entry),
|
577
|
+
relatedDocumentId: documentId,
|
578
|
+
locale: entry.locale,
|
579
|
+
status,
|
580
|
+
...schemas
|
581
|
+
});
|
582
|
+
}
|
566
583
|
});
|
567
584
|
});
|
568
585
|
return result;
|
@@ -1202,6 +1219,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1202
1219
|
const hasPermissions = createPolicy({
|
1203
1220
|
name: "plugin::content-manager.hasPermissions",
|
1204
1221
|
validator: validateHasPermissionsInput,
|
1222
|
+
/**
|
1223
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1224
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1225
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1226
|
+
*/
|
1205
1227
|
handler(ctx, config = {}) {
|
1206
1228
|
const { actions = [], hasAtLeastOne = false } = config;
|
1207
1229
|
const { userAbility } = ctx.state;
|
@@ -1595,9 +1617,11 @@ const multipleLocaleSchema = strapiUtils.yup.lazy(
|
|
1595
1617
|
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1596
1618
|
);
|
1597
1619
|
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1598
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1620
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1599
1621
|
const { allowMultipleLocales } = opts;
|
1600
|
-
const { locale, status, ...rest } = request || {};
|
1622
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1623
|
+
const defaultStatus = strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1624
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1601
1625
|
const schema = strapiUtils.yup.object().shape({
|
1602
1626
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1603
1627
|
status: statusSchema
|
@@ -1645,7 +1669,7 @@ const createDocument = async (ctx, opts) => {
|
|
1645
1669
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1646
1670
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1647
1671
|
const sanitizedBody = await sanitizeFn(body);
|
1648
|
-
const { locale, status
|
1672
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1649
1673
|
return documentManager2.create(model, {
|
1650
1674
|
data: sanitizedBody,
|
1651
1675
|
locale,
|
@@ -1664,7 +1688,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1664
1688
|
}
|
1665
1689
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1666
1690
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1667
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1691
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1668
1692
|
const [documentVersion, documentExists] = await Promise.all([
|
1669
1693
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1670
1694
|
documentManager2.exists(model, id)
|
@@ -1702,7 +1726,7 @@ const collectionTypes = {
|
|
1702
1726
|
}
|
1703
1727
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1704
1728
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1705
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1729
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1706
1730
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1707
1731
|
{ ...permissionQuery, populate, locale, status },
|
1708
1732
|
model
|
@@ -1737,7 +1761,7 @@ const collectionTypes = {
|
|
1737
1761
|
}
|
1738
1762
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1739
1763
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1740
|
-
const { locale, status
|
1764
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1741
1765
|
const version = await documentManager2.findOne(id, model, {
|
1742
1766
|
populate,
|
1743
1767
|
locale,
|
@@ -1804,7 +1828,7 @@ const collectionTypes = {
|
|
1804
1828
|
}
|
1805
1829
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1806
1830
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1807
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1831
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1808
1832
|
const document = await documentManager2.findOne(id, model, {
|
1809
1833
|
populate,
|
1810
1834
|
locale,
|
@@ -1849,7 +1873,7 @@ const collectionTypes = {
|
|
1849
1873
|
}
|
1850
1874
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1851
1875
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1852
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1876
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1853
1877
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1854
1878
|
if (documentLocales.length === 0) {
|
1855
1879
|
return ctx.notFound();
|
@@ -1878,11 +1902,28 @@ const collectionTypes = {
|
|
1878
1902
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1879
1903
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1880
1904
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1881
|
-
|
1905
|
+
let document;
|
1906
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1907
|
+
const isCreate = fp.isNil(id);
|
1908
|
+
if (isCreate) {
|
1909
|
+
if (permissionChecker2.cannot.create()) {
|
1910
|
+
throw new strapiUtils.errors.ForbiddenError();
|
1911
|
+
}
|
1912
|
+
document = await createDocument(ctx, { populate });
|
1913
|
+
}
|
1914
|
+
const isUpdate = !isCreate;
|
1915
|
+
if (isUpdate) {
|
1916
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
1917
|
+
if (!document) {
|
1918
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
1919
|
+
}
|
1920
|
+
if (permissionChecker2.can.update(document)) {
|
1921
|
+
await updateDocument(ctx);
|
1922
|
+
}
|
1923
|
+
}
|
1882
1924
|
if (permissionChecker2.cannot.publish(document)) {
|
1883
1925
|
throw new strapiUtils.errors.ForbiddenError();
|
1884
1926
|
}
|
1885
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1886
1927
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1887
1928
|
locale
|
1888
1929
|
// TODO: Allow setting creator fields on publish
|
@@ -1909,7 +1950,9 @@ const collectionTypes = {
|
|
1909
1950
|
}
|
1910
1951
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1911
1952
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1912
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
1953
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1954
|
+
allowMultipleLocales: true
|
1955
|
+
});
|
1913
1956
|
const entityPromises = documentIds.map(
|
1914
1957
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1915
1958
|
);
|
@@ -1936,7 +1979,7 @@ const collectionTypes = {
|
|
1936
1979
|
if (permissionChecker2.cannot.unpublish()) {
|
1937
1980
|
return ctx.forbidden();
|
1938
1981
|
}
|
1939
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1982
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1940
1983
|
const entityPromises = documentIds.map(
|
1941
1984
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1942
1985
|
);
|
@@ -1969,7 +2012,7 @@ const collectionTypes = {
|
|
1969
2012
|
}
|
1970
2013
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1971
2014
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1972
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2015
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1973
2016
|
const document = await documentManager2.findOne(id, model, {
|
1974
2017
|
populate,
|
1975
2018
|
locale,
|
@@ -2006,7 +2049,7 @@ const collectionTypes = {
|
|
2006
2049
|
}
|
2007
2050
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2008
2051
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2009
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2052
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2010
2053
|
const document = await documentManager2.findOne(id, model, {
|
2011
2054
|
populate,
|
2012
2055
|
locale,
|
@@ -2037,7 +2080,7 @@ const collectionTypes = {
|
|
2037
2080
|
}
|
2038
2081
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2039
2082
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2040
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2083
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2041
2084
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2042
2085
|
populate,
|
2043
2086
|
locale
|
@@ -2064,7 +2107,7 @@ const collectionTypes = {
|
|
2064
2107
|
}
|
2065
2108
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2066
2109
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2067
|
-
const { locale, status
|
2110
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2068
2111
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2069
2112
|
if (!entity) {
|
2070
2113
|
return ctx.notFound();
|
@@ -2287,20 +2330,13 @@ const sanitizeMainField = (model, mainField, userAbility) => {
|
|
2287
2330
|
userAbility,
|
2288
2331
|
model: model.uid
|
2289
2332
|
});
|
2290
|
-
|
2333
|
+
const isMainFieldListable = isListable(model, mainField);
|
2334
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2335
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2291
2336
|
return "id";
|
2292
2337
|
}
|
2293
|
-
if (
|
2294
|
-
|
2295
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2296
|
-
userAbility,
|
2297
|
-
model: "plugin::users-permissions.user"
|
2298
|
-
});
|
2299
|
-
if (userPermissionChecker.can.read()) {
|
2300
|
-
return "name";
|
2301
|
-
}
|
2302
|
-
}
|
2303
|
-
return "id";
|
2338
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2339
|
+
return "name";
|
2304
2340
|
}
|
2305
2341
|
return mainField;
|
2306
2342
|
};
|
@@ -2558,9 +2594,7 @@ const relations = {
|
|
2558
2594
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2559
2595
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2560
2596
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2561
|
-
ordering: "desc"
|
2562
|
-
page: ctx.request.query.page,
|
2563
|
-
pageSize: ctx.request.query.pageSize
|
2597
|
+
ordering: "desc"
|
2564
2598
|
});
|
2565
2599
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2566
2600
|
ctx.body = {
|
@@ -2592,7 +2626,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2592
2626
|
throw new strapiUtils.errors.ForbiddenError();
|
2593
2627
|
}
|
2594
2628
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2595
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2629
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2596
2630
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2597
2631
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2598
2632
|
// Find the first document to check if it exists
|
@@ -2633,7 +2667,7 @@ const singleTypes = {
|
|
2633
2667
|
return ctx.forbidden();
|
2634
2668
|
}
|
2635
2669
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2636
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2670
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2637
2671
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2638
2672
|
if (!version) {
|
2639
2673
|
if (permissionChecker2.cannot.create()) {
|
@@ -2678,7 +2712,7 @@ const singleTypes = {
|
|
2678
2712
|
}
|
2679
2713
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2680
2714
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2681
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2715
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2682
2716
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2683
2717
|
populate,
|
2684
2718
|
locale
|
@@ -2715,7 +2749,7 @@ const singleTypes = {
|
|
2715
2749
|
if (permissionChecker2.cannot.publish(document)) {
|
2716
2750
|
throw new strapiUtils.errors.ForbiddenError();
|
2717
2751
|
}
|
2718
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2752
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2719
2753
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2720
2754
|
return publishResult.at(0);
|
2721
2755
|
});
|
@@ -2738,7 +2772,7 @@ const singleTypes = {
|
|
2738
2772
|
return ctx.forbidden();
|
2739
2773
|
}
|
2740
2774
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2741
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2775
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2742
2776
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2743
2777
|
if (!document) {
|
2744
2778
|
return ctx.notFound();
|
@@ -2770,7 +2804,7 @@ const singleTypes = {
|
|
2770
2804
|
return ctx.forbidden();
|
2771
2805
|
}
|
2772
2806
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2773
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2807
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2774
2808
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2775
2809
|
if (!document) {
|
2776
2810
|
return ctx.notFound();
|
@@ -2790,7 +2824,7 @@ const singleTypes = {
|
|
2790
2824
|
const { query } = ctx.request;
|
2791
2825
|
const documentManager2 = getService$1("document-manager");
|
2792
2826
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2793
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2827
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2794
2828
|
if (permissionChecker2.cannot.read()) {
|
2795
2829
|
return ctx.forbidden();
|
2796
2830
|
}
|
@@ -2811,7 +2845,7 @@ const uid$1 = {
|
|
2811
2845
|
async generateUID(ctx) {
|
2812
2846
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2813
2847
|
const { query = {} } = ctx.request;
|
2814
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2848
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2815
2849
|
await validateUIDField(contentTypeUID, field);
|
2816
2850
|
const uidService = getService$1("uid");
|
2817
2851
|
ctx.body = {
|
@@ -2823,7 +2857,7 @@ const uid$1 = {
|
|
2823
2857
|
ctx.request.body
|
2824
2858
|
);
|
2825
2859
|
const { query = {} } = ctx.request;
|
2826
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2860
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2827
2861
|
await validateUIDField(contentTypeUID, field);
|
2828
2862
|
const uidService = getService$1("uid");
|
2829
2863
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3466,12 +3500,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3466
3500
|
ability: userAbility,
|
3467
3501
|
model
|
3468
3502
|
});
|
3469
|
-
const
|
3503
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3504
|
+
const toSubject = (entity) => {
|
3505
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3506
|
+
};
|
3470
3507
|
const can = (action, entity, field) => {
|
3471
|
-
|
3508
|
+
const subject = toSubject(entity);
|
3509
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3510
|
+
return (
|
3511
|
+
// Test the original action to see if it passes
|
3512
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3513
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3514
|
+
);
|
3472
3515
|
};
|
3473
3516
|
const cannot = (action, entity, field) => {
|
3474
|
-
|
3517
|
+
const subject = toSubject(entity);
|
3518
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3519
|
+
return (
|
3520
|
+
// Test both the original action
|
3521
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3522
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3523
|
+
);
|
3475
3524
|
};
|
3476
3525
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3477
3526
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -4129,7 +4178,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4129
4178
|
*/
|
4130
4179
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4131
4180
|
if (!document) {
|
4132
|
-
return
|
4181
|
+
return {
|
4182
|
+
data: document,
|
4183
|
+
meta: {
|
4184
|
+
availableLocales: [],
|
4185
|
+
availableStatus: []
|
4186
|
+
}
|
4187
|
+
};
|
4133
4188
|
}
|
4134
4189
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4135
4190
|
if (!hasDraftAndPublish) {
|
@@ -4237,10 +4292,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4237
4292
|
async clone(id, body, uid2) {
|
4238
4293
|
const populate = await buildDeepPopulate(uid2);
|
4239
4294
|
const params = {
|
4240
|
-
data:
|
4241
|
-
...omitIdField(body),
|
4242
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4243
|
-
},
|
4295
|
+
data: omitIdField(body),
|
4244
4296
|
populate
|
4245
4297
|
};
|
4246
4298
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|