fix permissions loop for charts route
This commit is contained in:
1 parent
712b32c7bf
commit
8a75208d5b
2 files changed
+73
-8
No files matched your search
@@ -1,10 +1,10 @@
|
||||
import { z } from 'zod';
|
||||
import { fromZonedTime } from 'date-fns-tz';
|
||||
import { parseDateRange } from '@/lib/date';
|
||||
import { canViewBatchWebsites } from '@/permissions/website';
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { json } from '@/lib/response';
|
||||
import { timezoneParam } from '@/lib/schema';
|
||||
import { canViewWebsite } from '@/permissions';
|
||||
import { getWebsiteListCharts } from '@/queries/sql';
|
||||
|
||||
const schema = z.object({
|
||||
@@ -32,13 +32,7 @@ export async function GET(request: Request) {
|
||||
: fromZonedTime(defaultRange.startDate, timezone);
|
||||
const endDate = hasDateRange ? new Date(query.endAt) : fromZonedTime(defaultRange.endDate, timezone);
|
||||
|
||||
const websiteIds = (
|
||||
await Promise.all(
|
||||
query.ids.map(async (websiteId: string) =>
|
||||
(await canViewWebsite(auth, websiteId)) ? websiteId : null,
|
||||
),
|
||||
)
|
||||
).filter(Boolean);
|
||||
const websiteIds = await canViewBatchWebsites(auth, query.ids);
|
||||
|
||||
const data = await getWebsiteListCharts(websiteIds, {
|
||||
startDate,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { hasPermission } from '@/lib/auth';
|
||||
import { PERMISSIONS } from '@/lib/constants';
|
||||
import { getEntity } from '@/lib/entity';
|
||||
import prisma from '@/lib/prisma';
|
||||
import type { Auth } from '@/lib/types';
|
||||
import { getTeamUser, getWebsite } from '@/queries/prisma';
|
||||
|
||||
@@ -39,6 +40,76 @@ export async function canViewWebsite({ user, shareToken }: Auth, websiteId: stri
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function canViewBatchWebsites({ user, shareToken }: Auth, websiteIds: string[]) {
|
||||
if (!websiteIds.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const requestedIds = Array.from(new Set(websiteIds));
|
||||
|
||||
if (user?.isAdmin) {
|
||||
return requestedIds;
|
||||
}
|
||||
|
||||
const shareAllowedIds = new Set(
|
||||
[
|
||||
shareToken?.websiteId,
|
||||
shareToken?.pixelId,
|
||||
shareToken?.linkId,
|
||||
...(shareToken?.websiteIds ?? []),
|
||||
...(shareToken?.pixelIds ?? []),
|
||||
...(shareToken?.linkIds ?? []),
|
||||
].filter((id): id is string => Boolean(id)),
|
||||
);
|
||||
|
||||
if (!user) {
|
||||
return requestedIds.filter(id => shareAllowedIds.has(id));
|
||||
}
|
||||
|
||||
const websites = await prisma.client.website.findMany({
|
||||
where: {
|
||||
id: {
|
||||
in: requestedIds,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
userId: true,
|
||||
teamId: true,
|
||||
},
|
||||
});
|
||||
|
||||
const ownedIds = new Set(
|
||||
websites.filter(website => website.userId === user.id).map(website => website.id),
|
||||
);
|
||||
const teamIds = Array.from(
|
||||
new Set(websites.map(website => website.teamId).filter((teamId): teamId is string => Boolean(teamId))),
|
||||
);
|
||||
const teamUsers = teamIds.length
|
||||
? await prisma.client.teamUser.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
teamId: {
|
||||
in: teamIds,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
teamId: true,
|
||||
},
|
||||
})
|
||||
: [];
|
||||
const allowedTeamIds = new Set(teamUsers.map(teamUser => teamUser.teamId));
|
||||
const teamOwnedIds = new Set(
|
||||
websites
|
||||
.filter(website => website.teamId && allowedTeamIds.has(website.teamId))
|
||||
.map(website => website.id),
|
||||
);
|
||||
|
||||
return requestedIds.filter(
|
||||
id => shareAllowedIds.has(id) || ownedIds.has(id) || teamOwnedIds.has(id),
|
||||
);
|
||||
}
|
||||
|
||||
export async function canViewAllWebsites({ user }: Auth) {
|
||||
return user?.isAdmin ?? false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user