Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Brian Cao 2023-09-06 11:37:43 -07:00
commit 6bd9916310
161 changed files with 4117 additions and 1753 deletions

View file

@ -2,21 +2,19 @@ import { NextApiRequest, NextApiResponse } from 'next';
import { ok, methodNotAllowed } from 'next-basics';
export interface ConfigResponse {
basePath: string;
trackerScriptName: string;
updatesDisabled: boolean;
telemetryDisabled: boolean;
cloudMode: boolean;
trackerScriptName: string;
uiDisabled: boolean;
updatesDisabled: boolean;
}
export default async (req: NextApiRequest, res: NextApiResponse<ConfigResponse>) => {
if (req.method === 'GET') {
return ok(res, {
basePath: process.env.BASE_PATH || '',
trackerScriptName: process.env.TRACKER_SCRIPT_NAME,
updatesDisabled: !!process.env.DISABLE_UPDATES,
telemetryDisabled: !!process.env.DISABLE_TELEMETRY,
cloudMode: !!process.env.CLOUD_MODE,
trackerScriptName: process.env.TRACKER_SCRIPT_NAME,
uiDisabled: !!process.env.DISABLE_UI,
updatesDisabled: !!process.env.DISABLE_UPDATES,
});
}

View file

@ -23,7 +23,6 @@ export interface UserPasswordRequestBody {
const schema = {
POST: yup.object().shape({
id: yup.string().uuid().required(),
currentPassword: yup.string().required(),
newPassword: yup.string().min(8).required(),
}),

View file

@ -3,11 +3,11 @@ import ipaddr from 'ipaddr.js';
import isbot from 'isbot';
import { COLLECTION_TYPE, HOSTNAME_REGEX } from 'lib/constants';
import { secret } from 'lib/crypto';
import { getIpAddress, getJsonBody } from 'lib/detect';
import { getIpAddress } from 'lib/detect';
import { useCors, useSession, useValidate } from 'lib/middleware';
import { CollectionType, YupRequest } from 'lib/types';
import { NextApiRequest, NextApiResponse } from 'next';
import { badRequest, createToken, forbidden, ok, send } from 'next-basics';
import { badRequest, createToken, forbidden, methodNotAllowed, ok, send } from 'next-basics';
import { saveEvent, saveSessionData } from 'queries';
import * as yup from 'yup';
@ -73,71 +73,75 @@ const schema = {
export default async (req: NextApiRequestCollect, res: NextApiResponse) => {
await useCors(req, res);
if (isbot(req.headers['user-agent']) && !process.env.DISABLE_BOT_CHECK) {
return ok(res);
}
const { type, payload } = getJsonBody<CollectRequestBody>(req);
req.yup = schema;
await useValidate(req, res);
if (await hasBlockedIp(req)) {
return forbidden(res);
}
const { url, referrer, name: eventName, data: eventData, title: pageTitle } = payload;
await useSession(req, res);
const session = req.session;
if (type === COLLECTION_TYPE.event) {
// eslint-disable-next-line prefer-const
let [urlPath, urlQuery] = url?.split('?') || [];
let [referrerPath, referrerQuery] = referrer?.split('?') || [];
let referrerDomain;
if (!urlPath) {
urlPath = '/';
if (req.method === 'POST') {
if (isbot(req.headers['user-agent']) && !process.env.DISABLE_BOT_CHECK) {
return ok(res);
}
if (referrerPath?.startsWith('http')) {
const refUrl = new URL(referrer);
referrerPath = refUrl.pathname;
referrerQuery = refUrl.search.substring(1);
referrerDomain = refUrl.hostname.replace(/www\./, '');
const { type, payload } = req.body;
req.yup = schema;
await useValidate(req, res);
if (await hasBlockedIp(req)) {
return forbidden(res);
}
if (process.env.REMOVE_TRAILING_SLASH) {
urlPath = urlPath.replace(/.+\/$/, '');
const { url, referrer, name: eventName, data: eventData, title: pageTitle } = payload;
await useSession(req, res);
const session = req.session;
if (type === COLLECTION_TYPE.event) {
// eslint-disable-next-line prefer-const
let [urlPath, urlQuery] = url?.split('?') || [];
let [referrerPath, referrerQuery] = referrer?.split('?') || [];
let referrerDomain;
if (!urlPath) {
urlPath = '/';
}
if (referrerPath?.startsWith('http')) {
const refUrl = new URL(referrer);
referrerPath = refUrl.pathname;
referrerQuery = refUrl.search.substring(1);
referrerDomain = refUrl.hostname.replace(/www\./, '');
}
if (process.env.REMOVE_TRAILING_SLASH) {
urlPath = urlPath.replace(/.+\/$/, '');
}
await saveEvent({
urlPath,
urlQuery,
referrerPath,
referrerQuery,
referrerDomain,
pageTitle,
eventName,
eventData,
...session,
sessionId: session.id,
});
}
await saveEvent({
urlPath,
urlQuery,
referrerPath,
referrerQuery,
referrerDomain,
pageTitle,
eventName,
eventData,
...session,
sessionId: session.id,
});
if (type === COLLECTION_TYPE.identify) {
if (!eventData) {
return badRequest(res, 'Data required.');
}
await saveSessionData({ ...session, sessionData: eventData, sessionId: session.id });
}
const token = createToken(session, secret());
return send(res, token);
}
if (type === COLLECTION_TYPE.identify) {
if (!eventData) {
return badRequest(res, 'Data required.');
}
await saveSessionData({ ...session, sessionData: eventData, sessionId: session.id });
}
const token = createToken(session, secret());
return send(res, token);
return methodNotAllowed(res);
};
async function hasBlockedIp(req: NextApiRequestCollect) {

17
src/pages/api/version.ts Normal file
View file

@ -0,0 +1,17 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { ok, methodNotAllowed } from 'next-basics';
import { CURRENT_VERSION } from 'lib/constants';
export interface VersionResponse {
version: string;
}
export default async (req: NextApiRequest, res: NextApiResponse<VersionResponse>) => {
if (req.method === 'GET') {
return ok(res, {
version: CURRENT_VERSION,
});
}
return methodNotAllowed(res);
};

View file

@ -13,23 +13,26 @@ export interface WebsiteMetricsRequestQuery {
type: string;
startAt: number;
endAt: number;
url: string;
referrer: string;
title: string;
query: string;
event: string;
os: string;
browser: string;
device: string;
country: string;
region: string;
city: string;
language: string;
url?: string;
referrer?: string;
title?: string;
query?: string;
os?: string;
browser?: string;
device?: string;
country?: string;
region?: string;
city?: string;
language?: string;
event?: string;
}
const schema = {
GET: yup.object().shape({
id: yup.string().uuid().required(),
type: yup.string().required(),
startAt: yup.number().required(),
endAt: yup.number().required(),
}),
};
@ -50,7 +53,6 @@ export default async (
referrer,
title,
query,
event,
os,
browser,
device,
@ -58,6 +60,7 @@ export default async (
region,
city,
language,
event,
} = req.query;
if (req.method === 'GET') {
@ -74,7 +77,6 @@ export default async (
referrer,
title,
query,
event,
os,
browser,
device,
@ -82,10 +84,9 @@ export default async (
region,
city,
language,
event,
};
filters[type] = undefined;
const column = FILTER_COLUMNS[type] || type;
if (SESSION_COLUMNS.includes(type)) {

View file

@ -42,8 +42,13 @@ export default async (
} = req.auth;
if (req.method === 'GET') {
req.query.id = userId;
req.query.pageSize = 100;
if (!req.query.id) {
req.query.id = userId;
}
if (!req.query.pageSize) {
req.query.pageSize = 100;
}
return userWebsites(req as any, res);
}