Skip to content

Releases: wekan/wekan

v9.67

21 Jun 16:24

Choose a tag to compare

v9.67 2026-06-21 WeKan ® release

This release fixes the following bugs:

  • Reworked confusing and unreliable list widths,
    #6409: a list now has one width instead of the old
    "min width / max width / automatic" trio, and it reliably persists across reloads (the render now drives the
    --list-width CSS variable the styles actually use, so a width no longer reverts to auto after reload).
    A new board setting Personal list widths chooses the scope:

    • Off (default) — Shared: the width lives on the list (lists.width), is the same for everyone on the board,
      and only members with write access can change it (read-only/comment-only members no longer see the resize
      handle). Shared widths are included in board export/import (the importer previously dropped lists.width;
      it now preserves width, color and collapsed state, and the board's list-width scope).
    • On — Personal: each user keeps their own widths (profile, or localStorage when not logged in), falling back
      to the shared width then the default. The per-list popup is simplified to a single width value plus an
      Auto list width toggle (fit lists to content); the advanced per-list min/max pixel options were removed.
      Auto-width follows the same Shared/Personal scope (per-board for everyone, or per-user) and is carried through
      export/import. Documented in docs/Features/Lists/Lists.md.
  • rebuild-wekan.sh / rebuild-wekan.bat menu option 2 ("Build WeKan") now also clears the rspack dev-build caches
    (_build and node_modules/.cache) in addition to node_modules / .meteor/local / .build, so the next
    meteor run recompiles from scratch instead of occasionally serving stale modules after a git checkout/merge.

  • rebuild-wekan.sh / rebuild-wekan.bat now give the Meteor build tool and Node a larger heap by default
    (TOOL_NODE_FLAGS and NODE_OPTIONS = --max-old-space-size=8192) for every dev-run, test and build option, so
    long development sessions and test runs no longer crash with "FATAL ERROR: ... JavaScript heap out of memory".
    Both honor an existing value, so you can lower it on machines with less RAM.

  • Fixed editing the 2nd/3rd organization or team in Admin Panel › People always showing the FIRST one,
    #6411: on /people, clicking Edit on any organization or team filled
    the form with the first one's values (so you could never edit the others). The edit/settings popups are opened from
    the row with data context { org } / { team }, but their helpers read this.orgId / this.teamId (undefined
    there) and called getOrg(undefined) / getTeam(undefined), which findOne({}) resolves to the first document.
    The popup helpers, the save handlers and the delete (settings) handlers now resolve the clicked row's id from the
    { org } / { team } context. Verified against a running instance (each org/team now edits its own values).

  • Fixed boards not rendering at all (blank board view) after the mongodb/bson 7.3.0 dependency bump. bson 7.x runs
    const { startupSnapshot } = globalThis?.process?.getBuiltinModule('v8') ?? {} at module-load time; the optional
    chaining stops before the call, so in the browser — where a partial process polyfill exists but has no
    getBuiltinModule — it threw TypeError: getBuiltinModule is not a function while evaluating
    client/components/cards/attachments.js (import { ObjectId } from 'bson'). That aborted the client bundle
    bootstrap part-way through client/imports.js, so every feature imported after it (notifications, swimlanes,
    rules, …) was never registered and the board view died with No such template: notifications. Added a tiny browser
    shim (client/lib/bsonBrowserShim.js, imported first in client/main.js) that gives the browser process a no-op
    getBuiltinModule, so bson takes its intended ?? {} fallback. New unit tests
    (client/lib/tests/bsonBrowserShim.tests.js); also hardened the #5686 Playwright spec to run against a rendering
    board. (PR #6410)

  • Fixed REST API returning HTTP 500 with a stack trace for an invalid request,
    #5804: posting a comment without the required comment parameter (or
    to a board that does not exist) returned an HTTP 500 error page. The schema-validation error thrown on insert is a
    circular object (SimpleSchemaValidationContextSimpleSchema → …), and serializing it crashed the response
    writer (Converting circular structure to JSON). Now: the comment parameter is validated and a missing/empty one
    returns HTTP 400; an unknown board returns HTTP 404 (the board-access checks no longer dereference
    board.members of a non-existent board); the JSON response writer is crash-proof (falls back to a safe
    { "error": … } payload instead of throwing); and REST comment errors now use their real status code instead of
    200. New unit tests in server/lib/tests/apiResponseHelpers.tests.js. (PR #6406)

  • Fixed selecting text in a checklist closing the card,
    #5686: selecting the text of a checklist item and releasing the
    mouse outside the card detail pane closed the card. The checklist items template stops mousedown propagation
    (for item sorting), so the existing cardDetailsIsDragging guard never engaged and the document-level
    "click outside to close" handler closed the card. The close handler now also keeps the card open whenever a
    live text selection is anchored inside the card pane (new propagation-independent guard
    client/lib/cardCloseGuard.js), so a deliberate click on empty board space still closes the card. New unit
    tests in client/lib/tests/cardCloseGuard.tests.js and a Playwright regression test in
    tests/playwright/specs/34-checklist-text-selection.e2e.js. (PR #6407)

  • Fixed list reordering throwing 403 Access denied for read-only members,
    #5462: read-only / comment-only board members could still drag-reorder
    lists, which fired a server write that allow/deny rejected with 403 Access denied (the list then snapped back). Of
    the three list jQuery-UI sortables in client/components/swimlanes/swimlanes.js, one was not gated on
    Utils.canModifyBoard(); it now is, consistent with the other two, plus a defense-in-depth guard so a logged-in
    user without write access can never persist a reorder (anonymous public-board reordering via localStorage is
    unaffected). The server already enforced this; the fix stops the unauthorized drag and the console error. New
    Playwright regression test in tests/playwright/specs/35-list-sort-permissions.e2e.js. (PR #6408)

Thanks to GitHub users Atry, mueller-ma and liferadioat for reporting.

v9.65

20 Jun 18:35

Choose a tag to compare

v9.65 2026-06-20 WeKan ® release

This release adds the following updates:

  • Issue triage: closed 13 already-fixed Bug issues (with evidence), relabeled ~25 mislabeled feature requests to Feature with a "Feature Request:" title prefix, and prefixed ~35 environment-specific reports "Environment specific:" and gave them the Bug:Environment-specific label.
  • Audited labels on all 533 open issues for correctness (type, Feature:Area, Targets:, Severity:, etc.).
  • Added 23 missing GitHub labels found by auditing docs/Login and docs/Features against the issue labels, matching the existing label style and colours (Feature:* = #0052cc, Targets:* = #fbca04), and applied them across open and closed issues:
    • Login methods (Feature:User-accounts:*): ADFS, Azure, B2C, Google, Header-Login, Nextcloud, Oracle, Zitadel, Autologin, Accounts-Lockout, Forgot-Password.
    • Features: Feature:LaTeX, Feature:Mermaid-Diagram, Feature:Emoji, Feature:Python, Feature:Cards:Cover, Feature:Cards:Location, Feature:Custom-Logo, Feature:RTL, Feature:Members, Feature:Multitenancy, Feature:Allow-private-boards-only.
    • Platform: Targets:Apache.

and adds the following new features:

  • Threaded comment replies: card comments gain an optional
    parentId; a "Reply" link links a new comment to its parent, rendered with an "in reply to" quote. Initial MVP
    (single-level visual threading).
  • Restrict board admins from editing/deleting other users' comments:
    new board setting restrictCommentEditing (default off). When on, only a comment's author may edit/delete it;
    enforced server-side via collection hooks.
  • Visible status of sub-tasks: each subtask now shows its current
    list (prefixed with the board title when on a different board) read-only next to its title.
  • Drag-and-drop search results into board columns: cards in the
    search-results list can be dragged onto board lists, reusing the existing card.move(). MVP: drops append to
    the end of the target list (no pixel-precise insertion index yet).
  • Per-user permanent dismissal of the Announcement banner: a user
    can permanently close the current announcement so it does not reappear on reload/board-switch, until the admin
    edits the announcement text (which makes it reappear for everyone).
  • Show how many times a card's due date was changed: the card detail
    now displays a "due date changed N times" count (derived from existing a-dueAt activities) for deadline
    accountability.
  • Restrict adding board members to the same Organization or Team:
    new global admin setting boardMembersFromSameOrgOrTeamOnly (default off). When on, a user can only be added to
    a board if they share an Organization or Team with the inviter or an active board member; enforced server-side in
    the invite/search paths. Site admins bypass.
  • Import Google Calendar .ics files into board cards: MVP,
    import-only. New dependency-free iCalendar parser (server/lib/icsImport.js) maps each VEVENT to a card with
    startAt/dueAt so events appear on Calendar/Gantt views, plus an importIcsToBoard Meteor method and a REST
    endpoint POST /api/boards/:boardId/swimlanes/:swimlaneId/lists/:listId/ics (documented in the OpenAPI spec, with
    an importics example in api.py). Two-way Google Calendar sync is not included (see
    wekan-ical-server for read-only WeKan→calendar export).

and fixes the following bugs:

Read more

v9.64

20 Jun 01:25

Choose a tag to compare

v9.64 2026-06-20 WeKan ® release

This release fixes the following CRITICAL SECURITY ISSUE of ChecklistBleed:

  • Fixed ChecklistBleed: any authenticated user can write checklist data into a private board they are not a member of (cross-board write via collection allow rule)
    (GHSA-gv8h-5p3p-6hx7,
    CWE-863 Incorrect Authorization). This is the same class as BoardBleed
    (GHSA-gm7v-pc38-53jr), but for the card-attached Checklist and ChecklistItem documents that the
    boardId-only denyCrossBoardMove fix did not cover. Checklists and checklist items are attached
    to a card and carry a denormalized boardId; they are MOVED between cards by $set-ting a new
    cardId (and, for items, a new checklistId) in a direct DDP collection update, after which the
    Checklists.before.update hook re-derives boardId from the destination card. The collection
    allow rules (server/permissions/checklists.js, server/permissions/checklistItems.js)
    authorized an update by checking only the document's CURRENT (source) cardId — i.e. the
    attacker's own board — and never inspected the new destination cardId/checklistId/boardId.
    Because every logged-in user can create a board where they are a write-capable member, a
    low-privileged user with write access to one board could create a checklist/item on their own
    card and then, in a single /checklists/update or /checklistItems/update DDP call, set its
    cardId to a card in a private board where they are not a member (if they know the target card
    id): the allow rule saw the attacker's source card, approved the write, and the before-update hook
    attached the attacker-controlled document to the victim's private board. The protected
    moveChecklist Meteor method correctly checks both source and destination board membership, but a
    DDP client can bypass that method and update the collections directly. CVSS:3.1 Moderate
    (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N). Fixed by adding denyCrossBoardMoveByCard and
    denyCrossBoardMoveByChecklistItem helpers in server/lib/utils.js and a Checklists.deny/
    ChecklistItems.deny update rule on each collection that rejects any update whose destination
    board — resolved from a new boardId, cardId, or checklistId in the modifier — the caller has
    no write access to. Legitimate moves into boards the user belongs to and same-card edits keep
    working, and the server-side moveChecklist method (which bypasses allow/deny) is unchanged.
    A regression test (server/lib/tests/checklistbleed.security.tests.js) was added.
    Affected Wekan v9.62 and earlier.
    Thanks to DavidCarliez, xet7 and Claude.

and adds the following updates:

  • Fix the Docker pre-build version guard false-failing the release.
    The bundle-version guard added for the Admin-Panel-version fix assumed the WeKan app
    package.json ships as a standalone file with a v-prefixed version, and made "not found"
    fatal. Meteor does not ship it that way — it inlines the app package.json into the compiled
    bundle/programs/server/app/app.js as a JSON module ({"name":"wekan","version":"v9.63.0",...}),
    so the guard found no v-prefixed package.json and aborted the v9.63 Docker build. The guard now
    reads the version from that inlined module (anchored on "name":"wekan", exactly what
    require('/package.json') resolves to), and a detection miss is now a warning that continues
    rather than a hard failure — only a confirmed version MISMATCH blocks the release, since
    --build-arg VERSION is the actual guarantee.
    Thanks to xet7 and Claude.

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

v9.63

19 Jun 19:24

Choose a tag to compare

v9.63 2026-06-19 WeKan ® release

This release adds the following features:

  • Fix the wekan.fi install page version never updating from a stale value.
    The release-all.yml website job ran every release but the install page's
    version stayed frozen at v9.57: releases/release-website.sh updated it with a
    sed anchored on >v$OLD</span>, which silently no-op'd once the published
    page's value no longer matched the old_version passed for a release. Anchor
    on the stable <span class="version-number"> instead and re-normalize whatever
    version is there to the new one, with an assert so a miss fails loudly. Same
    self-healing fix applied to the local-flow copy in releases/version.sh. The
    live wekan.fi install page was also corrected to the current version.
    Thanks to xet7 and Claude.

  • Make the remaining release version substitutions self-healing.
    Hardened the last $OLD_VERSION-anchored seds in releases/version.sh — the
    same fragile pattern that froze the Docker ARG VERSION and the install page.
    The snapcraft.yaml bundle download was release-critical (same class as the
    Docker bug: the snap downloads wekan-<v>-<arch>.zip, so a stale value ships
    the wrong bundle under the right name) and was stuck at v9.57; it now anchors
    on the wekan-<v>- / releases/download/v<v>/ shapes and asserts. The
    sandstorm appVersion rewrite is now global and self-healing (the redundant
    $OLD_NO_DOTS-anchored fixup is dropped), and the Windows Offline.md doc links
    self-heal with a soft warning (cosmetic, so they must not fail the release).
    snapcraft.yaml and Offline.md were also corrected from their stale v9.57.
    Thanks to xet7 and Claude.

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

v9.62

19 Jun 16:52

Choose a tag to compare

v9.62 2026-06-19 WeKan ® release

This release adds the following features:

  • Release All Platforms: Fix Docker image showing a stale Admin Panel version (image tagged vX reported v9.57).
    The Admin Panel reads the WeKan version from the bundled package.json, which
    comes verbatim from the wekan-<version>-<arch>.zip the Dockerfile downloads
    and unzips into /build. The docker job never passed --build-arg VERSION,
    so every image was built against the Dockerfile's hardcoded ARG VERSION
    default — and that default was stuck at 9.57 because releases/version.sh
    rewrote it with a sed anchored on the old version number, which silently
    no-op'd whenever old_version did not match (e.g. the skipped 9.58 numbering).
    The result: images tagged v9.59/v9.60/v9.61 shipped the v9.57 bundle and
    reported 9.57 in the Admin Panel. Fixed three ways: the docker job now passes
    --build-arg VERSION=${VERSION} (the release version is authoritative); the
    version.sh Dockerfile rewrite now anchors on the ^ARG VERSION= prefix and
    asserts the result, so the default can never go stale again; and a new
    pre-build guard downloads the release bundle and fails fast if its app
    package.json version does not match the release tag, before pushing a
    mislabeled image to the registries. Already-pushed v9.58–v9.61 images need a
    rebuild to carry their correct contents.
    Thanks to xet7 and Claude.

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

v9.61

19 Jun 14:32

Choose a tag to compare

v9.61 2026-06-19 WeKan ® release

This release adds the following features:

  • Release All Platforms: Set GH_REPO on the bundle-attach steps so gh finds the repository.
    The win64 / mac-arm64 / s390x / ppc64le bundles each finished building but
    then failed on gh release upload with failed to run git: fatal: not a git repository. gh tries to detect the target repo from a git remote, but
    build-win64 checks the repo out into src/ (so the workspace root is not a
    git repository) and build-mac-arm64 / build-extra-arches do not check it
    out at all. Set GH_REPO=${{ github.repository }} on all three attach steps
    so gh targets wekan/wekan directly without git remote detection. The snap
    job is unaffected (it does a full checkout into the workspace root).
    Thanks to xet7 and Claude.

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

v9.60

19 Jun 13:56

Choose a tag to compare

v9.60 2026-06-19 WeKan ® release

This release adds the following features:

  • Release All Platforms: Drop armv7l from extra-arch bundles, because Node.js 24 ships no armv7l binaries.
    The build-extra-arches armv7l matrix entry failed with no matching manifest for linux/arm/v7 when pulling node:24-slim. Root cause: Node.js
    24 publishes no armv7l (32-bit ARM) binaries at all — neither the official
    dist nor unofficial builds — so there is no node:24 arm/v7 image to rebuild
    native modules against, and no Node 24 runtime to run such a bundle on an
    armv7 device. The armv7l matrix entry is removed; extra-arch bundles are now
    s390x + ppc64le. armv7 was already excluded from the Docker image and snap,
    so those are unaffected.
    Thanks to xet7 and Claude.

  • Release All Platforms: Move win64 and mac-arm64 into the post-release extra-platform phase.
    build-win64 and build-mac-arm64 were prerequisites of the release job,
    so a slow or flaky Windows/macOS runner blocked creation of the GitHub
    Release (and thus the Docker and snap jobs, which depend on it). They now
    depend on release instead — alongside build-extra-arches — and each
    attaches its own wekan-<version>-<platform>.zip to the already-created
    Release via gh release upload --clobber. The core release now waits only on
    the amd64 + arm64 bundles. No build steps changed; only the dependency
    wiring, upload mechanism, and section grouping.
    Thanks to xet7 and Claude.

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

v9.59

19 Jun 13:30

Choose a tag to compare

v9.59 2026-06-19 WeKan ® release

This release adds the following features:

  • Release All Platforms: Fix duplicate mapping keys in generated OpenAPI spec that broke API docs rendering.
    The Release All Platforms bump job regenerates public/api/wekan.yml
    via openapi/generate_openapi.py and then renders it with @redocly/cli,
    whose strict YAML parser rejects duplicate mapping keys. The 3-level nested
    SimpleSchema in models/attachmentStorageSettings.js
    (storageConfig.filesystem.enabled, storageConfig.gridfs.enabled, …)
    exposed two generator bugs: the sub-schema name was derived from only the
    first dotted path segment, collapsing filesystem.* and gridfs.* leaf
    keys (enabled/read/write) into one mapping; and the linear emitter
    reopened the parent schema header for each interleaved nested object. The
    generator now builds sub-schema names from all leading path segments and
    groups each sub-schema's fields contiguously, so deeply nested objects emit
    distinct, valid sub-schemas. Output is unchanged for existing 1- and
    2-level schemas.
    Thanks to xet7 and Claude.

Thanks to GitHub users for their contributions.

v9.57

18 Jun 23:23

Choose a tag to compare

v9.57 2026-06-19 WeKan ® release

This release fixes the following bugs:

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

v9.56

18 Jun 16:58

Choose a tag to compare

v9.56 2026-06-18 WeKan ® release

This release adds the following updates:

  • Updated dependencies.
    Merged Dependabot update: dompurify 3.4.9 → 3.4.11
    (#6395), a patch update of the
    HTML sanitizer used for XSS protection.
    Thanks to xet7.

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