feat(wekan): update image docker.io/wekanteam/wekan v9.74 → v9.76 (#49930)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [docker.io/wekanteam/wekan](https://redirect.github.com/wekan/wekan) |
minor | `12c6429` → `6ed534c` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/18710) for more information.

Add the preset `:preserveSemverRanges` to your config if you don't want
to pin your dependencies.

---

### Release Notes

<details>
<summary>wekan/wekan (docker.io/wekanteam/wekan)</summary>

###
[`v9.76`](https://redirect.github.com/wekan/wekan/blob/HEAD/CHANGELOG.md#v976-2026-07-06-WeKan--release)

[Compare
Source](https://redirect.github.com/wekan/wekan/compare/v9.75...v9.76)

This release adds the following fixes:

- **[Fix notification emails linked to `/b/undefined/board/<cardId>`
instead of the real
board](https://redirect.github.com/wekan/wekan/commit/8b21158736f9e1360332903707c100bce3d6b164)**:
On the server `ReactiveCache.getBoard()` is async and returns a Promise,
but `Cards.board()` did not await it,
so the synchronous `Card.originRelativeUrl()`/`absoluteUrl()`
interpolated a Promise —
`board._id` and `board.slug` were `undefined`, producing
`/b/undefined/board/<cardId>` in
card activity notification emails (the client UI was unaffected because
`this.board()` is
synchronous there). Fixed by making
`Card.originRelativeUrl(board)`/`absoluteUrl(board)` accept an
already-resolved board and fall back to `this.boardId` (always available
synchronously) when the
board is a Promise, and by passing the awaited board from
`server/models/activities.js` so the
  correct board id and slug are used.
  Thanks to titver968 and xet7.

- **[Release workflow: publish the Helm chart only after the Docker
image is
pushed](https://redirect.github.com/wekan/wekan/commit/a2802a850b57ef7ac183ddb581be666d14d43705)**:
In `.github/workflows/release-all.yml` the `charts` job now depends on
the `docker` job
(`needs: docker`) instead of running in parallel right after `bump`.
GitHub Actions runs a job
only when all of its `needs` jobs succeed, so the wekan/charts Helm
chart is published only after
the multi-arch image is live on Docker Hub / Quay.io / GHCR (and is
skipped if `docker` fails).
This prevents ArtifactHub from scanning a freshly published chart whose
image tag does not exist
  yet and emailing the maintainer about the missing Docker image.
  Thanks to xet7.

- **[Fix thousands of unsolicited empty "Default" swimlanes created on
some
boards](https://redirect.github.com/wekan/wekan/commit/45fb54794755663307ef89636e2822ef9c65428d)**:
`Board.getDefaultSwimline()`/`getDefaultSwimlineAsync()` self-heal a
missing default swimlane by
reading the board's swimlanes and inserting one if none exist. That
check-then-insert is a race:
concurrent or repeated server calls for a swimlane-less board each saw
zero swimlanes and each
inserted a new one, so some boards accumulated 30 000+ empty "Default"
swimlanes and became
unloadable (the `key 'default (en)' returned an object instead of
string` log is a harmless i18n
side effect — the title correctly falls back to the string `Default`).
Follow-up to the
client-side
[#&#8203;6382](https://redirect.github.com/wekan/wekan/issues/6382) fix,
which only stopped the
browser from auto-creating them. Fixed by making the server self-heal
**idempotent**: the default
swimlane is now upserted with a deterministic `_id`
(`<boardId>-default`), so the `_id` unique
index guarantees at most one default swimlane per board no matter how
many times, or how
concurrently, the getters run. `archived`/`type` are set explicitly in
the `$setOnInsert` because
their schema autoValue/defaultValue only fire on insert, not upsert.
Note: this prevents new
duplicates; boards that already accumulated thousands still need a
one-off cleanup.
  Thanks to brlin-tw and xet7.

- **[Reduce card flicker on drag by only writing changed fields on a
card
move](https://redirect.github.com/wekan/wekan/commit/2e7c4ede2a6429048882e68084bb286aedbc42a5)**:
`Card.move()` wrote `boardId`/`swimlaneId`/`listId` into the update
unconditionally, even for a
same-board drag to another list (the reported case). Keeping `boardId`
in the `$set` on every drag
re-ran the `boardId`-gated `Cards.after.update` hook that re-syncs the
card's checklists and
checklist items via `multi` updates, ran the cross-board consistency
guard and the
`denyCrossBoardMove` deny-rule DB lookup, and invalidated more reactive
dependents than
necessary — server work and reactivity churn that contributed to a \~1s
card flicker on large
boards. `Card.move()` now writes **only the fields that actually
change** (via the pure
`computeCardMoveModifier` helper) and skips the write entirely when a
card is dropped back in the
same place, so a same-board move no longer touches boardId or the
cross-board hooks. The
`moveCard`/`moveCardBoard` activity generators already re-check `doc.X
!== oldX`, so trimming the
modifier does not drop any activity. Note: this reduces the drag-time
work behind the flicker; the
residual reactive re-render cost on very large boards is a separate
performance topic.
  Thanks to mimZD and xet7.

- **[Fix `DEFAULT_AUTHENTICATION_METHOD` env var ignored, and Admin
Panel Layout save
hanging](https://redirect.github.com/wekan/wekan/commit/d5596f05b7ee63a114d3479c34e930f0d9d5549c)**:
  Two related problems with the default login authentication method.
- **Env var ignored:** the stored setting was only ever seeded as
`password` and
`DEFAULT_AUTHENTICATION_METHOD` was never applied, so operators setting
it (e.g. Kubernetes/Helm
`DEFAULT_AUTHENTICATION_METHOD: ldap`) saw no effect. Startup now
applies the env var
authoritatively: it seeds the value on a fresh install and, on existing
installs, keeps the
stored `defaultAuthenticationMethod` in sync with the env var on every
boot (the operator's env
is the source of truth), so the method can be configured entirely by env
without the Admin Panel.
The value is normalized (trimmed + lower-cased), so
`DEFAULT_AUTHENTICATION_METHOD=LDAP` works.
- **Layout save hanging / not persisting:** the authentication-method
`<select>` is populated by an
async `Meteor.call`, so clicking **Admin Panel > Layout > Save** before
it loaded sent an empty
value for the **required** `defaultAuthenticationMethod` field, which
silently failed validation —
the save looked stuck and nothing changed. The save now falls back to
the currently stored method
when the select is empty, so a real value is never overwritten by `''`.
Both paths share one pure helper (`resolveDefaultAuthenticationMethod`)
that never resolves to an empty string.
    Thanks to joe-speedboat and xet7.

- **[Fix #&#8203;5808: linking a card to another linked card made both
cards
inaccessible](https://redirect.github.com/wekan/wekan/commit/878a24f586d698307bc3af1e65c903147f87a59a)**:
The "Link to this card" target picker only excluded template cards, so
an existing **linked** card
(or a card that already links back to the current board) could be chosen
as a link target. That
  builds a chain/cycle of `linkedId` pointers, but the card helpers
(`getTitle`/`getBoardTitle`/`getRealId`) resolve `linkedId` only **one
hop**, so such a card
renders as an empty/broken pointer and becomes effectively inaccessible
(the reported freeze). As
the reporter suggested, the fix **prevents the configuration** rather
than allowing it: only a real
card — not a linked card/linked board, not one of the linking board's
own cards, and not a card
that links back to one of them — may now be a link target. This is
enforced both in the picker's
query and re-checked at creation time (the options can be stale), via
the pure
`isLinkableCardTarget` guard, mirroring the existing
[#&#8203;3328](https://redirect.github.com/wekan/wekan/issues/3328)
parent/subtask cycle guard. Note: this
stops new inaccessible links; any already-created ones still need manual
cleanup.
  Thanks to the reporter and xet7.

- **[Fix the "Board not found" flicker (stale-while-revalidate for the
client board
cache)](https://redirect.github.com/wekan/wekan/commit/d00dc6056b241b0b3e383bb5b4e75ba10ed78f56)**:
While viewing a board, the board view could briefly flash the **"Board
not found"** shell — and on
WebKit throw a Blaze `Can't select in removed DomRange` error tearing
down the card view. Root
cause: the client board cache (`imports/lib/dataCache.js`) re-fetches
its value inside a reactive
computation, and when the board doc is momentarily absent from minimongo
(a subscription stops and
restarts, so Meteor transiently removes the doc) the re-fetch returns
`undefined` and that empty
value is surfaced immediately. It self-recovers when the subscription
re-delivers the doc, so it
presents as a flicker — reliably reproduced only on Firefox/WebKit,
where the reactive-render
timing hits the window (Chromium did not, which is why it surfaced as
browser-specific Playwright
failures in `14-voting-watchers` and `24-feature-issues`). Fixed with an
opt-in
**stale-while-revalidate** mode on `DataCache`, enabled only for
`getBoard`: a transient miss over
an already-cached board keeps the last value and re-checks after a short
delay, surfacing an empty
result only if the board is still gone then (a genuine deletion / access
loss). First-ever loads
and caches that did not opt in are unchanged. Core decision extracted to
the pure
  `shouldDeferCacheMiss` helper with unit tests.

Thanks to above GitHub users for their contributions and translators for
their translations.

###
[`v9.75`](https://redirect.github.com/wekan/wekan/blob/HEAD/CHANGELOG.md#v975-2026-07-05-WeKan--release)

[Compare
Source](https://redirect.github.com/wekan/wekan/compare/v9.74...v9.75)

This release fixes the following CRITICAL SECURITY ISSUE of
[ScannerBleed](https://wekan.fi/hall-of-fame/scannerbleed/):

-
**[ScannerBleed](https://redirect.github.com/wekan/wekan/commit/0137924d7ee0b28102f671e1badf5ed21d6ab22f):
shell injection (RCE) via a malicious upload filename in the external
antivirus scanner command path**

([GHSA-x3xm-pxrv-jg7p](https://redirect.github.com/wekan/wekan/security/advisories/GHSA-x3xm-pxrv-jg7p),
  CWE-78 OS Command Injection). Same RCE class as
[AvatarBleed](https://wekan.fi/hall-of-fame/avatarbleed/)
(CVE-2026-52891, GHSA-35j7-h385-2q9g)
and its follow-up regression (CVE-2026-53447 / GHSA-qfqv-42qw-vvwh
area), but in a code path that
  was **never** covered by those fixes.
In `models/fileValidation.js`, when an admin has configured an external
scanner (antivirus)
command line with a `{file}` placeholder, the uploaded file path was
interpolated into the command
and run through `asyncExec` (`promisify(exec)`), which spawns `/bin/sh
-c` and interprets **all**
  shell metacharacters:
  ```js
await asyncExec(externalCommandLine.replace("{file}", '"' + fileObj.path
+ '"'));
  ```
Wrapping the path in double quotes is not a shell boundary — inside
double quotes the shell still
expands `$(...)`, backticks and `\`, so a filename such as ``a`id`.png``
or `$(touch /tmp/pwn).png`
escaped the argument and executed as the Wekan server process. Any
**authenticated** user who can
upload an attachment could trigger it, on servers that have an external
scanner configured. Unlike
the sibling MIME-detection path (`detectMimeFromFile`, which already
uses `execFile` with no shell)
and unlike the AvatarBleed fix (which strips non-alphanumeric characters
from the filename), this
  scanner path had **zero** sanitization.
- **Fixed** by POSIX single-quote-escaping the interpolated file path
via a new `shellQuote()`
helper (wrap in single quotes, escape embedded `'` as `'\''`). Inside
single quotes the shell
interprets no metacharacters, so a malicious filename can no longer
break out of the argument or
inject commands, while the admin's arbitrary command line and the exact
on-disk path are both
preserved. CVSS:3.1 9.9 Critical (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H).
- Affected Wekan v9.06 and earlier through the current release; fixed at
the upcoming WeKan release.
    Reported by **DavidCarliez**.
    Thanks to DavidCarliez and xet7!

Thanks to above GitHub users for their contributions and translators for
their translations.

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMzAuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEzMC4xIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbImFwcC93ZWthbiIsImF1dG9tZXJnZSIsInJlbm92YXRlL2NvbnRhaW5lciIsInR5cGUvbWlub3IiXX0=-->
This commit is contained in:
TrueCharts Bot
2026-07-06 01:51:52 +02:00
committed by GitHub
parent c5cd961edd
commit b39ddc543a
2 changed files with 3 additions and 3 deletions
+2 -2
View File
@@ -9,7 +9,7 @@ annotations:
trueforge.org/min_helm_version: "3.14"
trueforge.org/train: stable
apiVersion: v2
appVersion: 9.74.0
appVersion: 9.76.0
dependencies:
- name: common
version: 29.7.1
@@ -44,5 +44,5 @@ sources:
- https://hub.docker.com/r/wekanteam/wekan
- https://wekan.github.io/
type: application
version: 21.40.0
version: 21.41.0
+1 -1
View File
@@ -1,7 +1,7 @@
# yaml-language-server: $schema=./values.schema.json
image:
repository: docker.io/wekanteam/wekan
tag: v9.74@sha256:12c64299caafe60d9dfe32d1daa66729f67a0da3c3de36da65c1ba9431f8952f
tag: v9.76@sha256:6ed534c13e1dda4902a93ad86a9d5e9f870fb3e82253da8535c6a6a79b6c5d18
pullPolicy: IfNotPresent
service:
main: