mirror of
https://github.com/docmost/docmost.git
synced 2026-05-20 00:14:10 +08:00
short circuit sidebar permissions
This commit is contained in:
@@ -298,11 +298,17 @@ export class PageController {
|
|||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const spaceCanEdit = ability.can(
|
||||||
|
SpaceCaslAction.Edit,
|
||||||
|
SpaceCaslSubject.Page,
|
||||||
|
);
|
||||||
|
|
||||||
return this.pageService.getSidebarPages(
|
return this.pageService.getSidebarPages(
|
||||||
spaceId,
|
spaceId,
|
||||||
pagination,
|
pagination,
|
||||||
dto.pageId,
|
dto.pageId,
|
||||||
user.id,
|
user.id,
|
||||||
|
spaceCanEdit,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ export class PageService {
|
|||||||
pagination: PaginationOptions,
|
pagination: PaginationOptions,
|
||||||
pageId?: string,
|
pageId?: string,
|
||||||
userId?: string,
|
userId?: string,
|
||||||
|
spaceCanEdit?: boolean,
|
||||||
): Promise<CursorPaginationResult<Partial<Page> & { hasChildren: boolean }>> {
|
): Promise<CursorPaginationResult<Partial<Page> & { hasChildren: boolean }>> {
|
||||||
let query = this.db
|
let query = this.db
|
||||||
.selectFrom('pages')
|
.selectFrom('pages')
|
||||||
@@ -222,42 +223,53 @@ export class PageService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (userId && result.items.length > 0) {
|
if (userId && result.items.length > 0) {
|
||||||
const pageIds = result.items.map((p: any) => p.id);
|
const hasRestrictions =
|
||||||
|
await this.pagePermissionRepo.hasRestrictedPagesInSpace(spaceId);
|
||||||
// Single query to get accessible pages with their edit permissions
|
|
||||||
const accessiblePages =
|
|
||||||
await this.pagePermissionRepo.filterAccessiblePageIdsWithPermissions(
|
|
||||||
pageIds,
|
|
||||||
userId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const permissionMap = new Map(
|
|
||||||
accessiblePages.map((p) => [p.id, p.canEdit]),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Filter and add canEdit flag in one pass
|
|
||||||
result.items = result.items
|
|
||||||
.filter((p: any) => permissionMap.has(p.id))
|
|
||||||
.map((p: any) => ({
|
|
||||||
...p,
|
|
||||||
canEdit: permissionMap.get(p.id),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// For pages with hasChildren: true, verify they have accessible children
|
|
||||||
const pagesWithChildren = result.items.filter((p: any) => p.hasChildren);
|
|
||||||
if (pagesWithChildren.length > 0) {
|
|
||||||
const parentIds = pagesWithChildren.map((p: any) => p.id);
|
|
||||||
const parentsWithAccessibleChildren =
|
|
||||||
await this.pagePermissionRepo.getParentIdsWithAccessibleChildren(
|
|
||||||
parentIds,
|
|
||||||
userId,
|
|
||||||
);
|
|
||||||
const hasAccessibleChildrenSet = new Set(parentsWithAccessibleChildren);
|
|
||||||
|
|
||||||
|
if (!hasRestrictions) {
|
||||||
result.items = result.items.map((p: any) => ({
|
result.items = result.items.map((p: any) => ({
|
||||||
...p,
|
...p,
|
||||||
hasChildren: p.hasChildren && hasAccessibleChildrenSet.has(p.id),
|
canEdit: spaceCanEdit ?? true,
|
||||||
}));
|
}));
|
||||||
|
} else {
|
||||||
|
const pageIds = result.items.map((p: any) => p.id);
|
||||||
|
|
||||||
|
const accessiblePages =
|
||||||
|
await this.pagePermissionRepo.filterAccessiblePageIdsWithPermissions(
|
||||||
|
pageIds,
|
||||||
|
userId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const permissionMap = new Map(
|
||||||
|
accessiblePages.map((p) => [p.id, p.canEdit]),
|
||||||
|
);
|
||||||
|
|
||||||
|
result.items = result.items
|
||||||
|
.filter((p: any) => permissionMap.has(p.id))
|
||||||
|
.map((p: any) => ({
|
||||||
|
...p,
|
||||||
|
canEdit: permissionMap.get(p.id),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const pagesWithChildren = result.items.filter(
|
||||||
|
(p: any) => p.hasChildren,
|
||||||
|
);
|
||||||
|
if (pagesWithChildren.length > 0) {
|
||||||
|
const parentIds = pagesWithChildren.map((p: any) => p.id);
|
||||||
|
const parentsWithAccessibleChildren =
|
||||||
|
await this.pagePermissionRepo.getParentIdsWithAccessibleChildren(
|
||||||
|
parentIds,
|
||||||
|
userId,
|
||||||
|
);
|
||||||
|
const hasAccessibleChildrenSet = new Set(
|
||||||
|
parentsWithAccessibleChildren,
|
||||||
|
);
|
||||||
|
|
||||||
|
result.items = result.items.map((p: any) => ({
|
||||||
|
...p,
|
||||||
|
hasChildren: p.hasChildren && hasAccessibleChildrenSet.has(p.id),
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user