umami/src/pages/api/reports/[reportId].ts

103 lines
2.5 KiB
TypeScript
Raw Normal View History

2023-08-20 05:23:15 +00:00
import { canDeleteReport, canUpdateReport, canViewReport } from 'lib/auth';
import { useAuth, useCors, useValidate } from 'lib/middleware';
import { NextApiRequestQueryBody, ReportType, YupRequest } from 'lib/types';
2023-05-18 20:13:18 +00:00
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
2024-01-30 08:10:25 +00:00
import { deleteReport, getReport, updateReport } from 'queries';
2023-08-20 05:23:15 +00:00
import * as yup from 'yup';
2023-05-18 20:13:18 +00:00
export interface ReportRequestQuery {
2024-02-01 06:08:48 +00:00
reportId: string;
2023-05-18 20:13:18 +00:00
}
export interface ReportRequestBody {
2023-05-18 20:13:18 +00:00
websiteId: string;
2023-08-20 05:23:15 +00:00
type: ReportType;
name: string;
description: string;
2023-05-18 20:13:18 +00:00
parameters: string;
}
2023-08-20 05:23:15 +00:00
const schema: YupRequest = {
GET: yup.object().shape({
2024-02-01 06:08:48 +00:00
reportId: yup.string().uuid().required(),
2023-08-20 05:23:15 +00:00
}),
POST: yup.object().shape({
2024-02-01 06:08:48 +00:00
reportId: yup.string().uuid().required(),
2023-08-20 05:23:15 +00:00
websiteId: yup.string().uuid().required(),
type: yup
.string()
2024-06-20 04:41:45 +00:00
.matches(/funnel|insights|retention|utm|goals|journey|revenue/i)
2023-08-20 05:23:15 +00:00
.required(),
name: yup.string().max(200).required(),
description: yup.string().max(500),
parameters: yup
.object()
.test('len', 'Must not exceed 6000 characters.', val => JSON.stringify(val).length < 6000),
}),
DELETE: yup.object().shape({
2024-02-01 06:08:48 +00:00
reportId: yup.string().uuid().required(),
2023-08-20 05:23:15 +00:00
}),
};
2023-05-18 20:13:18 +00:00
export default async (
req: NextApiRequestQueryBody<ReportRequestQuery, ReportRequestBody>,
2023-05-18 20:13:18 +00:00
res: NextApiResponse,
) => {
await useCors(req, res);
await useAuth(req, res);
2023-09-30 03:24:48 +00:00
await useValidate(schema, req, res);
2023-08-20 05:23:15 +00:00
2024-02-01 06:08:48 +00:00
const { reportId } = req.query;
2023-07-30 07:11:26 +00:00
const {
user: { id: userId },
} = req.auth;
2023-05-18 20:13:18 +00:00
2023-07-30 07:11:26 +00:00
if (req.method === 'GET') {
2024-01-30 08:10:25 +00:00
const report = await getReport(reportId);
2023-05-18 20:13:18 +00:00
2023-07-30 07:11:26 +00:00
if (!(await canViewReport(req.auth, report))) {
2023-05-18 20:13:18 +00:00
return unauthorized(res);
}
2023-07-30 07:11:26 +00:00
report.parameters = JSON.parse(report.parameters);
2023-07-30 07:11:26 +00:00
return ok(res, report);
2023-05-18 20:13:18 +00:00
}
if (req.method === 'POST') {
const { websiteId, type, name, description, parameters } = req.body;
2023-05-18 20:13:18 +00:00
2024-01-30 08:10:25 +00:00
const report = await getReport(reportId);
2023-05-18 20:13:18 +00:00
2023-07-30 07:11:26 +00:00
if (!(await canUpdateReport(req.auth, report))) {
2023-05-18 20:13:18 +00:00
return unauthorized(res);
}
2023-07-30 05:03:34 +00:00
const result = await updateReport(reportId, {
websiteId,
userId,
type,
name,
description,
parameters: JSON.stringify(parameters),
} as any);
2023-05-18 20:13:18 +00:00
return ok(res, result);
2023-05-18 20:13:18 +00:00
}
2023-07-30 07:11:26 +00:00
if (req.method === 'DELETE') {
2024-01-30 08:10:25 +00:00
const report = await getReport(reportId);
2023-07-30 07:11:26 +00:00
if (!(await canDeleteReport(req.auth, report))) {
return unauthorized(res);
}
await deleteReport(reportId);
return ok(res);
}
2023-05-18 20:13:18 +00:00
return methodNotAllowed(res);
};