14283 Commits

Author SHA1 Message Date
Elena Torró
f0680cf5f8
🐛 Handle empty variant options (#11499)
* 🐛 Handle empty variant options

* 🐛 Disable variant value select when there are no options
2026-09-07 09:53:45 +02:00
Andrey Antukh
9289e676e1 ✨ Require re-confirmation when plugin manifest differs on open
When the fetched manifest differs from the stored manifest
(code, name, etc.), show the permissions dialog instead of
silently updating — preventing execution of tampered/injected
plugins.

On fetch error, show a warning notification instead of loading
with the old manifest.

Bundled plugins (no URL) skip validation as they are trusted
with no remote source.

Completes the 3-layer defense for T3-N1-02: (1) closed
permission schema, (2) dedicated RPC methods, (3) integrity
validation on open.

AI-assisted-by: qwen3.7-plus
2026-09-07 09:30:01 +02:00
Andrey Antukh
a8e0b3c1f8 🐛 Add dedicated RPC methods for plugin registry operations
Add `add-profile-plugin` and `remove-profile-plugin` RPC methods for
atomic plugin registry operations, preventing manipulation via the
broader `update-profile-props` endpoint.

- Close the `:plugins` field in `update-profile-props` schema to
  eliminate the mass assignment attack vector for plugin data.
- Define `valid-permissions` and a closed `schema:permissions` enum to
  restrict plugin permissions to known values.
- Migrate the frontend to use the new granular RPC methods with
  optimistic updates and rollback on failure.
- Add comprehensive backend tests covering valid/invalid permissions,
  updates, removal, and rejection via old endpoint.

AI-assisted-by: qwen3.7-plus
2026-09-07 09:30:01 +02:00
Andrey Antukh
c8691d0cde
🐛 Fix crash when a nil shape id reaches WASM modifiers (#10896)
* 🐛 Fix crash when a nil shape id reaches WASM modifiers

A modif-tree containing a nil shape id crashed the WASM heap write
with "Cannot read properties of null (reading '__u32_buffer')" in
propagate-modifiers. Production builds elide the upstream asserts,
so a nil id (e.g. update-dimensions called with a missing shape's
parent id in the variants flow) reached the uuid heap write.

Drop nil-keyed modif-tree entries in apply-wasm-modifiers and
set-wasm-modifiers before they reach propagate-modifiers and
set-structure-modifiers, filter nil ids at the parse level, and
guard the variant reposition/creation events against missing shapes.

AI-assisted-by: hy3

* 🐛 Fix let scoping bugs in modifiers.cljs

Two let forms in set-wasm-modifiers and apply-wasm-modifiers
had their bindings vectors closed prematurely, causing undeclared
var warnings for snap-pixel?, translation?, ids, update-shape,
options, bool-ids, undo-id, and other bindings.

In set-wasm-modifiers: removed premature ) after ] on the let
bindings so the let body wraps snap-pixel? and translation?.

In apply-wasm-modifiers: the cond form was not explicitly closed,
so all subsequent bindings (ignore-tree, options, modif-tree, ids,
update-shape, bool-ids, undo-id) were parsed as cond clauses
instead of let bindings. Added ) to close cond after :else, and
moved ] to close the bindings vector after undo-id.

