Skip to content

Commit 94bf90d

Browse files
[WEB-3597] fix: guest work item view access when hyper mode is enabled (#6785)
* [WEB-3597] fix: guest work item view access when hyper mode is enabled * fix: only show work item created by the guest user if the guest_view_all_features is disabled
1 parent b0e941e commit 94bf90d

File tree

5 files changed

+63
-10
lines changed

5 files changed

+63
-10
lines changed

apiserver/plane/app/views/project/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ def list(self, request, slug):
177177
"module_view",
178178
"page_view",
179179
"inbox_view",
180+
"guest_view_all_features",
180181
"project_lead",
181182
"created_at",
182183
"updated_at",

packages/types/src/project/projects.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface IPartialProject {
2525
module_view: boolean;
2626
page_view: boolean;
2727
inbox_view: boolean;
28+
guest_view_all_features?: boolean;
2829
project_lead?: IUserLite | string | null;
2930
// Timestamps
3031
created_at?: Date;
@@ -46,11 +47,8 @@ export interface IProject extends IPartialProject {
4647
default_state?: string | null;
4748
description?: string;
4849
estimate?: string | null;
49-
guest_view_all_features?: boolean;
5050
anchor?: string | null;
5151
is_favorite?: boolean;
52-
is_issue_type_enabled?: boolean;
53-
is_time_tracking_enabled?: boolean;
5452
members?: string[];
5553
network?: number;
5654
timezone?: string;

web/core/local-db/storage.sqlite.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as Comlink from "comlink";
22
import set from "lodash/set";
33
// plane
44
import { EIssueGroupBYServerToProperty } from "@plane/constants";
5-
import { TIssue } from "@plane/types";
5+
import { TIssue, TIssueParams } from "@plane/types";
66
// lib
77
import { rootStore } from "@/lib/store-context";
88
// services
@@ -15,6 +15,7 @@ import { addIssuesBulk, syncDeletesToLocal } from "./utils/load-issues";
1515
import { loadWorkSpaceData } from "./utils/load-workspace";
1616
import { issueFilterCountQueryConstructor, issueFilterQueryConstructor } from "./utils/query-constructor";
1717
import { runQuery } from "./utils/query-executor";
18+
import { sanitizeWorkItemQueries } from "./utils/query-sanitizer.ts";
1819
import { createTables } from "./utils/tables";
1920
import { clearOPFS, getGroupedIssueResults, getSubGroupedIssueResults, log, logError } from "./utils/utils";
2021

@@ -269,7 +270,12 @@ export class Storage {
269270
return issue.updated_at;
270271
};
271272

272-
getIssues = async (workspaceSlug: string, projectId: string, queries: any, config: any) => {
273+
getIssues = async (
274+
workspaceSlug: string,
275+
projectId: string,
276+
queries: Partial<Record<TIssueParams, string | boolean>> | undefined,
277+
config: any
278+
) => {
273279
log("#### Queries", queries);
274280

275281
const currentProjectStatus = this.getStatus(projectId);
@@ -294,11 +300,12 @@ export class Storage {
294300
}
295301
}
296302

297-
const { cursor, group_by, sub_group_by } = queries;
303+
const sanitizedQueries = sanitizeWorkItemQueries(workspaceSlug, projectId, queries);
304+
const { cursor, group_by, sub_group_by } = sanitizedQueries || {};
298305

299-
const query = issueFilterQueryConstructor(this.workspaceSlug, projectId, queries);
306+
const query = issueFilterQueryConstructor(this.workspaceSlug, projectId, sanitizedQueries);
300307
log("#### Query", query);
301-
const countQuery = issueFilterCountQueryConstructor(this.workspaceSlug, projectId, queries);
308+
const countQuery = issueFilterCountQueryConstructor(this.workspaceSlug, projectId, sanitizedQueries);
302309
const start = performance.now();
303310
let issuesRaw: any[] = [];
304311
let count: any[];
@@ -313,7 +320,7 @@ export class Storage {
313320

314321
const { total_count } = count[0];
315322

316-
const [pageSize, page, offset] = cursor.split(":");
323+
const [pageSize, page, offset] = cursor && typeof cursor === "string" ? cursor.split(":") : [];
317324

318325
const groupByProperty: string =
319326
EIssueGroupBYServerToProperty[group_by as keyof typeof EIssueGroupBYServerToProperty];
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// plane constants
2+
import { EUserPermissions } from "@plane/constants";
3+
import { TIssueParams } from "@plane/types";
4+
// root store
5+
import { rootStore } from "@/lib/store-context";
6+
7+
export const sanitizeWorkItemQueries = (
8+
workspaceSlug: string,
9+
projectId: string,
10+
queries: Partial<Record<TIssueParams, string | boolean>> | undefined
11+
): Partial<Record<TIssueParams, string | boolean>> | undefined => {
12+
// Get current project details and user id and role for the project
13+
const currentProject = rootStore.projectRoot.project.getProjectById(projectId);
14+
const currentUserId = rootStore.user.data?.id;
15+
const currentUserRole = rootStore.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
16+
workspaceSlug,
17+
projectId
18+
);
19+
20+
// Only apply this restriction for guests when guest_view_all_features is disabled
21+
if (
22+
currentUserId &&
23+
currentUserRole === EUserPermissions.GUEST &&
24+
currentProject?.guest_view_all_features === false
25+
) {
26+
// Sanitize the created_by filter if it doesn't exist or if it exists and includes the current user id
27+
const existingCreatedByFilter = queries?.created_by;
28+
const shouldApplyFilter =
29+
!existingCreatedByFilter ||
30+
(typeof existingCreatedByFilter === "string" && existingCreatedByFilter.includes(currentUserId));
31+
32+
if (shouldApplyFilter) {
33+
queries = {
34+
...queries,
35+
created_by: currentUserId,
36+
};
37+
}
38+
}
39+
40+
return queries;
41+
};

web/core/services/issue/issue.service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { EIssueServiceType } from "@plane/constants";
22
// types
33
import {
4+
TIssueParams,
45
type IIssueDisplayProperties,
56
type TBulkOperationsPayload,
67
type TIssue,
@@ -75,7 +76,12 @@ export class IssueService extends APIService {
7576
});
7677
}
7778

78-
async getIssues(workspaceSlug: string, projectId: string, queries?: any, config = {}): Promise<TIssuesResponse> {
79+
async getIssues(
80+
workspaceSlug: string,
81+
projectId: string,
82+
queries?: Partial<Record<TIssueParams, string | boolean>>,
83+
config = {}
84+
): Promise<TIssuesResponse> {
7985
if (getIssuesShouldFallbackToServer(queries) || this.serviceType !== EIssueServiceType.ISSUES) {
8086
return await this.getIssuesFromServer(workspaceSlug, projectId, queries, config);
8187
}

0 commit comments

Comments
 (0)