fix sharetoken permissions on mixed boards

This commit is contained in:
Francis Cao
2026-04-13 11:32:47 -07:00
parent 5e6f88f123
commit a87d899e17
6 changed files with 44 additions and 13 deletions
+5 -2
View File
@@ -1,4 +1,4 @@
import { getBoardWebsiteIds } from '@/lib/boards';
import { getBoardEntityIds } from '@/lib/boards';
import { ENTITY_TYPE, ROLES } from '@/lib/constants';
import { secret } from '@/lib/crypto';
import { createToken } from '@/lib/jwt';
@@ -66,10 +66,13 @@ export async function GET(_request: Request, { params }: { params: Promise<{ slu
if (!board) return notFound();
entity = board;
data.boardId = share.entityId;
data.websiteIds = getBoardWebsiteIds({
const boardEntityIds = getBoardEntityIds({
type: board.type,
parameters: board.parameters as BoardParameters,
});
data.websiteIds = boardEntityIds.websiteIds;
data.pixelIds = boardEntityIds.pixelIds;
data.linkIds = boardEntityIds.linkIds;
} else if (share.shareType === ENTITY_TYPE.website) {
entity = await getWebsite(share.entityId);
if (!entity) return notFound();
+32 -8
View File
@@ -164,18 +164,34 @@ export function getFirstBoardComponentEntity(
return {};
}
export function getBoardWebsiteIds(
board?: Pick<Board, 'type' | 'parameters'> | Partial<Board>,
): string[] {
const ids = new Set<string>();
export function getBoardEntityIds(board?: Pick<Board, 'type' | 'parameters'> | Partial<Board>): {
websiteIds: string[];
pixelIds: string[];
linkIds: string[];
} {
const websiteIds = new Set<string>();
const pixelIds = new Set<string>();
const linkIds = new Set<string>();
const boardEntity = getBoardEntity(board);
if (boardEntity.entityType === BOARD_ENTITY_TYPES.website && boardEntity.entityId) {
ids.add(boardEntity.entityId);
websiteIds.add(boardEntity.entityId);
} else if (boardEntity.entityType === BOARD_ENTITY_TYPES.pixel && boardEntity.entityId) {
pixelIds.add(boardEntity.entityId);
} else if (boardEntity.entityType === BOARD_ENTITY_TYPES.link && boardEntity.entityId) {
linkIds.add(boardEntity.entityId);
}
if (board?.parameters?.websiteId) {
ids.add(board.parameters.websiteId);
websiteIds.add(board.parameters.websiteId);
}
if (board?.parameters?.pixelId) {
pixelIds.add(board.parameters.pixelId);
}
if (board?.parameters?.linkId) {
linkIds.add(board.parameters.linkId);
}
for (const row of board?.parameters?.rows ?? []) {
@@ -183,12 +199,20 @@ export function getBoardWebsiteIds(
const entity = getComponentEntity(column.component);
if (entity.entityType === BOARD_ENTITY_TYPES.website && entity.entityId) {
ids.add(entity.entityId);
websiteIds.add(entity.entityId);
} else if (entity.entityType === BOARD_ENTITY_TYPES.pixel && entity.entityId) {
pixelIds.add(entity.entityId);
} else if (entity.entityType === BOARD_ENTITY_TYPES.link && entity.entityId) {
linkIds.add(entity.entityId);
}
}
}
return [...ids];
return {
websiteIds: [...websiteIds],
pixelIds: [...pixelIds],
linkIds: [...linkIds],
};
}
export function clearBoardEntity(parameters: BoardParameters = {}): BoardParameters {
+2
View File
@@ -24,7 +24,9 @@ export interface Auth {
websiteIds?: string[];
boardId?: string;
pixelId?: string;
pixelIds?: string[];
linkId?: string;
linkIds?: string[];
};
}
+1 -1
View File
@@ -8,7 +8,7 @@ export async function canViewLink({ user, shareToken }: Auth, linkId: string) {
return true;
}
if (shareToken?.linkId === linkId || shareToken?.websiteId === linkId) {
if (shareToken?.linkId === linkId || shareToken?.websiteId === linkId || shareToken?.linkIds?.includes(linkId)) {
return true;
}
+1 -1
View File
@@ -8,7 +8,7 @@ export async function canViewPixel({ user, shareToken }: Auth, pixelId: string)
return true;
}
if (shareToken?.pixelId === pixelId || shareToken?.websiteId === pixelId) {
if (shareToken?.pixelId === pixelId || shareToken?.websiteId === pixelId || shareToken?.pixelIds?.includes(pixelId)) {
return true;
}
+3 -1
View File
@@ -13,7 +13,9 @@ export async function canViewWebsite({ user, shareToken }: Auth, websiteId: stri
shareToken?.websiteId === websiteId ||
shareToken?.pixelId === websiteId ||
shareToken?.linkId === websiteId ||
shareToken?.websiteIds?.includes(websiteId)
shareToken?.websiteIds?.includes(websiteId) ||
shareToken?.pixelIds?.includes(websiteId) ||
shareToken?.linkIds?.includes(websiteId)
) {
return true;
}