2022 Commits

Author SHA1 Message Date
Andrey Antukh
e5c99231da 📚 Update changelog 2026-05-12 18:43:08 +02:00
Andrey Antukh
ade0d2d0a8 📎 Update changelog with PR info 2026-05-12 13:01:42 +02:00
Andrey Antukh
bd3ca6f8e5 📚 Update changelog 2026-05-12 09:33:33 +02:00
Andrey Antukh
b312e6b059 📚 Update changelog 2026-05-11 11:26:54 +02:00
Andrey Antukh
1a212a2769 Merge remote-tracking branch 'origin/main-staging' 2026-05-11 08:46:25 +02:00
andrés gonzález
9c771ae6b9
🐛 Fix MCP integrations copy button to match displayed URL (#9239) 2026-05-10 19:23:03 +02:00
Andrey Antukh
cf3455a487 📎 Add missing entry on CHANGES.md 2026-05-10 09:18:52 +02:00
Francis Santiago
e9588f3939
🐳 Reuse shared Nginx security headers (#9473)
Signed-off-by: Francis Santiago <francis.santiago@kaleidos.net>
2026-05-08 14:11:09 +02:00
Andrey Antukh
a50785f105 📎 Update changelog 2026-05-08 09:29:28 +02:00
Andrey Antukh
279231240d
🐛 Harden outbound HTTP requests against SSRF and restrict assets handlers (#9390)
* ⬆️ Update root deps

* 🐛 Harden outbound HTTP requests against SSRF and restrict unauthenticated asset access

- Add app.util.ssrf URL/host validator that resolves hostnames and blocks
  loopback, link-local, site-local, cloud metadata, and operator-supplied CIDRs
- Add app.media.sanitize image EOF truncator that strips trailing data after
  PNG IEND, JPEG EOI, GIF trailer, and WebP RIFF markers
- Disable HTTP client auto-redirect; add req-with-redirects! helper that
  revalidates every redirect hop against the SSRF blocklist
- Wire SSRF validation and EOF sanitization into media/download-image
- Validate webhook URLs and OIDC profile picture URLs against SSRF
- Restrict /assets/by-id to require authentication for non-public buckets
  (profile) while keeping public access for file-media-object,
  file-object-thumbnail, team-font-variant, and file-data-fragment
- Add config knobs: ssrf-protection-enabled, ssrf-allowed-hosts,
  ssrf-extra-blocked-cidrs

Signed-off-by: Andrey Antukh <niwi@niwi.nz>

---------

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-05-08 09:18:22 +02:00
Andrey Antukh
3496435e69 📚 Update changelog 2026-05-08 00:32:21 +02:00
Andrey Antukh
d103feebfa 📚 Update changelog 2026-05-07 23:57:49 +02:00
Andrey Antukh
798ee46b4a 🐛 Bind MCP ReplServer to localhost to prevent unauthenticated RCE
The ReplServer Express app was calling `app.listen(port)` with no host
argument, causing Node/Express to default to binding on all interfaces
(0.0.0.0). Combined with the unauthenticated /execute endpoint, any
network peer could POST arbitrary JS and get it run inside the MCP
process.

Fix: add a `host` parameter (default "localhost") to the ReplServer
constructor and pass it to `app.listen`. The call site in
PenpotMcpServer now forwards `this.host` (sourced from
PENPOT_MCP_SERVER_HOST env var, default "localhost"), so environment-
variable overrides continue to work.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-05-07 12:59:31 +02:00
Andrey Antukh
54928e9ffb Merge branch 'backport-2.14' 2026-05-06 14:38:17 +02:00
Andrey Antukh
df01f76056 🐛 Fix incorrect invitation token handling on register process (#9380)
* 🐛 Fix incorrect invitation token handling on register process

- Reject prepare-register-profile when an active profile already
  exists for the requested email.
- Stop embedding an existing profile's :profile-id into the
  prepared-register JWE. Profile resolution in register-profile is
  now done exclusively by email lookup, never by a JWE claim.
- Add created? guard to the invitation-success branch in
  register-profile, so existing profiles (active or not) cannot
  reach session creation via anonymous registration.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>

* ♻️ Restructure invitation handling inside register-profile

Move the invitation-success branch into the created? sub-cond so it
sits alongside the other post-creation branches, making the control
flow consistent.

- Active new profile + matching invitation: mint session and return
  :invitation-token (frontend redirects to :auth-verify-token).
- Not-yet-active new profile + matching invitation: embed the
  invitation token inside the verify-email JWE and send the
  verification email. When the user clicks the link, they get
  logged in and the frontend completes the team-invitation flow.
- Extend send-email-verification! with an optional invitation-token
  parameter propagated into the verify-email JWE claims.
- Update the frontend verify-email handler to navigate to
  :auth-verify-token when the response carries :invitation-token.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>

* 🐛 Handle email-already-exists error on registration form

Add a specific handler for the [:validation :email-already-exists] error
code in the registration form's on-error callback. The backend raises
this error when an active profile already exists for the requested email,
but the frontend was falling through to the generic error message.

Now it shows the existing "Email already used" i18n message instead of
the generic "Something wrong has happened" toast.

* 🐛 Reset submitted state on registration form error

The on-error handler in the registration form was not resetting the
submitted? state, causing the submit button to remain disabled after
any error. The completion callback in rx/subs! only fires on success,
not on error.

Add (reset! submitted? false) at the beginning of the on-error handler
so the form becomes submittable again after any error, allowing the user
to fix their input and retry.

---------

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-05-06 14:32:31 +02:00
Andrey Antukh
1e1ca82ba5 📚 Add missing changelog entry and document changelog locations
Add changelog entry for the fix-incorrect-invitation-token-handling
change (PR #9380) under `## 2.15.0 (Unreleased)` > `🐛 Bugs fixed`.
Add a `## Changelogs` section to AGENTS.md documenting both changelog
locations (main project: `CHANGES.md`, plugins: `plugins/CHANGELOG.md`).

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-05-06 12:24:55 +00:00
Eva Marco
ce24fed32b
🐛 Fix incorrect text-edition warning when applying tokens (#9355) 2026-05-06 08:47:30 +02:00
Andrey Antukh
d06b45ec90 🐛 Fix Plugin API token application for JS array of strings
Two coupled defects made shape.applyToken(), token.applyToShapes() and

token.applyToSelected() silently no-op when invoked from JavaScript with

an array of strings (e.g. token.applyToShapes([rect], ["fill"])):

1. token-attr-plugin->token-attr only consulted its alias map when the

   input was already a keyword; string inputs fell through unchanged,

   causing downstream token-attr? to return false.

2. The inner schemas used plain [:set ...] which lacks the :decode/json

   transformer for JS array -> Clojure set coercion. Switching to

   Penpot's custom [::sm/set ...] lets the standard JSON decoder

   pipeline handle the conversion automatically.

This is a backport of commit 1eac3e2be5f973359ad2ec9bac4e80a9d5a9e022

which fixes GitHub #9162.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-04-29 19:09:25 +02:00
Andrey Antukh
4829b843b2 🐛 Fix dashboard modal clipping behind sidebar (#9233)
Backport from develop commit 510a015424b6b98529dba19cc72bdf002b8ff83a.

- Fix release notes modal appearing behind the dashboard sidebar (by @RenzoMXD)
- Change sidebar z-index from dropdown to panels layer

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-04-29 15:52:48 +00:00
Andrey Antukh
839754715a 📚 Update changelog 2026-04-27 17:30:02 +02:00
Andrey Antukh
29ba336928 Merge remote-tracking branch 'origin/main' into main-staging 2026-04-24 11:58:50 +02:00
Eva Marco
5a7ba7ee7e
🐛 Fix multiple selection on shapes with token applied to stroke-color (#9110)
*  Remove the need to navigate to page for deletion operation

* 🐛 Fix multiple selection with applied-tokens on stroke-color

* 🐛 Fix button position on page header

---------

Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 09:47:44 +02:00
Andrey Antukh
fd38f5b431 Merge remote-tracking branch 'origin/main' into main-staging 2026-04-24 08:18:55 +02:00
Andrey Antukh
c6b6b9ce00 📎 Update changelog 2026-04-23 09:59:11 +02:00
Yamila Moreno
3c542a1abc
🐛 Fix email validation (#9037) 2026-04-22 15:59:28 +02:00
Andrey Antukh
f716995ffd 📚 Update changelog 2026-04-21 21:08:57 +02:00
Andrey Antukh
3a39676969 Backport MCP from staging (part 1) 2026-04-20 19:37:02 +02:00
Andrey Antukh
69e505a6a2 📎 Update changelog 2026-04-16 10:21:15 +02:00
Andrey Antukh
390796f36e 📎 Update changelog 2026-04-16 10:20:05 +02:00
Andrey Antukh
28f65fec91 📚 Update changelog 2026-04-13 12:15:17 +02:00
Aitor Moreno
9c44f5bf65 🐛 Fix text editor v1 focus not being handled correctly (#8942) 2026-04-13 12:08:06 +02:00
Luis de Dios
cbe9d31599 🐛 Fix dashboard navigation tabs overlap with content when scrolling (#8937)
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-13 12:01:10 +02:00
Pablo Alba
ef6eeb5693
🐛 Fix variants corner cases with selrect and points (#8882)
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-10 11:23:03 +02:00
Andrey Antukh
ffac8d2861 📎 Update changelog 2026-04-08 17:34:00 +02:00
Andrey Antukh
ef3143dcb8 📎 Update changelog 2026-03-30 12:35:39 +02:00
Andrey Antukh
13b5c96a42 📎 Update changelog 2026-03-24 09:19:58 +01:00
Andrey Antukh
33c5f82c43 🐛 Fix penpot.openPage() to navigate in same tab by default
- Change the default for the newWindow param from true to false, so
  openPage() navigates in the same tab instead of opening a new one
- Accept a UUID string as the page argument in addition to a Page object,
  avoiding the need to call penpot.getPage(uuid) first
- Add validation error when an invalid page argument is passed

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-13 09:19:50 +01:00
Andrey Antukh
8d5450391e 🐛 Fix crash when pasting non-map transit clipboard data
Guard against transit-decoded clipboard content that is not a map
before calling assoc, which caused a runtime crash ('No protocol
method IAssociative.-assoc defined for type number').

Also route :copied-props paste data to paste-transit-props instead
of incorrectly sending it to paste-transit-shapes.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 15:05:22 +01:00
Eva Marco
8f5c38d476
🐛 Fix scroll on colorpicker (#8595) 2026-03-12 13:36:38 +01:00
Andrey Antukh
b68e400cc1
🐛 Fix crash in select* when options vector is empty (#8578)
Guard get-option fallback with (when (seq options) ...) to avoid
"No item 0 in vector of length 0" when options is an empty vector.
Also guard the selected-option memo in select* to mirror the same
pattern already present in combobox*.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 13:06:25 +01:00
Andrey Antukh
82e3a5fa53 🐛 Fix 'not ISeqable' error when entering float values in layout/opacity inputs
Replace int? with number? in on-change handlers for layout item margins,
min/max sizes, and layer opacity. Using int? caused float values like 8.5
to fall into the design token branch, calling (first 8.5) and crashing.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 12:37:22 +01:00
Eva Marco
c00ef7c128
🐛 Fix unnexpected warning (#8603) 2026-03-12 12:01:28 +01:00
Andrey Antukh
68fbacf8b3 Merge tag '2.14.0-RC2' 2026-03-10 14:38:58 +01:00
Pablo Alba
34d29328e6
🐛 Fix bad size on switching a layout with fixed sizing (#8504) 2026-03-09 12:12:03 +01:00
Andrey Antukh
86e851f408
🐛 Fix incorrect version visibility on workspace (#8463)
* 🐛 Add missing order by clause to snapshot query

This fixes the incorrect snapshot visibility when file
has a lot of versions.

*  Reduce allocation on milestone-group* component

* 🐛 Fix milestone group timestamp formatting

* 📎 Update changelog

* 🐛 Fix scroll on history panel

---------

Co-authored-by: Eva Marco <evamarcod@gmail.com>
2026-03-04 09:27:51 +01:00
Andrés Moya
31478c6afc
🐛 Fix validation of shadow token with missing keys (#8507) 2026-03-02 16:17:12 +01:00
Eva Marco
9345902a62
🐛 Fix cannot apply second token after creation while shape is selected (#8476) 2026-02-26 10:53:25 +01:00
Yamila Moreno
dd856ecf50 ♻️ Deprecate PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE envvar 2026-02-23 13:48:01 +01:00
Andrey Antukh
137febcbab 📎 Clean changelog 2026-02-17 10:00:42 +01:00
Andrey Antukh
f98c0bbd16 📎 Update changelog 2026-02-17 09:58:40 +01:00