@strapi/content-manager 0.0.0-experimental.d53e940834bf72ddc725f1d2fd36dac9abec30cb → 0.0.0-experimental.d834c9e658d1fb037e6da1105150593521c667cc
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/LICENSE +18 -3
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js → ComponentConfigurationPage-D_M8iBw5.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-D_M8iBw5.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs → ComponentConfigurationPage-qemkOlnj.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-qemkOlnj.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-BePwPuHy.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-BePwPuHy.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-CjUrEewK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-CjUrEewK.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-B-RJeiJD.js} +19 -8
- package/dist/_chunks/EditViewPage-B-RJeiJD.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-De8GyU8P.mjs} +19 -8
- package/dist/_chunks/EditViewPage-De8GyU8P.mjs.map +1 -0
- package/dist/_chunks/{Field-Boxf9Ajp.js → Field-dq8Tg1M_.js} +175 -84
- package/dist/_chunks/Field-dq8Tg1M_.js.map +1 -0
- package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-pb2o8uBe.mjs} +177 -86
- package/dist/_chunks/Field-pb2o8uBe.mjs.map +1 -0
- package/dist/_chunks/{Form-y5g1SRsh.js → Form-DGIf4jQU.js} +22 -11
- package/dist/_chunks/Form-DGIf4jQU.js.map +1 -0
- package/dist/_chunks/{Form-DHrru2AV.mjs → Form-DJn0Dxha.mjs} +22 -11
- package/dist/_chunks/Form-DJn0Dxha.mjs.map +1 -0
- package/dist/_chunks/{History-Bru_KoeP.mjs → History-BowL3JKP.mjs} +44 -19
- package/dist/_chunks/History-BowL3JKP.mjs.map +1 -0
- package/dist/_chunks/{History-CqN6K7SX.js → History-Dh2NEHnR.js} +44 -19
- package/dist/_chunks/History-Dh2NEHnR.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-BpVOB-hn.mjs} +20 -8
- package/dist/_chunks/ListConfigurationPage-BpVOB-hn.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-BxYCWz9e.js} +20 -8
- package/dist/_chunks/ListConfigurationPage-BxYCWz9e.js.map +1 -0
- package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-4XsciqHZ.js} +21 -7
- package/dist/_chunks/ListViewPage-4XsciqHZ.js.map +1 -0
- package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-CXFUjZQC.mjs} +22 -8
- package/dist/_chunks/ListViewPage-CXFUjZQC.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-C8OpoHeU.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-C8OpoHeU.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-DuhOTp3x.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-DuhOTp3x.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-DVz3mzDz.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-DVz3mzDz.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-y_r7DVA2.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-y_r7DVA2.js.map} +1 -1
- package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-CVNLrn1Y.mjs} +4 -4
- package/dist/_chunks/Relations-CVNLrn1Y.mjs.map +1 -0
- package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-DPFCAa7b.js} +4 -4
- package/dist/_chunks/Relations-DPFCAa7b.js.map +1 -0
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-BrCTWlZv.mjs} +5 -4
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
- package/dist/_chunks/{en-fbKQxLGn.js → en-uOUIxfcQ.js} +5 -4
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-uOUIxfcQ.js.map} +1 -1
- package/dist/_chunks/{index-DVPWZkbS.js → index-C3fJE-1-.js} +368 -168
- package/dist/_chunks/index-C3fJE-1-.js.map +1 -0
- package/dist/_chunks/{index-DJXJw9V5.mjs → index-DiMrfcfy.mjs} +387 -187
- package/dist/_chunks/index-DiMrfcfy.mjs.map +1 -0
- package/dist/_chunks/{layout-Dm6fbiQj.js → layout-C788OmNr.js} +22 -10
- package/dist/_chunks/layout-C788OmNr.js.map +1 -0
- package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-ls3gxfpH.mjs} +23 -11
- package/dist/_chunks/layout-ls3gxfpH.mjs.map +1 -0
- package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-CLcOmGO0.mjs} +2 -2
- package/dist/_chunks/{relations-BH_kBSJ0.mjs.map → relations-CLcOmGO0.mjs.map} +1 -1
- package/dist/_chunks/{relations-CKnpRgrN.js → relations-DYeotliT.js} +2 -2
- package/dist/_chunks/{relations-CKnpRgrN.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/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- 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 +165 -105
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +166 -106
- 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/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/_chunks/EditViewPage-CPj61RMh.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-zT3fBr4Y.js.map +0 -1
- package/dist/_chunks/Field-Boxf9Ajp.js.map +0 -1
- package/dist/_chunks/Field-dha5VnIQ.mjs.map +0 -1
- package/dist/_chunks/Form-DHrru2AV.mjs.map +0 -1
- package/dist/_chunks/Form-y5g1SRsh.js.map +0 -1
- package/dist/_chunks/History-Bru_KoeP.mjs.map +0 -1
- package/dist/_chunks/History-CqN6K7SX.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-D8wGABj0.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-R_p-SbHZ.js.map +0 -1
- package/dist/_chunks/ListViewPage-SID6TRb9.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-pEw_zug9.js.map +0 -1
- package/dist/_chunks/Relations-B9Crnhnn.mjs.map +0 -1
- package/dist/_chunks/Relations-DjTQ5kGB.js.map +0 -1
- package/dist/_chunks/index-DJXJw9V5.mjs.map +0 -1
- package/dist/_chunks/index-DVPWZkbS.js.map +0 -1
- package/dist/_chunks/layout-Bau7ZfLV.mjs.map +0 -1
- package/dist/_chunks/layout-Dm6fbiQj.js.map +0 -1
package/dist/server/index.js
CHANGED
@@ -226,20 +226,25 @@ 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": {
|
236
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
237
|
+
if (isMorphRelation) {
|
238
|
+
break;
|
239
|
+
}
|
235
240
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
236
241
|
if (isVisible2) {
|
237
|
-
acc[attributeName] = {
|
242
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
238
243
|
}
|
239
244
|
break;
|
240
245
|
}
|
241
246
|
case "media": {
|
242
|
-
acc[attributeName] = {
|
247
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
243
248
|
break;
|
244
249
|
}
|
245
250
|
case "component": {
|
@@ -490,6 +495,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
490
495
|
}
|
491
496
|
};
|
492
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
|
+
};
|
493
534
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
494
535
|
const state = {
|
495
536
|
deleteExpiredJob: null,
|
@@ -502,63 +543,43 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
502
543
|
return;
|
503
544
|
}
|
504
545
|
strapi2.documents.use(async (context, next) => {
|
505
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
506
|
-
return next();
|
507
|
-
}
|
508
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
509
|
-
return next();
|
510
|
-
}
|
511
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
512
|
-
return next();
|
513
|
-
}
|
514
|
-
const contentTypeUid = context.contentType.uid;
|
515
|
-
if (!contentTypeUid.startsWith("api::")) {
|
516
|
-
return next();
|
517
|
-
}
|
518
546
|
const result = await next();
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
547
|
+
if (!shouldCreateHistoryVersion(context)) {
|
548
|
+
return result;
|
549
|
+
}
|
550
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
523
551
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
524
|
-
const
|
525
|
-
if (
|
526
|
-
|
527
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
528
|
-
);
|
529
|
-
return next();
|
552
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
553
|
+
if (!locales.length) {
|
554
|
+
return result;
|
530
555
|
}
|
531
|
-
const
|
532
|
-
|
533
|
-
|
534
|
-
|
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
|
+
)
|
535
569
|
});
|
536
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
537
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
538
|
-
const componentsSchemas = Object.keys(
|
539
|
-
attributesSchema
|
540
|
-
).reduce((currentComponentSchemas, key) => {
|
541
|
-
const fieldSchema = attributesSchema[key];
|
542
|
-
if (fieldSchema.type === "component") {
|
543
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
544
|
-
return {
|
545
|
-
...currentComponentSchemas,
|
546
|
-
[fieldSchema.component]: componentSchema
|
547
|
-
};
|
548
|
-
}
|
549
|
-
return currentComponentSchemas;
|
550
|
-
}, {});
|
551
570
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
552
|
-
onCommit(() => {
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
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
|
+
}
|
562
583
|
});
|
563
584
|
});
|
564
585
|
return result;
|
@@ -1198,6 +1219,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1198
1219
|
const hasPermissions = createPolicy({
|
1199
1220
|
name: "plugin::content-manager.hasPermissions",
|
1200
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
|
+
*/
|
1201
1227
|
handler(ctx, config = {}) {
|
1202
1228
|
const { actions = [], hasAtLeastOne = false } = config;
|
1203
1229
|
const { userAbility } = ctx.state;
|
@@ -1591,9 +1617,11 @@ const multipleLocaleSchema = strapiUtils.yup.lazy(
|
|
1591
1617
|
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1592
1618
|
);
|
1593
1619
|
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1594
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1620
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1595
1621
|
const { allowMultipleLocales } = opts;
|
1596
|
-
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;
|
1597
1625
|
const schema = strapiUtils.yup.object().shape({
|
1598
1626
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1599
1627
|
status: statusSchema
|
@@ -1641,7 +1669,7 @@ const createDocument = async (ctx, opts) => {
|
|
1641
1669
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1642
1670
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1643
1671
|
const sanitizedBody = await sanitizeFn(body);
|
1644
|
-
const { locale, status
|
1672
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1645
1673
|
return documentManager2.create(model, {
|
1646
1674
|
data: sanitizedBody,
|
1647
1675
|
locale,
|
@@ -1660,7 +1688,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1660
1688
|
}
|
1661
1689
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1662
1690
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1663
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1691
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1664
1692
|
const [documentVersion, documentExists] = await Promise.all([
|
1665
1693
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1666
1694
|
documentManager2.exists(model, id)
|
@@ -1698,7 +1726,7 @@ const collectionTypes = {
|
|
1698
1726
|
}
|
1699
1727
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1700
1728
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1701
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1729
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1702
1730
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1703
1731
|
{ ...permissionQuery, populate, locale, status },
|
1704
1732
|
model
|
@@ -1733,7 +1761,7 @@ const collectionTypes = {
|
|
1733
1761
|
}
|
1734
1762
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1735
1763
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1736
|
-
const { locale, status
|
1764
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1737
1765
|
const version = await documentManager2.findOne(id, model, {
|
1738
1766
|
populate,
|
1739
1767
|
locale,
|
@@ -1800,7 +1828,7 @@ const collectionTypes = {
|
|
1800
1828
|
}
|
1801
1829
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1802
1830
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1803
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1831
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1804
1832
|
const document = await documentManager2.findOne(id, model, {
|
1805
1833
|
populate,
|
1806
1834
|
locale,
|
@@ -1845,7 +1873,7 @@ const collectionTypes = {
|
|
1845
1873
|
}
|
1846
1874
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1847
1875
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1848
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1876
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1849
1877
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1850
1878
|
if (documentLocales.length === 0) {
|
1851
1879
|
return ctx.notFound();
|
@@ -1874,11 +1902,28 @@ const collectionTypes = {
|
|
1874
1902
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1875
1903
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1876
1904
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1877
|
-
|
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
|
+
}
|
1878
1924
|
if (permissionChecker2.cannot.publish(document)) {
|
1879
1925
|
throw new strapiUtils.errors.ForbiddenError();
|
1880
1926
|
}
|
1881
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1882
1927
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1883
1928
|
locale
|
1884
1929
|
// TODO: Allow setting creator fields on publish
|
@@ -1905,7 +1950,9 @@ const collectionTypes = {
|
|
1905
1950
|
}
|
1906
1951
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1907
1952
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1908
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
1953
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1954
|
+
allowMultipleLocales: true
|
1955
|
+
});
|
1909
1956
|
const entityPromises = documentIds.map(
|
1910
1957
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1911
1958
|
);
|
@@ -1932,7 +1979,7 @@ const collectionTypes = {
|
|
1932
1979
|
if (permissionChecker2.cannot.unpublish()) {
|
1933
1980
|
return ctx.forbidden();
|
1934
1981
|
}
|
1935
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1982
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1936
1983
|
const entityPromises = documentIds.map(
|
1937
1984
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1938
1985
|
);
|
@@ -1965,7 +2012,7 @@ const collectionTypes = {
|
|
1965
2012
|
}
|
1966
2013
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1967
2014
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1968
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2015
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1969
2016
|
const document = await documentManager2.findOne(id, model, {
|
1970
2017
|
populate,
|
1971
2018
|
locale,
|
@@ -2002,7 +2049,7 @@ const collectionTypes = {
|
|
2002
2049
|
}
|
2003
2050
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2004
2051
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2005
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2052
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2006
2053
|
const document = await documentManager2.findOne(id, model, {
|
2007
2054
|
populate,
|
2008
2055
|
locale,
|
@@ -2033,7 +2080,7 @@ const collectionTypes = {
|
|
2033
2080
|
}
|
2034
2081
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2035
2082
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2036
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2083
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2037
2084
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2038
2085
|
populate,
|
2039
2086
|
locale
|
@@ -2060,7 +2107,7 @@ const collectionTypes = {
|
|
2060
2107
|
}
|
2061
2108
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2062
2109
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2063
|
-
const { locale, status
|
2110
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2064
2111
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2065
2112
|
if (!entity) {
|
2066
2113
|
return ctx.notFound();
|
@@ -2083,7 +2130,7 @@ const collectionTypes = {
|
|
2083
2130
|
if (permissionChecker2.cannot.read()) {
|
2084
2131
|
return ctx.forbidden();
|
2085
2132
|
}
|
2086
|
-
const
|
2133
|
+
const documents = await documentManager2.findMany(
|
2087
2134
|
{
|
2088
2135
|
filters: {
|
2089
2136
|
documentId: ids
|
@@ -2092,7 +2139,7 @@ const collectionTypes = {
|
|
2092
2139
|
},
|
2093
2140
|
model
|
2094
2141
|
);
|
2095
|
-
if (!
|
2142
|
+
if (!documents) {
|
2096
2143
|
return ctx.notFound();
|
2097
2144
|
}
|
2098
2145
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2283,20 +2330,13 @@ const sanitizeMainField = (model, mainField, userAbility) => {
|
|
2283
2330
|
userAbility,
|
2284
2331
|
model: model.uid
|
2285
2332
|
});
|
2286
|
-
|
2333
|
+
const isMainFieldListable = isListable(model, mainField);
|
2334
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2335
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2287
2336
|
return "id";
|
2288
2337
|
}
|
2289
|
-
if (
|
2290
|
-
|
2291
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2292
|
-
userAbility,
|
2293
|
-
model: "plugin::users-permissions.user"
|
2294
|
-
});
|
2295
|
-
if (userPermissionChecker.can.read()) {
|
2296
|
-
return "name";
|
2297
|
-
}
|
2298
|
-
}
|
2299
|
-
return "id";
|
2338
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2339
|
+
return "name";
|
2300
2340
|
}
|
2301
2341
|
return mainField;
|
2302
2342
|
};
|
@@ -2554,9 +2594,7 @@ const relations = {
|
|
2554
2594
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2555
2595
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2556
2596
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2557
|
-
ordering: "desc"
|
2558
|
-
page: ctx.request.query.page,
|
2559
|
-
pageSize: ctx.request.query.pageSize
|
2597
|
+
ordering: "desc"
|
2560
2598
|
});
|
2561
2599
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2562
2600
|
ctx.body = {
|
@@ -2588,7 +2626,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2588
2626
|
throw new strapiUtils.errors.ForbiddenError();
|
2589
2627
|
}
|
2590
2628
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2591
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2629
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2592
2630
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2593
2631
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2594
2632
|
// Find the first document to check if it exists
|
@@ -2629,7 +2667,7 @@ const singleTypes = {
|
|
2629
2667
|
return ctx.forbidden();
|
2630
2668
|
}
|
2631
2669
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2632
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2670
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2633
2671
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2634
2672
|
if (!version) {
|
2635
2673
|
if (permissionChecker2.cannot.create()) {
|
@@ -2674,7 +2712,7 @@ const singleTypes = {
|
|
2674
2712
|
}
|
2675
2713
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2676
2714
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2677
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2715
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2678
2716
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2679
2717
|
populate,
|
2680
2718
|
locale
|
@@ -2711,7 +2749,7 @@ const singleTypes = {
|
|
2711
2749
|
if (permissionChecker2.cannot.publish(document)) {
|
2712
2750
|
throw new strapiUtils.errors.ForbiddenError();
|
2713
2751
|
}
|
2714
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2752
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2715
2753
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2716
2754
|
return publishResult.at(0);
|
2717
2755
|
});
|
@@ -2734,7 +2772,7 @@ const singleTypes = {
|
|
2734
2772
|
return ctx.forbidden();
|
2735
2773
|
}
|
2736
2774
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2737
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2775
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2738
2776
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2739
2777
|
if (!document) {
|
2740
2778
|
return ctx.notFound();
|
@@ -2766,7 +2804,7 @@ const singleTypes = {
|
|
2766
2804
|
return ctx.forbidden();
|
2767
2805
|
}
|
2768
2806
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2769
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2807
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2770
2808
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2771
2809
|
if (!document) {
|
2772
2810
|
return ctx.notFound();
|
@@ -2786,7 +2824,7 @@ const singleTypes = {
|
|
2786
2824
|
const { query } = ctx.request;
|
2787
2825
|
const documentManager2 = getService$1("document-manager");
|
2788
2826
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2789
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2827
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2790
2828
|
if (permissionChecker2.cannot.read()) {
|
2791
2829
|
return ctx.forbidden();
|
2792
2830
|
}
|
@@ -2807,7 +2845,7 @@ const uid$1 = {
|
|
2807
2845
|
async generateUID(ctx) {
|
2808
2846
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2809
2847
|
const { query = {} } = ctx.request;
|
2810
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2848
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2811
2849
|
await validateUIDField(contentTypeUID, field);
|
2812
2850
|
const uidService = getService$1("uid");
|
2813
2851
|
ctx.body = {
|
@@ -2819,7 +2857,7 @@ const uid$1 = {
|
|
2819
2857
|
ctx.request.body
|
2820
2858
|
);
|
2821
2859
|
const { query = {} } = ctx.request;
|
2822
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2860
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2823
2861
|
await validateUIDField(contentTypeUID, field);
|
2824
2862
|
const uidService = getService$1("uid");
|
2825
2863
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3462,12 +3500,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3462
3500
|
ability: userAbility,
|
3463
3501
|
model
|
3464
3502
|
});
|
3465
|
-
const
|
3503
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3504
|
+
const toSubject = (entity) => {
|
3505
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3506
|
+
};
|
3466
3507
|
const can = (action, entity, field) => {
|
3467
|
-
|
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
|
+
);
|
3468
3515
|
};
|
3469
3516
|
const cannot = (action, entity, field) => {
|
3470
|
-
|
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
|
+
);
|
3471
3524
|
};
|
3472
3525
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3473
3526
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3744,6 +3797,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3744
3797
|
const attribute = model.attributes[attributeName];
|
3745
3798
|
switch (attribute.type) {
|
3746
3799
|
case "relation": {
|
3800
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
3801
|
+
if (isMorphRelation) {
|
3802
|
+
break;
|
3803
|
+
}
|
3747
3804
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3748
3805
|
populateAcc[attributeName] = {
|
3749
3806
|
count: true,
|
@@ -4121,7 +4178,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4121
4178
|
*/
|
4122
4179
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4123
4180
|
if (!document) {
|
4124
|
-
return
|
4181
|
+
return {
|
4182
|
+
data: document,
|
4183
|
+
meta: {
|
4184
|
+
availableLocales: [],
|
4185
|
+
availableStatus: []
|
4186
|
+
}
|
4187
|
+
};
|
4125
4188
|
}
|
4126
4189
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4127
4190
|
if (!hasDraftAndPublish) {
|
@@ -4229,10 +4292,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4229
4292
|
async clone(id, body, uid2) {
|
4230
4293
|
const populate = await buildDeepPopulate(uid2);
|
4231
4294
|
const params = {
|
4232
|
-
data:
|
4233
|
-
...omitIdField(body),
|
4234
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4235
|
-
},
|
4295
|
+
data: omitIdField(body),
|
4236
4296
|
populate
|
4237
4297
|
};
|
4238
4298
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|