AI-assisted-by: mimo-v2.5-pro
2026-09-07 08:34:06 +02:00
Elena Torró
d82038a570
🐛 Fix paragraph span restyle on line change (#11503)
* 🐛 Fix paragraph span restyle on line change

* 🐛 Fix text shape boundaries on resize
2026-09-04 13:43:23 +02:00
Marina López
5452eb5c8a
🐛 Fix email sales (#11514) 2026-09-04 13:36:10 +02:00
Elena Torró
0533be100d
🐛 Fix text selection render overlay and double/triple click flash (#11512) 2026-09-04 12:38:31 +02:00
Eva Marco
df48c834e3
🐛 Fix create nil typography token (#11489)
* 🐛 Fix stroke width token dropdown closing mid-interaction

The stroke-row* key included a hash of applied-tokens, forcing a full
remount whenever the async token-resolution pipeline updated that
state (e.g. after a detach action settles). If the remount landed
while the width dropdown was open, it destroyed the dropdown and
reset its open state, permanently closing it before the user could
pick a token.

Drop the hash from the key so the row only remounts on actual
structural changes (add/remove/reorder), not on every token
resolution tick.

AI-assisted-by: claude-sonnet-5

* 🐛 Fix crash when a typography token has a nil value

A composite typography token saved with no fields filled in stores a
nil :value. That value reached StyleDictionary's tokens-studio
font-styles preprocessor, which assumes a typography value is never
null and threw, crashing token resolution for every other token in
the file.

Reject the nil value at the source in the typography token form
validation, and as defense in depth, filter nil-valued tokens out of
every resolve-tokens* entry point before they reach StyleDictionary,
tagging them with the existing empty-input error instead.

Also remove a stray debug prn left in find-refs.

AI-assisted-by: claude-sonnet-5

* 🔧 Gitignore local CLAUDE.md

Keep the commit-conventions instructions file local to each
contributor's checkout instead of tracking it in the repo.

AI-assisted-by: claude-sonnet-5

* ⚡ Use a single transducer to tag invalid-value tokens

merge-invalid-value-tokens ran three separate passes over the token
map (remove, map, into) and then merged the result back in. Combine
the remove/map steps into one ns-level transducer, defined once
instead of rebuilt on every call, and pass resolved as the seed to
into so the trailing merge isn't needed either.

AI-assisted-by: claude-sonnet-5

* ♻️ Drop redundant t/testing wrapper in nil-value token test

The outer t/testing just repeated the deftest's own name and added
nothing the two inner t/testing blocks (each covering one concrete
assertion group) don't already say.

AI-assisted-by: claude-sonnet-5

* 🐛 Fail the nil-value token test on a resolution error

rx/sub! only handles the success case, so if token resolution ever
errors instead, done is never called and the async test hangs
instead of failing. Switch to rx/subs! with an error handler that
reports the failure and calls done, matching the pattern already
used elsewhere in the tokens test suite.

AI-assisted-by: claude-sonnet-5
2026-09-04 12:31:26 +02:00
Alejandro Alonso
86aebd3429
⚡ Reduce WASM text selrect churn after batch page load (#11471)
* 🐛 Align WASM auto-width text size with HTML measurement

Include the HTML paragraph-set 1px right margin in Skia auto-width
so WASM and DOM measurements match.

* ⚡ Scope and defer post-font WASM text relayout

Track pending font faces per shape, force-relayout only affected
texts, defer stale-selrect sync until the first tiles paint, and
batch request-render after attr updates. Tolerate missing font-face
keys so callers that omit them do not blow up.
2026-09-04 12:24:37 +02:00
Alejandro Alonso
7f46c8c80e Merge remote-tracking branch 'origin/staging' into develop 2026-09-04 11:00:56 +02:00
Elena Torró
fdcc4666e3
🐛 Fix multiple shapes export on files rendered with webgl (#11506) 2026-09-04 11:00:35 +02:00
Eva Marco
064f200774
🐛 Fix crash pressing Ctrl+D with no shape selected (#11491)
AI-assisted-by: claude-sonnet-5
2026-09-04 10:21:31 +02:00
Eva Marco
214dbd0c8b
🐛 Stop opening Comments section from persisting display-comments (#11492)
AI-assisted-by: claude-sonnet-5
2026-09-04 10:15:38 +02:00
Elena Torró
eb8d3a2fef
🐛 Fix paragraph selection (#11493) 2026-09-03 16:17:38 +02:00
Philippe Accorsi
6b113566f3
🌐 Add translations for: French
Currently translated at 99.8% (2429 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr/
2026-09-03 11:51:27 +00:00
Surfoo
45b3bdf625
🌐 Add translations for: French
Currently translated at 99.8% (2429 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr/
2026-09-03 11:51:26 +00:00
Alejandro Alonso
fb22c1547c
🐛 Skip component sync for derived WASM text layout commits (#11490)
Post-font-load selrect fixes and position-data regeneration write
sync-attrs on texts inside mains. That made watch-component-changes
treat them as edits and run touch/sync per component, freezing large
files. Mark those commits with skip-component-sync? (same idea as
translation?) so only real user edits propagate.
2026-09-03 13:43:36 +02:00
Alejandro Alonso
7b26949c76 🐛 Fix typography.cljs error from staging merge 2026-09-03 12:34:54 +02:00
Alejandro Alonso
37f1d3f0fd Merge remote-tracking branch 'origin/staging' into develop 2026-09-03 12:24:44 +02:00
Luis de Dios
a19b3c8d62 🐛 Fix font preview in assets breaks the font row (#11428)
* 🐛 Fix font preview in assets breaks the font row

* 🐛 Fix font height problem also in the font dropdown

* 🐛 Fix a small bug within the changes

---------

Co-authored-by: Eva Marco <evamarcod@gmail.com>
2026-09-03 12:16:26 +02:00
Elena Torró
80dea409c6
🐛 Fix share-link viewers unable to load file fragments (#11484) 2026-09-03 12:15:35 +02:00
María Valderrama
7c762d8a98
🐛 Fix recommended plan (#11488) 2026-09-03 11:59:20 +02:00
Pablo Alba
15dff4a9e1
💄 Fix sales email (#11478) 2026-09-03 08:46:52 +02:00
Eva Marco
c6a32a2f5a
🐛 Fix list on registration toast notification (#11479) 2026-09-02 17:19:37 +02:00
Eva Marco
cb80ea98ba
🎉 Add a new favicon for localhost enviroment (#11459) 2026-09-02 16:02:23 +02:00
0xTHAC0
b2fb63988f
🐛 Fix font-size dropdown clipping multi-digit values in Firefox (#11162)
The .custom-select-dropdown used width: fit-content which, in Firefox,
is capped to the containing block width (60 px for the font-size input).
This caused two- and three-digit font-size values (e.g. 48, 120, 1000)
to be visually clipped in the dropdown list.

Switching to width: max-content lets the dropdown expand to fit its
content regardless of the containing block width, matching the behaviour
Chrome already exhibited with fit-content.

Fixes #11008
2026-09-02 15:54:33 +02:00
Elena Torró
70b443a716
✨ Render multiple-object SVG exports with render-wasm (#11475) 2026-09-02 14:45:32 +02:00
Eva Marco
7620386215
🐛 Fix font family preview sample (#11473)
* 🐛 Fix font family preview sample

* 🐛 Fix font line height inside font selector
2026-09-02 13:55:38 +02:00
Elena Torró
03e6f119e5
♻️ Clean unnecessary methods (#11472)
* ♻️ Remove duplicated/unused set-children code

* ♻️ Remove unused methods
2026-09-02 12:58:52 +02:00
Surfoo
c0f5fc601c
🌐 Add translations for: French
Currently translated at 99.7% (2425 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr/
2026-09-02 12:29:59 +02:00
Surfoo
9e66f5653e
🌐 Add translations for: French
Currently translated at 85.8% (2088 of 2432 strings)

Translation: Penpot/frontend
Translate-URL: https://hosted.weblate.org/projects/penpot/frontend/fr/
2026-09-02 10:54:29 +02:00
Alejandro Alonso
b9ddfc1596
⚡ Batch WASM shape upload to speed up page switches (#11443)
Upload structural shape attrs (base, children, blur, shadows,
flex, layout-item) via multi-shape `_set_shapes_batch` FFI in
chunks of 512, then apply host attrs with use-shape selection.
2026-09-02 10:32:52 +02:00
Alejandro Alonso
d1a54134bb
✨ Add text and @font-face to WASM SVG export (#11442)
* ✨ Add text and @font-face to WASM SVG export

Emit selectable <text> elements and inject @font-face rules that
reference the font URLs registered at load time. Text fill bypasses
save_layer wrappers that SkSVGDevice drops. Text strokes are deferred
to a follow-up PR.

* 🐛 Strip trailing commas from Skia SVG text positions

Skia's SVG backend appends a trailing comma to per-glyph x/y lists.
Firefox rejects the malformed attribute and drops glyph positioning,
making exported text vanish or mis-render.
2026-09-01 17:06:50 +02:00
Luis de Dios
99378dc02d
🐛 Fix font preview in assets breaks the font row (#11428)
* 🐛 Fix font preview in assets breaks the font row

* 🐛 Fix font height problem also in the font dropdown

* 🐛 Fix a small bug within the changes

---------

Co-authored-by: Eva Marco <evamarcod@gmail.com>
2026-09-01 15:48:09 +02:00
Eva Marco
c7b3a0849f
🐛 Fix colopicker image checkbox (#11456) 2026-09-01 13:27:09 +02:00
Elena Torró
b458dc764e
🔧 Set wasm export by flag instead of team feature (#11449) 2026-09-01 12:47:05 +02:00
Andrey Antukh
f5aad7b1ae Merge remote-tracking branch 'origin/staging' into develop 2026-09-01 12:45:17 +02:00
Andrey Antukh
a1079cf788
⬆️ Update JVM, pnpm and node dependencies (#11404)
* ⬆️ Update pnpm and its deps

* ⬆️ Update JVM dependencies in backend and common

Update several JVM dependencies across backend and common:

- passay 1.6.6 -> 2.0.0 (package reorg, ctor-based rules)
- siphash 2.0.0 -> 3.0.0 (SipHasher* renamed to SipHash*)
- lettuce-core, guava, sqlite-jdbc, jsoup, lz4-java, markdown-clj,
  awssdk s3/sts, selmer, jackson-core/databind, shadow-cljs

Adapt passay validation to the new API (moved packages, constructor
configuration) and siphash to the renamed classes. Add tests for
password validation and UUID advisory-lock hashing.

AI-assisted-by: deepseek-v4-flash

* ⬆️ Update node on docker images

* 📎 Minor fixes related to pnpm12 compatibility
2026-09-01 12:01:35 +02:00
Eva Marco
5c4b35e350
🐛 Fix top spacing on left sidebar (#11446) 2026-09-01 10:56:53 +02:00
Pablo Alba
5b3a1d9360
✨ Add check version menu entry (#11411)
* ✨ Add check version menu entry

* ✨ MR fixes

* ✨ MR changes 2
2026-08-31 16:47:17 +02:00
Alejandro Alonso
89a17df403
✨ Add basic WASM SVG export path (#10891)
Introduce a minimal vector SVG exporter via render-wasm: solid fills,
native opacity/blend wrappers, frame clip-content, FFI/frontend wiring,
insta snapshots, and a visual preview gallery. Defer save_layer
workarounds (shadows, blur, masks, special strokes) to follow-up PRs.
2026-08-31 16:06:38 +02:00
Elena Torró
66b4a99ac3
🎉 Implement export jobs to process export requests (#11296)
* ✨ Add export job model, store and scheduler to exporter

* ✨ Render wasm exports on pooled worker threads

* ✨ Add export job REST API to exporter

* ✨ Use export job API and allow cancelling wasm exports

* 🔧 Show export jobs in the internal debug panel

* 🔧 Pass flags and export job settings to the exporter container

* 📚 Document the exporter job API and its redis layout
2026-08-31 14:42:51 +02:00
Luis de Dios
fc207a1768
🐛 Fix shapes flyout in toolbar only opens with the space key, and doesn't close when pressed again (#11331) 2026-08-31 14:00:14 +02:00
Luis de Dios
806f947360
🐛 Fix avoid empty space at the bottom when there are many layers (#11427) 2026-08-31 12:38:20 +02:00
Luis de Dios
bfb5cae9f4
🐛 Fix viewer login modal lacks spacing between SSO buttons and work email field (#11312)
* 🐛 Fix spacing between SSO buttons and email field

* ♻️ Update scrollbar on register page

* ♻️ Translate hardcoded string

---------

Co-authored-by: Eva Marco <evamarcod@gmail.com>
2026-08-31 12:17:57 +02:00
Andrey Antukh
292390f0eb Merge remote-tracking branch 'origin/staging' into develop 2026-08-31 11:52:26 +02:00
Luis de Dios
2ed0981e8a
🐛 Fix disabled numeric input with token applied is broken (#11324) 2026-08-31 11:51:42 +02:00
Luis de Dios
169e6fcbca
🐛 Fix comments not close main menu (#11347) 2026-08-31 11:50:59 +02:00
María Valderrama
c01306734a
🐛 Fix default team and UI labels to use Personal Projects (#11418)
* 🐛 Fix default team and UI labels to use Personal Projects

* 📎 Code review
2026-08-28 14:04:56 +02:00
Pablo Alba
10e40e62a2
✨ Add airgapped check to nitrate (#11421) 2026-08-28 13:58:18 +02:00