UNPKG

dobo

Version:

DBMS for Bajo Framework

58 lines (54 loc) 3.07 kB
/** * Sanitize the payload body based on the model's properties and rules. * @method * @memberof DoboModel * @async * @param {Object} [options={}] - Options object * @param {Object} [options.body={}] - Body object to sanitize * @param {boolean} [options.partial=false] - If `true`, only the fields present in the body will be sanitized * @param {boolean} [options.strict=false] - If `true`, only the fields defined in the model's properties will be included in the sanitized body * @param {Array} [options.extFields=[]] - Additional fields to include in the sanitized body * @param {boolean} [options.truncateString=false] - If `true`, string fields will be truncated to their maximum length defined in the model's properties * @param {string} [options.action] - The action being performed (e.g., 'createRecord', 'updateRecord', etc.) * @param {boolean} [options.allProps=false] - If `true`, all properties including virtual ones will be considered for sanitization * @returns {Object} Returns sanitized body object */ async function sanitizeBody (options = {}) { const { body = {}, partial, strict, extFields = [], truncateString, action, allProps } = options const { isSet } = this.app.lib.aneka const { sanitizeByType } = this.app.dobo const { omit, has } = this.app.lib._ const result = {} const sanitize = (name, type) => { const opts = { strict, action, model: this.name, outputFormat: 'native' } result[name] = sanitizeByType(result[name], type, opts) if (['updateRecord', 'upsertRecord'].includes(action) && type === 'string' && result[name] === '') result[name] = null } const omitted = [] const details = [] const props = allProps ? this.properties : this.getNonVirtualProperties() const properties = [...props, ...extFields] for (const prop of properties) { try { if (partial && !has(body, prop.name)) { // if (prop.type === 'array') result[prop.name] = null continue } result[prop.name] = body[prop.name] if (prop.type === 'array' && isSet(result[prop.name]) && !Array.isArray(result[prop.name])) result[prop.name] = [result[prop.name]] if (isSet(result[prop.name])) sanitize(prop.name, prop.type) if (result[prop.name] === null) continue if (truncateString && isSet(result[prop.name]) && ['string', 'text'].includes(prop.type)) result[prop.name] = result[prop.name].slice(0, prop.maxLength) if (prop.name.endsWith('Id') && isSet(result[prop.name]) && prop.type === 'string' && ['smallint', 'integer'].includes(this.adapter.idField.type)) result[prop.name] = result[prop.name] + '' if (result[prop.name] === undefined) omitted.push(prop.name) } catch (err) { details.push({ field: prop.name, error: err.message, value: body[prop.name], ext: { type: prop.type } }) } } if (details.length > 0) { const payload = { details, statusCode: 422, code: 'BODY_SANITIZATION', model: this.name } throw this.plugin.error('sanitizeBodyError', payload) } return omit(result, omitted) } export default sanitizeBody