Fix share URL permissions. (#1745)

* Fix share URL permissions.

* Add sql param logic.

* Add permissions to edit website.

* Update permissions.

* Move parameters to param injection.

* Sanitize eventdata.

* Remove caret.

* Fix avg.
This commit is contained in:
Brian Cao 2023-01-18 15:09:49 -08:00 committed by GitHub
parent 558ce268a0
commit 922c3acab3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 139 additions and 79 deletions

View file

@ -35,7 +35,7 @@ export function isValidToken(token, validation) {
return false;
}
export async function allowQuery(req, type) {
export async function allowQuery(req, type, allowShareToken = true) {
const { id } = req.query;
const { userId, isAdmin, shareToken } = req.auth ?? {};
@ -44,7 +44,7 @@ export async function allowQuery(req, type) {
return true;
}
if (shareToken) {
if (allowShareToken && shareToken) {
return isValidToken(shareToken, { id });
}

View file

@ -36,6 +36,18 @@ function logQuery(e) {
log(chalk.yellow(e.params), '->', e.query, chalk.greenBright(`${e.duration}ms`));
}
function toUuid() {
const db = getDatabaseType(process.env.DATABASE_URL);
if (db === POSTGRESQL) {
return '::uuid';
}
if (db === MYSQL) {
return '';
}
}
function getClient(options) {
const prisma = new PrismaClient(options);
@ -85,11 +97,23 @@ function getTimestampInterval(field) {
}
}
function getJsonField(column, property, isNumber) {
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) {
const db = getDatabaseType(process.env.DATABASE_URL);
if (db === POSTGRESQL) {
let accessor = `${column} ->> '${property}'`;
params.push(property);
let accessor = `${column} ->> $${params.length}`;
if (isNumber) {
accessor = `CAST(${accessor} AS DECIMAL)`;
@ -99,21 +123,29 @@ function getJsonField(column, property, isNumber) {
}
if (db === MYSQL) {
return `${column} ->> "$.${property}"`;
return `${column} ->> '$.${property}'`;
}
}
function getEventDataColumnsQuery(column, columns) {
const query = Object.keys(columns).reduce((arr, key) => {
function getEventDataColumnsQuery(column, columns, params) {
const query = Object.keys(columns).reduce((arr, key, i) => {
const filter = columns[key];
if (filter === undefined) {
return arr;
}
const isNumber = ['sum', 'avg', 'min', 'max'].some(a => a === filter);
arr.push(`${filter}(${getJsonField(column, key, isNumber)}) as "${filter}(${key})"`);
switch (filter) {
case 'sum':
case 'avg':
case 'min':
case 'max':
arr.push(`${filter}(${getJsonField(column, key, true, params)}) as "${i}"`);
break;
case 'count':
arr.push(`${filter}(${getJsonField(column, key, false, params)}) as "${i}"`);
break;
}
return arr;
}, []);
@ -121,7 +153,7 @@ function getEventDataColumnsQuery(column, columns) {
return query.join(',\n');
}
function getEventDataFilterQuery(column, filters) {
function getEventDataFilterQuery(column, filters, params) {
const query = Object.keys(filters).reduce((arr, key) => {
const filter = filters[key];
@ -131,11 +163,9 @@ function getEventDataFilterQuery(column, filters) {
const isNumber = filter && typeof filter === 'number';
arr.push(
`${getJsonField(column, key, isNumber)} = ${
typeof filter === 'string' ? `'${filter}'` : filter
}`,
);
arr.push(`${getJsonField(column, key, isNumber, params)} = $${params.length + 1}`);
params.push(filter);
return arr;
}, []);
@ -248,11 +278,13 @@ const prisma = global[PRISMA] || getClient(PRISMA_OPTIONS);
export default {
client: prisma,
log,
toUuid,
getDateQuery,
getTimestampInterval,
getFilterQuery,
getEventDataColumnsQuery,
getEventDataFilterQuery,
getSanitizedColumns,
parseFilters,
rawQuery,
transaction,