2021-11-08 15:52:42 +01:00
|
|
|
'use strict';
|
|
|
|
|
2023-02-09 11:35:50 +01:00
|
|
|
const { curry, isEmpty, isNil, isArray, isObject } = require('lodash/fp');
|
2021-11-08 15:52:42 +01:00
|
|
|
|
2022-12-08 17:17:11 +01:00
|
|
|
const { pipeAsync } = require('../async');
|
2021-11-08 15:52:42 +01:00
|
|
|
const traverseEntity = require('../traverse-entity');
|
2023-02-09 11:35:50 +01:00
|
|
|
const { isScalarAttribute } = require('../content-types');
|
2021-11-08 15:52:42 +01:00
|
|
|
|
2023-02-09 11:35:50 +01:00
|
|
|
const {
|
|
|
|
traverseQueryFilters,
|
|
|
|
traverseQuerySort,
|
|
|
|
traverseQueryPopulate,
|
|
|
|
traverseQueryFields,
|
|
|
|
} = require('../traverse');
|
|
|
|
|
|
|
|
const {
|
|
|
|
removePassword,
|
|
|
|
removePrivate,
|
|
|
|
removeDynamicZones,
|
|
|
|
removeMorphToRelations,
|
|
|
|
} = require('./visitors');
|
2021-11-08 15:52:42 +01:00
|
|
|
|
2023-03-21 18:37:21 +01:00
|
|
|
const sanitizePasswords = (schema) => async (entity) => {
|
2021-11-08 15:52:42 +01:00
|
|
|
return traverseEntity(removePassword, { schema }, entity);
|
2023-03-21 18:37:21 +01:00
|
|
|
};
|
2021-11-08 15:52:42 +01:00
|
|
|
|
2023-03-21 18:37:21 +01:00
|
|
|
const defaultSanitizeOutput = async (schema, entity) => {
|
|
|
|
return traverseEntity(
|
|
|
|
(...args) => {
|
|
|
|
removePassword(...args);
|
|
|
|
removePrivate(...args);
|
|
|
|
},
|
|
|
|
{ schema },
|
|
|
|
entity
|
|
|
|
);
|
|
|
|
};
|
2021-11-08 15:52:42 +01:00
|
|
|
|
2023-02-09 11:35:50 +01:00
|
|
|
const defaultSanitizeFilters = curry((schema, filters) => {
|
|
|
|
return pipeAsync(
|
|
|
|
// Remove dynamic zones from filters
|
|
|
|
traverseQueryFilters(removeDynamicZones, { schema }),
|
|
|
|
// Remove morpTo relations from filters
|
|
|
|
traverseQueryFilters(removeMorphToRelations, { schema }),
|
|
|
|
// Remove passwords from filters
|
|
|
|
traverseQueryFilters(removePassword, { schema }),
|
|
|
|
// Remove private from filters
|
|
|
|
traverseQueryFilters(removePrivate, { schema }),
|
|
|
|
// Remove empty objects
|
|
|
|
traverseQueryFilters(
|
|
|
|
({ key, value }, { remove }) => {
|
|
|
|
if (isObject(value) && isEmpty(value)) {
|
|
|
|
remove(key);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ schema }
|
|
|
|
)
|
|
|
|
)(filters);
|
|
|
|
});
|
|
|
|
|
|
|
|
const defaultSanitizeSort = curry((schema, sort) => {
|
|
|
|
return pipeAsync(
|
|
|
|
// Remove non attribute keys
|
|
|
|
traverseQuerySort(
|
|
|
|
({ key, attribute }, { remove }) => {
|
2023-03-20 10:11:33 +01:00
|
|
|
// ID is not an attribute per se, so we need to make
|
|
|
|
// an extra check to ensure we're not removing it
|
|
|
|
if (key === 'id') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-02-09 11:35:50 +01:00
|
|
|
if (!attribute) {
|
|
|
|
remove(key);
|
|
|
|
}
|
|
|
|
},
|
2023-03-20 10:16:31 +01:00
|
|
|
{ schema }
|
2023-02-09 11:35:50 +01:00
|
|
|
),
|
|
|
|
// Remove dynamic zones from sort
|
|
|
|
traverseQuerySort(removeDynamicZones, { schema }),
|
|
|
|
// Remove morpTo relations from sort
|
|
|
|
traverseQuerySort(removeMorphToRelations, { schema }),
|
|
|
|
// Remove private from sort
|
|
|
|
traverseQuerySort(removePrivate, { schema }),
|
|
|
|
// Remove passwords from filters
|
|
|
|
traverseQuerySort(removePassword, { schema }),
|
|
|
|
// Remove keys for empty non-scalar values
|
|
|
|
traverseQuerySort(
|
|
|
|
({ key, attribute, value }, { remove }) => {
|
|
|
|
if (!isScalarAttribute(attribute) && isEmpty(value)) {
|
|
|
|
remove(key);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ schema }
|
|
|
|
)
|
|
|
|
)(sort);
|
|
|
|
});
|
|
|
|
|
|
|
|
const defaultSanitizeFields = curry((schema, fields) => {
|
|
|
|
return pipeAsync(
|
|
|
|
// Only keep scalar attributes
|
|
|
|
traverseQueryFields(
|
|
|
|
({ key, attribute }, { remove }) => {
|
|
|
|
if (isNil(attribute) || !isScalarAttribute(attribute)) {
|
|
|
|
remove(key);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ schema }
|
|
|
|
),
|
|
|
|
// Remove private fields
|
|
|
|
traverseQueryFields(removePrivate, { schema }),
|
|
|
|
// Remove password fields
|
|
|
|
traverseQueryFields(removePassword, { schema }),
|
|
|
|
// Remove nil values from fields array
|
|
|
|
(value) => (isArray(value) ? value.filter((field) => !isNil(field)) : value)
|
|
|
|
)(fields);
|
|
|
|
});
|
|
|
|
|
|
|
|
const defaultSanitizePopulate = curry((schema, populate) => {
|
|
|
|
return pipeAsync(
|
|
|
|
traverseQueryPopulate(
|
|
|
|
async ({ key, value, schema, attribute }, { set }) => {
|
|
|
|
if (attribute) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (key === 'sort') {
|
|
|
|
set(key, await defaultSanitizeSort(schema, value));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (key === 'filters') {
|
|
|
|
set(key, await defaultSanitizeFilters(schema, value));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (key === 'fields') {
|
|
|
|
set(key, await defaultSanitizeFields(schema, value));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ schema }
|
|
|
|
),
|
|
|
|
// Remove private fields
|
|
|
|
traverseQueryPopulate(removePrivate, { schema })
|
|
|
|
)(populate);
|
|
|
|
});
|
|
|
|
|
2021-11-08 15:52:42 +01:00
|
|
|
module.exports = {
|
|
|
|
sanitizePasswords,
|
|
|
|
defaultSanitizeOutput,
|
2023-02-09 11:35:50 +01:00
|
|
|
defaultSanitizeFilters,
|
|
|
|
defaultSanitizeSort,
|
|
|
|
defaultSanitizeFields,
|
|
|
|
defaultSanitizePopulate,
|
2021-11-08 15:52:42 +01:00
|
|
|
};
|