harden report references in boards

This commit is contained in:
Francis Cao committed 2026-07-06 10:58:43 -07:00
1 parent a4a0167515
commit 7bdc2f215e
8 files changed
+346 -10

No files matched your search

+9 -1
View File
@@ -10,6 +10,8 @@ import {
canCreateWebsite,
canUpdateBoard,
canViewBoardEntities,
hasValidBoardReports,
stripInvalidBoardReports,
} from '@/permissions';
import { createBoard, getBoard } from '@/queries/prisma';
@@ -57,12 +59,18 @@ export async function POST(request: Request, { params }: { params: Promise<{ boa
return badRequest({ message: 'Board contains inaccessible entities.' });
}
const sanitizedParameters = await stripInvalidBoardReports(sourceType, parameters);
if (!(await hasValidBoardReports(sourceType, sanitizedParameters))) {
return badRequest({ message: 'Board contains invalid saved reports.' });
}
const result = await createBoard({
id: uuid(),
type: sourceType,
name: body.name ?? sourceBoard.name,
description: body.description ?? sourceBoard.description,
parameters: parameters as Prisma.InputJsonValue,
parameters: sanitizedParameters as Prisma.InputJsonValue,
teamId: sourceBoard.teamId,
userId: sourceBoard.teamId ? undefined : sourceBoard.userId ?? auth.user.id,
});
+11 -1
View File
@@ -3,7 +3,13 @@ import { BOARD_TYPES, normalizeBoardType } from '@/lib/boards';
import type { BoardParameters } from '@/lib/types';
import { parseRequest } from '@/lib/request';
import { badRequest, json, ok, serverError, unauthorized } from '@/lib/response';
import { canDeleteBoard, canUpdateBoard, canViewBoard, canViewBoardEntities } from '@/permissions';
import {
canDeleteBoard,
canUpdateBoard,
canViewBoard,
canViewBoardEntities,
hasValidBoardReports,
} from '@/permissions';
import { deleteBoard, getBoard, updateBoard } from '@/queries/prisma';
export async function GET(request: Request, { params }: { params: Promise<{ boardId: string }> }) {
@@ -68,6 +74,10 @@ export async function POST(request: Request, { params }: { params: Promise<{ boa
if (!(await canViewBoardEntities(auth, nextType, nextParameters))) {
return badRequest({ message: 'Board contains inaccessible entities.' });
}
if (!(await hasValidBoardReports(nextType, nextParameters))) {
return badRequest({ message: 'Board contains invalid saved reports.' });
}
}
try {
+10 -1
View File
@@ -4,7 +4,12 @@ import { uuid } from '@/lib/crypto';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { badRequest, json, unauthorized } from '@/lib/response';
import { pagingParams, searchParams, sortingParams } from '@/lib/schema';
import { canCreateTeamWebsite, canCreateWebsite, canViewBoardEntities } from '@/permissions';
import {
canCreateTeamWebsite,
canCreateWebsite,
canViewBoardEntities,
hasValidBoardReports,
} from '@/permissions';
import { createBoard, getUserBoards } from '@/queries/prisma';
export async function GET(request: Request) {
@@ -62,6 +67,10 @@ export async function POST(request: Request) {
return badRequest({ message: 'Board contains inaccessible entities.' });
}
if (!(await hasValidBoardReports(body.type, body.parameters))) {
return badRequest({ message: 'Board contains invalid saved reports.' });
}
const data = {
...body,
type: normalizeBoardType(body.type),
+6 -1
View File
@@ -1,6 +1,7 @@
import { z } from 'zod';
import { hasValidBoardReports } from '@/permissions';
import { parseRequest } from '@/lib/request';
import { json, unauthorized } from '@/lib/response';
import { badRequest, json, unauthorized } from '@/lib/response';
import { createBoard, getBoard, updateBoard } from '@/queries/prisma';
export async function GET(request: Request) {
@@ -45,6 +46,10 @@ export async function POST(request: Request) {
parameters: body.parameters ?? {},
};
if (!(await hasValidBoardReports(existing?.type ?? 'dashboard', data.parameters))) {
return badRequest({ message: 'Board contains invalid saved reports.' });
}
if (existing) {
const result = await updateBoard(userId, data);