diff --git a/loopback/server/middleware/error-handler.js b/loopback/server/middleware/error-handler.js index b0b4cb55a..73441f862 100644 --- a/loopback/server/middleware/error-handler.js +++ b/loopback/server/middleware/error-handler.js @@ -1,81 +1,10 @@ const UserError = require('../../util/user-error'); const logToConsole = require('strong-error-handler/lib/logger'); -function isJsonString(str) { - try { - let json = JSON.parse(str); - return (typeof json === 'object'); - } catch (e) { - return false; - } -} +const valueIsNot = require('./value-is-not'); + const validations = [{ - validation: message => String(message).startsWith('Value is not'), - message: ({__: $t}, _tag) => - $t('Field are invalid', {tag: $t(_tag)}), - handleError: ({method: verb, originalUrl, body}) => { - const {models} = require('vn-loopback/server/server'); - let tag = null; - try { - let [module, ...path] = originalUrl.split('?')[0].split('api/')[1]; - path = path.join('/'); - // let module = url.split('/')[0]; - // let [id, path] = url.substring(url.indexOf('/') + 1).split('/'); - - let model = models[module]; - if (!model) { - module = module.substring(0, module.length - 1); - model = models[module]; - } - if (!model) throw new Error('No matching model found'); - const currentMethod = model.sharedClass.methods().find(method => { - const methodMatch = [method.http].flat().filter(el => el.verb === verb.toLowerCase()); - if (methodMatch.length > 0) { - const http = methodMatch.find(el => el.path.endsWith(path)); - if (http) - return method; - } - } - ); - const {accepts} = currentMethod; - for (const [key, value] of Object.entries(body)) { - const accept = accepts.find(acc => acc.arg === key); - if (accept.type !== 'any') { - let isValid = false; - if (value) { - switch (accept.type) { - case 'object': - isValid = isJsonString(value); - break; - case 'number': - isValid = /^[0-9]*$/.test(value); - break; - - case 'boolean': - isValid = value instanceof Boolean; - break; - - case 'date': - isValid = (new Date(date) !== 'Invalid Date') && !isNaN(new Date(date)); - break; - - case 'string': - isValid = typeof value == 'string'; - break; - } - } - if (!value || !isValid) { - tag = key; - break; - } - } - } - return tag; - } catch (error) { - throw new Error(error); - } - } - + ...valueIsNot }]; module.exports = function() { return function(err, req, res, next) { @@ -93,12 +22,6 @@ module.exports = function() { const error = validation.handleError(req); if (error) err.message = validation.message(req, error); - // const tag = handleNullProperty(req); - // if (tag) { - // const message = validation.message(req); - // } - // const tag = validateModel(req); - // if (tag) validation.message(req); } }); diff --git a/loopback/server/middleware/value-is-not.js b/loopback/server/middleware/value-is-not.js new file mode 100644 index 000000000..ef2e2513f --- /dev/null +++ b/loopback/server/middleware/value-is-not.js @@ -0,0 +1,89 @@ +module.exports = { + validation: message => String(message).startsWith('Value is not'), + message: ({__: $t}, _tag) => + $t('Field are invalid', {tag: $t(_tag)}), + handleError: ({method: verb, originalUrl, body}) => { + const {models} = require('vn-loopback/server/server'); + let tag = null; + let module = null; + let path = null; + let hasId = false; + try { + if (originalUrl.includes('?')) + originalUrl = originalUrl.split('?')[0]; + + originalUrl = originalUrl.split('api/')[1]; + [module, ...path] = originalUrl.split('/'); + hasId = path.length > 1; + // let module = url.split('/')[0]; + // let [id, path] = url.substring(url.indexOf('/') + 1).split('/'); + + let model = models[module]; + if (!model) { + module = module.substring(0, module.length - 1); + model = models[module]; + } + if (!model) throw new Error('No matching model found'); + const currentMethod = model.sharedClass.methods().find(method => { + const methodMatch = [method.http].flat().find(el => { + let isValid = false; + if (el.verb === verb.toLowerCase()) { + if (hasId) + isValid = el.path.replace(':id', path[0]) === '/' + path.join('/'); + else + isValid = el.path.endsWith(path[0]); + } + return isValid; + }); + if (methodMatch) + return method; + } + ); + const {accepts} = currentMethod; + for (const [key, value] of Object.entries(body)) { + const accept = accepts.find(acc => acc.arg === key); + if (accept.type !== 'any') { + let isValid = false; + if (value) { + switch (accept.type) { + case 'object': + isValid = isJsonString(value); + break; + case 'number': + isValid = /^[0-9]*$/.test(value); + break; + + case 'boolean': + isValid = value instanceof Boolean; + break; + + case 'date': + isValid = (new Date(date) !== 'Invalid Date') && !isNaN(new Date(date)); + break; + + case 'string': + isValid = typeof value == 'string'; + break; + } + } + if (!value || !isValid) { + tag = key; + break; + } + } + } + return tag; + } catch (error) { + throw new Error(error); + } + } + +}; +function isJsonString(str) { + try { + let json = JSON.parse(str); + return (typeof json === 'object'); + } catch (e) { + return false; + } +}