Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encode Values returned from DB for filter panel #983

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/api.js
Original file line number Diff line number Diff line change
@@ -115,7 +115,7 @@ module.exports = async (req, res) => {
Object.entries(req.params)
.filter(entry => typeof entry[1] === 'string')
.forEach(entry => {
req.params[entry[0]] = decodeURIComponent(entry[1])
req.params[entry[0]] = decodeURIComponent(encodeURIComponent(entry[1]))
})

// Short circuit login view or post request.
2 changes: 1 addition & 1 deletion lib/ui/elements/dropdown.mjs
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ export default (params) => {

// Set btn text to reflect selection or show placeholder.
btn.querySelector('[data-id=header-span]')
.textContent = params.selectedTitles.size && Array.from(params.selectedTitles).map(v => decodeURIComponent(v)).join(', ')
.textContent = params.selectedTitles.size && Array.from(params.selectedTitles).map(v => decodeURIComponent(encodeURIComponent(v))).join(', ')
|| params.span || params.placeholder

// Execute callback method and pass array of current selection.
5 changes: 4 additions & 1 deletion lib/ui/layers/filters.mjs
Original file line number Diff line number Diff line change
@@ -182,10 +182,13 @@ async function filter_in(layer, filter) {

if (filter.dropdown) {

// Encode values for dropdown.
const encoded = filter[filter.type].map(val => encodeURIComponent(val));

return mapp.ui.elements.dropdown({
multi: true,
placeholder: 'Select Multiple',
entries: filter[filter.type].map(val => ({
entries: encoded.map(val => ({
title: decodeURIComponent(val),
option: encodeURIComponent(val),
selected: chkSet.has(val)
35 changes: 22 additions & 13 deletions mod/query.js
Original file line number Diff line number Diff line change
@@ -44,13 +44,22 @@ module.exports = async (req, res) => {
// Get array of role filter from layer configuration.
const roles = Roles.filter(layer, req.params.user?.roles)

// Create params filter string from roleFilter filter params.
req.params.filter =
` ${layer.filter?.default && 'AND ' + layer.filter?.default || ''}
${req.params.filter && `AND ${sqlFilter(JSON.parse(req.params.filter), SQLparams)}` || ''}
${roles && Object.values(roles).some(r => !!r)
? `AND ${sqlFilter(Object.values(roles).filter(r => !!r), SQLparams)}`
: ''}`
// Create a params filter string from roleFilter filter params.
// Include 'AND' followed by layer.filter?.default if it exists.
const layerFilterPart = layer.filter?.default ? `AND ${layer.filter.default}` : '';
console.log('layerFilterPart', layerFilterPart);
// Include 'AND' followed by the result of sqlFilter if req.params.filter is provided.
console.log('Filter', req.params.filter);
const reqFilterPart = req.params.filter ? `AND ${sqlFilter(JSON.parse(req.params.filter), SQLparams)}` : '';
console.log('reqFilterPart', reqFilterPart);
// Include 'AND' followed by the result of sqlFilter applied to roles with truthy values.
const rolesFilterPart = roles && Object.values(roles).some(r => !!r)
? `AND ${sqlFilter(Object.values(roles).filter(r => !!r), SQLparams)}`
: '';
console.log('rolesFilterPart', rolesFilterPart);
// Combine the parts into a single filter string with spaces.
req.params.filter = `${layerFilterPart} ${reqFilterPart} ${rolesFilterPart}`;
console.log('req.params.filter', req.params.filter);

// Split viewport param.
const viewport = req.params.viewport?.split(',')
@@ -176,9 +185,9 @@ module.exports = async (req, res) => {
}

let rows = await dbs(query, SQLparams, req.params.statement_timeout || template.statement_timeout);

if (rows instanceof Error) {

return res.status(500).send('Failed to query PostGIS table.');
}

@@ -191,17 +200,17 @@ module.exports = async (req, res) => {

// Check whether any row of the rows array is empty.
if (rows.length && !rows.some(row => checkEmptyRow(row))

// Check whether a single rows is empty.
|| !checkEmptyRow(rows)) {

return res.status(202).send('No rows returned from table.')
}

if (req.params.reduced || req.params.template?.reduce) {

// Reduce row values to an values array.
return res.send(rows.map(row=>Object.values(row)))
return res.send(rows.map(row => Object.values(row)))
}

// Send the infoj object with values back to the client.
6 changes: 3 additions & 3 deletions mod/utils/sqlFilter.js
Original file line number Diff line number Diff line change
@@ -30,11 +30,11 @@ const filterTypes = {
let SQLparams

function addValues(val, skip) {

console.log('addValues',val);
SQLparams.push(Array.isArray(val)
&& val[0].map(v=>decodeURIComponent(v))
&& val[0].map(v=>decodeURIComponent(encodeURIComponent(v)))
|| skip && val
|| decodeURIComponent(val))
|| decodeURIComponent(encodeURIComponent(val)))

return SQLparams.length
}