@strapi/content-manager 0.0.0-experimental.7afdc9b682bc83a53ce599c4fb7c9e4506b31fff → 0.0.0-experimental.81dfdf02b1367004c7deed9e01afa9d3a15d0fa5
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-DJcn1DrO.js → ComponentConfigurationPage-D_M8iBw5.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage-D_M8iBw5.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-qemkOlnj.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-qemkOlnj.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-BePwPuHy.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-BePwPuHy.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-CjUrEewK.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-CjUrEewK.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-B-RJeiJD.js} +57 -46
- package/dist/_chunks/EditViewPage-B-RJeiJD.js.map +1 -0
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-De8GyU8P.mjs} +58 -47
- package/dist/_chunks/EditViewPage-De8GyU8P.mjs.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-dq8Tg1M_.js} +514 -168
- package/dist/_chunks/Field-dq8Tg1M_.js.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-pb2o8uBe.mjs} +516 -170
- package/dist/_chunks/Field-pb2o8uBe.mjs.map +1 -0
- package/dist/_chunks/{Form-Bpig5rch.js → Form-DGIf4jQU.js} +38 -28
- package/dist/_chunks/Form-DGIf4jQU.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-DJn0Dxha.mjs} +40 -30
- package/dist/_chunks/Form-DJn0Dxha.mjs.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-BowL3JKP.mjs} +141 -37
- package/dist/_chunks/History-BowL3JKP.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-Dh2NEHnR.js} +140 -36
- package/dist/_chunks/History-Dh2NEHnR.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-BpVOB-hn.mjs} +58 -48
- package/dist/_chunks/ListConfigurationPage-BpVOB-hn.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-BxYCWz9e.js} +57 -46
- package/dist/_chunks/ListConfigurationPage-BxYCWz9e.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-4XsciqHZ.js} +65 -68
- package/dist/_chunks/ListViewPage-4XsciqHZ.js.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-CXFUjZQC.mjs} +67 -70
- package/dist/_chunks/ListViewPage-CXFUjZQC.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-C8OpoHeU.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-C8OpoHeU.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-DuhOTp3x.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-DuhOTp3x.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-DVz3mzDz.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-DVz3mzDz.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-y_r7DVA2.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-y_r7DVA2.js.map} +1 -1
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-CVNLrn1Y.mjs} +4 -4
- package/dist/_chunks/Relations-CVNLrn1Y.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-DPFCAa7b.js} +4 -4
- package/dist/_chunks/Relations-DPFCAa7b.js.map +1 -0
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-BrCTWlZv.mjs} +8 -4
- package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-BrCTWlZv.mjs.map} +1 -1
- package/dist/_chunks/{en-BN1bvFK7.js → en-uOUIxfcQ.js} +8 -4
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-uOUIxfcQ.js.map} +1 -1
- package/dist/_chunks/{index-DzN3kBgx.js → index-C3fJE-1-.js} +491 -431
- package/dist/_chunks/index-C3fJE-1-.js.map +1 -0
- package/dist/_chunks/{index-VHviNMeW.mjs → index-DiMrfcfy.mjs} +511 -451
- package/dist/_chunks/index-DiMrfcfy.mjs.map +1 -0
- package/dist/_chunks/{layout-b91XRlD2.js → layout-C788OmNr.js} +37 -20
- package/dist/_chunks/layout-C788OmNr.js.map +1 -0
- package/dist/_chunks/{layout-CPn1PM6x.mjs → layout-ls3gxfpH.mjs} +39 -22
- package/dist/_chunks/layout-ls3gxfpH.mjs.map +1 -0
- package/dist/_chunks/{relations-BsqxS6tR.mjs → relations-CLcOmGO0.mjs} +2 -2
- package/dist/_chunks/{relations-BsqxS6tR.mjs.map → relations-CLcOmGO0.mjs.map} +1 -1
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-DYeotliT.js} +2 -2
- package/dist/_chunks/{relations-CA7IYmcP.js.map → relations-DYeotliT.js.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +5 -5
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- 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 +8 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -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 +12 -32
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- 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 +164 -103
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +165 -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/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/_chunks/EditViewPage-CoQEnFlC.js.map +0 -1
- package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
- package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
- package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
- package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
- package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
- package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
- package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
- package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
- package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
- package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
- package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
- package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
- package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
- package/dist/_chunks/layout-b91XRlD2.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,13 +495,47 @@ 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,
|
496
537
|
isInitialized: false
|
497
538
|
};
|
498
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
499
|
-
const historyService = getService(strapi2, "history");
|
500
539
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
501
540
|
return {
|
502
541
|
async bootstrap() {
|
@@ -504,60 +543,43 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
504
543
|
return;
|
505
544
|
}
|
506
545
|
strapi2.documents.use(async (context, next) => {
|
507
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
508
|
-
return next();
|
509
|
-
}
|
510
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
511
|
-
return next();
|
512
|
-
}
|
513
|
-
const contentTypeUid = context.contentType.uid;
|
514
|
-
if (!contentTypeUid.startsWith("api::")) {
|
515
|
-
return next();
|
516
|
-
}
|
517
546
|
const result = await next();
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
547
|
+
if (!shouldCreateHistoryVersion(context)) {
|
548
|
+
return result;
|
549
|
+
}
|
550
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
522
551
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
523
|
-
const
|
524
|
-
if (
|
525
|
-
|
526
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
527
|
-
);
|
528
|
-
return next();
|
552
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
553
|
+
if (!locales.length) {
|
554
|
+
return result;
|
529
555
|
}
|
530
|
-
const
|
531
|
-
|
532
|
-
|
533
|
-
|
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
|
+
)
|
534
569
|
});
|
535
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
536
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
537
|
-
const componentsSchemas = Object.keys(
|
538
|
-
attributesSchema
|
539
|
-
).reduce((currentComponentSchemas, key) => {
|
540
|
-
const fieldSchema = attributesSchema[key];
|
541
|
-
if (fieldSchema.type === "component") {
|
542
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
543
|
-
return {
|
544
|
-
...currentComponentSchemas,
|
545
|
-
[fieldSchema.component]: componentSchema
|
546
|
-
};
|
547
|
-
}
|
548
|
-
return currentComponentSchemas;
|
549
|
-
}, {});
|
550
570
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
551
|
-
onCommit(() => {
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
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
|
+
}
|
561
583
|
});
|
562
584
|
});
|
563
585
|
return result;
|
@@ -565,7 +587,7 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
565
587
|
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
566
588
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
567
589
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
568
|
-
query.deleteMany({
|
590
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
569
591
|
where: {
|
570
592
|
created_at: {
|
571
593
|
$lt: expirationDate.toISOString()
|
@@ -1197,6 +1219,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1197
1219
|
const hasPermissions = createPolicy({
|
1198
1220
|
name: "plugin::content-manager.hasPermissions",
|
1199
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
|
+
*/
|
1200
1227
|
handler(ctx, config = {}) {
|
1201
1228
|
const { actions = [], hasAtLeastOne = false } = config;
|
1202
1229
|
const { userAbility } = ctx.state;
|
@@ -1590,9 +1617,11 @@ const multipleLocaleSchema = strapiUtils.yup.lazy(
|
|
1590
1617
|
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1591
1618
|
);
|
1592
1619
|
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1593
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1620
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1594
1621
|
const { allowMultipleLocales } = opts;
|
1595
|
-
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;
|
1596
1625
|
const schema = strapiUtils.yup.object().shape({
|
1597
1626
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1598
1627
|
status: statusSchema
|
@@ -1640,7 +1669,7 @@ const createDocument = async (ctx, opts) => {
|
|
1640
1669
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1641
1670
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1642
1671
|
const sanitizedBody = await sanitizeFn(body);
|
1643
|
-
const { locale, status
|
1672
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1644
1673
|
return documentManager2.create(model, {
|
1645
1674
|
data: sanitizedBody,
|
1646
1675
|
locale,
|
@@ -1659,7 +1688,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1659
1688
|
}
|
1660
1689
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1661
1690
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1662
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1691
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1663
1692
|
const [documentVersion, documentExists] = await Promise.all([
|
1664
1693
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1665
1694
|
documentManager2.exists(model, id)
|
@@ -1697,7 +1726,7 @@ const collectionTypes = {
|
|
1697
1726
|
}
|
1698
1727
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1699
1728
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1700
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1729
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1701
1730
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1702
1731
|
{ ...permissionQuery, populate, locale, status },
|
1703
1732
|
model
|
@@ -1732,7 +1761,7 @@ const collectionTypes = {
|
|
1732
1761
|
}
|
1733
1762
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1734
1763
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1735
|
-
const { locale, status
|
1764
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1736
1765
|
const version = await documentManager2.findOne(id, model, {
|
1737
1766
|
populate,
|
1738
1767
|
locale,
|
@@ -1799,7 +1828,7 @@ const collectionTypes = {
|
|
1799
1828
|
}
|
1800
1829
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1801
1830
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1802
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1831
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1803
1832
|
const document = await documentManager2.findOne(id, model, {
|
1804
1833
|
populate,
|
1805
1834
|
locale,
|
@@ -1844,7 +1873,7 @@ const collectionTypes = {
|
|
1844
1873
|
}
|
1845
1874
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1846
1875
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1847
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1876
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1848
1877
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1849
1878
|
if (documentLocales.length === 0) {
|
1850
1879
|
return ctx.notFound();
|
@@ -1873,11 +1902,28 @@ const collectionTypes = {
|
|
1873
1902
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1874
1903
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1875
1904
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1876
|
-
|
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
|
+
}
|
1877
1924
|
if (permissionChecker2.cannot.publish(document)) {
|
1878
1925
|
throw new strapiUtils.errors.ForbiddenError();
|
1879
1926
|
}
|
1880
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1881
1927
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1882
1928
|
locale
|
1883
1929
|
// TODO: Allow setting creator fields on publish
|
@@ -1904,7 +1950,9 @@ const collectionTypes = {
|
|
1904
1950
|
}
|
1905
1951
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1906
1952
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1907
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
1953
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1954
|
+
allowMultipleLocales: true
|
1955
|
+
});
|
1908
1956
|
const entityPromises = documentIds.map(
|
1909
1957
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1910
1958
|
);
|
@@ -1931,7 +1979,7 @@ const collectionTypes = {
|
|
1931
1979
|
if (permissionChecker2.cannot.unpublish()) {
|
1932
1980
|
return ctx.forbidden();
|
1933
1981
|
}
|
1934
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1982
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1935
1983
|
const entityPromises = documentIds.map(
|
1936
1984
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1937
1985
|
);
|
@@ -1964,7 +2012,7 @@ const collectionTypes = {
|
|
1964
2012
|
}
|
1965
2013
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1966
2014
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1967
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2015
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1968
2016
|
const document = await documentManager2.findOne(id, model, {
|
1969
2017
|
populate,
|
1970
2018
|
locale,
|
@@ -2001,7 +2049,7 @@ const collectionTypes = {
|
|
2001
2049
|
}
|
2002
2050
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2003
2051
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2004
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2052
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2005
2053
|
const document = await documentManager2.findOne(id, model, {
|
2006
2054
|
populate,
|
2007
2055
|
locale,
|
@@ -2032,7 +2080,7 @@ const collectionTypes = {
|
|
2032
2080
|
}
|
2033
2081
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2034
2082
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2035
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2083
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2036
2084
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2037
2085
|
populate,
|
2038
2086
|
locale
|
@@ -2059,7 +2107,7 @@ const collectionTypes = {
|
|
2059
2107
|
}
|
2060
2108
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2061
2109
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2062
|
-
const { locale, status
|
2110
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2063
2111
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2064
2112
|
if (!entity) {
|
2065
2113
|
return ctx.notFound();
|
@@ -2282,20 +2330,13 @@ const sanitizeMainField = (model, mainField, userAbility) => {
|
|
2282
2330
|
userAbility,
|
2283
2331
|
model: model.uid
|
2284
2332
|
});
|
2285
|
-
|
2333
|
+
const isMainFieldListable = isListable(model, mainField);
|
2334
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2335
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2286
2336
|
return "id";
|
2287
2337
|
}
|
2288
|
-
if (
|
2289
|
-
|
2290
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2291
|
-
userAbility,
|
2292
|
-
model: "plugin::users-permissions.user"
|
2293
|
-
});
|
2294
|
-
if (userPermissionChecker.can.read()) {
|
2295
|
-
return "name";
|
2296
|
-
}
|
2297
|
-
}
|
2298
|
-
return "id";
|
2338
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2339
|
+
return "name";
|
2299
2340
|
}
|
2300
2341
|
return mainField;
|
2301
2342
|
};
|
@@ -2553,9 +2594,7 @@ const relations = {
|
|
2553
2594
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2554
2595
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2555
2596
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2556
|
-
ordering: "desc"
|
2557
|
-
page: ctx.request.query.page,
|
2558
|
-
pageSize: ctx.request.query.pageSize
|
2597
|
+
ordering: "desc"
|
2559
2598
|
});
|
2560
2599
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2561
2600
|
ctx.body = {
|
@@ -2587,7 +2626,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2587
2626
|
throw new strapiUtils.errors.ForbiddenError();
|
2588
2627
|
}
|
2589
2628
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2590
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2629
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2591
2630
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2592
2631
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2593
2632
|
// Find the first document to check if it exists
|
@@ -2628,7 +2667,7 @@ const singleTypes = {
|
|
2628
2667
|
return ctx.forbidden();
|
2629
2668
|
}
|
2630
2669
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2631
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2670
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2632
2671
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2633
2672
|
if (!version) {
|
2634
2673
|
if (permissionChecker2.cannot.create()) {
|
@@ -2673,7 +2712,7 @@ const singleTypes = {
|
|
2673
2712
|
}
|
2674
2713
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2675
2714
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2676
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2715
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2677
2716
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2678
2717
|
populate,
|
2679
2718
|
locale
|
@@ -2710,7 +2749,7 @@ const singleTypes = {
|
|
2710
2749
|
if (permissionChecker2.cannot.publish(document)) {
|
2711
2750
|
throw new strapiUtils.errors.ForbiddenError();
|
2712
2751
|
}
|
2713
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2752
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2714
2753
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2715
2754
|
return publishResult.at(0);
|
2716
2755
|
});
|
@@ -2733,7 +2772,7 @@ const singleTypes = {
|
|
2733
2772
|
return ctx.forbidden();
|
2734
2773
|
}
|
2735
2774
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2736
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2775
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2737
2776
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2738
2777
|
if (!document) {
|
2739
2778
|
return ctx.notFound();
|
@@ -2765,7 +2804,7 @@ const singleTypes = {
|
|
2765
2804
|
return ctx.forbidden();
|
2766
2805
|
}
|
2767
2806
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2768
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2807
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2769
2808
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2770
2809
|
if (!document) {
|
2771
2810
|
return ctx.notFound();
|
@@ -2785,7 +2824,7 @@ const singleTypes = {
|
|
2785
2824
|
const { query } = ctx.request;
|
2786
2825
|
const documentManager2 = getService$1("document-manager");
|
2787
2826
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2788
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2827
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2789
2828
|
if (permissionChecker2.cannot.read()) {
|
2790
2829
|
return ctx.forbidden();
|
2791
2830
|
}
|
@@ -2806,7 +2845,7 @@ const uid$1 = {
|
|
2806
2845
|
async generateUID(ctx) {
|
2807
2846
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2808
2847
|
const { query = {} } = ctx.request;
|
2809
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2848
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2810
2849
|
await validateUIDField(contentTypeUID, field);
|
2811
2850
|
const uidService = getService$1("uid");
|
2812
2851
|
ctx.body = {
|
@@ -2818,7 +2857,7 @@ const uid$1 = {
|
|
2818
2857
|
ctx.request.body
|
2819
2858
|
);
|
2820
2859
|
const { query = {} } = ctx.request;
|
2821
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2860
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2822
2861
|
await validateUIDField(contentTypeUID, field);
|
2823
2862
|
const uidService = getService$1("uid");
|
2824
2863
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3461,12 +3500,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3461
3500
|
ability: userAbility,
|
3462
3501
|
model
|
3463
3502
|
});
|
3464
|
-
const
|
3503
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3504
|
+
const toSubject = (entity) => {
|
3505
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3506
|
+
};
|
3465
3507
|
const can = (action, entity, field) => {
|
3466
|
-
|
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
|
+
);
|
3467
3515
|
};
|
3468
3516
|
const cannot = (action, entity, field) => {
|
3469
|
-
|
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
|
+
);
|
3470
3524
|
};
|
3471
3525
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3472
3526
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3743,6 +3797,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3743
3797
|
const attribute = model.attributes[attributeName];
|
3744
3798
|
switch (attribute.type) {
|
3745
3799
|
case "relation": {
|
3800
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
3801
|
+
if (isMorphRelation) {
|
3802
|
+
break;
|
3803
|
+
}
|
3746
3804
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3747
3805
|
populateAcc[attributeName] = {
|
3748
3806
|
count: true,
|
@@ -4120,7 +4178,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4120
4178
|
*/
|
4121
4179
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4122
4180
|
if (!document) {
|
4123
|
-
return
|
4181
|
+
return {
|
4182
|
+
data: document,
|
4183
|
+
meta: {
|
4184
|
+
availableLocales: [],
|
4185
|
+
availableStatus: []
|
4186
|
+
}
|
4187
|
+
};
|
4124
4188
|
}
|
4125
4189
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4126
4190
|
if (!hasDraftAndPublish) {
|
@@ -4228,10 +4292,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4228
4292
|
async clone(id, body, uid2) {
|
4229
4293
|
const populate = await buildDeepPopulate(uid2);
|
4230
4294
|
const params = {
|
4231
|
-
data:
|
4232
|
-
...omitIdField(body),
|
4233
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4234
|
-
},
|
4295
|
+
data: omitIdField(body),
|
4235
4296
|
populate
|
4236
4297
|
};
|
4237
4298
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|