mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 14:17:13 +01:00
Add api validations.
This commit is contained in:
parent
7d5a24044a
commit
7a7233ead4
41 changed files with 690 additions and 180 deletions
|
|
@ -1,19 +1,20 @@
|
|||
import redis from '@umami/redis-client';
|
||||
import cors from 'cors';
|
||||
import debug from 'debug';
|
||||
import { getAuthToken, parseShareToken } from 'lib/auth';
|
||||
import { ROLES } from 'lib/constants';
|
||||
import { isUuid, secret } from 'lib/crypto';
|
||||
import { findSession } from 'lib/session';
|
||||
import {
|
||||
createMiddleware,
|
||||
unauthorized,
|
||||
badRequest,
|
||||
createMiddleware,
|
||||
parseSecureToken,
|
||||
tooManyRequest,
|
||||
unauthorized,
|
||||
} from 'next-basics';
|
||||
import debug from 'debug';
|
||||
import cors from 'cors';
|
||||
import redis from '@umami/redis-client';
|
||||
import { findSession } from 'lib/session';
|
||||
import { getAuthToken, parseShareToken } from 'lib/auth';
|
||||
import { secret, isUuid } from 'lib/crypto';
|
||||
import { ROLES } from 'lib/constants';
|
||||
import { getUserById } from '../queries';
|
||||
import { NextApiRequestCollect } from 'pages/api/send';
|
||||
import { getUserById } from '../queries';
|
||||
import { NextApiRequestQueryBody } from './types';
|
||||
|
||||
const log = debug('umami:middleware');
|
||||
|
||||
|
|
@ -75,3 +76,15 @@ export const useAuth = createMiddleware(async (req, res, next) => {
|
|||
|
||||
next();
|
||||
});
|
||||
|
||||
export const useValidate = createMiddleware(async (req: any, res, next) => {
|
||||
try {
|
||||
const { yup } = req as NextApiRequestQueryBody;
|
||||
|
||||
yup[req.method].validateSync({ ...req.query, ...req.body });
|
||||
} catch (e: any) {
|
||||
return badRequest(res, e.message);
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
|
|
|||
17
lib/types.ts
17
lib/types.ts
|
|
@ -5,11 +5,13 @@ import {
|
|||
EVENT_TYPE,
|
||||
KAFKA_TOPIC,
|
||||
REPORT_FILTER_TYPES,
|
||||
REPORT_TYPES,
|
||||
ROLES,
|
||||
TEAM_FILTER_TYPES,
|
||||
USER_FILTER_TYPES,
|
||||
WEBSITE_FILTER_TYPES,
|
||||
} from './constants';
|
||||
import * as yup from 'yup';
|
||||
|
||||
type ObjectValues<T> = T[keyof T];
|
||||
|
||||
|
|
@ -18,6 +20,8 @@ export type Role = ObjectValues<typeof ROLES>;
|
|||
export type EventType = ObjectValues<typeof EVENT_TYPE>;
|
||||
export type DynamicDataType = ObjectValues<typeof DATA_TYPE>;
|
||||
export type KafkaTopic = ObjectValues<typeof KAFKA_TOPIC>;
|
||||
export type ReportType = ObjectValues<typeof REPORT_TYPES>;
|
||||
|
||||
export type ReportSearchFilterType = ObjectValues<typeof REPORT_FILTER_TYPES>;
|
||||
export type UserSearchFilterType = ObjectValues<typeof USER_FILTER_TYPES>;
|
||||
export type WebsiteSearchFilterType = ObjectValues<typeof WEBSITE_FILTER_TYPES>;
|
||||
|
|
@ -47,8 +51,8 @@ export interface ReportSearchFilter extends SearchFilter<ReportSearchFilterType>
|
|||
export interface SearchFilter<T> {
|
||||
filter?: string;
|
||||
filterType?: T;
|
||||
pageSize?: number;
|
||||
page?: number;
|
||||
pageSize: number;
|
||||
page: number;
|
||||
orderBy?: string;
|
||||
}
|
||||
|
||||
|
|
@ -76,11 +80,19 @@ export interface Auth {
|
|||
};
|
||||
}
|
||||
|
||||
export interface YupRequest {
|
||||
GET?: yup.ObjectSchema<any>;
|
||||
POST?: yup.ObjectSchema<any>;
|
||||
PUT?: yup.ObjectSchema<any>;
|
||||
DELETE?: yup.ObjectSchema<any>;
|
||||
}
|
||||
|
||||
export interface NextApiRequestQueryBody<TQuery = any, TBody = any> extends NextApiRequest {
|
||||
auth?: Auth;
|
||||
query: TQuery & { [key: string]: string | string[] };
|
||||
body: TBody;
|
||||
headers: any;
|
||||
yup: YupRequest;
|
||||
}
|
||||
|
||||
export interface NextApiRequestAuth extends NextApiRequest {
|
||||
|
|
@ -168,7 +180,6 @@ export interface RealtimeUpdate {
|
|||
export interface DateRange {
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
unit: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
19
lib/yup.ts
Normal file
19
lib/yup.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import * as yup from 'yup';
|
||||
|
||||
export function getDateRangeValidation() {
|
||||
return {
|
||||
startAt: yup.number().integer().required(),
|
||||
endAt: yup.number().integer().moreThan(yup.ref('startAt')).required(),
|
||||
};
|
||||
}
|
||||
|
||||
// ex: /funnel|insights|retention/i
|
||||
export function getFilterValidation(matchRegex) {
|
||||
return {
|
||||
filter: yup.string(),
|
||||
filterType: yup.string().matches(matchRegex),
|
||||
pageSize: yup.number().integer().positive().max(200),
|
||||
page: yup.number().integer().positive(),
|
||||
orderBy: yup.string(),
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue