[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
This commit is contained in:
parent
b0e941e4e2
commit
94bf90dac5
5 changed files with 63 additions and 10 deletions
|
|
@ -177,6 +177,7 @@ class ProjectViewSet(BaseViewSet):
|
|||
"module_view",
|
||||
"page_view",
|
||||
"inbox_view",
|
||||
"guest_view_all_features",
|
||||
"project_lead",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
|
|
|
|||
4
packages/types/src/project/projects.d.ts
vendored
4
packages/types/src/project/projects.d.ts
vendored
|
|
@ -25,6 +25,7 @@ export interface IPartialProject {
|
|||
module_view: boolean;
|
||||
page_view: boolean;
|
||||
inbox_view: boolean;
|
||||
guest_view_all_features?: boolean;
|
||||
project_lead?: IUserLite | string | null;
|
||||
// Timestamps
|
||||
created_at?: Date;
|
||||
|
|
@ -46,11 +47,8 @@ export interface IProject extends IPartialProject {
|
|||
default_state?: string | null;
|
||||
description?: string;
|
||||
estimate?: string | null;
|
||||
guest_view_all_features?: boolean;
|
||||
anchor?: string | null;
|
||||
is_favorite?: boolean;
|
||||
is_issue_type_enabled?: boolean;
|
||||
is_time_tracking_enabled?: boolean;
|
||||
members?: string[];
|
||||
network?: number;
|
||||
timezone?: string;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import * as Comlink from "comlink";
|
|||
import set from "lodash/set";
|
||||
// plane
|
||||
import { EIssueGroupBYServerToProperty } from "@plane/constants";
|
||||
import { TIssue } from "@plane/types";
|
||||
import { TIssue, TIssueParams } from "@plane/types";
|
||||
// lib
|
||||
import { rootStore } from "@/lib/store-context";
|
||||
// services
|
||||
|
|
@ -15,6 +15,7 @@ import { addIssuesBulk, syncDeletesToLocal } from "./utils/load-issues";
|
|||
import { loadWorkSpaceData } from "./utils/load-workspace";
|
||||
import { issueFilterCountQueryConstructor, issueFilterQueryConstructor } from "./utils/query-constructor";
|
||||
import { runQuery } from "./utils/query-executor";
|
||||
import { sanitizeWorkItemQueries } from "./utils/query-sanitizer.ts";
|
||||
import { createTables } from "./utils/tables";
|
||||
import { clearOPFS, getGroupedIssueResults, getSubGroupedIssueResults, log, logError } from "./utils/utils";
|
||||
|
||||
|
|
@ -269,7 +270,12 @@ export class Storage {
|
|||
return issue.updated_at;
|
||||
};
|
||||
|
||||
getIssues = async (workspaceSlug: string, projectId: string, queries: any, config: any) => {
|
||||
getIssues = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
queries: Partial<Record<TIssueParams, string | boolean>> | undefined,
|
||||
config: any
|
||||
) => {
|
||||
log("#### Queries", queries);
|
||||
|
||||
const currentProjectStatus = this.getStatus(projectId);
|
||||
|
|
@ -294,11 +300,12 @@ export class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
const { cursor, group_by, sub_group_by } = queries;
|
||||
const sanitizedQueries = sanitizeWorkItemQueries(workspaceSlug, projectId, queries);
|
||||
const { cursor, group_by, sub_group_by } = sanitizedQueries || {};
|
||||
|
||||
const query = issueFilterQueryConstructor(this.workspaceSlug, projectId, queries);
|
||||
const query = issueFilterQueryConstructor(this.workspaceSlug, projectId, sanitizedQueries);
|
||||
log("#### Query", query);
|
||||
const countQuery = issueFilterCountQueryConstructor(this.workspaceSlug, projectId, queries);
|
||||
const countQuery = issueFilterCountQueryConstructor(this.workspaceSlug, projectId, sanitizedQueries);
|
||||
const start = performance.now();
|
||||
let issuesRaw: any[] = [];
|
||||
let count: any[];
|
||||
|
|
@ -313,7 +320,7 @@ export class Storage {
|
|||
|
||||
const { total_count } = count[0];
|
||||
|
||||
const [pageSize, page, offset] = cursor.split(":");
|
||||
const [pageSize, page, offset] = cursor && typeof cursor === "string" ? cursor.split(":") : [];
|
||||
|
||||
const groupByProperty: string =
|
||||
EIssueGroupBYServerToProperty[group_by as keyof typeof EIssueGroupBYServerToProperty];
|
||||
|
|
|
|||
41
web/core/local-db/utils/query-sanitizer.ts.ts
Normal file
41
web/core/local-db/utils/query-sanitizer.ts.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// plane constants
|
||||
import { EUserPermissions } from "@plane/constants";
|
||||
import { TIssueParams } from "@plane/types";
|
||||
// root store
|
||||
import { rootStore } from "@/lib/store-context";
|
||||
|
||||
export const sanitizeWorkItemQueries = (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
queries: Partial<Record<TIssueParams, string | boolean>> | undefined
|
||||
): Partial<Record<TIssueParams, string | boolean>> | undefined => {
|
||||
// Get current project details and user id and role for the project
|
||||
const currentProject = rootStore.projectRoot.project.getProjectById(projectId);
|
||||
const currentUserId = rootStore.user.data?.id;
|
||||
const currentUserRole = rootStore.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
|
||||
workspaceSlug,
|
||||
projectId
|
||||
);
|
||||
|
||||
// Only apply this restriction for guests when guest_view_all_features is disabled
|
||||
if (
|
||||
currentUserId &&
|
||||
currentUserRole === EUserPermissions.GUEST &&
|
||||
currentProject?.guest_view_all_features === false
|
||||
) {
|
||||
// Sanitize the created_by filter if it doesn't exist or if it exists and includes the current user id
|
||||
const existingCreatedByFilter = queries?.created_by;
|
||||
const shouldApplyFilter =
|
||||
!existingCreatedByFilter ||
|
||||
(typeof existingCreatedByFilter === "string" && existingCreatedByFilter.includes(currentUserId));
|
||||
|
||||
if (shouldApplyFilter) {
|
||||
queries = {
|
||||
...queries,
|
||||
created_by: currentUserId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return queries;
|
||||
};
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { EIssueServiceType } from "@plane/constants";
|
||||
// types
|
||||
import {
|
||||
TIssueParams,
|
||||
type IIssueDisplayProperties,
|
||||
type TBulkOperationsPayload,
|
||||
type TIssue,
|
||||
|
|
@ -75,7 +76,12 @@ export class IssueService extends APIService {
|
|||
});
|
||||
}
|
||||
|
||||
async getIssues(workspaceSlug: string, projectId: string, queries?: any, config = {}): Promise<TIssuesResponse> {
|
||||
async getIssues(
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
queries?: Partial<Record<TIssueParams, string | boolean>>,
|
||||
config = {}
|
||||
): Promise<TIssuesResponse> {
|
||||
if (getIssuesShouldFallbackToServer(queries) || this.serviceType !== EIssueServiceType.ISSUES) {
|
||||
return await this.getIssuesFromServer(workspaceSlug, projectId, queries, config);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue