mirror of https://github.com/pelias/api.git
Peter Johnson
9 years ago
21 changed files with 405 additions and 350 deletions
@ -0,0 +1,3 @@ |
|||||||
|
module.exports = function controller( req, res, next) { |
||||||
|
res.send('status: ok'); |
||||||
|
}; |
@ -1,39 +1,26 @@ |
|||||||
var isObject = require('is-object'); |
|
||||||
var geo_common = require ('./_geo_common'); |
var geo_common = require ('./_geo_common'); |
||||||
|
var LAT_LON_IS_REQUIRED = true, |
||||||
|
CIRCLE_IS_REQUIRED = false, |
||||||
|
CIRCLE_MUST_BE_COMPLETE = false; |
||||||
|
|
||||||
// validate inputs, convert types and apply defaults
|
// validate inputs, convert types and apply defaults
|
||||||
module.exports = function sanitize( req ){ |
module.exports = function sanitize( raw, clean ){ |
||||||
var clean = req.clean || {}; |
|
||||||
var params = req.query; |
|
||||||
var latlon_is_required = true; |
|
||||||
var circle_is_required = false; |
|
||||||
var circle_must_be_complete = false; |
|
||||||
|
|
||||||
// ensure the input params are a valid object
|
// error & warning messages
|
||||||
if( !isObject( params ) ){ |
var messages = { errors: [], warnings: [] }; |
||||||
params = {}; |
|
||||||
} |
|
||||||
|
|
||||||
if( !isObject( params.point ) ){ |
|
||||||
params.point = {}; |
|
||||||
} |
|
||||||
|
|
||||||
try { |
try { |
||||||
geo_common.sanitize_coord( 'lat', clean, params['point.lat'], latlon_is_required ); |
geo_common.sanitize_coord( 'lat', clean, raw['point.lat'], LAT_LON_IS_REQUIRED ); |
||||||
geo_common.sanitize_coord( 'lon', clean, params['point.lon'], latlon_is_required ); |
geo_common.sanitize_coord( 'lon', clean, raw['point.lon'], LAT_LON_IS_REQUIRED ); |
||||||
|
|
||||||
// boundary.circle.* is not mandatory, and only specifying radius is fine,
|
// boundary.circle.* is not mandatory, and only specifying radius is fine,
|
||||||
// as point.lat/lon will be used to fill those values by default
|
// as point.lat/lon will be used to fill those values by default
|
||||||
geo_common.sanitize_boundary_circle( clean, params, circle_is_required, circle_must_be_complete); |
geo_common.sanitize_boundary_circle( clean, raw, CIRCLE_IS_REQUIRED, CIRCLE_MUST_BE_COMPLETE); |
||||||
} |
} |
||||||
catch (err) { |
catch (err) { |
||||||
return { |
messages.errors.push( err.message ); |
||||||
'error': true, |
|
||||||
'message': err.message |
|
||||||
}; |
|
||||||
} |
} |
||||||
|
|
||||||
req.clean = clean; |
return messages; |
||||||
|
|
||||||
return { 'error': false }; |
|
||||||
}; |
}; |
||||||
|
@ -1,38 +1,21 @@ |
|||||||
var isObject = require('is-object'); |
|
||||||
var geo_common = require ('./_geo_common'); |
var geo_common = require ('./_geo_common'); |
||||||
|
var LAT_LON_IS_REQUIRED = false; |
||||||
|
|
||||||
// validate inputs, convert types and apply defaults
|
// validate inputs, convert types and apply defaults
|
||||||
module.exports = function sanitize( req ){ |
module.exports = function sanitize( raw, clean ){ |
||||||
var clean = req.clean || {}; |
|
||||||
var params = req.query; |
|
||||||
var latlon_is_required = false; |
|
||||||
|
|
||||||
// ensure the input params are a valid object
|
|
||||||
if( !isObject( params ) ){ |
|
||||||
params = {}; |
|
||||||
} |
|
||||||
|
|
||||||
if( !isObject( params.focus ) ){ |
// error & warning messages
|
||||||
params.focus = {}; |
var messages = { errors: [], warnings: [] }; |
||||||
} |
|
||||||
|
|
||||||
if( !isObject( params.focus.point ) ){ |
|
||||||
params.focus.point = {}; |
|
||||||
} |
|
||||||
|
|
||||||
try { |
try { |
||||||
geo_common.sanitize_coord( 'lat', clean, params['focus.point.lat'], latlon_is_required ); |
geo_common.sanitize_coord( 'lat', clean, raw['focus.point.lat'], LAT_LON_IS_REQUIRED ); |
||||||
geo_common.sanitize_coord( 'lon', clean, params['focus.point.lon'], latlon_is_required ); |
geo_common.sanitize_coord( 'lon', clean, raw['focus.point.lon'], LAT_LON_IS_REQUIRED ); |
||||||
geo_common.sanitize_bbox(clean, params.bbox); |
geo_common.sanitize_bbox(raw, clean); |
||||||
} |
} |
||||||
catch (err) { |
catch (err) { |
||||||
return { |
messages.errors.push( err.message ); |
||||||
'error': true, |
|
||||||
'message': err.message |
|
||||||
}; |
|
||||||
} |
} |
||||||
|
|
||||||
req.clean = clean; |
return messages; |
||||||
|
|
||||||
return { 'error': false }; |
|
||||||
}; |
}; |
||||||
|
@ -1,17 +0,0 @@ |
|||||||
function sanitize( req, sanitiser, cb ){ |
|
||||||
|
|
||||||
req.clean = req.clean || {}; |
|
||||||
|
|
||||||
for (var s in sanitiser) {
|
|
||||||
var sanity = sanitiser[s](req); |
|
||||||
if (sanity.error) { |
|
||||||
return cb(sanity.message); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return cb( undefined, req.clean ); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
// export function
|
|
||||||
module.exports = sanitize; |
|
@ -1,57 +1,81 @@ |
|||||||
var _ = require('lodash'); |
|
||||||
|
|
||||||
function setup(paramName, targetMap) { |
var _ = require('lodash'), |
||||||
return function (req ) { |
check = require('check-types'); |
||||||
return sanitize(paramName, targetMap, req); |
|
||||||
|
function setup( paramName, targetMap ) { |
||||||
|
return function( raw, clean ){ |
||||||
|
return sanitize( raw, clean, { |
||||||
|
paramName: paramName, |
||||||
|
targetMap: targetMap, |
||||||
|
targetMapKeysString: Object.keys(targetMap).join(',') |
||||||
|
}); |
||||||
}; |
}; |
||||||
} |
} |
||||||
|
|
||||||
function sanitize( paramName, targetMap, req ) { |
function sanitize( raw, clean, opts ) { |
||||||
var params = req.query || {}; |
|
||||||
|
|
||||||
req.clean = req.clean || {}; |
// error & warning messages
|
||||||
req.clean.types = req.clean.types || {}; |
var messages = { errors: [], warnings: [] }; |
||||||
|
|
||||||
// default case (no sources specified in GET params)
|
// init clean.types
|
||||||
// there is a case where the property is present, but set to null or undefined
|
clean.types = clean.types || {}; |
||||||
if (params.hasOwnProperty(paramName) === false || typeof params[paramName] === 'undefined') { |
|
||||||
return { error: false }; |
|
||||||
} |
|
||||||
|
|
||||||
params[paramName] = params[paramName].trim(); |
// the string of targets (comma delimeted)
|
||||||
|
var targetsString = raw[opts.paramName]; |
||||||
|
|
||||||
if (params[paramName].length === 0) { |
// trim whitespace
|
||||||
return { |
if( check.unemptyString( targetsString ) ){ |
||||||
error: true, |
targetsString = targetsString.trim(); |
||||||
message: paramName + ' parameter cannot be an empty string. Valid options: ' + Object.keys(targetMap).join(', ') |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
var targets = params[paramName].split(',').map( function( target ){ |
// param must be a valid non-empty string
|
||||||
return target.toLowerCase(); // lowercase inputs
|
if( !check.unemptyString( targetsString ) ){ |
||||||
}); |
messages.errors.push( |
||||||
|
opts.paramName + ' parameter cannot be an empty string. Valid options: ' + opts.targetMapKeysString |
||||||
|
); |
||||||
|
} |
||||||
|
else { |
||||||
|
|
||||||
var invalidTargets = targets.filter(function(target) { |
// split string in to array and lowercase each target string
|
||||||
return targetMap.hasOwnProperty(target) === false; |
var targets = targetsString.split(',').map( function( target ){ |
||||||
}); |
return target.toLowerCase(); // lowercase inputs
|
||||||
|
}); |
||||||
|
|
||||||
if (invalidTargets.length > 0) { |
// emit an error for each target *not* present in the targetMap
|
||||||
return { |
targets.filter( function( target ){ |
||||||
error: true, |
return !opts.targetMap.hasOwnProperty(target); |
||||||
message: invalidTargets[0] + ' is an invalid ' + paramName + ' parameter. Valid options: ' + Object.keys(targetMap).join(', ') |
}).forEach( function( target ){ |
||||||
}; |
messages.errors.push( |
||||||
} |
'\'' + target + '\' is an invalid ' + opts.paramName + ' parameter. Valid options: ' + opts.targetMapKeysString |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
// only set types value when no error occured
|
||||||
|
if( !messages.errors.length ){ |
||||||
|
|
||||||
var cleanPropName = 'from_' + paramName; |
// store the values under a new key as 'clean.types.from_*'
|
||||||
|
var typesKey = 'from_' + opts.paramName; |
||||||
|
|
||||||
req.clean.types[cleanPropName] = targets.reduce(function(acc, target) { |
// ?
|
||||||
return acc.concat(targetMap[target]); |
clean.types[typesKey] = targets.reduce(function(acc, target) { |
||||||
}, []); |
return acc.concat(opts.targetMap[target]); |
||||||
|
}, []); |
||||||
|
|
||||||
|
// dedupe in case aliases expanded to common things or user typed in duplicates
|
||||||
|
clean.types[typesKey] = _.unique(clean.types[typesKey]); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// string is empty
|
||||||
|
else if( check.string( targetsString ) ){ |
||||||
|
messages.errors.push( |
||||||
|
opts.paramName + ' parameter cannot be an empty string. Valid options: ' + opts.targetMapKeysString |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
// dedupe in case aliases expanded to common things or user typed in duplicates
|
|
||||||
req.clean.types[cleanPropName] = _.unique(req.clean.types[cleanPropName]); |
|
||||||
|
|
||||||
return { error: false }; |
return messages; |
||||||
} |
} |
||||||
|
|
||||||
module.exports = setup; |
module.exports = setup; |
||||||
|
@ -0,0 +1,26 @@ |
|||||||
|
|
||||||
|
function sanitize( req, sanitizers, cb ){ |
||||||
|
|
||||||
|
// init an object to store clean
|
||||||
|
// (sanitized) input parameters
|
||||||
|
req.clean = {}; |
||||||
|
|
||||||
|
// source of input parameters
|
||||||
|
// (in this case from the GET querystring params)
|
||||||
|
var params = req.query || {}; |
||||||
|
|
||||||
|
for (var s in sanitizers) { |
||||||
|
var sanity = sanitizers[s]( params, req.clean ); |
||||||
|
|
||||||
|
// errors
|
||||||
|
if( sanity.errors.length ){ |
||||||
|
return cb( sanity.errors[0] ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return cb( undefined, req.clean ); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// export function
|
||||||
|
module.exports = sanitize; |
Loading…
Reference in new issue