const Middleware = require('libflitter/middleware/Middleware') /* * RequiredFields Middleware * ------------------------------------------------------------- * Put some description here! */ class RequiredFields extends Middleware { static get services() { return [...super.services, 'configs', 'output', 'utility'] } /* * Run the middleware test. * This method is required by all Flitter middleware. * It should either call the next function in the stack, * or it should handle the response accordingly. */ async test(req, res, next, args){ // Do stuff here const search_fields = args.search ? (Array.isArray(args.search) ? args.search : [args.search]) : ['params', 'body', 'query'] const form_config = this.configs.get('api:forms:'+args.form) const values = {} for ( const field in form_config.fields ) { if ( !form_config.fields.hasOwnProperty(field) ) continue const field_config = form_config.fields[field] let field_value = this.get_field({ request: req, field, search_fields }) if ( !field_value ) { if ( field_config.required ) { return this.fail({ response: res, reason: `Missing required field: ${field}`}) } } else { if ( field_config.infer !== false ) { field_value = this.utility.infer(field_value) } if ( field_config.coerce ) { field_value = field_config.coerce(field_value) if ( field_config.coerce === Number && isNaN(field_value) ) { return this.fail({ response: res, reason: 'Invalid numerical value for field: '+field }) } } if ( field_config.in_set ) { if ( Array.isArray(field_config.in_set) ) { if ( !field_config.in_set.includes(field_value) ) { return this.fail({ response: res, reason: `Invalid value for ${field}. Value must be one of: ${field_config.join(', ')}`}) } } else { this.output.warn(`[Middleware RequiredFields] Invalid in_set for ${field} in ${args.form}. Must be array.`) } } values[field] = field_value } } req.form = values /* * Call the next function in the stack. */ next() } get_field({ request, field, search_fields }) { for ( const search_field of search_fields ) { if ( Object.keys(request).includes(search_field) ) { if ( Object.keys(request[search_field]).includes(field) ) { return request[search_field][field] } } else { this.output.warn(`[Middleware RequiredFields] Requested search of request field that does not exist: ${search_field}`) this.output.debug(`[Middleware RequiredFields] Available request keys: ${Object.keys(request).join(', ')}`) } } } fail({ response, reason }) { return response.status(400).message(reason).api({}) } } module.exports = exports = RequiredFields