2021-11-04 15:47:53 +01:00
|
|
|
'use strict';
|
|
|
|
|
2023-02-09 11:35:50 +01:00
|
|
|
const { isArray, cloneDeep } = require('lodash/fp');
|
2021-11-04 15:47:53 +01:00
|
|
|
|
|
|
|
const { getNonWritableAttributes } = require('../content-types');
|
2022-12-08 17:17:11 +01:00
|
|
|
const { pipeAsync } = require('../async');
|
2021-11-04 16:43:27 +01:00
|
|
|
|
2021-11-04 15:47:53 +01:00
|
|
|
const visitors = require('./visitors');
|
2021-11-10 17:08:54 +01:00
|
|
|
const sanitizers = require('./sanitizers');
|
2023-02-09 11:35:50 +01:00
|
|
|
const traverseEntity = require('../traverse-entity');
|
|
|
|
|
|
|
|
const { traverseQueryFilters, traverseQuerySort, traverseQueryPopulate } = require('../traverse');
|
|
|
|
|
|
|
|
const createContentAPISanitizers = () => {
|
|
|
|
const sanitizeInput = (data, schema, { auth } = {}) => {
|
|
|
|
if (isArray(data)) {
|
|
|
|
return Promise.all(data.map((entry) => sanitizeInput(entry, schema, { auth })));
|
|
|
|
}
|
|
|
|
|
|
|
|
const nonWritableAttributes = getNonWritableAttributes(schema);
|
|
|
|
|
|
|
|
const transforms = [
|
|
|
|
// Remove non writable attributes
|
|
|
|
traverseEntity(visitors.restrictedFields(nonWritableAttributes), { schema }),
|
|
|
|
];
|
|
|
|
|
|
|
|
if (auth) {
|
|
|
|
// Remove restricted relations
|
|
|
|
transforms.push(traverseEntity(visitors.removeRestrictedRelations(auth), { schema }));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply sanitizers from registry if exists
|
|
|
|
strapi.sanitizers
|
|
|
|
.get('content-api.input')
|
|
|
|
.forEach((sanitizer) => transforms.push(sanitizer(schema)));
|
|
|
|
|
|
|
|
return pipeAsync(...transforms)(data);
|
|
|
|
};
|
|
|
|
|
|
|
|
const sanitizeOuput = (data, schema, { auth } = {}) => {
|
|
|
|
if (isArray(data)) {
|
|
|
|
return Promise.all(data.map((entry) => sanitizeOuput(entry, schema, { auth })));
|
|
|
|
}
|
|
|
|
|
|
|
|
const transforms = [sanitizers.defaultSanitizeOutput(schema)];
|
|
|
|
|
|
|
|
if (auth) {
|
|
|
|
transforms.push(traverseEntity(visitors.removeRestrictedRelations(auth), { schema }));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply sanitizers from registry if exists
|
|
|
|
strapi.sanitizers
|
|
|
|
.get('content-api.output')
|
|
|
|
.forEach((sanitizer) => transforms.push(sanitizer(schema)));
|
|
|
|
|
|
|
|
return pipeAsync(...transforms)(data);
|
|
|
|
};
|
|
|
|
|
|
|
|
const sanitizeQuery = async (query, schema, { auth } = {}) => {
|
|
|
|
const { filters, sort, fields, populate } = query;
|
|
|
|
|
|
|
|
const sanitizedQuery = cloneDeep(query);
|
|
|
|
|
|
|
|
if (filters) {
|
|
|
|
Object.assign(sanitizedQuery, { filters: await sanitizeFilters(filters, schema, { auth }) });
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sort) {
|
|
|
|
Object.assign(sanitizedQuery, { sort: await sanitizeSort(sort, schema, { auth }) });
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fields) {
|
|
|
|
Object.assign(sanitizedQuery, { fields: await sanitizeFields(fields, schema) });
|
|
|
|
}
|
|
|
|
|
|
|
|
if (populate) {
|
|
|
|
Object.assign(sanitizedQuery, { populate: await sanitizePopulate(populate, schema) });
|
|
|
|
}
|
|
|
|
|
|
|
|
return sanitizedQuery;
|
|
|
|
};
|
|
|
|
|
|
|
|
const sanitizeFilters = (filters, schema, { auth } = {}) => {
|
|
|
|
if (isArray(filters)) {
|
|
|
|
return Promise.all(filters.map((filter) => sanitizeFilters(filter, schema, { auth })));
|
|
|
|
}
|
|
|
|
|
|
|
|
const transforms = [sanitizers.defaultSanitizeFilters(schema)];
|
|
|
|
|
|
|
|
if (auth) {
|
|
|
|
transforms.push(traverseQueryFilters(visitors.removeRestrictedRelations(auth), { schema }));
|
|
|
|
}
|
|
|
|
|
|
|
|
return pipeAsync(...transforms)(filters);
|
|
|
|
};
|
|
|
|
|
|
|
|
const sanitizeSort = (sort, schema, { auth } = {}) => {
|
|
|
|
const transforms = [sanitizers.defaultSanitizeSort(schema)];
|
|
|
|
|
|
|
|
if (auth) {
|
|
|
|
transforms.push(traverseQuerySort(visitors.removeRestrictedRelations(auth), { schema }));
|
|
|
|
}
|
|
|
|
|
|
|
|
return pipeAsync(...transforms)(sort);
|
|
|
|
};
|
|
|
|
|
|
|
|
const sanitizeFields = (fields, schema) => {
|
|
|
|
const transforms = [sanitizers.defaultSanitizeFields(schema)];
|
|
|
|
|
|
|
|
return pipeAsync(...transforms)(fields);
|
|
|
|
};
|
|
|
|
|
|
|
|
const sanitizePopulate = (populate, schema, { auth } = {}) => {
|
|
|
|
const transforms = [sanitizers.defaultSanitizePopulate(schema)];
|
|
|
|
|
|
|
|
if (auth) {
|
|
|
|
transforms.push(traverseQueryPopulate(visitors.removeRestrictedRelations(auth), { schema }));
|
|
|
|
}
|
|
|
|
|
|
|
|
return pipeAsync(...transforms)(populate);
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
input: sanitizeInput,
|
|
|
|
output: sanitizeOuput,
|
|
|
|
query: sanitizeQuery,
|
|
|
|
filters: sanitizeFilters,
|
|
|
|
sort: sanitizeSort,
|
|
|
|
fields: sanitizeFields,
|
|
|
|
populate: sanitizePopulate,
|
|
|
|
};
|
|
|
|
};
|
2021-11-04 15:47:53 +01:00
|
|
|
|
|
|
|
module.exports = {
|
2023-02-09 11:35:50 +01:00
|
|
|
contentAPI: createContentAPISanitizers(),
|
2021-11-04 15:47:53 +01:00
|
|
|
|
2021-11-10 17:08:54 +01:00
|
|
|
sanitizers,
|
2021-11-04 15:47:53 +01:00
|
|
|
visitors,
|
|
|
|
};
|