mirror of
https://github.com/umami-software/umami.git
synced 2026-02-20 20:45:39 +01:00
Merge branch 'master' into db-merge-test
This commit is contained in:
commit
00a7272ec7
44 changed files with 3303 additions and 228 deletions
|
|
@ -40,7 +40,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 ?? {};
|
||||
|
|
@ -49,7 +49,7 @@ export async function allowQuery(req, type) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (shareToken) {
|
||||
if (allowShareToken && shareToken) {
|
||||
return isValidToken(shareToken, { id });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,11 @@ export const customFormats = {
|
|||
p: 'ha',
|
||||
pp: 'h:mm:ss',
|
||||
},
|
||||
'fr-FR': {
|
||||
'M/d': 'd/M',
|
||||
'MMM d': 'd MMM',
|
||||
'EEE M/d': 'EEE d/M',
|
||||
},
|
||||
};
|
||||
|
||||
export function dateFormat(date, str, locale = 'en-US') {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
faIR,
|
||||
he,
|
||||
hi,
|
||||
hr,
|
||||
id,
|
||||
it,
|
||||
ja,
|
||||
|
|
@ -39,6 +40,7 @@ import {
|
|||
ca,
|
||||
hu,
|
||||
vi,
|
||||
si,
|
||||
} from 'date-fns/locale';
|
||||
|
||||
export const languages = {
|
||||
|
|
@ -61,6 +63,7 @@ export const languages = {
|
|||
'he-IL': { label: 'עברית', dateLocale: he },
|
||||
'hi-IN': { label: 'हिन्दी', dateLocale: hi },
|
||||
'hu-HU': { label: 'Hungarian', dateLocale: hu },
|
||||
'hr-HR': { label: 'Hrvatski', dateLocale: hr },
|
||||
'it-IT': { label: 'Italiano', dateLocale: it },
|
||||
'id-ID': { label: 'Bahasa Indonesia', dateLocale: id },
|
||||
'ja-JP': { label: '日本語', dateLocale: ja },
|
||||
|
|
@ -80,6 +83,7 @@ export const languages = {
|
|||
'fi-FI': { label: 'Suomi', dateLocale: fi },
|
||||
'sv-SE': { label: 'Svenska', dateLocale: sv },
|
||||
'ta-IN': { label: 'தமிழ்', dateLocale: ta },
|
||||
'si-LK': { label: 'සිංහල', dateLocale: si },
|
||||
'th-TH': { label: 'ภาษาไทย', dateLocale: th },
|
||||
'tr-TR': { label: 'Türkçe', dateLocale: tr },
|
||||
'uk-UA': { label: 'українська', dateLocale: uk },
|
||||
|
|
|
|||
|
|
@ -3,7 +3,12 @@ import cors from 'cors';
|
|||
import { getSession } from './session';
|
||||
import { parseAuthToken, parseShareToken } from './auth';
|
||||
|
||||
export const useCors = createMiddleware(cors());
|
||||
export const useCors = createMiddleware(
|
||||
cors({
|
||||
// Cache CORS preflight request 24 hours by default
|
||||
maxAge: process.env.CORS_MAX_AGE || 86400,
|
||||
}),
|
||||
);
|
||||
|
||||
export const useSession = createMiddleware(async (req, res, next) => {
|
||||
let session;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -92,11 +104,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 || db === COCKROACHDB) {
|
||||
let accessor = `${column} ->> '${property}'`;
|
||||
params.push(property);
|
||||
|
||||
let accessor = `${column} ->> $${params.length}`;
|
||||
|
||||
if (isNumber) {
|
||||
accessor = `CAST(${accessor} AS DECIMAL)`;
|
||||
|
|
@ -106,21 +130,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;
|
||||
}, []);
|
||||
|
|
@ -128,7 +160,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];
|
||||
|
||||
|
|
@ -138,11 +170,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;
|
||||
}, []);
|
||||
|
|
@ -255,11 +285,13 @@ const prisma = global[PRISMA] || getClient(PRISMA_OPTIONS);
|
|||
export default {
|
||||
client: prisma,
|
||||
log,
|
||||
toUuid,
|
||||
getDateQuery,
|
||||
getTimestampInterval,
|
||||
getFilterQuery,
|
||||
getEventDataColumnsQuery,
|
||||
getEventDataFilterQuery,
|
||||
getSanitizedColumns,
|
||||
parseFilters,
|
||||
rawQuery,
|
||||
transaction,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue