From 27a934dcfd579093b066c78d67eba782ba6229cb Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 10 Mar 2026 11:20:45 +0000 Subject: [PATCH] :bug: Fix plugin sandbox freezing CLJS Proxy constructor breaking Transit encoding When the plugin sandbox calls harden() (SES lockdown) on any proxy object returned from the penpot.* API, SES traverses the prototype chain up to Proxy.prototype and freezes the CLJS Proxy constructor function. Transit's typeTag helper later fails with "object is not extensible" when trying to set its cache property on that frozen constructor. Fix by deleting the constructor data property from Proxy.prototype so that harden never traverses to the CLJS Proxy constructor function. Signed-off-by: Andrey Antukh --- frontend/src/app/util/object.cljc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/util/object.cljc b/frontend/src/app/util/object.cljc index 090effd710..9ff10e7b9f 100644 --- a/frontend/src/app/util/object.cljc +++ b/frontend/src/app/util/object.cljc @@ -466,10 +466,17 @@ #?(:cljs (def Proxy - (app.util.object/class - :name "Proxy" - :extends js/Object - :constructor (constantly nil)))) + (let [ctor (app.util.object/class + :name "Proxy" + :extends js/Object + :constructor (constantly nil))] + ;; Remove the `constructor` data property from the prototype so that + ;; SES `harden` (used by the plugin sandbox) does not traverse from a + ;; proxy instance back to this constructor function and freeze it. + ;; If the constructor is frozen before Transit's `typeTag` helper sets + ;; its cache property, Transit throws "object is not extensible". + (js-delete (.-prototype ctor) "constructor") + ctor))) (defmacro reify "A domain specific variation of reify that creates anonymous objects