@strapi/content-manager 0.0.0-experimental.d53e940834bf72ddc725f1d2fd36dac9abec30cb → 0.0.0-experimental.d65615a2b9130dd742d3c396674457d7971da928
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-CO977CPh.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-CO977CPh.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs → ComponentConfigurationPage-CQroR9Qk.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-CQroR9Qk.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-BPgoE-kf.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-BPgoE-kf.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-tVCJ5vWC.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-tVCJ5vWC.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-8mOu02ji.mjs} +30 -9
- package/dist/_chunks/EditViewPage-8mOu02ji.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-BMVgUNOX.js} +30 -9
- package/dist/_chunks/EditViewPage-BMVgUNOX.js.map +1 -0
- package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-CJPYzwD7.mjs} +249 -152
- package/dist/_chunks/Field-CJPYzwD7.mjs.map +1 -0
- package/dist/_chunks/{Field-Boxf9Ajp.js → Field-CdSLKFQk.js} +251 -154
- package/dist/_chunks/Field-CdSLKFQk.js.map +1 -0
- package/dist/_chunks/{Form-DHrru2AV.mjs → Form-DJOJ-GF1.mjs} +36 -17
- package/dist/_chunks/Form-DJOJ-GF1.mjs.map +1 -0
- package/dist/_chunks/{Form-y5g1SRsh.js → Form-eP5bZwap.js} +36 -17
- package/dist/_chunks/Form-eP5bZwap.js.map +1 -0
- package/dist/_chunks/{History-CqN6K7SX.js → History-B-Mrquzu.js} +63 -25
- package/dist/_chunks/History-B-Mrquzu.js.map +1 -0
- package/dist/_chunks/{History-Bru_KoeP.mjs → History-MnQLtk1g.mjs} +64 -26
- package/dist/_chunks/History-MnQLtk1g.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-BcycI8Lw.mjs} +21 -9
- package/dist/_chunks/ListConfigurationPage-BcycI8Lw.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-C0n4rUzH.js} +21 -9
- package/dist/_chunks/ListConfigurationPage-C0n4rUzH.js.map +1 -0
- package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-CRXONXwZ.mjs} +59 -41
- package/dist/_chunks/ListViewPage-CRXONXwZ.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-q0SHVPUS.js} +61 -43
- package/dist/_chunks/ListViewPage-q0SHVPUS.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-Bh3komDV.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-Bh3komDV.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-ukzFRF3z.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-ukzFRF3z.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-B4sD7Ble.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-B4sD7Ble.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-BGBpj_Y1.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-BGBpj_Y1.js.map} +1 -1
- package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-B53wYe8g.js} +33 -24
- package/dist/_chunks/Relations-B53wYe8g.js.map +1 -0
- package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-CIexb8gr.mjs} +33 -24
- package/dist/_chunks/Relations-CIexb8gr.mjs.map +1 -0
- package/dist/_chunks/{en-fbKQxLGn.js → en-Bm0D0IWz.js} +17 -15
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-Bm0D0IWz.js.map} +1 -1
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-DKV44jRb.mjs} +17 -15
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-DKV44jRb.mjs.map} +1 -1
- package/dist/_chunks/{index-DJXJw9V5.mjs → index-CJ2vYwuT.mjs} +997 -690
- package/dist/_chunks/index-CJ2vYwuT.mjs.map +1 -0
- package/dist/_chunks/{index-DVPWZkbS.js → index-DbT2sx-Q.js} +978 -671
- package/dist/_chunks/index-DbT2sx-Q.js.map +1 -0
- package/dist/_chunks/{layout-Dm6fbiQj.js → layout-CeBSIkmP.js} +24 -11
- package/dist/_chunks/layout-CeBSIkmP.js.map +1 -0
- package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-vzKSrr7p.mjs} +25 -12
- package/dist/_chunks/layout-vzKSrr7p.mjs.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-CKnpRgrN.js → relations-Cl-6t9iz.js} +2 -2
- package/dist/_chunks/{relations-CKnpRgrN.js.map → relations-Cl-6t9iz.js.map} +1 -1
- package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-DI0lguF0.mjs} +2 -2
- package/dist/_chunks/{relations-BH_kBSJ0.mjs.map → relations-DI0lguF0.mjs.map} +1 -1
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.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/hooks/useDocument.d.ts +32 -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 +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- 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 +19 -17
- 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 +207 -120
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +208 -121
- 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/history.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 +2 -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/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/package.json +12 -12
- 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/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat,
|
2
|
+
import { pick, omit, difference, castArray, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -173,7 +173,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
173
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
174
|
};
|
175
175
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
176
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
177
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
178
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
179
|
const getLocaleDictionary = async () => {
|
178
180
|
if (!localesService)
|
179
181
|
return {};
|
@@ -200,20 +202,25 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
202
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
203
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
204
|
};
|
203
|
-
const getDeepPopulate2 = (uid2) => {
|
205
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
206
|
const model = strapi2.getModel(uid2);
|
205
207
|
const attributes = Object.entries(model.attributes);
|
208
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
209
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
210
|
switch (attribute.type) {
|
208
211
|
case "relation": {
|
212
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
213
|
+
if (isMorphRelation) {
|
214
|
+
break;
|
215
|
+
}
|
209
216
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
210
217
|
if (isVisible2) {
|
211
|
-
acc[attributeName] = {
|
218
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
212
219
|
}
|
213
220
|
break;
|
214
221
|
}
|
215
222
|
case "media": {
|
216
|
-
acc[attributeName] = {
|
223
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
217
224
|
break;
|
218
225
|
}
|
219
226
|
case "component": {
|
@@ -286,6 +293,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
286
293
|
getRelationRestoreValue,
|
287
294
|
getMediaRestoreValue,
|
288
295
|
getDefaultLocale,
|
296
|
+
isLocalizedContentType,
|
289
297
|
getLocaleDictionary,
|
290
298
|
getRetentionDays,
|
291
299
|
getVersionStatus,
|
@@ -308,7 +316,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
308
316
|
});
|
309
317
|
},
|
310
318
|
async findVersionsPage(params) {
|
311
|
-
const
|
319
|
+
const model = strapi2.getModel(params.query.contentType);
|
320
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
321
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
322
|
+
let locale = null;
|
323
|
+
if (isLocalizedContentType) {
|
324
|
+
locale = params.query.locale || defaultLocale;
|
325
|
+
}
|
312
326
|
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
313
327
|
query.findPage({
|
314
328
|
...params.query,
|
@@ -353,7 +367,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
353
367
|
if (userToPopulate == null) {
|
354
368
|
return null;
|
355
369
|
}
|
356
|
-
return strapi2.query("admin::user").findOne({
|
370
|
+
return strapi2.query("admin::user").findOne({
|
371
|
+
where: {
|
372
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
373
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
374
|
+
}
|
375
|
+
});
|
357
376
|
})
|
358
377
|
);
|
359
378
|
return {
|
@@ -464,6 +483,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
464
483
|
}
|
465
484
|
};
|
466
485
|
};
|
486
|
+
const shouldCreateHistoryVersion = (context) => {
|
487
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
488
|
+
return false;
|
489
|
+
}
|
490
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
491
|
+
return false;
|
492
|
+
}
|
493
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
494
|
+
return false;
|
495
|
+
}
|
496
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
497
|
+
return false;
|
498
|
+
}
|
499
|
+
return true;
|
500
|
+
};
|
501
|
+
const getSchemas = (uid2) => {
|
502
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
503
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
504
|
+
(currentComponentSchemas, key) => {
|
505
|
+
const fieldSchema = attributesSchema[key];
|
506
|
+
if (fieldSchema.type === "component") {
|
507
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
508
|
+
return {
|
509
|
+
...currentComponentSchemas,
|
510
|
+
[fieldSchema.component]: componentSchema
|
511
|
+
};
|
512
|
+
}
|
513
|
+
return currentComponentSchemas;
|
514
|
+
},
|
515
|
+
{}
|
516
|
+
);
|
517
|
+
return {
|
518
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
519
|
+
componentsSchemas
|
520
|
+
};
|
521
|
+
};
|
467
522
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
468
523
|
const state = {
|
469
524
|
deleteExpiredJob: null,
|
@@ -476,63 +531,45 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
476
531
|
return;
|
477
532
|
}
|
478
533
|
strapi2.documents.use(async (context, next) => {
|
479
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
480
|
-
return next();
|
481
|
-
}
|
482
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
483
|
-
return next();
|
484
|
-
}
|
485
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
486
|
-
return next();
|
487
|
-
}
|
488
|
-
const contentTypeUid = context.contentType.uid;
|
489
|
-
if (!contentTypeUid.startsWith("api::")) {
|
490
|
-
return next();
|
491
|
-
}
|
492
534
|
const result = await next();
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
535
|
+
if (!shouldCreateHistoryVersion(context)) {
|
536
|
+
return result;
|
537
|
+
}
|
538
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
497
539
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
498
|
-
const
|
499
|
-
if (
|
500
|
-
|
501
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
502
|
-
);
|
503
|
-
return next();
|
540
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
541
|
+
if (!locales.length) {
|
542
|
+
return result;
|
504
543
|
}
|
505
|
-
const
|
506
|
-
|
507
|
-
|
508
|
-
|
544
|
+
const uid2 = context.contentType.uid;
|
545
|
+
const schemas = getSchemas(uid2);
|
546
|
+
const model = strapi2.getModel(uid2);
|
547
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
548
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
549
|
+
where: {
|
550
|
+
documentId,
|
551
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
552
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
553
|
+
},
|
554
|
+
populate: serviceUtils.getDeepPopulate(
|
555
|
+
uid2,
|
556
|
+
true
|
557
|
+
/* use database syntax */
|
558
|
+
)
|
509
559
|
});
|
510
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
511
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
512
|
-
const componentsSchemas = Object.keys(
|
513
|
-
attributesSchema
|
514
|
-
).reduce((currentComponentSchemas, key) => {
|
515
|
-
const fieldSchema = attributesSchema[key];
|
516
|
-
if (fieldSchema.type === "component") {
|
517
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
518
|
-
return {
|
519
|
-
...currentComponentSchemas,
|
520
|
-
[fieldSchema.component]: componentSchema
|
521
|
-
};
|
522
|
-
}
|
523
|
-
return currentComponentSchemas;
|
524
|
-
}, {});
|
525
560
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
526
|
-
onCommit(() => {
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
561
|
+
onCommit(async () => {
|
562
|
+
for (const entry of localeEntries) {
|
563
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
564
|
+
await getService(strapi2, "history").createVersion({
|
565
|
+
contentType: uid2,
|
566
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
567
|
+
relatedDocumentId: documentId,
|
568
|
+
locale: entry.locale,
|
569
|
+
status,
|
570
|
+
...schemas
|
571
|
+
});
|
572
|
+
}
|
536
573
|
});
|
537
574
|
});
|
538
575
|
return result;
|
@@ -1172,6 +1209,11 @@ const { createPolicy } = policy;
|
|
1172
1209
|
const hasPermissions = createPolicy({
|
1173
1210
|
name: "plugin::content-manager.hasPermissions",
|
1174
1211
|
validator: validateHasPermissionsInput,
|
1212
|
+
/**
|
1213
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1214
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1215
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1216
|
+
*/
|
1175
1217
|
handler(ctx, config = {}) {
|
1176
1218
|
const { actions = [], hasAtLeastOne = false } = config;
|
1177
1219
|
const { userAbility } = ctx.state;
|
@@ -1565,9 +1607,11 @@ const multipleLocaleSchema = yup$1.lazy(
|
|
1565
1607
|
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1566
1608
|
);
|
1567
1609
|
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1568
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1610
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1569
1611
|
const { allowMultipleLocales } = opts;
|
1570
|
-
const { locale, status, ...rest } = request || {};
|
1612
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1613
|
+
const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1614
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1571
1615
|
const schema = yup$1.object().shape({
|
1572
1616
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1573
1617
|
status: statusSchema
|
@@ -1615,7 +1659,7 @@ const createDocument = async (ctx, opts) => {
|
|
1615
1659
|
const setCreator = setCreatorFields({ user });
|
1616
1660
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1617
1661
|
const sanitizedBody = await sanitizeFn(body);
|
1618
|
-
const { locale, status
|
1662
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1619
1663
|
return documentManager2.create(model, {
|
1620
1664
|
data: sanitizedBody,
|
1621
1665
|
locale,
|
@@ -1634,7 +1678,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1634
1678
|
}
|
1635
1679
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1636
1680
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1637
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1681
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1638
1682
|
const [documentVersion, documentExists] = await Promise.all([
|
1639
1683
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1640
1684
|
documentManager2.exists(model, id)
|
@@ -1650,7 +1694,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1650
1694
|
throw new errors.ForbiddenError();
|
1651
1695
|
}
|
1652
1696
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1653
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1697
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1654
1698
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1655
1699
|
const sanitizedBody = await sanitizeFn(body);
|
1656
1700
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1672,7 +1716,7 @@ const collectionTypes = {
|
|
1672
1716
|
}
|
1673
1717
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1674
1718
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1675
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1719
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1676
1720
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1677
1721
|
{ ...permissionQuery, populate, locale, status },
|
1678
1722
|
model
|
@@ -1707,7 +1751,7 @@ const collectionTypes = {
|
|
1707
1751
|
}
|
1708
1752
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1709
1753
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1710
|
-
const { locale, status
|
1754
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1711
1755
|
const version = await documentManager2.findOne(id, model, {
|
1712
1756
|
populate,
|
1713
1757
|
locale,
|
@@ -1722,7 +1766,7 @@ const collectionTypes = {
|
|
1722
1766
|
permissionChecker2,
|
1723
1767
|
model,
|
1724
1768
|
// @ts-expect-error TODO: fix
|
1725
|
-
{ id, locale, publishedAt: null },
|
1769
|
+
{ documentId: id, locale, publishedAt: null },
|
1726
1770
|
{ availableLocales: true, availableStatus: false }
|
1727
1771
|
);
|
1728
1772
|
ctx.body = { data: {}, meta };
|
@@ -1774,7 +1818,7 @@ const collectionTypes = {
|
|
1774
1818
|
}
|
1775
1819
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1776
1820
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1777
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1821
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1778
1822
|
const document = await documentManager2.findOne(id, model, {
|
1779
1823
|
populate,
|
1780
1824
|
locale,
|
@@ -1819,7 +1863,7 @@ const collectionTypes = {
|
|
1819
1863
|
}
|
1820
1864
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1821
1865
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1822
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
1866
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1823
1867
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1824
1868
|
if (documentLocales.length === 0) {
|
1825
1869
|
return ctx.notFound();
|
@@ -1848,11 +1892,34 @@ const collectionTypes = {
|
|
1848
1892
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1849
1893
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1850
1894
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1851
|
-
|
1895
|
+
let document;
|
1896
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1897
|
+
const isCreate = isNil$1(id);
|
1898
|
+
if (isCreate) {
|
1899
|
+
if (permissionChecker2.cannot.create()) {
|
1900
|
+
throw new errors.ForbiddenError();
|
1901
|
+
}
|
1902
|
+
document = await createDocument(ctx, { populate });
|
1903
|
+
}
|
1904
|
+
const isUpdate = !isCreate;
|
1905
|
+
if (isUpdate) {
|
1906
|
+
const documentExists = documentManager2.exists(model, id);
|
1907
|
+
if (!documentExists) {
|
1908
|
+
throw new errors.NotFoundError("Document not found");
|
1909
|
+
}
|
1910
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
1911
|
+
if (!document) {
|
1912
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
1913
|
+
throw new errors.ForbiddenError();
|
1914
|
+
}
|
1915
|
+
document = await updateDocument(ctx);
|
1916
|
+
} else if (permissionChecker2.can.update(document)) {
|
1917
|
+
await updateDocument(ctx);
|
1918
|
+
}
|
1919
|
+
}
|
1852
1920
|
if (permissionChecker2.cannot.publish(document)) {
|
1853
1921
|
throw new errors.ForbiddenError();
|
1854
1922
|
}
|
1855
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1856
1923
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1857
1924
|
locale
|
1858
1925
|
// TODO: Allow setting creator fields on publish
|
@@ -1879,7 +1946,9 @@ const collectionTypes = {
|
|
1879
1946
|
}
|
1880
1947
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1881
1948
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1882
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
1949
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1950
|
+
allowMultipleLocales: true
|
1951
|
+
});
|
1883
1952
|
const entityPromises = documentIds.map(
|
1884
1953
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1885
1954
|
);
|
@@ -1906,7 +1975,9 @@ const collectionTypes = {
|
|
1906
1975
|
if (permissionChecker2.cannot.unpublish()) {
|
1907
1976
|
return ctx.forbidden();
|
1908
1977
|
}
|
1909
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
1978
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1979
|
+
allowMultipleLocales: true
|
1980
|
+
});
|
1910
1981
|
const entityPromises = documentIds.map(
|
1911
1982
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1912
1983
|
);
|
@@ -1939,7 +2010,7 @@ const collectionTypes = {
|
|
1939
2010
|
}
|
1940
2011
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1941
2012
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1942
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2013
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1943
2014
|
const document = await documentManager2.findOne(id, model, {
|
1944
2015
|
populate,
|
1945
2016
|
locale,
|
@@ -1976,7 +2047,7 @@ const collectionTypes = {
|
|
1976
2047
|
}
|
1977
2048
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1978
2049
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1979
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2050
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1980
2051
|
const document = await documentManager2.findOne(id, model, {
|
1981
2052
|
populate,
|
1982
2053
|
locale,
|
@@ -2007,7 +2078,7 @@ const collectionTypes = {
|
|
2007
2078
|
}
|
2008
2079
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2009
2080
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2010
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2081
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2011
2082
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2012
2083
|
populate,
|
2013
2084
|
locale
|
@@ -2034,7 +2105,7 @@ const collectionTypes = {
|
|
2034
2105
|
}
|
2035
2106
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2036
2107
|
const populate = await getService$1("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2037
|
-
const { locale, status
|
2108
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2038
2109
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2039
2110
|
if (!entity) {
|
2040
2111
|
return ctx.notFound();
|
@@ -2057,7 +2128,7 @@ const collectionTypes = {
|
|
2057
2128
|
if (permissionChecker2.cannot.read()) {
|
2058
2129
|
return ctx.forbidden();
|
2059
2130
|
}
|
2060
|
-
const
|
2131
|
+
const documents = await documentManager2.findMany(
|
2061
2132
|
{
|
2062
2133
|
filters: {
|
2063
2134
|
documentId: ids
|
@@ -2066,7 +2137,7 @@ const collectionTypes = {
|
|
2066
2137
|
},
|
2067
2138
|
model
|
2068
2139
|
);
|
2069
|
-
if (!
|
2140
|
+
if (!documents) {
|
2070
2141
|
return ctx.notFound();
|
2071
2142
|
}
|
2072
2143
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2257,20 +2328,13 @@ const sanitizeMainField = (model, mainField, userAbility) => {
|
|
2257
2328
|
userAbility,
|
2258
2329
|
model: model.uid
|
2259
2330
|
});
|
2260
|
-
|
2331
|
+
const isMainFieldListable = isListable(model, mainField);
|
2332
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2333
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2261
2334
|
return "id";
|
2262
2335
|
}
|
2263
|
-
if (
|
2264
|
-
|
2265
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2266
|
-
userAbility,
|
2267
|
-
model: "plugin::users-permissions.user"
|
2268
|
-
});
|
2269
|
-
if (userPermissionChecker.can.read()) {
|
2270
|
-
return "name";
|
2271
|
-
}
|
2272
|
-
}
|
2273
|
-
return "id";
|
2336
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2337
|
+
return "name";
|
2274
2338
|
}
|
2275
2339
|
return mainField;
|
2276
2340
|
};
|
@@ -2303,11 +2367,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2303
2367
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2304
2368
|
const isSourceLocalized = isLocalized(sourceModel);
|
2305
2369
|
const isTargetLocalized = isLocalized(targetModel);
|
2306
|
-
let validatedLocale = locale;
|
2307
|
-
if (!targetModel || !isTargetLocalized)
|
2308
|
-
validatedLocale = void 0;
|
2309
2370
|
return {
|
2310
|
-
locale
|
2371
|
+
locale,
|
2311
2372
|
isSourceLocalized,
|
2312
2373
|
isTargetLocalized
|
2313
2374
|
};
|
@@ -2410,7 +2471,7 @@ const relations = {
|
|
2410
2471
|
attribute,
|
2411
2472
|
fieldsToSelect,
|
2412
2473
|
mainField,
|
2413
|
-
source: { schema: sourceSchema },
|
2474
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2414
2475
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2415
2476
|
sourceSchema,
|
2416
2477
|
targetSchema,
|
@@ -2432,7 +2493,8 @@ const relations = {
|
|
2432
2493
|
fieldsToSelect,
|
2433
2494
|
mainField,
|
2434
2495
|
source: {
|
2435
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2496
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2497
|
+
isLocalized: isSourceLocalized
|
2436
2498
|
},
|
2437
2499
|
target: {
|
2438
2500
|
schema: { uid: targetUid },
|
@@ -2470,12 +2532,16 @@ const relations = {
|
|
2470
2532
|
} else {
|
2471
2533
|
where.id = id;
|
2472
2534
|
}
|
2473
|
-
|
2474
|
-
|
2535
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2536
|
+
if (!isEmpty(publishedAt)) {
|
2537
|
+
where[`${alias}.published_at`] = publishedAt;
|
2475
2538
|
}
|
2476
|
-
if (
|
2539
|
+
if (isTargetLocalized && locale) {
|
2477
2540
|
where[`${alias}.locale`] = locale;
|
2478
2541
|
}
|
2542
|
+
if (isSourceLocalized && locale) {
|
2543
|
+
where.locale = locale;
|
2544
|
+
}
|
2479
2545
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2480
2546
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2481
2547
|
}
|
@@ -2493,7 +2559,8 @@ const relations = {
|
|
2493
2559
|
id: { $notIn: uniq(idsToOmit) }
|
2494
2560
|
});
|
2495
2561
|
}
|
2496
|
-
const
|
2562
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2563
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2497
2564
|
ctx.body = {
|
2498
2565
|
...res,
|
2499
2566
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2528,9 +2595,7 @@ const relations = {
|
|
2528
2595
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2529
2596
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2530
2597
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2531
|
-
ordering: "desc"
|
2532
|
-
page: ctx.request.query.page,
|
2533
|
-
pageSize: ctx.request.query.pageSize
|
2598
|
+
ordering: "desc"
|
2534
2599
|
});
|
2535
2600
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2536
2601
|
ctx.body = {
|
@@ -2562,7 +2627,7 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2562
2627
|
throw new errors.ForbiddenError();
|
2563
2628
|
}
|
2564
2629
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2565
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2630
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2566
2631
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2567
2632
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2568
2633
|
// Find the first document to check if it exists
|
@@ -2603,7 +2668,7 @@ const singleTypes = {
|
|
2603
2668
|
return ctx.forbidden();
|
2604
2669
|
}
|
2605
2670
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2606
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2671
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2607
2672
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2608
2673
|
if (!version) {
|
2609
2674
|
if (permissionChecker2.cannot.create()) {
|
@@ -2617,7 +2682,7 @@ const singleTypes = {
|
|
2617
2682
|
permissionChecker2,
|
2618
2683
|
model,
|
2619
2684
|
// @ts-expect-error - fix types
|
2620
|
-
{
|
2685
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2621
2686
|
{ availableLocales: true, availableStatus: false }
|
2622
2687
|
);
|
2623
2688
|
ctx.body = { data: {}, meta };
|
@@ -2648,7 +2713,7 @@ const singleTypes = {
|
|
2648
2713
|
}
|
2649
2714
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2650
2715
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2651
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2716
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2652
2717
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2653
2718
|
populate,
|
2654
2719
|
locale
|
@@ -2685,7 +2750,7 @@ const singleTypes = {
|
|
2685
2750
|
if (permissionChecker2.cannot.publish(document)) {
|
2686
2751
|
throw new errors.ForbiddenError();
|
2687
2752
|
}
|
2688
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2753
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2689
2754
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2690
2755
|
return publishResult.at(0);
|
2691
2756
|
});
|
@@ -2708,7 +2773,7 @@ const singleTypes = {
|
|
2708
2773
|
return ctx.forbidden();
|
2709
2774
|
}
|
2710
2775
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2711
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2776
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2712
2777
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2713
2778
|
if (!document) {
|
2714
2779
|
return ctx.notFound();
|
@@ -2740,7 +2805,7 @@ const singleTypes = {
|
|
2740
2805
|
return ctx.forbidden();
|
2741
2806
|
}
|
2742
2807
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2743
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2808
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2744
2809
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2745
2810
|
if (!document) {
|
2746
2811
|
return ctx.notFound();
|
@@ -2760,7 +2825,7 @@ const singleTypes = {
|
|
2760
2825
|
const { query } = ctx.request;
|
2761
2826
|
const documentManager2 = getService$1("document-manager");
|
2762
2827
|
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2763
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2828
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2764
2829
|
if (permissionChecker2.cannot.read()) {
|
2765
2830
|
return ctx.forbidden();
|
2766
2831
|
}
|
@@ -2781,7 +2846,7 @@ const uid$1 = {
|
|
2781
2846
|
async generateUID(ctx) {
|
2782
2847
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2783
2848
|
const { query = {} } = ctx.request;
|
2784
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2849
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2785
2850
|
await validateUIDField(contentTypeUID, field);
|
2786
2851
|
const uidService = getService$1("uid");
|
2787
2852
|
ctx.body = {
|
@@ -2793,7 +2858,7 @@ const uid$1 = {
|
|
2793
2858
|
ctx.request.body
|
2794
2859
|
);
|
2795
2860
|
const { query = {} } = ctx.request;
|
2796
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2861
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2797
2862
|
await validateUIDField(contentTypeUID, field);
|
2798
2863
|
const uidService = getService$1("uid");
|
2799
2864
|
const isAvailable = await uidService.checkUIDAvailability({
|
@@ -3436,12 +3501,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3436
3501
|
ability: userAbility,
|
3437
3502
|
model
|
3438
3503
|
});
|
3439
|
-
const
|
3504
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3505
|
+
const toSubject = (entity) => {
|
3506
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3507
|
+
};
|
3440
3508
|
const can = (action, entity, field) => {
|
3441
|
-
|
3509
|
+
const subject = toSubject(entity);
|
3510
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3511
|
+
return (
|
3512
|
+
// Test the original action to see if it passes
|
3513
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3514
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3515
|
+
);
|
3442
3516
|
};
|
3443
3517
|
const cannot = (action, entity, field) => {
|
3444
|
-
|
3518
|
+
const subject = toSubject(entity);
|
3519
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3520
|
+
return (
|
3521
|
+
// Test both the original action
|
3522
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3523
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3524
|
+
);
|
3445
3525
|
};
|
3446
3526
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3447
3527
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3718,6 +3798,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3718
3798
|
const attribute = model.attributes[attributeName];
|
3719
3799
|
switch (attribute.type) {
|
3720
3800
|
case "relation": {
|
3801
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
3802
|
+
if (isMorphRelation) {
|
3803
|
+
break;
|
3804
|
+
}
|
3721
3805
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3722
3806
|
populateAcc[attributeName] = {
|
3723
3807
|
count: true,
|
@@ -4095,7 +4179,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4095
4179
|
*/
|
4096
4180
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4097
4181
|
if (!document) {
|
4098
|
-
return
|
4182
|
+
return {
|
4183
|
+
data: document,
|
4184
|
+
meta: {
|
4185
|
+
availableLocales: [],
|
4186
|
+
availableStatus: []
|
4187
|
+
}
|
4188
|
+
};
|
4099
4189
|
}
|
4100
4190
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
4101
4191
|
if (!hasDraftAndPublish) {
|
@@ -4203,10 +4293,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4203
4293
|
async clone(id, body, uid2) {
|
4204
4294
|
const populate = await buildDeepPopulate(uid2);
|
4205
4295
|
const params = {
|
4206
|
-
data:
|
4207
|
-
...omitIdField(body),
|
4208
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4209
|
-
},
|
4296
|
+
data: omitIdField(body),
|
4210
4297
|
populate
|
4211
4298
|
};
|
4212
4299
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|