21625 Commits

Author SHA1 Message Date
Pablo Alba
101bbe8bd8 Add organization logo to nitrate invitations emails 2026-04-24 18:11:16 +02:00
Pablo Alba
700f3e9c10 MR changes 2026-04-24 17:19:41 +02:00
Pablo Alba
debfe5490f 🐛 Fix switching a team nitrate organization lose the background 2026-04-24 17:19:41 +02:00
Andrey Antukh
01d68ec09b Merge remote-tracking branch 'origin/staging' into develop 2026-04-24 14:16:03 +02:00
Andrey Antukh
35f8e1b084 Merge remote-tracking branch 'origin/main-staging' into staging 2026-04-24 14:09:21 +02:00
Andrey Antukh
0b6416e53b Merge remote-tracking branch 'origin/main' into main-staging 2026-04-24 14:09:03 +02:00
Andrey Antukh
d380efdb0c
⬆️ Update devenv dependencies (#9142)
* ⬆️ Update devenv dependencies

*  Fix formatting issues

* 📎 Fix linter issues
2026-04-24 14:07:51 +02:00
moorsecopers99
7e499c5e5f
🐛 Fix Settings/Notifications submit button always active with no changes (#9091)
The "Update Settings" button in Your Account > Settings and Notifications
was always enabled, even when the form had no changes, and clicking it
emitted a success notification despite no data being modified.

Disable the submit button when the current form data equals its initial
state, so it activates only when there are actual changes to persist.

Signed-off-by: moorsecopers99 <patellscott18@gmail.com>
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 13:24:55 +02:00
Juan Flores
38d67c8e96
🐛 Fix Help & Learning submenu vertical alignment in account menu (#9138)
The submenu opened by hovering Help & Learning in the user account
menu rendered with a vertical offset, making it appear visually
disconnected from its parent row and aligned instead with the
Community

Signed-off-by: Juan Flores <112629487+juan-flores077@users.noreply.github.com>
2026-04-24 13:17:57 +02:00
Eva Marco
6c4ab8940d
🐛 Fix colorpicker eyedropper on gradients tab (#9125)
* 🐛 Fix colorpicker eyedropper on gradients tab

* 🐛 Fix gradient test deleting opacity input
2026-04-24 12:48:58 +02:00
boskodev790
9ebd17f31f
🐛 Fix PENPOT_OIDC_USER_INFO_SOURCE flag being silently ignored (#9114)
Closes #9108.

The `case` expression in `get-info` (`backend/src/app/auth/oidc.clj`)
dispatched on `:token` and `:userinfo` keywords, but the provider map's
`:user-info-source` value is a string — both from config (the malli
schema in `app.config` pins it to one of `"token"`, `"userinfo"`,
`"auto"`) and from the hard-coded Google / GitHub provider maps (which
already write `"userinfo"`). Strings never equal keywords in Clojure
`case`, so every call fell through to the auto-fallback that prefers
ID-token claims and only hits the UserInfo endpoint when claims are
empty. The net effect: setting `PENPOT_OIDC_USER_INFO_SOURCE=userinfo`
did nothing, and OIDC flows whose IdP requires the UserInfo endpoint
(so claims come back empty/partial) failed with "incomplete user info".

- Extract a pure helper `select-user-info-source` that maps the raw
  config string to a dispatch keyword (`:token`, `:userinfo`, `:auto`),
  falling back to `:auto` for unknown / missing / accidentally-keyword
  values
- Rewrite `get-info`'s `case` to dispatch on the helper's output so
  the arms unambiguously match the normalised keyword
- Add vitest-style deftests in `auth_oidc_test.clj` pinning the three
  valid strings, the nil / "auto" / unknown fallback, and the reverse
  regression (a keyword input must not slip through as if it were the
  matching string)
- Add a CHANGES.md entry under the 2.17.0 Unreleased `🐛 Bugs fixed`
  section linking back to #9108

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 12:14:46 +02:00
Alejandro Alonso
89a1ee7813 Merge remote-tracking branch 'origin/main-staging' into staging 2026-04-24 12:06:27 +02:00
Andrey Antukh
29ba336928 Merge remote-tracking branch 'origin/main' into main-staging 2026-04-24 11:58:50 +02:00
Andrey Antukh
cfb076dd61 📚 Update AGENTS.md with common github operations 2026-04-24 11:45:36 +02:00
Eva Marco
4a7140d82d
🐛 Fix theme modal height (#9105)
* 🐛 Fix CI

* 🐛 Fix theme modal height
2026-04-24 11:38:34 +02:00
Pablo Alba
4061673528
Add nitrate api endpoints to get and cancel org invitations (#9124)
*  Add nitrate api endpoints to get and cancel org invitations

*  MR changes
2026-04-24 11:35:53 +02:00
Alejandro Alonso
e05ea1392a
Merge pull request #9140 from penpot/superalex-fix-merge-develop
🐛 Fix text.cljs error from staging merge
2026-04-24 10:57:59 +02:00
Alejandro Alonso
58fae0a04d 🐛 Fix text.cljs error from staging merge 2026-04-24 10:10:00 +02:00
Alejandro Alonso
078663b0fa 🔧 Fix rust linter errors 2026-04-24 09:52:51 +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
Alejandro Alonso
7532bf411c Merge remote-tracking branch 'origin/develop' into develop 2026-04-24 09:32:35 +02:00
Alejandro Alonso
984d292ab2 Merge remote-tracking branch 'origin/staging' into develop 2026-04-24 09:29:24 +02:00
Full Stack Developer
25e6b939ba
Show detailed messages on file import errors (#9004)
*  Show detailed messages on file import errors

Signed-off-by: jsdevninja <topit89807@gmail.com>

*  Fix test

*  Fix build error

---------

Signed-off-by: jsdevninja <topit89807@gmail.com>
2026-04-24 09:13:46 +02:00
FairyPiggyDev
361c1c574b
🐛 Fix plugin parse-point returning plain map instead of Point record (#9129)
The plugin parser's parse-point returned a plain `{:x … :y …}` map,
but shape interaction schemas (for example schema:open-overlay-interaction)
require the attribute to be a `::gpt/point` record. `(instance? Point {:x 0 :y 0})`
is false, so validation silently rejected plugin `addInteraction` calls
that passed `manualPositionLocation`; only a console warning was produced.

Change parse-point to return a `gpt/point` record via `gpt/point`.
All three call sites (parser.cljs:open-overlay, plugins/page.cljs,
plugins/comments.cljs) continue to work because Point records support
the same `:x`/`:y` access plain maps do.

Add a unit test that covers nil input and verifies the returned value
satisfies `gpt/point?`.

Github #8409

Signed-off-by: FairyPigDev <luislee3108@gmail.com>
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 09:12:13 +02:00
Juan Flores
841b2e156e
🐛 Fix typography style creation with tokenized line-height (#9121)
When a text element has a line-height coming from a design token, the value
may be a number (e.g. 1.5) and fails frontend data validation expecting a
string. Normalize line-height before creating the typography style so the
operation succeeds without throwing an assertion error.

Signed-off-by: juan-flores077 <toptalent399@gmail.com>
2026-04-24 09:11:31 +02:00
boskodev790
6c7843f4b6
🐛 Fix obfuscate-email crashing on malformed email or dotless domain (#9120)
The viewer-side `obfuscate-email` helper used by `anonymize-member` when
building share-link bundles called `clojure.string/split` on the raw
email input and then on the extracted domain. Two failure modes:

1. When the stored email had no `@` (legacy data, LDAP-sourced UIDs, direct
   DB inserts, or fixtures that bypassed `::sm/email`), destructuring
   left `domain` bound to `nil` and the follow-up `(str/split nil "." 2)`
   raised `NullPointerException`. Because `obfuscate-email` runs inside
   `get-view-only-bundle`, the exception aborted the whole RPC response
   for share-link viewers, not just the field.

2. When the stored email used a single-label domain (`alice@localhost`),
   `(str/split "localhost" "." 2)` returned `["localhost"]`; destructuring
   bound `rest` to `nil` and the final `(str name "@****." rest)` produced
   a dangling-dot output `"****@****."` (nil coerces to empty in `str`).

Guard both split calls with `(or x "")` so the chain is nil-safe, and
emit the trailing `.<tld>` segment only when `rest` is present. Add three
`deftest` groups covering the happy path, dotless domains, and malformed
inputs (nil / empty / no-`@`), plus a CHANGES.md entry under the 2.17.0
Unreleased bugs-fixed section.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 09:09:49 +02:00
Renzo
8aacda2249
Add Shift+Numpad0/1/2 zoom shortcut aliases (#2457) (#9063)
Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>
2026-04-24 09:08:31 +02:00
wdeveloper16
50bee5e176
Add clipboard:read/write permissions to plugin system (#6980) (#9053)
*  Add clipboard:read/write permissions to plugin system (#6980)

* 🔧 Fix prettier formatting in clipboard permission files

---------

Co-authored-by: wdeveloper16 <wdeveloer16@protonmail.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 09:07:58 +02:00
Andrey Antukh
20c6a28b52 📎 Add commit agent for opencode 2026-04-24 08:54:01 +02:00
Andrey Antukh
7135782e7d Merge remote-tracking branch 'origin/main-staging' into staging 2026-04-24 08:19:47 +02:00
Andrey Antukh
fd38f5b431 Merge remote-tracking branch 'origin/main' into main-staging 2026-04-24 08:18:55 +02:00
Andrey Antukh
2d5e50f352 ⬆️ Update root repo deps 2026-04-24 08:17:32 +02:00
wdeveloper16
e280168de9
Add read-only preview mode for saved versions (#7622) (#8976)
*  Add read-only preview mode for saved versions (#7622)

* 🔧 Address review feedback on version preview (#7622)

* 🐛 Fix version preview for WASM renderer (#7622)

* 🐛 Fix stylelint color-named and color-function-notation in preview banner (#7622)

* 🐛 Fix invalid-arity call to initialize-workspace in exit-preview (#7622)

* 🐛 Fix unclosed defn paren in exit-preview (#7622)

* ♻️ Refactor version preview/restore flow

Separate enter-preview and enter-restore flows with dedicated dialogs
instead of a persistent banner. Removes preview-banner component in favor
of inline actions dialog. Uses backup/restore pattern for exit-preview
instead of full workspace reinitialization. Adds analytics events for
preview/restore actions.

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

*  Extract on-name-input-focus as namespace-level private function

The callback had no dependencies on component-local state or props,
making it a pure function that can be hoisted to a defn-. This avoids
recreating the same callback identity on every render of version-entry*.

*  Extract extract-id-from-event helper to deduplicate snapshot callbacks

Three callbacks in snapshot-entry* shared the same DOM extraction logic
(get current target, read data-id, parse UUID). Extracted into a private
defn- to remove the duplication and simplify each callback.

*  Extract pure state-update callbacks from versions-toolbox* to namespace level

Eight callbacks that only emit fixed Potok events with no meaningful
deps were hoisted out of the component as defn- functions:

- on-create-version
- on-edit-version
- on-cancel-version-edition
- on-rename-version
- on-delete-version
- on-pin-version
- on-lock-version
- on-unlock-version

These no longer need mf/use-fn wrappers since namespace-level functions
have stable identity across renders, avoiding unnecessary callback
recreation on each render cycle.

*  Rename filter parameter to filter-value in on-change-filter to avoid core shadowing

The parameter name 'filter' shadowed clojure.core/filter within the
function scope. Renamed to 'filter-value' for clarity and to prevent
potential bugs if core/filter were needed in future changes.

* 🔧 Fix linter warnings and errors across version-related namespaces

frontend/src/app/main/ui/workspace.cljs:
- Remove unused requires: app.common.data, app.main.data.notifications,
  app.main.data.workspace.versions

frontend/src/app/main/data/workspace/versions.cljs:
- Remove unused require: app.common.uuid
- Fix duplicate reify type: enter-restore used ::restore-version
  (same as the private restore-version fn), renamed to ::enter-restore
- Remove unused bindings: state in enter-restore, team-id in
  exit-preview and restore-version-from-plugin

---------

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Signed-off-by: wdeveloper16 <wdeveloer16@protonmail.com>
Co-authored-by: wdeveloper16 <wdeveloer16@protonmail.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-24 08:13:16 +02:00
Renzo
7c1a29ccf7
🐛 Remove corepack dependency from MCP server for Node.js 25+ (#9119)
* 🐛 Remove corepack dependency from MCP server for Node.js 25+

* 🐛 Update
2026-04-23 22:08:11 +02:00
Luis de Dios
cd417443f6
🐛 Fix layer hierarchy to match old and new SCSS (#9126) 2026-04-23 18:00:40 +02:00
Eva Marco
0c60db56a2
🐛 Fix multiselection error with typography texts (#9071)
* 🐛 Ensure typography-ref attrs are always present and fix nil encoding

Add :typography-ref-file and :typography-ref-id (both defaulting to nil)
to default-text-attrs so these keys are always present in text node maps,
whether or not a typography is attached.

Skip nil values in attrs-to-styles (Draft.js style encoder) and in
attrs->styles (v2 CSS custom-property mapper) so nil typography-ref
entries are never serialised to CSS.

Replace when with if/acc in get-styles-from-style-declaration to prevent
the accumulator from being clobbered to nil when a mixed-value entry is
skipped during style decoding.

* 🎉 Add test

---------

Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-04-23 16:08:56 +02:00
Marina López
a3c330d6e7 Add downgrade nitrate to unlimited modal 2026-04-23 12:54:42 +02:00
Elena Torro
96722fde4b 🐛 Support EvenOdd SVG attribute across all path operations 2026-04-23 12:02:40 +02:00
Elena Torro
4a549d0907 Drain GPU queue during pan/zoom to avoid render_from_cache hitch 2026-04-23 11:19:51 +02:00
Eva Marco
d6b341c053
🐛 Fix color token (#9095) 2026-04-23 10:51:30 +02:00
Eva Marco
5c9696e20c
🐛 Fix color dropdown option update (#9100) 2026-04-23 10:51:20 +02:00
Eva Marco
28b33b9acc
🐛 Fix props on text components (#9099) 2026-04-23 10:49:48 +02:00
Andrey Antukh
c6b6b9ce00 📎 Update changelog 2.14.4 2026-04-23 09:59:11 +02:00
Yamila Moreno
5f7de04efe
🚑 Fix email blacklisting (#9122) 2026-04-23 09:42:40 +02:00
Elena Torró
d43d1f431f
Merge pull request #9112 from penpot/superalex-improve-atlas-growth
🎉 Improve atlas growth
2026-04-23 09:22:39 +02:00
Yamila Moreno
dc8073f924 🐳 Add PENPOT_PUBLIC_URI to penpot-frontend 2026-04-23 09:06:10 +02:00
Renzo
5bbb2c5cff
🐛 Fix Copy as SVG for multi-shape selection (#838) (#9066)
Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>
2026-04-22 19:46:38 +02:00
Alejandro Alonso
9e990a975a 🎉 Improve atlas growth 2026-04-22 17:21:11 +02:00
Andrey Antukh
ba42cc04b7 ♻️ Derive v-sizing from values instead of passing as prop
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-04-22 14:17:15 +00:00
Luis de Dios
b60695f54a 🐛 Fix indicate that the mcp is disabled if the mcp key has expired
If the mcp key has expired, the switch that indicates the status in the dashboard will appear as disabled, and will show a modal for regenerate the key. It will also appear as disabled in the workspace, not allowing the plugin to connect
2026-04-22 16:00:52 +02:00