From ce69644d53104fb59128497f6e196ebf31c5c199 Mon Sep 17 00:00:00 2001 From: sriramveeraghanta Date: Fri, 12 Dec 2025 13:41:17 +0530 Subject: [PATCH 01/12] chore(deps): upgrade next themes package --- apps/admin/package.json | 2 +- apps/space/package.json | 2 +- apps/web/package.json | 2 +- package.json | 3 +- pnpm-lock.yaml | 248 ++-------------------------------------- 5 files changed, 15 insertions(+), 242 deletions(-) diff --git a/apps/admin/package.json b/apps/admin/package.json index e81a3e073..5f0f7f306 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -37,7 +37,7 @@ "lucide-react": "catalog:", "mobx": "catalog:", "mobx-react": "catalog:", - "next-themes": "^0.2.1", + "next-themes": "0.4.6", "react": "catalog:", "react-dom": "catalog:", "react-hook-form": "7.51.5", diff --git a/apps/space/package.json b/apps/space/package.json index 73101a7f6..1fe1fbd37 100644 --- a/apps/space/package.json +++ b/apps/space/package.json @@ -40,7 +40,7 @@ "mobx": "catalog:", "mobx-react": "catalog:", "mobx-utils": "catalog:", - "next-themes": "^0.2.1", + "next-themes": "0.4.6", "react": "catalog:", "react-dom": "catalog:", "react-dropzone": "^14.2.3", diff --git a/apps/web/package.json b/apps/web/package.json index ed9730543..858c332d1 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -52,7 +52,7 @@ "mobx": "catalog:", "mobx-react": "catalog:", "mobx-utils": "catalog:", - "next-themes": "^0.2.1", + "next-themes": "0.4.6", "posthog-js": "^1.255.1", "react": "catalog:", "react-color": "^2.19.3", diff --git a/package.json b/package.json index b73f0acc8..fc531f827 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,7 @@ "prosemirror-view": "1.40.0", "@types/express": "4.17.23", "typescript": "catalog:", - "vite": "catalog:", - "next": "16.0.7" + "vite": "catalog:" }, "onlyBuiltDependencies": [ "@sentry/cli", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81c799fe1..65d7bdd97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -115,7 +115,6 @@ overrides: '@types/express': 4.17.23 typescript: 5.8.3 vite: 7.1.11 - next: 16.0.7 importers: @@ -245,8 +244,8 @@ importers: specifier: 'catalog:' version: 9.1.1(mobx@6.12.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: - specifier: ^0.2.1 - version: 0.2.1(next@14.2.32(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 0.4.6 + version: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 'catalog:' version: 18.3.1 @@ -490,8 +489,8 @@ importers: specifier: 'catalog:' version: 6.0.8(mobx@6.12.0) next-themes: - specifier: ^0.2.1 - version: 0.2.1(next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 0.4.6 + version: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 'catalog:' version: 18.3.1 @@ -662,8 +661,8 @@ importers: specifier: 'catalog:' version: 6.0.8(mobx@6.12.0) next-themes: - specifier: ^0.2.1 - version: 0.2.1(next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 0.4.6 + version: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) posthog-js: specifier: ^1.255.1 version: 1.255.1 @@ -2281,63 +2280,6 @@ packages: '@napi-rs/wasm-runtime@1.1.0': resolution: {integrity: sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==} - '@next/env@14.2.32': - resolution: {integrity: sha512-n9mQdigI6iZ/DF6pCTwMKeWgF2e8lg7qgt5M7HXMLtyhZYMnf/u905M18sSpPmHL9MKp9JHo56C6jrD2EvWxng==} - - '@next/swc-darwin-arm64@14.2.32': - resolution: {integrity: sha512-osHXveM70zC+ilfuFa/2W6a1XQxJTvEhzEycnjUaVE8kpUS09lDpiDDX2YLdyFCzoUbvbo5r0X1Kp4MllIOShw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@14.2.32': - resolution: {integrity: sha512-P9NpCAJuOiaHHpqtrCNncjqtSBi1f6QUdHK/+dNabBIXB2RUFWL19TY1Hkhu74OvyNQEYEzzMJCMQk5agjw1Qg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@14.2.32': - resolution: {integrity: sha512-v7JaO0oXXt6d+cFjrrKqYnR2ubrD+JYP7nQVRZgeo5uNE5hkCpWnHmXm9vy3g6foMO8SPwL0P3MPw1c+BjbAzA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@14.2.32': - resolution: {integrity: sha512-tA6sIKShXtSJBTH88i0DRd6I9n3ZTirmwpwAqH5zdJoQF7/wlJXR8DkPmKwYl5mFWhEKr5IIa3LfpMW9RRwKmQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@14.2.32': - resolution: {integrity: sha512-7S1GY4TdnlGVIdeXXKQdDkfDysoIVFMD0lJuVVMeb3eoVjrknQ0JNN7wFlhCvea0hEk0Sd4D1hedVChDKfV2jw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@14.2.32': - resolution: {integrity: sha512-OHHC81P4tirVa6Awk6eCQ6RBfWl8HpFsZtfEkMpJ5GjPsJ3nhPe6wKAJUZ/piC8sszUkAgv3fLflgzPStIwfWg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@14.2.32': - resolution: {integrity: sha512-rORQjXsAFeX6TLYJrCG5yoIDj+NKq31Rqwn8Wpn/bkPNy5rTHvOXkW8mLFonItS7QC6M+1JIIcLe+vOCTOYpvg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-ia32-msvc@14.2.32': - resolution: {integrity: sha512-jHUeDPVHrgFltqoAqDB6g6OStNnFxnc7Aks3p0KE0FbwAvRg6qWKYF5mSTdCTxA3axoSAUwxYdILzXJfUwlHhA==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@next/swc-win32-x64-msvc@14.2.32': - resolution: {integrity: sha512-2N0lSoU4GjfLSO50wvKpMQgKd4HdI2UHEhQPPPnlgfBJlOgJxkjpkYBqzk08f1gItBB6xF/n+ykso2hgxuydsA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} engines: {node: ^14.21.3 || >=16} @@ -3681,9 +3623,6 @@ packages: '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@swc/helpers@0.5.5': - resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} - '@swc/types@0.1.24': resolution: {integrity: sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==} @@ -4832,10 +4771,6 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -7254,30 +7189,11 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - next-themes@0.2.1: - resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==} + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} peerDependencies: - next: 16.0.7 - react: '*' - react-dom: '*' - - next@14.2.32: - resolution: {integrity: sha512-fg5g0GZ7/nFc09X8wLe6pNSU8cLWbLRG3TZzPJ1BJvi2s9m7eF991se67wliM9kR5yLHRkyGKU49MMx58s3LJg==} - engines: {node: '>=18.17.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - sass: - optional: true + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -7727,10 +7643,6 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -8524,10 +8436,6 @@ packages: prettier: optional: true - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -8626,19 +8534,6 @@ packages: style-to-object@0.4.4: resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} - styled-jsx@5.1.1: - resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -10440,35 +10335,6 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@next/env@14.2.32': {} - - '@next/swc-darwin-arm64@14.2.32': - optional: true - - '@next/swc-darwin-x64@14.2.32': - optional: true - - '@next/swc-linux-arm64-gnu@14.2.32': - optional: true - - '@next/swc-linux-arm64-musl@14.2.32': - optional: true - - '@next/swc-linux-x64-gnu@14.2.32': - optional: true - - '@next/swc-linux-x64-musl@14.2.32': - optional: true - - '@next/swc-win32-arm64-msvc@14.2.32': - optional: true - - '@next/swc-win32-ia32-msvc@14.2.32': - optional: true - - '@next/swc-win32-x64-msvc@14.2.32': - optional: true - '@noble/ciphers@1.3.0': {} '@noble/curves@1.9.7': @@ -11985,11 +11851,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.5': - dependencies: - '@swc/counter': 0.1.3 - tslib: 2.8.1 - '@swc/types@0.1.24': dependencies: '@swc/counter': 0.1.3 @@ -13333,10 +13194,6 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - bytes@3.0.0: {} bytes@3.1.2: {} @@ -16228,70 +16085,11 @@ snapshots: neo-async@2.6.2: {} - next-themes@0.2.1(next@14.2.32(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-themes@0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - next: 14.2.32(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next-themes@0.2.1(next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - next: 14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - next@14.2.32(@babel/core@7.28.3)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@next/env': 14.2.32 - '@swc/helpers': 0.5.5 - busboy: 1.6.0 - caniuse-lite: 1.0.30001759 - graceful-fs: 4.2.11 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(@babel/core@7.28.3)(babel-plugin-macros@3.1.0)(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 14.2.32 - '@next/swc-darwin-x64': 14.2.32 - '@next/swc-linux-arm64-gnu': 14.2.32 - '@next/swc-linux-arm64-musl': 14.2.32 - '@next/swc-linux-x64-gnu': 14.2.32 - '@next/swc-linux-x64-musl': 14.2.32 - '@next/swc-win32-arm64-msvc': 14.2.32 - '@next/swc-win32-ia32-msvc': 14.2.32 - '@next/swc-win32-x64-msvc': 14.2.32 - '@opentelemetry/api': 1.9.0 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@next/env': 14.2.32 - '@swc/helpers': 0.5.5 - busboy: 1.6.0 - caniuse-lite: 1.0.30001759 - graceful-fs: 4.2.11 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 14.2.32 - '@next/swc-darwin-x64': 14.2.32 - '@next/swc-linux-arm64-gnu': 14.2.32 - '@next/swc-linux-arm64-musl': 14.2.32 - '@next/swc-linux-x64-gnu': 14.2.32 - '@next/swc-linux-x64-musl': 14.2.32 - '@next/swc-win32-arm64-msvc': 14.2.32 - '@next/swc-win32-ia32-msvc': 14.2.32 - '@next/swc-win32-x64-msvc': 14.2.32 - '@opentelemetry/api': 1.9.0 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -16731,12 +16529,6 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.4.31: - dependencies: - nanoid: 3.3.8 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.8 @@ -17762,8 +17554,6 @@ snapshots: - utf-8-validate - vite - streamsearch@1.1.0: {} - string-argv@0.3.2: {} string-width@4.2.3: @@ -17886,22 +17676,6 @@ snapshots: dependencies: inline-style-parser: 0.1.1 - styled-jsx@5.1.1(@babel/core@7.28.3)(babel-plugin-macros@3.1.0)(react@18.3.1): - dependencies: - client-only: 0.0.1 - react: 18.3.1 - optionalDependencies: - '@babel/core': 7.28.3 - babel-plugin-macros: 3.1.0 - - styled-jsx@5.1.1(@babel/core@7.28.4)(babel-plugin-macros@3.1.0)(react@18.3.1): - dependencies: - client-only: 0.0.1 - react: 18.3.1 - optionalDependencies: - '@babel/core': 7.28.4 - babel-plugin-macros: 3.1.0 - sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.13 From 07f269e7f3e25d247a362025a8b9602786caf925 Mon Sep 17 00:00:00 2001 From: sriramveeraghanta Date: Fri, 12 Dec 2025 15:09:53 +0530 Subject: [PATCH 02/12] chore: version bump --- apps/admin/package.json | 2 +- apps/api/package.json | 2 +- apps/live/package.json | 2 +- apps/space/package.json | 2 +- apps/web/package.json | 2 +- package.json | 2 +- packages/codemods/package.json | 2 +- packages/constants/package.json | 2 +- packages/editor/package.json | 2 +- packages/hooks/package.json | 2 +- packages/i18n/package.json | 2 +- packages/logger/package.json | 2 +- packages/propel/package.json | 2 +- packages/services/package.json | 2 +- packages/shared-state/package.json | 2 +- packages/tailwind-config/package.json | 2 +- packages/types/package.json | 2 +- packages/typescript-config/package.json | 2 +- packages/ui/package.json | 2 +- packages/utils/package.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/admin/package.json b/apps/admin/package.json index 5f0f7f306..07f0b51d3 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -1,7 +1,7 @@ { "name": "admin", "description": "Admin UI for Plane", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/apps/api/package.json b/apps/api/package.json index 6e62f2bd1..4767d0cb4 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "plane-api", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "private": true, "description": "API server powering Plane's backend" diff --git a/apps/live/package.json b/apps/live/package.json index b773efb44..7115af53a 100644 --- a/apps/live/package.json +++ b/apps/live/package.json @@ -1,6 +1,6 @@ { "name": "live", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "description": "A realtime collaborative server powers Plane's rich text editor", "main": "./dist/start.mjs", diff --git a/apps/space/package.json b/apps/space/package.json index 1fe1fbd37..c3e6f3dbf 100644 --- a/apps/space/package.json +++ b/apps/space/package.json @@ -1,6 +1,6 @@ { "name": "space", - "version": "1.2.0", + "version": "1.2.1", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/apps/web/package.json b/apps/web/package.json index 858c332d1..fbf921ff7 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.2.0", + "version": "1.2.1", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/package.json b/package.json index fc531f827..1229aa3c9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "plane", "description": "Open-source project management that unlocks customer value", "repository": "https://github.com/makeplane/plane.git", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "private": true, "scripts": { diff --git a/packages/codemods/package.json b/packages/codemods/package.json index e2bac61cd..8b7104d81 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,6 +1,6 @@ { "name": "@plane/codemods", - "version": "1.2.0", + "version": "1.2.1", "private": true, "scripts": { "test": "vitest run", diff --git a/packages/constants/package.json b/packages/constants/package.json index 9e1a2ca69..05b5e8e85 100644 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,6 +1,6 @@ { "name": "@plane/constants", - "version": "1.2.0", + "version": "1.2.1", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/packages/editor/package.json b/packages/editor/package.json index f1e79781c..930e9f4b6 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@plane/editor", - "version": "1.2.0", + "version": "1.2.1", "description": "Core Editor that powers Plane", "license": "AGPL-3.0", "private": true, diff --git a/packages/hooks/package.json b/packages/hooks/package.json index c78d17b3c..5fa0cd637 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@plane/hooks", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "description": "React hooks that are shared across multiple apps internally", "private": true, diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 21fac2cbd..2cf34926d 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@plane/i18n", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "description": "I18n shared across multiple apps internally", "private": true, diff --git a/packages/logger/package.json b/packages/logger/package.json index 339a4c2f1..a4a57328b 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@plane/logger", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "description": "Logger shared across multiple apps internally", "private": true, diff --git a/packages/propel/package.json b/packages/propel/package.json index 74ca9036d..230c7b076 100644 --- a/packages/propel/package.json +++ b/packages/propel/package.json @@ -1,6 +1,6 @@ { "name": "@plane/propel", - "version": "1.2.0", + "version": "1.2.1", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/packages/services/package.json b/packages/services/package.json index 497215747..981b86df3 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -1,6 +1,6 @@ { "name": "@plane/services", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/packages/shared-state/package.json b/packages/shared-state/package.json index b3f7c2506..effd12ef6 100644 --- a/packages/shared-state/package.json +++ b/packages/shared-state/package.json @@ -1,6 +1,6 @@ { "name": "@plane/shared-state", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "description": "Shared state shared across multiple apps internally", "private": true, diff --git a/packages/tailwind-config/package.json b/packages/tailwind-config/package.json index 9deb622cc..ece3b586a 100644 --- a/packages/tailwind-config/package.json +++ b/packages/tailwind-config/package.json @@ -1,6 +1,6 @@ { "name": "@plane/tailwind-config", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "description": "common tailwind configuration across monorepo", "main": "tailwind.config.js", diff --git a/packages/types/package.json b/packages/types/package.json index 020b98bbe..47be22684 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@plane/types", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/packages/typescript-config/package.json b/packages/typescript-config/package.json index c8d21d9ae..b8190c40d 100644 --- a/packages/typescript-config/package.json +++ b/packages/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@plane/typescript-config", - "version": "1.2.0", + "version": "1.2.1", "license": "AGPL-3.0", "private": true, "files": [ diff --git a/packages/ui/package.json b/packages/ui/package.json index 51fb33f6c..ffed74cde 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -2,7 +2,7 @@ "name": "@plane/ui", "description": "UI components shared across multiple apps internally", "private": true, - "version": "1.2.0", + "version": "1.2.1", "sideEffects": false, "license": "AGPL-3.0", "type": "module", diff --git a/packages/utils/package.json b/packages/utils/package.json index c6294ff07..4e60cac8c 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@plane/utils", - "version": "1.2.0", + "version": "1.2.1", "description": "Helper functions shared across multiple apps internally", "license": "AGPL-3.0", "private": true, From 1548288e95722ccfa310046079ab3fe9c323282d Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Fri, 20 Feb 2026 18:02:12 +0530 Subject: [PATCH 03/12] fix: IDOR Vulnerabilities in Asset & Attachment Endpoints (#8644) * fix: idor issues in project assets and issue attachements * fix: comments --- apps/api/plane/app/views/asset/v2.py | 2 +- apps/api/plane/app/views/issue/attachment.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/api/plane/app/views/asset/v2.py b/apps/api/plane/app/views/asset/v2.py index c0580c114..3677537bb 100644 --- a/apps/api/plane/app/views/asset/v2.py +++ b/apps/api/plane/app/views/asset/v2.py @@ -603,7 +603,7 @@ class ProjectAssetEndpoint(BaseAPIView): @allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST]) def patch(self, request, slug, project_id, pk): # get the asset id - asset = FileAsset.objects.get(id=pk) + asset = FileAsset.objects.get(id=pk, workspace__slug=slug, project_id=project_id) # get the storage metadata asset.is_uploaded = True # get the storage metadata diff --git a/apps/api/plane/app/views/issue/attachment.py b/apps/api/plane/app/views/issue/attachment.py index 7b7ecf378..3600a0766 100644 --- a/apps/api/plane/app/views/issue/attachment.py +++ b/apps/api/plane/app/views/issue/attachment.py @@ -56,7 +56,11 @@ class IssueAttachmentEndpoint(BaseAPIView): @allow_permission([ROLE.ADMIN], creator=True, model=FileAsset) def delete(self, request, slug, project_id, issue_id, pk): - issue_attachment = FileAsset.objects.get(pk=pk) + issue_attachment = FileAsset.objects.filter( + pk=pk, workspace__slug=slug, project_id=project_id, issue_id=issue_id + ).first() + if not issue_attachment: + return Response(status=status.HTTP_404_NOT_FOUND) issue_attachment.asset.delete(save=False) issue_attachment.delete() issue_activity.delay( From ec44b63027cfd96974c1c964aa3ca615ebbc52fd Mon Sep 17 00:00:00 2001 From: sriramveeraghanta Date: Fri, 20 Feb 2026 18:05:15 +0530 Subject: [PATCH 04/12] chore: pacakge version --- apps/admin/package.json | 2 +- apps/api/package.json | 2 +- apps/live/package.json | 2 +- apps/space/package.json | 2 +- apps/web/package.json | 2 +- package.json | 2 +- packages/codemods/package.json | 2 +- packages/constants/package.json | 2 +- packages/editor/package.json | 2 +- packages/hooks/package.json | 2 +- packages/i18n/package.json | 2 +- packages/logger/package.json | 2 +- packages/propel/package.json | 2 +- packages/services/package.json | 2 +- packages/shared-state/package.json | 2 +- packages/tailwind-config/package.json | 2 +- packages/types/package.json | 2 +- packages/typescript-config/package.json | 2 +- packages/ui/package.json | 2 +- packages/utils/package.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/admin/package.json b/apps/admin/package.json index 07f0b51d3..d2fa5a4c2 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -1,7 +1,7 @@ { "name": "admin", "description": "Admin UI for Plane", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/apps/api/package.json b/apps/api/package.json index 4767d0cb4..46fb0dd47 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "plane-api", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "private": true, "description": "API server powering Plane's backend" diff --git a/apps/live/package.json b/apps/live/package.json index 7115af53a..bd09ce142 100644 --- a/apps/live/package.json +++ b/apps/live/package.json @@ -1,6 +1,6 @@ { "name": "live", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "description": "A realtime collaborative server powers Plane's rich text editor", "main": "./dist/start.mjs", diff --git a/apps/space/package.json b/apps/space/package.json index c3e6f3dbf..e40f60927 100644 --- a/apps/space/package.json +++ b/apps/space/package.json @@ -1,6 +1,6 @@ { "name": "space", - "version": "1.2.1", + "version": "1.2.2", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/apps/web/package.json b/apps/web/package.json index fbf921ff7..3a116f6e0 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.2.1", + "version": "1.2.2", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/package.json b/package.json index 1229aa3c9..eef3f0ca6 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "plane", "description": "Open-source project management that unlocks customer value", "repository": "https://github.com/makeplane/plane.git", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "private": true, "scripts": { diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 8b7104d81..218bc986b 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,6 +1,6 @@ { "name": "@plane/codemods", - "version": "1.2.1", + "version": "1.2.2", "private": true, "scripts": { "test": "vitest run", diff --git a/packages/constants/package.json b/packages/constants/package.json index 05b5e8e85..ecb8d1c5b 100644 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,6 +1,6 @@ { "name": "@plane/constants", - "version": "1.2.1", + "version": "1.2.2", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/packages/editor/package.json b/packages/editor/package.json index 930e9f4b6..ac4f67e11 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@plane/editor", - "version": "1.2.1", + "version": "1.2.2", "description": "Core Editor that powers Plane", "license": "AGPL-3.0", "private": true, diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 5fa0cd637..e63a99d72 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@plane/hooks", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "description": "React hooks that are shared across multiple apps internally", "private": true, diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 2cf34926d..046c75cbb 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@plane/i18n", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "description": "I18n shared across multiple apps internally", "private": true, diff --git a/packages/logger/package.json b/packages/logger/package.json index a4a57328b..5f9de0fc3 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@plane/logger", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "description": "Logger shared across multiple apps internally", "private": true, diff --git a/packages/propel/package.json b/packages/propel/package.json index 230c7b076..97d67c8db 100644 --- a/packages/propel/package.json +++ b/packages/propel/package.json @@ -1,6 +1,6 @@ { "name": "@plane/propel", - "version": "1.2.1", + "version": "1.2.2", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/packages/services/package.json b/packages/services/package.json index 981b86df3..cf0bec6ee 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -1,6 +1,6 @@ { "name": "@plane/services", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/packages/shared-state/package.json b/packages/shared-state/package.json index effd12ef6..af792136c 100644 --- a/packages/shared-state/package.json +++ b/packages/shared-state/package.json @@ -1,6 +1,6 @@ { "name": "@plane/shared-state", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "description": "Shared state shared across multiple apps internally", "private": true, diff --git a/packages/tailwind-config/package.json b/packages/tailwind-config/package.json index ece3b586a..61b73daec 100644 --- a/packages/tailwind-config/package.json +++ b/packages/tailwind-config/package.json @@ -1,6 +1,6 @@ { "name": "@plane/tailwind-config", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "description": "common tailwind configuration across monorepo", "main": "tailwind.config.js", diff --git a/packages/types/package.json b/packages/types/package.json index 47be22684..e37e9b877 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@plane/types", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/packages/typescript-config/package.json b/packages/typescript-config/package.json index b8190c40d..f7f44b203 100644 --- a/packages/typescript-config/package.json +++ b/packages/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@plane/typescript-config", - "version": "1.2.1", + "version": "1.2.2", "license": "AGPL-3.0", "private": true, "files": [ diff --git a/packages/ui/package.json b/packages/ui/package.json index ffed74cde..f84e6bddd 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -2,7 +2,7 @@ "name": "@plane/ui", "description": "UI components shared across multiple apps internally", "private": true, - "version": "1.2.1", + "version": "1.2.2", "sideEffects": false, "license": "AGPL-3.0", "type": "module", diff --git a/packages/utils/package.json b/packages/utils/package.json index 4e60cac8c..71a9b4429 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@plane/utils", - "version": "1.2.1", + "version": "1.2.2", "description": "Helper functions shared across multiple apps internally", "license": "AGPL-3.0", "private": true, From 6c984e18ae8d63617ad51836a88fd397b9b2d31f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:06:42 +0530 Subject: [PATCH 05/12] chore(deps): bump cryptography (#8625) Bumps the pip group with 1 update in the /apps/api/requirements directory: [cryptography](https://github.com/pyca/cryptography). Updates `cryptography` from 44.0.1 to 46.0.5 - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/44.0.1...46.0.5) --- updated-dependencies: - dependency-name: cryptography dependency-version: 46.0.5 dependency-type: direct:production dependency-group: pip ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- apps/api/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/requirements/base.txt b/apps/api/requirements/base.txt index 7f2c64be4..4a707a718 100644 --- a/apps/api/requirements/base.txt +++ b/apps/api/requirements/base.txt @@ -51,7 +51,7 @@ beautifulsoup4==4.12.3 # analytics posthog==3.5.0 # crypto -cryptography==44.0.1 +cryptography==46.0.5 # html validator lxml==6.0.0 # s3 From 318c9930821a2d15b2d4e844de089e1cdf4e426d Mon Sep 17 00:00:00 2001 From: Sangeetha Date: Mon, 9 Feb 2026 14:50:29 +0530 Subject: [PATCH 06/12] [SECUR-104] fix: Arbitrary Modification of API Token Rate Limits#8612 --- apps/api/plane/app/serializers/api.py | 3 + .../tests/contract/app/test_api_token.py | 78 +++++++++++++++---- 2 files changed, 67 insertions(+), 14 deletions(-) diff --git a/apps/api/plane/app/serializers/api.py b/apps/api/plane/app/serializers/api.py index 009f7a611..d14dcacff 100644 --- a/apps/api/plane/app/serializers/api.py +++ b/apps/api/plane/app/serializers/api.py @@ -15,6 +15,9 @@ class APITokenSerializer(BaseSerializer): "updated_at", "workspace", "user", + "is_active", + "last_used", + "user_type", ] diff --git a/apps/api/plane/tests/contract/app/test_api_token.py b/apps/api/plane/tests/contract/app/test_api_token.py index 35d92b11e..24fac7bb4 100644 --- a/apps/api/plane/tests/contract/app/test_api_token.py +++ b/apps/api/plane/tests/contract/app/test_api_token.py @@ -138,7 +138,7 @@ class TestApiTokenEndpoint: """Test retrieving a specific API token""" # Arrange session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": create_api_token_for_user.pk}) + url = reverse("api-tokens-details", kwargs={"pk": create_api_token_for_user.pk}) # Act response = session_client.get(url) @@ -155,7 +155,7 @@ class TestApiTokenEndpoint: # Arrange session_client.force_authenticate(user=create_user) fake_pk = uuid4() - url = reverse("api-tokens", kwargs={"pk": fake_pk}) + url = reverse("api-tokens-details", kwargs={"pk": fake_pk}) # Act response = session_client.get(url) @@ -174,7 +174,7 @@ class TestApiTokenEndpoint: other_user = User.objects.create(email=unique_email, username=unique_username) other_token = APIToken.objects.create(label="Other Token", user=other_user, user_type=0) session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": other_token.pk}) + url = reverse("api-tokens-details", kwargs={"pk": other_token.pk}) # Act response = session_client.get(url) @@ -188,7 +188,7 @@ class TestApiTokenEndpoint: """Test successful API token deletion""" # Arrange session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": create_api_token_for_user.pk}) + url = reverse("api-tokens-details", kwargs={"pk": create_api_token_for_user.pk}) # Act response = session_client.delete(url) @@ -203,7 +203,7 @@ class TestApiTokenEndpoint: # Arrange session_client.force_authenticate(user=create_user) fake_pk = uuid4() - url = reverse("api-tokens", kwargs={"pk": fake_pk}) + url = reverse("api-tokens-details", kwargs={"pk": fake_pk}) # Act response = session_client.delete(url) @@ -222,7 +222,7 @@ class TestApiTokenEndpoint: other_user = User.objects.create(email=unique_email, username=unique_username) other_token = APIToken.objects.create(label="Other Token", user=other_user, user_type=0) session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": other_token.pk}) + url = reverse("api-tokens-details", kwargs={"pk": other_token.pk}) # Act response = session_client.delete(url) @@ -238,7 +238,7 @@ class TestApiTokenEndpoint: # Arrange service_token = APIToken.objects.create(label="Service Token", user=create_user, user_type=0, is_service=True) session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": service_token.pk}) + url = reverse("api-tokens-details", kwargs={"pk": service_token.pk}) # Act response = session_client.delete(url) @@ -254,7 +254,7 @@ class TestApiTokenEndpoint: """Test successful API token update""" # Arrange session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": create_api_token_for_user.pk}) + url = reverse("api-tokens-details", kwargs={"pk": create_api_token_for_user.pk}) update_data = { "label": "Updated Token Label", "description": "Updated description", @@ -278,7 +278,7 @@ class TestApiTokenEndpoint: """Test partial API token update""" # Arrange session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": create_api_token_for_user.pk}) + url = reverse("api-tokens-details", kwargs={"pk": create_api_token_for_user.pk}) original_description = create_api_token_for_user.description update_data = {"label": "Only Label Updated"} @@ -296,7 +296,7 @@ class TestApiTokenEndpoint: # Arrange session_client.force_authenticate(user=create_user) fake_pk = uuid4() - url = reverse("api-tokens", kwargs={"pk": fake_pk}) + url = reverse("api-tokens-details", kwargs={"pk": fake_pk}) update_data = {"label": "New Label"} # Act @@ -316,7 +316,7 @@ class TestApiTokenEndpoint: other_user = User.objects.create(email=unique_email, username=unique_username) other_token = APIToken.objects.create(label="Other Token", user=other_user, user_type=0) session_client.force_authenticate(user=create_user) - url = reverse("api-tokens", kwargs={"pk": other_token.pk}) + url = reverse("api-tokens-details", kwargs={"pk": other_token.pk}) update_data = {"label": "Hacked Label"} # Act @@ -329,6 +329,56 @@ class TestApiTokenEndpoint: other_token.refresh_from_db() assert other_token.label == "Other Token" + @pytest.mark.django_db + def test_patch_cannot_modify_token(self, session_client, create_user, create_api_token_for_user): + """Test that token value cannot be modified via PATCH""" + # Arrange + session_client.force_authenticate(user=create_user) + url = reverse("api-tokens-details", kwargs={"pk": create_api_token_for_user.pk}) + original_token = create_api_token_for_user.token + update_data = {"token": "plane_api_malicious_token_value"} + + # Act + response = session_client.patch(url, update_data, format="json") + + # Assert + assert response.status_code == status.HTTP_200_OK + create_api_token_for_user.refresh_from_db() + assert create_api_token_for_user.token == original_token + + @pytest.mark.django_db + def test_patch_cannot_modify_user_type(self, session_client, create_user, create_api_token_for_user): + """Test that user_type cannot be modified via PATCH""" + # Arrange + session_client.force_authenticate(user=create_user) + url = reverse("api-tokens-details", kwargs={"pk": create_api_token_for_user.pk}) + update_data = {"user_type": 1} + + # Act + response = session_client.patch(url, update_data, format="json") + + # Assert + assert response.status_code == status.HTTP_200_OK + create_api_token_for_user.refresh_from_db() + assert create_api_token_for_user.user_type == 0 + + @pytest.mark.django_db + def test_patch_cannot_modify_service_token(self, session_client, create_user): + """Test that service tokens cannot be modified through user token endpoint""" + # Arrange + service_token = APIToken.objects.create(label="Service Token", user=create_user, user_type=0, is_service=True) + session_client.force_authenticate(user=create_user) + url = reverse("api-tokens-details", kwargs={"pk": service_token.pk}) + update_data = {"label": "Hacked Service Token"} + + # Act + response = session_client.patch(url, update_data, format="json") + + # Assert + assert response.status_code == status.HTTP_404_NOT_FOUND + service_token.refresh_from_db() + assert service_token.label == "Service Token" + # Authentication tests @pytest.mark.django_db def test_all_endpoints_require_authentication(self, api_client): @@ -337,9 +387,9 @@ class TestApiTokenEndpoint: endpoints = [ (reverse("api-tokens"), "get"), (reverse("api-tokens"), "post"), - (reverse("api-tokens", kwargs={"pk": uuid4()}), "get"), - (reverse("api-tokens", kwargs={"pk": uuid4()}), "patch"), - (reverse("api-tokens", kwargs={"pk": uuid4()}), "delete"), + (reverse("api-tokens-details", kwargs={"pk": uuid4()}), "get"), + (reverse("api-tokens-details", kwargs={"pk": uuid4()}), "patch"), + (reverse("api-tokens-details", kwargs={"pk": uuid4()}), "delete"), ] # Act & Assert From 95d121ce3867f1edc61b627a840c37cbd7a36be5 Mon Sep 17 00:00:00 2001 From: sriramveeraghanta Date: Mon, 9 Feb 2026 14:51:53 +0530 Subject: [PATCH 07/12] chore(deps): upgrade django version --- apps/api/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/requirements/base.txt b/apps/api/requirements/base.txt index 4a707a718..b0ffb54e8 100644 --- a/apps/api/requirements/base.txt +++ b/apps/api/requirements/base.txt @@ -1,7 +1,7 @@ # base requirements # django -Django==4.2.27 +Django==4.2.28 # rest framework djangorestframework==3.15.2 # postgres From b783f25bfacd6c2b10ec639889266f6eb28e567e Mon Sep 17 00:00:00 2001 From: Sangeetha Date: Thu, 5 Feb 2026 15:03:43 +0530 Subject: [PATCH 08/12] [SECUR-113] fix: ssrf for work item links (#8607) --- apps/api/plane/bgtasks/work_item_link_task.py | 94 +++++++++++++++---- 1 file changed, 77 insertions(+), 17 deletions(-) diff --git a/apps/api/plane/bgtasks/work_item_link_task.py b/apps/api/plane/bgtasks/work_item_link_task.py index 7ceaacaf5..442396c7f 100644 --- a/apps/api/plane/bgtasks/work_item_link_task.py +++ b/apps/api/plane/bgtasks/work_item_link_task.py @@ -1,6 +1,10 @@ +# Copyright (c) 2023-present Plane Software, Inc. and contributors +# SPDX-License-Identifier: AGPL-3.0-only +# See the LICENSE file for details. + # Python imports import logging - +import socket # Third party imports from celery import shared_task @@ -20,6 +24,48 @@ logger = logging.getLogger("plane.worker") DEFAULT_FAVICON = "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWxpbmstaWNvbiBsdWNpZGUtbGluayI+PHBhdGggZD0iTTEwIDEzYTUgNSAwIDAgMCA3LjU0LjU0bDMtM2E1IDUgMCAwIDAtNy4wNy03LjA3bC0xLjcyIDEuNzEiLz48cGF0aCBkPSJNMTQgMTFhNSA1IDAgMCAwLTcuNTQtLjU0bC0zIDNhNSA1IDAgMCAwIDcuMDcgNy4wN2wxLjcxLTEuNzEiLz48L3N2Zz4=" # noqa: E501 +def validate_url_ip(url: str) -> None: + """ + Validate that a URL doesn't point to a private/internal IP address. + Resolves hostnames to IPs before checking. + + Args: + url: The URL to validate + + Raises: + ValueError: If the URL points to a private/internal IP + """ + parsed = urlparse(url) + hostname = parsed.hostname + + if not hostname: + raise ValueError("Invalid URL: No hostname found") + + # Only allow HTTP and HTTPS to prevent file://, gopher://, etc. + if parsed.scheme not in ("http", "https"): + raise ValueError("Invalid URL scheme. Only HTTP and HTTPS are allowed") + + # Resolve hostname to IP addresses — this catches domain names that + # point to internal IPs (e.g. attacker.com -> 169.254.169.254) + + try: + addr_info = socket.getaddrinfo(hostname, None) + except socket.gaierror: + raise ValueError("Hostname could not be resolved") + + if not addr_info: + raise ValueError("No IP addresses found for the hostname") + + # Check every resolved IP against blocked ranges to prevent SSRF + for addr in addr_info: + ip = ipaddress.ip_address(addr[4][0]) + if ip.is_private or ip.is_loopback or ip.is_reserved or ip.is_link_local: + raise ValueError("Access to private/internal networks is not allowed") + + +MAX_REDIRECTS = 5 + + def crawl_work_item_link_title_and_favicon(url: str) -> Dict[str, Any]: """ Crawls a URL to extract the title and favicon. @@ -31,17 +77,6 @@ def crawl_work_item_link_title_and_favicon(url: str) -> Dict[str, Any]: str: JSON string containing title and base64-encoded favicon """ try: - # Prevent access to private IP ranges - parsed = urlparse(url) - - try: - ip = ipaddress.ip_address(parsed.hostname) - if ip.is_private or ip.is_loopback or ip.is_reserved: - raise ValueError("Access to private/internal networks is not allowed") - except ValueError: - # Not an IP address, continue with domain validation - pass - # Set up headers to mimic a real browser headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" # noqa: E501 @@ -49,9 +84,28 @@ def crawl_work_item_link_title_and_favicon(url: str) -> Dict[str, Any]: soup = None title = None + final_url = url + + validate_url_ip(final_url) try: - response = requests.get(url, headers=headers, timeout=1) + # Manually follow redirects to validate each URL before requesting + redirect_count = 0 + response = requests.get(final_url, headers=headers, timeout=1, allow_redirects=False) + + while response.is_redirect and redirect_count < MAX_REDIRECTS: + redirect_url = response.headers.get("Location") + if not redirect_url: + break + # Resolve relative redirects against current URL + final_url = urljoin(final_url, redirect_url) + # Validate the redirect target BEFORE making the request + validate_url_ip(final_url) + redirect_count += 1 + response = requests.get(final_url, headers=headers, timeout=1, allow_redirects=False) + + if redirect_count >= MAX_REDIRECTS: + logger.warning(f"Too many redirects for URL: {url}") soup = BeautifulSoup(response.content, "html.parser") title_tag = soup.find("title") @@ -60,8 +114,8 @@ def crawl_work_item_link_title_and_favicon(url: str) -> Dict[str, Any]: except requests.RequestException as e: logger.warning(f"Failed to fetch HTML for title: {str(e)}") - # Fetch and encode favicon - favicon_base64 = fetch_and_encode_favicon(headers, soup, url) + # Fetch and encode favicon using final URL (after redirects) + favicon_base64 = fetch_and_encode_favicon(headers, soup, final_url) # Prepare result result = { @@ -107,7 +161,9 @@ def find_favicon_url(soup: Optional[BeautifulSoup], base_url: str) -> Optional[s for selector in favicon_selectors: favicon_tag = soup.select_one(selector) if favicon_tag and favicon_tag.get("href"): - return urljoin(base_url, favicon_tag["href"]) + favicon_href = urljoin(base_url, favicon_tag["href"]) + validate_url_ip(favicon_href) + return favicon_href # Fallback to /favicon.ico parsed_url = urlparse(base_url) @@ -115,7 +171,9 @@ def find_favicon_url(soup: Optional[BeautifulSoup], base_url: str) -> Optional[s # Check if fallback exists try: - response = requests.head(fallback_url, timeout=2) + validate_url_ip(fallback_url) + response = requests.head(fallback_url, timeout=2, allow_redirects=False) + if response.status_code == 200: return fallback_url except requests.RequestException as e: @@ -146,6 +204,8 @@ def fetch_and_encode_favicon( "favicon_base64": f"data:image/svg+xml;base64,{DEFAULT_FAVICON}", } + validate_url_ip(favicon_url) + response = requests.get(favicon_url, headers=headers, timeout=1) # Get content type From a77af4e67ee8032f5c17fd22d3b7aeef660f01f6 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Fri, 20 Feb 2026 18:33:09 +0530 Subject: [PATCH 09/12] Update apps/api/plane/app/views/issue/attachment.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- apps/api/plane/app/views/issue/attachment.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/api/plane/app/views/issue/attachment.py b/apps/api/plane/app/views/issue/attachment.py index 3600a0766..2207d2419 100644 --- a/apps/api/plane/app/views/issue/attachment.py +++ b/apps/api/plane/app/views/issue/attachment.py @@ -60,7 +60,10 @@ class IssueAttachmentEndpoint(BaseAPIView): pk=pk, workspace__slug=slug, project_id=project_id, issue_id=issue_id ).first() if not issue_attachment: - return Response(status=status.HTTP_404_NOT_FOUND) + return Response( + {"error": "Issue attachment not found."}, + status=status.HTTP_404_NOT_FOUND, + ) issue_attachment.asset.delete(save=False) issue_attachment.delete() issue_activity.delay( From 8c23fdd1d865f9bf3fd7edc7c7f2a60828523216 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Fri, 20 Feb 2026 18:33:45 +0530 Subject: [PATCH 10/12] fix: Member Information Disclosure via Public Endpoint #8646 --- apps/api/plane/space/views/project.py | 10 ++++++---- apps/space/core/types/member.d.ts | 6 +----- packages/types/src/users.ts | 6 +----- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/apps/api/plane/space/views/project.py b/apps/api/plane/space/views/project.py index 6f332781f..0e19085a0 100644 --- a/apps/api/plane/space/views/project.py +++ b/apps/api/plane/space/views/project.py @@ -63,6 +63,11 @@ class ProjectMembersEndpoint(BaseAPIView): def get(self, request, anchor): deploy_board = DeployBoard.objects.filter(anchor=anchor).first() + if not deploy_board: + return Response( + {"error": "Invalid anchor"}, + status=status.HTTP_404_NOT_FOUND, + ) members = ProjectMember.objects.filter( project=deploy_board.project, @@ -71,10 +76,7 @@ class ProjectMembersEndpoint(BaseAPIView): ).values( "id", "member", - "member__first_name", - "member__last_name", "member__display_name", - "project", - "workspace", + "member__avatar", ) return Response(members, status=status.HTTP_200_OK) diff --git a/apps/space/core/types/member.d.ts b/apps/space/core/types/member.d.ts index 721ccd98f..34c95daf6 100644 --- a/apps/space/core/types/member.d.ts +++ b/apps/space/core/types/member.d.ts @@ -1,10 +1,6 @@ export type TPublicMember = { id: string; member: string; - member__avatar: string; - member__first_name: string; - member__last_name: string; member__display_name: string; - project: string; - workspace: string; + member__avatar: string; }; diff --git a/packages/types/src/users.ts b/packages/types/src/users.ts index 9278996a7..7760a0a8c 100644 --- a/packages/types/src/users.ts +++ b/packages/types/src/users.ts @@ -196,12 +196,8 @@ export type TProfileViews = "assigned" | "created" | "subscribed"; export type TPublicMember = { id: string; member: string; - member__avatar: string; - member__first_name: string; - member__last_name: string; member__display_name: string; - project: string; - workspace: string; + member__avatar: string; }; // export interface ICurrentUser { From 9a7696acac92c68280f6efc2173e2ea9a4e1bb14 Mon Sep 17 00:00:00 2001 From: sriramveeraghanta Date: Thu, 5 Mar 2026 17:25:22 +0530 Subject: [PATCH 11/12] chore: version upgrade --- apps/admin/package.json | 2 +- apps/api/package.json | 2 +- apps/live/package.json | 2 +- apps/space/package.json | 2 +- apps/web/package.json | 2 +- package.json | 2 +- packages/codemods/package.json | 2 +- packages/constants/package.json | 2 +- packages/editor/package.json | 2 +- packages/hooks/package.json | 2 +- packages/i18n/package.json | 2 +- packages/logger/package.json | 2 +- packages/propel/package.json | 2 +- packages/services/package.json | 2 +- packages/shared-state/package.json | 2 +- packages/tailwind-config/package.json | 2 +- packages/types/package.json | 2 +- packages/typescript-config/package.json | 2 +- packages/ui/package.json | 2 +- packages/utils/package.json | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/admin/package.json b/apps/admin/package.json index d2fa5a4c2..573a3ddfe 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -1,7 +1,7 @@ { "name": "admin", "description": "Admin UI for Plane", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/apps/api/package.json b/apps/api/package.json index 46fb0dd47..9f4b7879c 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,6 +1,6 @@ { "name": "plane-api", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "private": true, "description": "API server powering Plane's backend" diff --git a/apps/live/package.json b/apps/live/package.json index bd09ce142..2130f9d86 100644 --- a/apps/live/package.json +++ b/apps/live/package.json @@ -1,6 +1,6 @@ { "name": "live", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "description": "A realtime collaborative server powers Plane's rich text editor", "main": "./dist/start.mjs", diff --git a/apps/space/package.json b/apps/space/package.json index e40f60927..5442a46bc 100644 --- a/apps/space/package.json +++ b/apps/space/package.json @@ -1,6 +1,6 @@ { "name": "space", - "version": "1.2.2", + "version": "1.2.3", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/apps/web/package.json b/apps/web/package.json index 3a116f6e0..2d474e00c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.2.2", + "version": "1.2.3", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/package.json b/package.json index eef3f0ca6..999e41411 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "plane", "description": "Open-source project management that unlocks customer value", "repository": "https://github.com/makeplane/plane.git", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "private": true, "scripts": { diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 218bc986b..31b481c34 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,6 +1,6 @@ { "name": "@plane/codemods", - "version": "1.2.2", + "version": "1.2.3", "private": true, "scripts": { "test": "vitest run", diff --git a/packages/constants/package.json b/packages/constants/package.json index ecb8d1c5b..4ac4d295d 100644 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,6 +1,6 @@ { "name": "@plane/constants", - "version": "1.2.2", + "version": "1.2.3", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/packages/editor/package.json b/packages/editor/package.json index ac4f67e11..e346b8ba1 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@plane/editor", - "version": "1.2.2", + "version": "1.2.3", "description": "Core Editor that powers Plane", "license": "AGPL-3.0", "private": true, diff --git a/packages/hooks/package.json b/packages/hooks/package.json index e63a99d72..5a706120b 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -1,6 +1,6 @@ { "name": "@plane/hooks", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "description": "React hooks that are shared across multiple apps internally", "private": true, diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 046c75cbb..e11bdcd54 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@plane/i18n", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "description": "I18n shared across multiple apps internally", "private": true, diff --git a/packages/logger/package.json b/packages/logger/package.json index 5f9de0fc3..2d9d6af42 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@plane/logger", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "description": "Logger shared across multiple apps internally", "private": true, diff --git a/packages/propel/package.json b/packages/propel/package.json index 97d67c8db..b12950f37 100644 --- a/packages/propel/package.json +++ b/packages/propel/package.json @@ -1,6 +1,6 @@ { "name": "@plane/propel", - "version": "1.2.2", + "version": "1.2.3", "private": true, "license": "AGPL-3.0", "type": "module", diff --git a/packages/services/package.json b/packages/services/package.json index cf0bec6ee..3e42079ba 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -1,6 +1,6 @@ { "name": "@plane/services", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/packages/shared-state/package.json b/packages/shared-state/package.json index af792136c..a98d5eaed 100644 --- a/packages/shared-state/package.json +++ b/packages/shared-state/package.json @@ -1,6 +1,6 @@ { "name": "@plane/shared-state", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "description": "Shared state shared across multiple apps internally", "private": true, diff --git a/packages/tailwind-config/package.json b/packages/tailwind-config/package.json index 61b73daec..73858f9cf 100644 --- a/packages/tailwind-config/package.json +++ b/packages/tailwind-config/package.json @@ -1,6 +1,6 @@ { "name": "@plane/tailwind-config", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "description": "common tailwind configuration across monorepo", "main": "tailwind.config.js", diff --git a/packages/types/package.json b/packages/types/package.json index e37e9b877..fe4a0954b 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@plane/types", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "private": true, "type": "module", diff --git a/packages/typescript-config/package.json b/packages/typescript-config/package.json index f7f44b203..30aa8ea7c 100644 --- a/packages/typescript-config/package.json +++ b/packages/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@plane/typescript-config", - "version": "1.2.2", + "version": "1.2.3", "license": "AGPL-3.0", "private": true, "files": [ diff --git a/packages/ui/package.json b/packages/ui/package.json index f84e6bddd..cc799f5bc 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -2,7 +2,7 @@ "name": "@plane/ui", "description": "UI components shared across multiple apps internally", "private": true, - "version": "1.2.2", + "version": "1.2.3", "sideEffects": false, "license": "AGPL-3.0", "type": "module", diff --git a/packages/utils/package.json b/packages/utils/package.json index 71a9b4429..573118f24 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@plane/utils", - "version": "1.2.2", + "version": "1.2.3", "description": "Helper functions shared across multiple apps internally", "license": "AGPL-3.0", "private": true, From 7b1f5a47f56072f24a3fdcf7198c940020c469ec Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Thu, 5 Mar 2026 17:26:06 +0530 Subject: [PATCH 12/12] [SECUR-116] fix: ssrf webhook url for ip address #8716 --- apps/api/plane/app/serializers/webhook.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api/plane/app/serializers/webhook.py b/apps/api/plane/app/serializers/webhook.py index ef193e24d..2aecebcde 100644 --- a/apps/api/plane/app/serializers/webhook.py +++ b/apps/api/plane/app/serializers/webhook.py @@ -34,7 +34,7 @@ class WebhookSerializer(DynamicBaseSerializer): for addr in ip_addresses: ip = ipaddress.ip_address(addr[4][0]) - if ip.is_loopback: + if ip.is_private or ip.is_loopback or ip.is_reserved or ip.is_link_local: raise serializers.ValidationError({"url": "URL resolves to a blocked IP address."}) # Additional validation for multiple request domains and their subdomains @@ -69,7 +69,7 @@ class WebhookSerializer(DynamicBaseSerializer): for addr in ip_addresses: ip = ipaddress.ip_address(addr[4][0]) - if ip.is_loopback: + if ip.is_private or ip.is_loopback or ip.is_reserved or ip.is_link_local: raise serializers.ValidationError({"url": "URL resolves to a blocked IP address."}) # Additional validation for multiple request domains and their subdomains