Sanitize eventdata.

pull/1745/head
Brian Cao 2023-01-17 21:59:14 -08:00
parent 509739fc9a
commit e6a6222088
3 changed files with 35 additions and 12 deletions

View File

@ -97,6 +97,16 @@ function getTimestampInterval(field) {
} }
} }
function getSanitizedColumns(columns) {
return Object.keys(columns).reduce((acc, keyName) => {
const sanitizedProperty = keyName.replace(/[^\w\s_]/g, '');
acc[sanitizedProperty] = columns[keyName];
return acc;
}, {});
}
function getJsonField(column, property, isNumber, params) { function getJsonField(column, property, isNumber, params) {
const db = getDatabaseType(process.env.DATABASE_URL); const db = getDatabaseType(process.env.DATABASE_URL);
@ -113,9 +123,7 @@ function getJsonField(column, property, isNumber, params) {
} }
if (db === MYSQL) { if (db === MYSQL) {
params.push(`$.?${params.length}`); return `${column} ->> '$.${property}'`;
return `${column} ->> ${params.length}`;
} }
} }
@ -276,6 +284,7 @@ export default {
getFilterQuery, getFilterQuery,
getEventDataColumnsQuery, getEventDataColumnsQuery,
getEventDataFilterQuery, getEventDataFilterQuery,
getSanitizedColumns,
parseFilters, parseFilters,
rawQuery, rawQuery,
transaction, transaction,

View File

@ -10,17 +10,21 @@ export default async (req, res) => {
const { id: websiteUuid } = req.query; const { id: websiteUuid } = req.query;
if (!(await allowQuery(req, TYPE_WEBSITE, false))) { if (req.method === 'GET') {
if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res); return unauthorized(res);
} }
if (req.method === 'GET') {
const website = await getWebsite({ websiteUuid }); const website = await getWebsite({ websiteUuid });
return ok(res, website); return ok(res, website);
} }
if (req.method === 'POST') { if (req.method === 'POST') {
if (!(await allowQuery(req, TYPE_WEBSITE, false))) {
return unauthorized(res);
}
const { name, domain, owner, enableShareUrl, shareId } = req.body; const { name, domain, owner, enableShareUrl, shareId } = req.body;
const { accountUuid } = req.auth; const { accountUuid } = req.auth;
@ -58,6 +62,10 @@ export default async (req, res) => {
} }
if (req.method === 'DELETE') { if (req.method === 'DELETE') {
if (!(await allowQuery(req, TYPE_WEBSITE, false))) {
return unauthorized(res);
}
await deleteWebsite(websiteUuid); await deleteWebsite(websiteUuid);
return ok(res); return ok(res);

View File

@ -10,15 +10,21 @@ export async function getEventData(...args) {
} }
async function relationalQuery(websiteId, { startDate, endDate, event_name, columns, filters }) { async function relationalQuery(websiteId, { startDate, endDate, event_name, columns, filters }) {
const { rawQuery, getEventDataColumnsQuery, getEventDataFilterQuery, toUuid } = prisma; const {
rawQuery,
getEventDataColumnsQuery,
getEventDataFilterQuery,
toUuid,
getSanitizedColumns,
} = prisma;
const sanitizedColumns = getSanitizedColumns(columns);
const params = [websiteId, startDate, endDate]; const params = [websiteId, startDate, endDate];
if (event_name) { if (event_name) {
params.push(event_name); params.push(event_name);
} }
const columnQuery = getEventDataColumnsQuery('event_data.event_data', columns, params); const columnQuery = getEventDataColumnsQuery('event_data.event_data', sanitizedColumns, params);
const filterQuery = const filterQuery =
Object.keys(filters).length > 0 Object.keys(filters).length > 0
? `and ${getEventDataFilterQuery('event_data.event_data', filters, params)}` ? `and ${getEventDataFilterQuery('event_data.event_data', filters, params)}`
@ -38,10 +44,10 @@ async function relationalQuery(websiteId, { startDate, endDate, event_name, colu
${filterQuery}`, ${filterQuery}`,
params, params,
).then(results => { ).then(results => {
const fields = Object.keys(columns); const fields = Object.keys(sanitizedColumns);
return Object.keys(results[0]).map((a, i) => { return Object.keys(results[0]).map((a, i) => {
return { x: `${columns[fields[i]]}(${fields[i]})`, y: results[0][i] }; return { x: `${sanitizedColumns[fields[i]]}(${fields[i]})`, y: results[0][i] };
}); });
}); });
} }