Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d1db13c
chore(deps): bump vite in the npm_and_yarn group across 1 directory (…
dependabot[bot] Apr 7, 2026
7c2fc2d
fix: update Twitter icon and links to X (#8785) (#8790)
nielskaspers Apr 7, 2026
8a2579c
fix: prevent ORM field injection via segment parameter in analytics (…
sriramveeraghanta Apr 7, 2026
77c4b9c
fix: strip whitespace and handle null values in instance configuratio…
okxint Apr 8, 2026
6023e8c
[WEB-6784] feat scrollbar in shortcuts modal (#8872)
b-saikrishnakanth Apr 9, 2026
e6b9d4c
[WEB-6785] fix: update border for project timezone (#8870)
b-saikrishnakanth Apr 9, 2026
c21d2c6
chore: remove Intercom integration and chat support components (#8875)
sriramveeraghanta Apr 9, 2026
39325d2
chore: update dependencies (Django, cryptography, axios, lodash) (#8880)
sriramveeraghanta Apr 9, 2026
db3c8f2
[WEB-6840] feat: skip role & use-case steps for self-hosted instances…
anmolsinghbhatia Apr 13, 2026
bbf14fb
chore(deps): bump pytest (#8891)
dependabot[bot] Apr 14, 2026
13db2f8
enhance sub-issue query performance with optimized annotations and su…
PhuongPN6689 Apr 14, 2026
ac11c3e
fix: enforce workspace membership on V2 asset endpoints (#8885)
sriramveeraghanta Apr 20, 2026
a8a16c8
fix: replace IS_SELF_MANAGED with WEBHOOK_ALLOWED_IPS allowlist (#8884)
sriramveeraghanta Apr 20, 2026
45b4fc8
[SILO-1158] chore: add context for project in relations API (#8860)
Saurabhkmr98 Apr 20, 2026
aea66f5
fix: sanitize filenames in upload paths to prevent path traversal (#8…
sriramveeraghanta Apr 20, 2026
da41f14
chore(ci): suppress CodeQL file coverage deprecation warning (#8916)
sriramveeraghanta Apr 20, 2026
62b2d1b
chore: update CODEOWNERS for apps and deployments (#8919)
sriramveeraghanta Apr 20, 2026
f1d567a
chore: add Claude Code skills for PR descriptions and release notes (…
sriramveeraghanta Apr 20, 2026
c62930e
chore: bump up the package version
sriramveeraghanta Apr 20, 2026
03a2be8
chore(deps): bump lxml (#8925)
dependabot[bot] Apr 22, 2026
32fb88a
chore(deps): bump axios, uuid and add security overrides (#8930)
sriramveeraghanta Apr 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
contents: read
security-events: write

env:
CODEQL_ACTION_FILE_COVERAGE_ON_PRS: "false"

strategy:
fail-fast: false
matrix:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<p align="center">
<a href="https://plane.so/"><b>Website</b></a> β€’
<a href="https://forum.plane.so"><b>Forum</b></a> β€’
<a href="https://twitter.com/planepowers"><b>Twitter</b></a> β€’
<a href="https://x.com/planepowers"><b>X</b></a> β€’
<a href="https://docs.plane.so/"><b>Documentation</b></a>
</p>

Expand Down
19 changes: 2 additions & 17 deletions apps/admin/app/(all)/(dashboard)/general/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { Input, ToggleSwitch } from "@plane/ui";
import { ControllerInput } from "@/components/common/controller-input";
// hooks
import { useInstance } from "@/hooks/store";
// components
import { IntercomConfig } from "./intercom";

export interface IGeneralConfigurationForm {
instance: IInstance;
Expand All @@ -27,14 +25,13 @@ export interface IGeneralConfigurationForm {
export const GeneralConfigurationForm = observer(function GeneralConfigurationForm(props: IGeneralConfigurationForm) {
const { instance, instanceAdmins } = props;
// hooks
const { instanceConfigurations, updateInstanceInfo, updateInstanceConfigurations } = useInstance();
const { updateInstanceInfo } = useInstance();

// form data
const {
handleSubmit,
control,
formState: { errors, isSubmitting },
watch,
} = useForm<Partial<IInstance>>({
defaultValues: {
instance_name: instance?.instance_name,
Expand All @@ -45,17 +42,6 @@ export const GeneralConfigurationForm = observer(function GeneralConfigurationFo
const onSubmit = async (formData: Partial<IInstance>) => {
const payload: Partial<IInstance> = { ...formData };

// update the intercom configuration
const isIntercomEnabled =
instanceConfigurations?.find((config) => config.key === "IS_INTERCOM_ENABLED")?.value === "1";
if (!payload.is_telemetry_enabled && isIntercomEnabled) {
try {
await updateInstanceConfigurations({ IS_INTERCOM_ENABLED: "0" });
} catch (error) {
console.error(error);
}
}

await updateInstanceInfo(payload)
.then(() =>
setToast({
Expand Down Expand Up @@ -112,8 +98,7 @@ export const GeneralConfigurationForm = observer(function GeneralConfigurationFo
</div>

<div className="space-y-6">
<div className="border-b border-subtle pb-1.5 text-16 font-medium text-primary">Chat + telemetry</div>
<IntercomConfig isTelemetryEnabled={watch("is_telemetry_enabled") ?? false} />
<div className="border-b border-subtle pb-1.5 text-16 font-medium text-primary">Telemetry</div>
<div className="flex items-center gap-14">
<div className="flex grow items-center gap-4">
<div className="shrink-0">
Expand Down
86 changes: 0 additions & 86 deletions apps/admin/app/(all)/(dashboard)/general/intercom.tsx

This file was deleted.

42 changes: 25 additions & 17 deletions apps/api/plane/api/serializers/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,44 +480,52 @@ class Meta:
]


class IssueRelationRefSerializer(serializers.Serializer):
"""Project-scoped reference to a related work item."""

project_id = serializers.UUIDField(help_text="Project containing the related work item")
issue_id = serializers.UUIDField(help_text="ID of the related work item")


class IssueRelationResponseSerializer(serializers.Serializer):
"""
Serializer for issue relations response showing grouped relation types.

Returns issue IDs organized by relation type for efficient client-side processing.
Each list contains project_id and issue_id pairs so clients can resolve
cross-project relations.
"""

blocking = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that are blocking this issue",
child=IssueRelationRefSerializer(),
help_text="Work items blocking this issue",
)
blocked_by = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that this issue is blocked by",
child=IssueRelationRefSerializer(),
help_text="Work items this issue is blocked by",
)
duplicate = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that are duplicates of this issue",
child=IssueRelationRefSerializer(),
help_text="Duplicate work items",
)
relates_to = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that relate to this issue",
child=IssueRelationRefSerializer(),
help_text="Related work items",
)
start_after = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that start after this issue",
child=IssueRelationRefSerializer(),
help_text="Work items that start after this issue",
)
start_before = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that start before this issue",
child=IssueRelationRefSerializer(),
help_text="Work items that start before this issue",
)
finish_after = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that finish after this issue",
child=IssueRelationRefSerializer(),
help_text="Work items that finish after this issue",
)
finish_before = serializers.ListField(
child=serializers.UUIDField(),
help_text="List of issue IDs that finish before this issue",
child=IssueRelationRefSerializer(),
help_text="Work items that finish before this issue",
)


Expand Down
7 changes: 4 additions & 3 deletions apps/api/plane/api/views/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# Module Imports
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
from plane.settings.storage import S3Storage
from plane.utils.path_validator import sanitize_filename
from plane.db.models import FileAsset, User, Workspace
from plane.api.views.base import BaseAPIView
from plane.api.serializers import (
Expand Down Expand Up @@ -114,7 +115,7 @@ def post(self, request):
This endpoint generates the necessary credentials for direct S3 upload.
"""
# get the asset key
name = request.data.get("name")
name = sanitize_filename(request.data.get("name")) or "unnamed"
type = request.data.get("type", "image/jpeg")
size = int(request.data.get("size", settings.FILE_SIZE_LIMIT))
entity_type = request.data.get("entity_type", False)
Expand Down Expand Up @@ -287,7 +288,7 @@ def post(self, request):
necessary credentials for direct S3 upload with server-side authentication.
"""
# get the asset key
name = request.data.get("name")
name = sanitize_filename(request.data.get("name")) or "unnamed"
type = request.data.get("type", "image/jpeg")
size = int(request.data.get("size", settings.FILE_SIZE_LIMIT))
entity_type = request.data.get("entity_type", False)
Expand Down Expand Up @@ -498,7 +499,7 @@ def post(self, request, slug):
Create a presigned URL for uploading generic assets that can be bound to entities like work items.
Supports various file types and includes external source tracking for integrations.
"""
name = request.data.get("name")
name = sanitize_filename(request.data.get("name"))
type = request.data.get("type")
size = int(request.data.get("size", settings.FILE_SIZE_LIMIT))
project_id = request.data.get("project_id")
Expand Down
Loading
Loading