Try our Chrome extension

Chrome store icon Chrome Webstore

Easily add the current web-page from your browser directly into your changedetection.io tool, more great features coming soon!

Changedetection.io needs your support!

You can help us by supporting changedetection.io on these platforms;

The more popular changedetection.io is, the more time we can dedicate to adding amazing features!

Many thanks :)

changedetection.io team

Not yet seconds ago.
            False
        
Not yet seconds ago
Current error-ing screenshot from most recent request
✨ AI Change Summary

Generating change summary…

You are a concise web change detector. Summarize ONLY what actually changed on the page in clear, plain English. Structure your reply using this exact format (omit sections with nothing to report): Added: - ... Changed: - ... Removed: - ... Focus only on meaningful changes. Ignore layout shifts, whitespace, timestamps, ads, cookies, or minor styling. Be direct and brief. Use bullet points.

tag:github.com,2008:https://github.com/go-vikunja/vikunja/releases

Release notes from vikunja

2026-10-02T17:10:44Z tag:github.com,2008:Repository/159556794/v2.7.0 2026-10-02T17:10:44Z

v2.7.0: [2.7.0] - 2026-10-02

<p>Bug Fixes</p> <ul> <li><em>(a11y)</em> Open task datepickers when activating date fields</li> <li><em>(a11y)</em> Focus the first date shortcut with a visible ring</li> <li><em>(a11y)</em> Support keyboard navigation and confirmation in date shortcuts</li> <li><em>(a11y)</em> Keep loading buttons focusable instead of natively disabling them</li> <li><em>(account)</em> Preserve public mutation option types</li> <li><em>(admin)</em> Show project owner with user component</li> <li><em>(admin)</em> Rank exact and prefix user matches before the page cap</li> <li><em>(admin)</em> Rank exact and prefix team matches before the page cap</li> <li><em>(admin)</em> Match admin user search case-insensitively</li> <li><em>(api)</em> Do not transform an already serialized payload on a retried request</li> <li><em>(api)</em> Respect service.maxitemsperpage in v2 list endpoints</li> <li><em>(api)</em> Describe public feature names as strings</li> <li><em>(api-tokens)</em> Order token list by id before paging</li> <li><em>(api/v2)</em> Bound the body read on upload routes instead of huma's 5s default</li> <li><em>(assignees)</em> Include public team members in project user search</li> <li><em>(auth)</em> Keep the request error as cause when refreshing user info fails</li> <li><em>(auth)</em> Show request password reset error when the request has no response</li> <li><em>(auth)</em> Show password reset error when the request has no response</li> <li><em>(auth)</em> Link OIDC users by email when username fallback misses (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5558770114" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/4012" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/4012/hovercard" href="https://github.com/go-vikunja/vikunja/pull/4012">#4012</a>)</li> <li><em>(auth)</em> Add an iat claim to issued JWTs</li> <li><em>(auth)</em> Compute token expiry against server time</li> <li><em>(auth)</em> Drop the v1 refresh fallback</li> <li><em>(auth)</em> Drop the stale token once its refresh is rejected</li> <li><em>(auth)</em> Skip the refresh retry when no refresh cookie was sent</li> <li><em>(auth)</em> Type login registration and link share credentials</li> <li><em>(auth)</em> Narrow refresh error causes before reading status</li> <li><em>(auth)</em> Reject missing OpenID providers before callback</li> <li><em>(auth)</em> Keep recoverable sessions after a failed refresh</li> <li><em>(auth)</em> Send the refresh cookie with SameSite=Lax</li> <li><em>(avatar)</em> Read FileReader result directly</li> <li><em>(bots)</em> Allow owners to manage disabled bots</li> <li><em>(bots)</em> 404 unowned bots, require status on PUT, audit owner status changes</li> <li><em>(bots)</em> Order the bot list by id so pages are stable</li> <li><em>(bots)</em> Lock the bot list while the previous page is shown</li> <li><em>(bots)</em> Show a newly created bot on the page it lands on</li> <li><em>(caldav)</em> Stop reporting home sets as calendars</li> <li><em>(caldav)</em> Report home sets as non-calendars through caldav-go</li> <li><em>(caldav)</em> Parse Z-suffixed timestamps as UTC (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5448385723" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3883" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3883/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3883">#3883</a>)</li> <li><em>(caldav-tokens)</em> Honour page in the v2 token list</li> <li><em>(ci)</em> Use upstream LLM action</li> <li><em>(cli)</em> Audit user change-status</li> <li><em>(client)</em> Stamp the response status onto Echo-level error bodies</li> <li><em>(client)</em> Keep a newer pending secret mutation when an older call settles</li> <li><em>(client)</em> Hand mutations their request context and never toast its aborts</li> <li><em>(comments)</em> Stop returning the author's email when reading a single comment</li> <li><em>(config)</em> Migrate deprecated webhooks.* keys after loading the config</li> <li><em>(datepicker)</em> Defer quick-select focus after pointer clicks</li> <li><em>(datepicker)</em> Wait for Tab before focusing quick select</li> <li><em>(datepicker)</em> Remove popup timing workarounds</li> <li><em>(datepicker)</em> Confirm typed times with Enter</li> <li><em>(dates)</em> Restore the DateKebab type</li> <li><em>(dates)</em> Preserve text when no date expression matches</li> <li><em>(dates)</em> Respect time format in date tooltips</li> <li><em>(db)</em> Redact PostgreSQL credentials from connection errors (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5319023910" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3707" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3707/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3707">#3707</a>)</li> <li><em>(db)</em> Disable prepared statements when ParadeDB is installed</li> <li><em>(desktop)</em> Re-add ad-hoc signing in macos builds</li> <li><em>(doctor)</em> Qualify PostgreSQL system catalog queries</li> <li><em>(doctor)</em> Check OIDC discovery through the outgoing proxy</li> <li><em>(dragging)</em> Declare typed list items and draggable slots</li> <li><em>(dump)</em> Rebuild project_ancestors after restoring a dump</li> <li><em>(editor)</em> Don't strike through nested checklist items of a checked parent (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5325271246" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3715" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3715/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3715">#3715</a>)</li> <li><em>(editor)</em> Do not crash on enter with a selection starting at a block boundary</li> <li><em>(editor)</em> Stop positioning suggestion popups after teardown</li> <li><em>(editor)</em> Keep suggestion popups anchored to the caret while scrolling</li> <li><em>(editor)</em> Do not crash when pasting markdown with an empty list item</li> <li><em>(editor)</em> Repair pasted content the schema cannot hold</li> <li><em>(editor)</em> Keep formatting when pasting rich text</li> <li><em>(editor)</em> Test rendered filter decorations</li> <li><em>(editor)</em> Remove ignored StarterKit history option</li> <li><em>(editor)</em> Type slash command suggestion options</li> <li><em>(editor)</em> Export the emoji suggestion prop type</li> <li><em>(editor)</em> Narrow DOM targets and checkbox click events</li> <li><em>(editor)</em> Keep double-clicked text in place and put the cursor there</li> <li><em>(errors)</em> Update the attachment size webtest and yaegi symbols for the moved codes</li> <li><em>(feeds)</em> Set target on task assigned notifications in atom feed</li> <li><em>(files)</em> Map ErrFileDoesNotExist to a 404 http error</li> <li><em>(files)</em> Move ErrCodeFileIsTooLarge off the task sort param code</li> </ul> <ul> <li><strong>BREAKING</strong>: uploading a file larger than the configured limit now returns 4035 instead of 4013.</li> </ul> <ul> <li><em>(filters)</em> Keep date filter boundaries inside the driver's year range</li> <li><em>(filters)</em> Highlight unquoted date, label and project values</li> <li><em>(filters)</em> Respect filter_include_nulls on saved filter views</li> <li><em>(filters)</em> Return a boolean from query detection</li> <li><em>(filters)</em> Preserve generic route filter ref types</li> <li><em>(frontend)</em> Keep avatar and name visible in a narrow multiselect (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5324849724" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3714" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3714/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3714">#3714</a>)</li> <li><em>(frontend)</em> Don't report errors wrapping axios failures to sentry</li> <li><em>(frontend)</em> Reload on stale chunk load errors instead of reporting them</li> <li><em>(frontend)</em> Don't read attachment name after delete modal closes</li> <li><em>(frontend)</em> Fall back to blob url when FileReader is unavailable</li> <li><em>(frontend)</em> Don't render empty src on avatar images</li> <li><em>(frontend)</em> Skip sentry reports for placeholder image sources</li> <li><em>(frontend)</em> Use shared blob cache for attachment previews</li> <li><em>(frontend)</em> Use shared blob cache for editor images</li> <li><em>(frontend)</em> Don't crash the project view switcher when views are missing</li> <li><em>(frontend)</em> Let the views computed keep its inferred type</li> <li><em>(frontend)</em> Take the project id for gantt from props, not the route</li> <li><em>(frontend)</em> Don't crash the archive modal when the project is gone</li> <li><em>(frontend)</em> Don't render delete confirmation without a target</li> <li><em>(frontend)</em> Don't touch the api token form after it unmounts</li> <li><em>(frontend)</em> Guard password field focus on settings pages</li> <li><em>(frontend)</em> Don't use the tiptap editor after it was destroyed</li> <li><em>(frontend)</em> Guard mention suggestion teardown against a missing renderer</li> <li><em>(frontend)</em> Reject instead of crashing when a blob request has no body</li> <li><em>(frontend)</em> Ignore drag events without a pointer position</li> <li><em>(frontend)</em> Don't render app routes in the logged out shell</li> <li><em>(frontend)</em> Guard the external user check against a null user</li> <li><em>(frontend)</em> Treat html-for-chunk mime errors as stale chunk loads</li> <li><em>(frontend)</em> Don't report browser extension and webview injection errors to sentry</li> <li><em>(frontend)</em> Drop empty sentry events</li> <li><em>(frontend)</em> Fall back to a blob url when reading an svg attachment fails</li> <li><em>(frontend)</em> Notify instead of throwing when an attachment upload fails</li> <li><em>(frontend)</em> Keep Date instances intact when camel casing objects</li> <li><em>(frontend)</em> Never serialize an invalid date</li> <li><em>(frontend)</em> Render nothing instead of throwing on invalid dates</li> <li><em>(frontend)</em> Guard the datepicker toISOString call sites</li> <li><em>(frontend)</em> Keep flatpickr's alt input out of the expiry flex row</li> <li><em>(frontend)</em> Show the server message of a request error given as cause</li> <li><em>(frontend)</em> Drop sentry events for promises rejected with an empty object</li> <li><em>(frontend)</em> Don't render the custom logo img without a custom logo</li> <li><em>(frontend)</em> Skip image errors whose src resolves to the page itself</li> <li><em>(frontend)</em> Disambiguate project and filter settings routes</li> <li><em>(frontend)</em> Close the bucket dropdown after selecting a bucket</li> <li><em>(frontend)</em> Keep the remove assignee button below popups</li> <li><em>(frontend)</em> Stop dropping DOMExceptions before they reach sentry</li> <li><em>(frontend)</em> Don't report broken images inside user content</li> <li><em>(frontend)</em> Hold sidebar project list updates until a drag ends</li> <li><em>(frontend)</em> Handle the pop sound play() rejection (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5609342636" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/4030" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/4030/hovercard" href="https://github.com/go-vikunja/vikunja/pull/4030">#4030</a>)</li> <li><em>(frontend)</em> Delay task loading spinners for fast requests</li> <li><em>(frontend)</em> Delay project, filter, sharing and time entry spinners</li> <li><em>(frontend)</em> Delay spinners inside shared input and card components</li> <li><em>(frontend)</em> Keep kanban add-task input disabled while the create is in flight</li> <li><em>(frontend)</em> Delay task detail partial and quick actions spinners</li> <li><em>(frontend)</em> Delay webhook, sharing and project background spinners</li> <li><em>(frontend)</em> Delay admin, team, label and session spinners</li> <li><em>(frontend)</em> Hide token creation on disabled bots</li> <li><em>(frontend)</em> Show a rate limit message when booting hits a 429</li> <li><em>(gantt)</em> Retain inferred route query type</li> <li><em>(histoire)</em> Correct button import casing</li> <li><em>(home)</em> Omit unset background filter styles</li> <li><em>(home)</em> Filter empty label query values</li> <li><em>(i18n)</em> Exclude bound keypaths from literal key checks</li> <li><em>(i18n)</em> Type lowercase Day.js locale keys</li> <li><em>(i18n)</em> Pass typed interpolation objects and plural counts</li> <li><em>(i18n)</em> Derive the message schema from English translations</li> <li><em>(import)</em> Create imported tasks in one batch with preserved indexes</li> <li><em>(inputs)</em> Retain numeric multiselect result indexes</li> <li><em>(inputs)</em> Type emoji picker component and element refs</li> <li><em>(kanban)</em> Do not crash when moving a task into a bucket that is not loaded</li> <li><em>(kanban)</em> Resolve the moved task by its id when dropping it</li> <li><em>(kanban)</em> Resolve the moved bucket by its id when dropping it</li> <li><em>(kanban)</em> Don't write a bucket update into a board that was replaced</li> <li><em>(kanban)</em> Keep bucket footer out of the task scroll container</li> <li><em>(kanban)</em> Keep the add task button under the bucket content (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5451730530" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3888" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3888/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3888">#3888</a>)</li> <li><em>(kanban)</em> Move tasks into saved filter done bucket when done elsewhere</li> <li><em>(kanban)</em> Type drag events timers and debug flag</li> <li><em>(labels)</em> Remove task associations when deleting a label</li> <li><em>(list)</em> Resolve the dropped task by its id when saving its position</li> <li><em>(mage)</em> Create the frontend dist placeholder for test and worktree targets</li> <li><em>(mage)</em> Run webtests in test:filter instead of silently skipping them</li> <li><em>(metrics)</em> Don't log an error for every unauthenticated request</li> <li><em>(migration)</em> Quote index identifiers so the swap works on postgres</li> <li><em>(migration)</em> Don't report upstream 4xx migration failures to sentry</li> <li><em>(migration)</em> Return 400 when an import zip has no data file</li> <li><em>(migration)</em> Use 14009 for ErrNoDataFileInZip to avoid clashing with <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5356995950" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3745" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3745/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3745">#3745</a></li> <li><em>(migration)</em> Handle a CSV without data rows</li> <li><em>(migration)</em> Return 400 for unparseable import files</li> <li><em>(migration)</em> Treat a truncated import file as a client error too</li> <li><em>(migration)</em> Use 14010 for ErrInvalidImportFile, 14008 is taken</li> <li><em>(migration)</em> Do not report 4xx domain errors to sentry</li> <li><em>(migration)</em> Move zip/empty file error codes off the api token codes</li> </ul> <ul> <li><strong>BREAKING</strong>: a failed import now returns 14011 instead of 14001 and 14012 instead of 14002.</li> </ul> <ul> <li><em>(migration)</em> Return 400 instead of 500 for broken vikunja exports</li> <li><em>(migration)</em> Preserve todoist task descriptions (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5383083897" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3819" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3819/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3819">#3819</a>)</li> <li><em>(migration)</em> Leave subscriptions unique index to its dedupe migration</li> <li><em>(migration)</em> Answer 412 instead of 500 when a migration claim collides</li> <li><em>(migration)</em> Judge an abandoned claim by a heartbeat, not by start time</li> <li><em>(migration)</em> Log migration start and completion at info level</li> <li><em>(migration)</em> Don't report a failed success mail as a failed migration</li> <li><em>(migration)</em> Run file imports in the background</li> <li><em>(migration)</em> Keep a queued import upload out of the storage quota</li> <li><em>(migration)</em> Remove the partial blob of a failed import upload write</li> <li><em>(migration)</em> Clean up label_tasks rows orphaned by deleted labels</li> <li><em>(migration)</em> Route Trello API requests through the outgoing client</li> <li><em>(multiselect)</em> Keep multiple value an array while a create is pending</li> <li><em>(notifications)</em> Narrow unknown errors without crashing</li> <li><em>(notifications)</em> Fetch the inbox only once the first socket connection settles</li> <li><em>(notifications)</em> Skip mail rendering when the mailer is disabled</li> <li><em>(popup)</em> Open the popup on browsers without the Popover API</li> <li><em>(project)</em> Don't crash the background settings when no project is loaded</li> <li><em>(project)</em> Skip background previews whose blur hash can't be decoded</li> <li><em>(projects)</em> Narrow filter routes and specify submit events</li> <li><em>(projects)</em> Normalize route ids before lookup</li> <li><em>(projects)</em> Guard absent project ids in list actions</li> <li><em>(projects)</em> Avoid refetching patched project lists</li> <li><em>(projects)</em> Count a project as default only for its owner</li> <li><em>(projects)</em> Let owners delete their own default project</li> <li><em>(projects)</em> Let a nearer grant lower an inherited permission</li> <li><em>(quick-actions)</em> Handle a null current project</li> <li><em>(quick-actions)</em> Type keyboard shortcut events</li> <li><em>(ratelimit)</em> Don't log an error for unauthenticated requests</li> <li><em>(reminders)</em> Skip inactive assignees when collecting task users</li> <li><em>(reminders)</em> Show due reminders in notifications without email</li> <li><em>(restore)</em> Restore empty json column values as NULL</li> <li><em>(restore)</em> Convert numeric bools when restoring into postgres</li> <li><em>(router)</em> Type lazy modal component loaders</li> <li><em>(router)</em> Declare the auth guard dependency contract</li> <li><em>(router)</em> Use supported scroll position properties</li> <li><em>(router)</em> Don't persist one-time tokens in last visited route</li> <li><em>(routes)</em> Send and expose Retry-After on rate-limited responses</li> <li><em>(saved-filters)</em> Delete by id instead of every loaded field</li> <li><em>(sentry)</em> Drop the router and async component errors a stale chunk causes</li> <li><em>(sentry)</em> Drop the WKWebView postMessage error host apps inject</li> <li><em>(sentry)</em> Group reported errors by the error, not the reporting frame</li> <li><em>(sentry)</em> Stop attaching component props to error events</li> <li><em>(sentry)</em> Redact one-time tokens from urls in events, spans and replays</li> <li><em>(sentry)</em> Only report resource load failures for fetched urls</li> <li><em>(sessions)</em> Clamp the page against real data, not the placeholder</li> <li><em>(sessions)</em> Break last_active ties by id so pages stay stable</li> <li><em>(settings)</em> Only save the settings that changed onto the server's current settings</li> <li><em>(sharing)</em> Require project admin to manage link shares</li> <li><em>(sharing)</em> Delete a user's webhooks when they lose project access</li> <li><em>(sharing)</em> List what is deleted when removing project access</li> <li><em>(sharing)</em> Call the shared entity a project in the remove dialog</li> <li><em>(shortcuts)</em> Narrow event targets and type test listeners</li> <li><em>(table)</em> Show priorities for completed tasks</li> <li><em>(table)</em> Preserve sort field types when filtering columns</li> <li><em>(task)</em> Tolerate partial tasks when preparing a task for the api</li> <li><em>(task)</em> Do not replace the related tasks of the task being saved</li> <li><em>(task)</em> Type the related task entries in processModel</li> <li><em>(task)</em> Remove duplicate close button in task detail modal</li> <li><em>(task)</em> Make modal close button readable on task card</li> <li><em>(task)</em> Cancel the debounced scroll-container lookup when the detail view unmounts</li> <li><em>(tasks)</em> Stop mapTasksDeep from descending into the updated task</li> <li><em>(tasks)</em> Keep cached related tasks one level deep like the API</li> <li><em>(tasks)</em> Retain inferred task draft defaults</li> <li><em>(tasks)</em> Type optional task color styles</li> <li><em>(tasks)</em> Keep id as the final sort tie-breaker</li> <li><em>(tasks)</em> Narrow caught task creation errors</li> <li><em>(tasks)</em> Handle absent bucket and deferred date values</li> <li><em>(tasks)</em> Handle absent repeat task values</li> <li><em>(tasks)</em> Type task links and guard optional list fields</li> <li><em>(tasks)</em> Align overview date and event types</li> <li><em>(tasks)</em> Preserve detail draft types and narrow history state</li> <li><em>(tasks)</em> Return no tasks when a search has no project scope</li> <li><em>(tasks)</em> Skip position recalculation for views without projects</li> <li><em>(teams)</em> Order team list by relevance and id before paginating</li> <li><em>(teams)</em> Clamp an out-of-range team list page</li> <li><em>(test)</em> Rebuild project_ancestors when the testing API resets projects</li> <li><em>(tests)</em> Type fixture values for pgx parameter binding</li> <li><em>(tests)</em> Narrow parsed dates before assertions</li> <li><em>(tests)</em> Use the auth type value union</li> <li><em>(typecheck)</em> Inherit app libraries in Vitest</li> <li><em>(typecheck)</em> Declare Workbox service worker globals</li> <li><em>(types)</em> Import reactive value types from Vue</li> <li><em>(ui)</em> Avoid expanding icon unions in prop defaults</li> <li><em>(ui)</em> Register buttons without expanding component unions</li> <li><em>(upcoming)</em> Reload tasks when date filter toggles change</li> <li><em>(user)</em> Move ErrCodeOpenIDCustomScopeMalformed off the username code</li> </ul> <ul> <li><strong>BREAKING</strong>: a malformed OIDC custom scope now returns 1038 instead of 1022.</li> </ul> <ul> <li><em>(user)</em> Give ErrCodeTOTPPasscodeUsed a unique error code</li> </ul> <ul> <li><strong>BREAKING</strong>: a reused TOTP passcode now returns 1039 instead of 1025.</li> </ul> <ul> <li><em>(user)</em> Give ErrCodeAccountLocked a unique error code</li> </ul> <ul> <li><strong>BREAKING</strong>: a locked account now returns 1040 instead of 1026.</li> </ul> <ul> <li><em>(user)</em> Fallback empty user timezone to valid UTC location (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5520516422" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3965" data-hovercard-type="issue" data-hovercard-url="/go-vikunja/vikunja/issues/3965/hovercard" href="https://github.com/go-vikunja/vikunja/issues/3965">#3965</a>) (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5530319563" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3991" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3991/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3991">#3991</a>)</li> <li><em>(user)</em> Only allow writable projects as the default project</li> <li><em>(user)</em> Revoke sessions when too many TOTP attempts lock the account</li> <li><em>(utils)</em> Honor proxy env vars for outgoing requests</li> <li><em>(utils)</em> Exempt the proxy dial from the SSRF guard</li> <li><em>(utils)</em> Use the configured proxy without a password</li> <li><em>(utils)</em> Stop exempting direct requests to the proxy address from the SSRF guard</li> <li><em>(validation)</em> Parse v2 request body errors</li> <li><em>(views)</em> Preserve saved sort restoration during navigation</li> <li><em>(views)</em> Load tasks after restoring the saved query</li> <li><em>(webhooks)</em> Add stable id ordering to Webhook.ReadAll</li> <li><em>(websocket)</em> Type the first-connection timer so clearTimeout accepts it</li> <li><em>(websocket)</em> Check the session and close sockets on revocation</li> <li><em>(websocket)</em> Refresh an expired token before reconnecting</li> <li>Don't report failed webhook deliveries to sentry (<a href="/go-vikunja/vikunja/blob/v2.7.0/8dcd71db73ebc7466b0a00fb49b0742ed9910a9a">8dcd71d</a>)</li> <li>Return 404 instead of 500 when a stored file is missing from disk (<a href="/go-vikunja/vikunja/blob/v2.7.0/fe52d4e23ee41975a8caea33c6ebedb2e2a8eb89">fe52d4e</a>)</li> <li>Fall back to full recalculation when updating a task position (<a href="/go-vikunja/vikunja/blob/v2.7.0/206975997f2301fd1ae183ac9cbdf63e26901ac5">2069759</a>)</li> <li>Unwrap wrapped domain errors in the http error handler (<a href="/go-vikunja/vikunja/blob/v2.7.0/c7bd8ba20912af3f083cd2d4be031a3690bf095c">c7bd8ba</a>)</li> <li>Unwrap wrapped domain errors in attachment upload results (<a href="/go-vikunja/vikunja/blob/v2.7.0/79083df2ea9dd21559184ff614d8a1771d206eac">79083df</a>)</li> <li>Lock project views before writing task positions on create (<a href="/go-vikunja/vikunja/blob/v2.7.0/d20d4da86797f10bf36ef49b9f37d21dd6dd4546">d20d4da</a>)</li> <li>Lock project views before writing task positions on update and delete (<a href="/go-vikunja/vikunja/blob/v2.7.0/2a0f16a96770c08283cc1f5aa6c1934b6fd12494">2a0f16a</a>)</li> <li>Lock project views before writing task positions in saved filter sync (<a href="/go-vikunja/vikunja/blob/v2.7.0/33e82a956d49c1e0e69c78c32abf8b3b37128fea">33e82a9</a>)</li> <li>Lock project views before deleting a project's task positions (<a href="/go-vikunja/vikunja/blob/v2.7.0/a9a9945bc88a18c7818c521c8ded47424bd7f8bc">a9a9945</a>)</li> <li>Lock views before repairing task positions (<a href="/go-vikunja/vikunja/blob/v2.7.0/72844bf71587d75aa72e492c3d9c3c09d03d6b91">72844bf</a>)</li> </ul> <p>Dependencies</p> <ul> <li><em>(deps)</em> Update crowdin/github-action action to v3.0.1</li> <li><em>(deps)</em> Update dependency @sentry/vue to v10.72.0</li> <li><em>(deps)</em> Update aws-sdk-go-v2 monorepo</li> <li><em>(deps)</em> Update dependency happy-dom to v20.11.15</li> <li><em>(deps)</em> Update module github.com/aws/aws-sdk-go-v2/config to v1.33.2</li> <li><em>(deps)</em> Update dependency ip-address to v10.7.0</li> <li><em>(deps)</em> Update pnpm to v11.25.0</li> <li><em>(deps)</em> Update dependency serialize-javascript to v7.1.1</li> <li><em>(deps)</em> Update module github.com/coreos/go-oidc/v3 to v3.21.0</li> <li><em>(deps)</em> Update dependency go to v1.27.1</li> <li><em>(deps)</em> Update dependency happy-dom to v20.12.0</li> <li><em>(deps)</em> Update module github.com/go-sql-driver/mysql to v1.10.1</li> <li><em>(deps)</em> Update ghcr.io/techknowlogick/xgo:go-1.27.x docker digest to 8cc742b</li> <li><em>(deps)</em> Update module golang.org/x/crypto to v0.56.0</li> <li><em>(deps)</em> Update dev-dependencies</li> <li><em>(deps)</em> Update dependency @sentry/vue to v10.73.0</li> <li><em>(deps)</em> Update tiptap to v3.30.6</li> <li><em>(deps)</em> Update dependency undici@7 to v8.10.1</li> <li><em>(deps)</em> Update module github.com/yuin/goldmark/v2 to v2.0.1</li> <li><em>(deps)</em> Update dependency undici@6 to v8.10.1</li> <li><em>(deps)</em> Update tiptap to v3.31.0</li> <li><em>(deps)</em> Update crowdin/github-action action to v3.0.2</li> <li><em>(deps)</em> Update module github.com/mattn/go-sqlite3 to v1.14.52</li> <li><em>(deps)</em> Update dependency @tiptap/vue-3 to v3.31.0</li> <li><em>(deps)</em> Update pnpm/action-setup action to v6.1.0</li> <li><em>(deps)</em> Update dependency fast-uri@3 to v4.1.4</li> <li><em>(deps)</em> Update dependency vue-router to v5.3.1</li> <li><em>(deps)</em> Update dependency happy-dom to v20.13.2</li> <li><em>(deps)</em> Update dependency postcss to v8.5.27</li> <li><em>(deps)</em> Update tiptap to v3.31.1</li> <li><em>(deps)</em> Update tiptap to v3.31.2</li> <li><em>(deps)</em> Update mcr.microsoft.com/playwright docker tag to v1.63.0 (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5369424778" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3806" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3806/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3806">#3806</a>)</li> <li><em>(deps)</em> Update tiptap to v3.31.3</li> <li><em>(deps)</em> Update danielroe/provenance-action digest to ba56f4e</li> <li><em>(deps)</em> Update dependency postcss to v8.5.28</li> <li><em>(deps)</em> Update module github.com/jackc/pgx/v5 to v5.11.0</li> <li><em>(deps)</em> Update dependency undici@7 to v8.10.2</li> <li><em>(deps)</em> Group all undici variants in Renovate</li> <li><em>(deps)</em> Update dependency undici@6 to v8.10.2</li> <li><em>(deps)</em> Update danielroe/provenance-action digest to 345413a</li> <li><em>(deps)</em> Update module golang.org/x/oauth2 to v0.37.0</li> <li><em>(deps)</em> Update module golang.org/x/sync to v0.23.0</li> <li><em>(deps)</em> Update module golang.org/x/net to v0.59.0</li> <li><em>(deps)</em> Update node.js to v24.21.0</li> <li><em>(deps)</em> Update module github.com/aws/aws-sdk-go-v2/service/s3 to v1.112.0</li> <li><em>(deps)</em> Update dependency dompurify to v3.4.15</li> <li><em>(deps)</em> Update module golang.org/x/term to v0.46.0</li> <li><em>(deps)</em> Update module golang.org/x/image to v0.46.0</li> <li><em>(deps)</em> Update module github.com/yuin/goldmark/v2 to v2.0.2</li> <li><em>(deps)</em> Update pnpm to v11.26.0</li> <li><em>(deps)</em> Update dependency marked to v18.0.12</li> <li><em>(deps)</em> Pin caldav-go to the merged fork commit</li> <li><em>(deps)</em> Add the MCP go-sdk and jsonschema-go</li> <li><em>(deps)</em> Update appleboy/llm-action digest to 7752011</li> <li><em>(deps)</em> Update module github.com/yuin/goldmark/v2 to v2.1.1</li> <li><em>(deps)</em> Update dependency @sentry/vue to v10.74.0</li> <li><em>(deps)</em> Update dependency @babel/core to v8.0.5</li> <li><em>(deps)</em> Update dependency floating-vue to v5.4.0</li> <li><em>(deps)</em> Update danielroe/provenance-action digest to c40e78d</li> <li><em>(deps)</em> Update dependency markdown-it to v15.0.2</li> <li><em>(deps)</em> Update dependency rollup to v4.63.2</li> <li><em>(deps)</em> Update dependency js-yaml to v5.4.2</li> <li><em>(deps)</em> Update dependency js-yaml@4 to v5.4.2</li> <li><em>(deps)</em> Update dependency marked to v18.0.13</li> <li><em>(deps)</em> Update module github.com/olekukonko/tablewriter to v1.1.5</li> <li><em>(deps)</em> Update docker/build-push-action action to v7.4.0</li> <li><em>(deps)</em> Update docker/setup-buildx-action action to v4.4.1</li> <li><em>(deps)</em> Update dependency rollup to v4.63.3</li> <li><em>(deps)</em> Update pnpm to v11.27.0</li> <li><em>(deps)</em> Update jlumbroso/free-disk-space action to v1.3.2</li> <li><em>(deps)</em> Update module github.com/yuin/goldmark/v2 to v2.1.3</li> <li><em>(deps)</em> Update axllent/mailpit docker tag to v1.31.2</li> <li><em>(deps)</em> Update dependency ip-address to v10.7.2</li> <li><em>(deps)</em> Update node.js to ebfe2f9</li> <li><em>(deps)</em> Update dependency brace-expansion@5 to v5.0.12</li> <li><em>(deps)</em> Update postgres:18 docker digest to 86c951e</li> <li><em>(deps)</em> Update axllent/mailpit docker tag to v1.31.3</li> <li><em>(deps)</em> Update postgres:18 docker digest to 5a5a84b</li> <li><em>(deps)</em> Update aws-sdk-go</li> <li><em>(deps)</em> Bump dompurify from 3.4.15 to 3.4.16 in /frontend</li> <li><em>(deps)</em> Update dependency serialize-javascript to v7.1.2 [security]</li> <li><em>(deps)</em> Update dependency fast-uri@3 to v4.1.5 [security]</li> <li><em>(deps)</em> Update github-actions</li> <li><em>(frontend)</em> Drop removed editor deps from extension tests</li> </ul> <p>Documentation</p> <ul> <li><em>(agents)</em> Require generated clients for new API routes</li> <li><em>(agents)</em> Document query cache conventions for frontend mutations</li> <li><em>(agents)</em> Route component mutations through use*Mutation hooks</li> <li><em>(agents)</em> Record conventions from the projects and project views migrations</li> <li><em>(agents)</em> Add query cache and mutation call rules from the v2 sharing migration</li> <li><em>(agents)</em> Add frontend UI state, v-model and focus rules</li> <li><em>(agents)</em> Require stored-state e2e checks and flag tests that cannot fail</li> <li><em>(agents)</em> Cover shared helper PRs, stack layers and i18n-safe renames</li> <li><em>(agents)</em> Apply the one-entry-per-line literal rule to frontend code</li> <li><em>(agents)</em> Record the v2 error shape, response normalization and patch-only boards</li> <li><em>(agents)</em> Add e2e cache, drag fixture and sdk mock rules from the task migration review</li> <li><em>(agents)</em> Fixup targets, cascade rebases and pre-merge squash for stacks</li> <li><em>(agents)</em> Point secret-bearing mutations at useSecretMutation</li> <li><em>(agents)</em> Describe the generated-client frontend conventions</li> <li><em>(ai)</em> Add sentry-triage skill</li> <li><em>(api)</em> Declare web.HTTPError and all refresh token 401 codes on v1 refresh</li> <li><em>(code-style)</em> Require multi-line composite literals</li> <li><em>(config)</em> Document proxy env var fallback for outgoing requests</li> <li><em>(config)</em> Document proxy credentials and OIDC coverage</li> <li><em>(e2e)</em> Add spec-writing gotchas and late full-suite failure triage</li> <li><em>(queries)</em> Correct pagination limit behavior</li> <li><em>(skills)</em> Only declare added columns in migration structs</li> <li>Add prepare-worktree and run-e2e-tests skills (<a href="/go-vikunja/vikunja/blob/v2.7.0/993d0ccf33dde190cfc79521c93e460758465062">993d0cc</a>)</li> <li>Trim derivable content from AGENTS.md (<a href="/go-vikunja/vikunja/blob/v2.7.0/e4f8187c96de7802221205156a5976fb765ec311">e4f8187</a>)</li> <li>Note sha256 convention for high-entropy tokens (<a href="/go-vikunja/vikunja/blob/v2.7.0/2699eb00bf79191e84571818443d56a0508ac4bc">2699eb0</a>)</li> <li>Prefer existing e2e coverage over component tests (<a href="/go-vikunja/vikunja/blob/v2.7.0/5424113e990ffe072361ba6d0a08ae40a1c83b81">5424113</a>)</li> <li>Add swagger annotations for the OAuth 2.0 endpoints (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5391258002" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3837" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3837/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3837">#3837</a>) (<a href="/go-vikunja/vikunja/blob/v2.7.0/a59dbc2842ca7ee014e36e894a77349540fa475d">a59dbc2</a>)</li> <li>Split AGENTS.md into progressive-disclosure docs (<a href="/go-vikunja/vikunja/blob/v2.7.0/0c2963d5a7520aa1a599ae851f5e3fdd71512827">0c2963d</a>)</li> <li>Describe MCP exposure for v2 contributors (<a href="/go-vikunja/vikunja/blob/v2.7.0/f16a5d6dff168d96b631a5fe5c6725df4fcf739f">f16a5d6</a>)</li> </ul> <p>Features</p> <ul> <li><em>(account)</em> Save settings as a merge patch of the changed fields</li> <li><em>(admin)</em> Filter and sort the admin project list</li> <li><em>(admin)</em> Show the capped-results hint in the admin pickers</li> <li><em>(admin)</em> Show the capped-results hint in the admin project owner filter</li> <li><em>(api)</em> Generate canonical v2 frontend client</li> <li><em>(api)</em> Redirect historical task indexes on v2</li> <li><em>(api)</em> Read the current user's general settings on v2</li> <li><em>(api-tokens)</em> Verify tokens by indexed sha256 instead of pbkdf2</li> <li><em>(api-tokens)</em> Add the mcp:access scope and permission helpers</li> <li><em>(api-v2)</em> Export the rich-text format header</li> <li><em>(auth)</em> Return error code 16005 when the refresh cookie is missing</li> <li><em>(auth)</em> Route OIDC requests through the outgoing proxy</li> <li><em>(client)</em> Toast failed query reads globally</li> <li><em>(config)</em> Default per-category log levels to log.level</li> <li><em>(datepicker)</em> Add vue-native calendar, shortcut and time components</li> <li><em>(datepicker)</em> Rebuild the date picker without flatpickr</li> <li><em>(frontend)</em> Configure v2 client runtime</li> <li><em>(frontend)</em> Add shared attachment blob cache</li> <li><em>(frontend)</em> Add shared UserAvatar component</li> <li><em>(frontend)</em> Show pro license status in about dialog</li> <li><em>(frontend)</em> Filter and sort the admin project list</li> <li><em>(frontend)</em> Add useDelayedLoading composable</li> <li><em>(gantt)</em> Show tooltip with full title on bars too narrow for their label</li> <li><em>(i18n)</em> Add section headings for the overdue tasks mail</li> <li><em>(invites)</em> Add admin-managed user invite links</li> <li><em>(license)</em> Add user_invites feature</li> <li><em>(link-sharing)</em> Add generated queries and share helpers</li> <li><em>(log)</em> Add log.httplevel and log requests by status</li> <li><em>(mcp)</em> Derive tool specs from the v2 OpenAPI document</li> <li><em>(mcp)</em> Dispatch tool calls through the v2 handlers</li> <li><em>(mcp)</em> Add catalog discovery and execution meta-tools</li> <li><em>(mcp)</em> Add the module and streamable-http transport</li> <li><em>(mcp)</em> Expose connection settings and token presets</li> <li><em>(metrics)</em> Optional Go profiler endpoint at /debug/pprof</li> <li><em>(migration)</em> Typed error for failed upstream requests</li> <li><em>(migration)</em> Add token_sha256 to api_tokens and make legacy hash columns nullable</li> <li><em>(migration)</em> Create and backfill project_ancestors</li> <li><em>(migration)</em> Record whether a migration succeeded</li> <li><em>(migration)</em> Show import progress and outcome in the migration views</li> <li><em>(migration)</em> Keep queued import uploads in the file storage</li> <li><em>(multiselect)</em> Hint when the results list only the first matches</li> <li><em>(popup)</em> Anchor with floating-ui and open as a bottom sheet on mobile</li> <li><em>(project-sharing)</em> Add generated membership queries and mutations</li> <li><em>(projects)</em> Maintain a project_ancestors closure table</li> <li><em>(queries)</em> Support optimistic updates in contextMutationOptions</li> <li><em>(quick-add)</em> Set first due date for repeating tasks without a date</li> <li><em>(reminders)</em> Track whether a task user is an assignee</li> <li><em>(reminders)</em> Split overdue mail into assigned and followed sections</li> <li><em>(routes)</em> Serve the MCP endpoint at /api/v2/mcp</li> <li><em>(sentry)</em> Derive a stable fingerprint from an error</li> <li><em>(settings)</em> Add MCP tokens and client connection guides</li> <li><em>(task)</em> Improve relation task search results (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5324209452" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3711" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3711/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3711">#3711</a>)</li> <li><em>(tasks)</em> Add task index counters and historical aliases</li> <li><em>(tasks)</em> Allocate task indexes from the per-project counter</li> <li><em>(teams)</em> Add generated queries and fenced membership mutations</li> <li><em>(tokens)</em> Support supplied routes and locked permissions</li> <li><em>(ui)</em> Add a bottom sheet variant to Modal</li> <li><em>(user-search)</em> Add scoped generated client queries</li> <li><em>(webhooks)</em> Paginate the webhook list</li> <li><em>(websocket)</em> Expose whether the session's first connection is still pending</li> <li><em>(websocket)</em> Re-authenticate open sockets with a renewed token</li> <li>Add /.well-known/change-password redirect (<a href="/go-vikunja/vikunja/blob/v2.7.0/5cb283802452ee1baf69e83686eaaee279740574">5cb2838</a>)</li> </ul> <p>Miscellaneous Tasks</p> <ul> <li><em>(ai)</em> Make vikunja skills generally available</li> <li><em>(client)</em> Regenerate for the user settings read and patch</li> <li><em>(client)</em> Regenerate the frontend API client</li> <li><em>(frontend)</em> Disable sentry rage click issues</li> <li><em>(frontend)</em> Regenerate v2 client for the per_page docs</li> <li><em>(frontend)</em> Regenerate API client for admin project filters</li> <li><em>(i18n)</em> Update translations via Crowdin</li> <li><em>(renovate)</em> Default to a weekly schedule</li> <li><em>(renovate)</em> Group overrides monthly and block major bumps</li> <li><em>(renovate)</em> Update github actions and digests monthly</li> <li><em>(renovate)</em> Group aws-sdk-go monthly and golang.org/x weekly</li> <li><em>(renovate)</em> Update node and pnpm monthly</li> <li><em>(renovate)</em> Group xgo image with go releases</li> <li>Remove flatpickr (<a href="/go-vikunja/vikunja/blob/v2.7.0/911842d1256b3889c3a5d1b5e8a18cc954795bfe">911842d</a>)</li> </ul> <p>Other</p> <ul> <li><em>(frontend)</em> Fail CI on typecheck errors</li> <li><em>(other)</em> Verify generated frontend client is current</li> <li><em>(other)</em> Update auth.go</li> <li><em>(other)</em> [skip ci] Updated swagger docs</li> <li><em>(other)</em> [skip ci] Updated yaegi symbols</li> <li><em>(other)</em> Keep TaskModel.created and updated as plain Dates</li> <li><em>(other)</em> Refactor comment for NewReadSession function</li> </ul> <p>Updated the comment for NewReadSession to clarify its behavior regarding transaction handling and connection pooling.</p> <ul> <li><em>(other)</em> Quote API cleanup trap for shellcheck</li> </ul> <p>Performance</p> <ul> <li><em>(auth)</em> Reuse the api token owner from the request context</li> <li><em>(db)</em> Use the pgx driver for postgres</li> <li><em>(db)</em> Default connection lifetime 30 min instead of 10 s</li> <li><em>(db)</em> Match the leading SQL keyword without regexps</li> <li><em>(db)</em> Scan WITH statements for write verbs without a regexp</li> <li><em>(db)</em> Memoize single-row task, project and user lookups per session</li> <li><em>(db)</em> Read handlers and token auth run without a transaction</li> <li><em>(log)</em> Skip formatting database log lines the level would drop</li> <li><em>(projects)</em> Store the parent of top-level projects as null</li> <li><em>(projects)</em> Partial index on parent_project_id for child projects (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5361793244" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3777" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3777/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3777">#3777</a>)</li> <li><em>(projects)</em> Resolve project access and ancestors through project_ancestors</li> <li><em>(subscriptions)</em> Bind entity and user ids as parameters instead of literals (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="5361511917" data-permission-text="Title is private" data-url="https://github.com/go-vikunja/vikunja/issues/3776" data-hovercard-type="pull_request" data-hovercard-url="/go-vikunja/vikunja/pull/3776/hovercard" href="https://github.com/go-vikunja/vikunja/pull/3776">#3776</a>)</li> <li><em>(tasks)</em> Index (project_id, done, due_date) instead of (done, due_date)</li> </ul> <p>Refactor</p> <ul> <li><em>(admin)</em> Add generated queries and scoped mutation callbacks</li> <li><em>(admin)</em> Rename wire fields (mechanical)</li> <li><em>(admin)</em> Use query subscriptions for admin pages</li> <li><em>(admin)</em> Remove legacy resource stacks</li> <li><em>(admin)</em> Fetch only the first page of user picker matches</li> <li><em>(admin)</em> Fetch only the first page of team picker matches</li> <li><em>(admin)</em> Share the picker page size</li> <li><em>(admin)</em> Keep the match total in admin picker queries</li> <li><em>(api-tokens)</em> Use the native date picker for custom expiry</li> <li><em>(api-tokens)</em> Share the bearer selection and usage audit</li> <li><em>(api-tokens)</em> Add generated queries and mutations</li> <li><em>(api-tokens)</em> Use generated fields and types (mechanical)</li> <li><em>(api-tokens)</em> Share cached lists across settings consumers</li> <li><em>(api-tokens)</em> Delete legacy resource stack</li> <li><em>(api-tokens)</em> Query token lists page by page</li> <li><em>(api-tokens)</em> Paginate the token settings and bot token lists</li> <li><em>(api-v2)</em> Rename the projecttask path parameter to task</li> <li><em>(attachments)</em> Add generated queries and cache mutations</li> <li><em>(attachments)</em> Switch consumers to generated types (mechanical)</li> <li><em>(attachments)</em> Activate query-owned uploads and previews</li> <li><em>(attachments)</em> Delete legacy attachment and file layers</li> <li><em>(attachments)</em> Opt blob downloads out of the global error toast</li> <li><em>(auth)</em> Expose identity key</li> <li><em>(auth)</em> Refresh through generated public SDK calls</li> <li><em>(auth)</em> Migrate session operations to the v2 SDK</li> <li><em>(avatar)</em> Add image and provider query operations</li> <li><em>(avatar)</em> Subscribe to blobs and mutate through v2</li> <li><em>(avatar)</em> Delete the legacy avatar stack</li> <li><em>(bots)</em> Add generated resource queries and mutations</li> <li><em>(bots)</em> Subscribe settings to v2 query cache</li> <li><em>(bots)</em> Delete legacy service</li> <li><em>(bots)</em> Query the bot list one page at a time</li> <li><em>(bots)</em> Paginate the bot settings page</li> <li><em>(caldav)</em> Add token queries and generated mutations</li> <li><em>(caldav)</em> Switch token types (mechanical)</li> <li><em>(caldav)</em> Subscribe to tokens and scope creation secrets</li> <li><em>(caldav)</em> Delete the legacy token stack</li> <li><em>(caldav-tokens)</em> Page the token list query on the server</li> <li><em>(caldav-tokens)</em> Paginate the settings token table</li> <li><em>(caldav-tokens)</em> Adopt shared pagination helpers for the token list</li> <li><em>(client)</em> Extract shared request-context infrastructure</li> <li><em>(client)</em> Add a shared blob response guard</li> <li><em>(client)</em> Move the blob response guards onto expectBlob</li> <li><em>(client)</em> Add a secret-bearing mutation composable</li> <li><em>(client)</em> Move URL imports off the fetcher (mechanical)</li> <li><em>(client)</em> Store the API base suffix-less and canonicalize v2 URLs</li> <li><em>(client)</em> Delete shared legacy infrastructure and Axios</li> <li><em>(client)</em> Share the paginated envelope normalisation as toPaginated</li> <li><em>(client)</em> Move normalizePageNumber into the pagination helpers</li> <li><em>(client)</em> Share removing a deleted row from cached pages</li> <li><em>(client)</em> Add a shared out-of-range page clamp</li> <li><em>(comments)</em> Add paged queries and mutation bookkeeping</li> <li><em>(comments)</em> Switch consumers to generated types (mechanical)</li> <li><em>(comments)</em> Activate paged queries and local editor drafts</li> <li><em>(comments)</em> Delete legacy comment layers</li> <li><em>(config)</em> Switch consumers to wire fields (mechanical)</li> <li><em>(config)</em> Bootstrap through the generated public client</li> <li><em>(config)</em> Drop the no-op empty license.key default</li> <li><em>(db)</em> Add search relevance order helper</li> <li><em>(deletion)</em> Add generated account lifecycle mutations</li> <li><em>(deletion)</em> Reconcile scheduled deletion through queries</li> <li><em>(deletion)</em> Delete the legacy account service</li> <li><em>(email)</em> Add generated account email mutations</li> <li><em>(email)</em> Use the wire field in the form (mechanical)</li> <li><em>(email)</em> Submit account changes through query mutations</li> <li><em>(email)</em> Delete the legacy email stack</li> <li><em>(export)</em> Add metadata query and generated actions</li> <li><em>(export)</em> Query status and download through generated actions</li> <li><em>(export)</em> Delete the legacy export service</li> <li><em>(filters)</em> Reopen the date picker instead of ignoring clicks</li> <li><em>(frontend)</em> Migrate labels to v2 client</li> <li><em>(frontend)</em> Consolidate task identifier display</li> <li><em>(frontend)</em> Use UserAvatar in User.vue</li> <li><em>(frontend)</em> Use UserAvatar in Comments.vue</li> <li><em>(frontend)</em> Use UserAvatar in the app header</li> <li><em>(frontend)</em> Use UserAvatar in the mention suggestion list</li> <li><em>(frontend)</em> Use UserAvatar in the comment quote node</li> <li><em>(frontend)</em> Migrate project navigation to v2 client</li> <li><em>(frontend)</em> Stop hydrating link-share project store</li> <li><em>(frontend)</em> Extract useTableSort composable</li> <li><em>(frontend)</em> Pass raw loading flags to self-delaying components</li> <li><em>(frontend)</em> Drop the repeated rate limit check around ApiConfig</li> <li><em>(gantt)</em> Replace the flatpickr range input with DateRangeInput</li> <li><em>(helpers)</em> Extract getScrollParent from task detail view</li> <li><em>(humabridge)</em> Export the echo-context accessor</li> <li><em>(kanban)</em> Add bucket mutations and scoped pagination</li> <li><em>(labels)</em> Move cache writes into mutation options</li> <li><em>(labels)</em> Render the label create row through the createOption slot</li> <li><em>(labels)</em> Fetch all label pages through fetchAllPages</li> <li><em>(link-shares)</em> Create link shares through useSecretMutation</li> <li><em>(link-sharing)</em> Use generated fields (mechanical)</li> <li><em>(link-sharing)</em> Manage links through query subscriptions</li> <li><em>(link-sharing)</em> Delete legacy link sharing layers</li> <li><em>(migration)</em> Scan the vikunja-file archive once before importing</li> <li><em>(migration)</em> Parse the csv import config once per request</li> <li><em>(migration)</em> Tidy the ticktick, wekan and csv read paths</li> <li><em>(migrators)</em> Add generated provider operations and status queries</li> <li><em>(migrators)</em> Use generated credential body (mechanical)</li> <li><em>(migrators)</em> Subscribe views and background polling to v2 queries</li> <li><em>(migrators)</em> Remove legacy migration services</li> <li><em>(models)</em> Load tasks by id through the memoized GetTaskByIDSimple</li> <li><em>(models)</em> Drop the unused GetProjectsByIDs</li> </ul> <ul> <li><strong>BREAKING</strong>: drop the unused GetProjectsByIDs</li> </ul> <ul> <li><em>(multiselect)</em> Give the create option its own slot</li> <li><em>(multiselect)</em> Drop unreachable string branches from search result slots</li> <li><em>(notifications)</em> Rename local that shadowed the mail package</li> <li><em>(notifications)</em> Add generated queries and display helpers</li> <li><em>(notifications)</em> Rename read timestamp (mechanical)</li> <li><em>(notifications)</em> Subscribe inbox to query cache</li> <li><em>(notifications)</em> Remove legacy resource stack</li> <li><em>(password)</em> Add generated password mutations</li> <li><em>(password)</em> Use wire fields in the change form (mechanical)</li> <li><em>(password)</em> Submit forms through generated mutations</li> <li><em>(password)</em> Delete the legacy password stacks</li> <li><em>(popup)</em> Show the popup box as a native popover</li> <li><em>(popup)</em> Drop consumer styles the top layer replaces</li> <li><em>(popup)</em> Drop the stale hint about positioning popups via CSS</li> <li><em>(popup)</em> Drop the unused hasOverflow prop</li> <li><em>(project)</em> Anchor the sort and column popups to their triggers</li> <li><em>(project-backgrounds)</em> Migrate project backgrounds to v2 client</li> <li><em>(project-backgrounds)</em> Derive the current project background from the query cache</li> <li><em>(project-backgrounds)</em> Take the delete mutation input as an object</li> <li><em>(project-backgrounds)</em> Fence background mutations through contextMutationOptions</li> <li><em>(project-sharing)</em> Use generated relation types (mechanical)</li> <li><em>(project-sharing)</em> Reconcile sharing controls through query caches</li> <li><em>(project-sharing)</em> Remove legacy sharing layers</li> <li><em>(project-sharing)</em> Render user and team sharing components (mechanical)</li> <li><em>(project-views)</em> Migrate project views to the v2 client</li> <li><em>(project-views)</em> Fence view mutations through contextMutationOptions</li> <li><em>(projects)</em> Extract query and mutation data layer</li> <li><em>(projects)</em> Fence project mutations through contextMutationOptions</li> <li><em>(projects)</em> Fetch all project pages through fetchAllPages</li> <li><em>(queries)</em> Remove hand-rolled request-context fencing helpers</li> <li><em>(queries)</em> Share the paginated envelope, page count and page size helpers</li> <li><em>(queries)</em> Pass optimistic context to settled callbacks</li> <li><em>(queries)</em> Let full-list sweeps use the server page size</li> <li><em>(queries)</em> Drop the stale v2 per_page maximum</li> <li><em>(queries)</em> Let comments and time entries use the server page size</li> <li><em>(reactions)</em> Add generated mutations and immutable updates</li> <li><em>(reactions)</em> Switch consumers to generated types (mechanical)</li> <li><em>(reactions)</em> Reconcile task reactions without refetching</li> <li><em>(reactions)</em> Delete legacy reaction layers</li> <li><em>(saved-filters)</em> Migrate saved filters to v2 client</li> <li><em>(saved-filters)</em> Fence saved filter mutations through contextMutationOptions</li> <li><em>(session)</em> Add session queries and revocation mutation</li> <li><em>(session)</em> Use generated types and wire fields (mechanical)</li> <li><em>(session)</em> Subscribe to the session cache</li> <li><em>(session)</em> Delete the legacy session stack</li> <li><em>(sessions)</em> Query the session list page by page</li> <li><em>(sessions)</em> Paginate the session settings page</li> <li><em>(settings)</em> Add account queries and editable drafts</li> <li><em>(settings)</em> Use wire field names in consumers (mechanical)</li> <li><em>(settings)</em> Read profile state from account queries</li> <li><em>(settings)</em> Delete the legacy settings stack</li> <li><em>(sharing)</em> Add a shared list for user and team project shares</li> <li><em>(sharing)</em> Add user and team sharing components</li> <li><em>(sharing)</em> Remove UserTeam component</li> <li><em>(subscriptions)</em> Toggle project and task subscriptions through v2</li> <li><em>(subscriptions)</em> Move task subscriptions into query mutations</li> <li><em>(subscriptions)</em> Switch to generated fields (mechanical)</li> <li><em>(subscriptions)</em> Remove adapters and wire task mutations</li> <li><em>(subscriptions)</em> Delete legacy subscription model and type</li> <li><em>(tasks)</em> Use the native picker for due dates, reminders and postponing</li> <li><em>(tasks)</em> Create quick-add labels through the label mutation</li> <li><em>(tasks)</em> Extract task domain helpers</li> <li><em>(tasks)</em> Add task and board query definitions</li> <li><em>(tasks)</em> Reconcile task detail list and board caches</li> <li><em>(tasks)</em> Add generated task mutations and optimistic moves</li> <li><em>(tasks)</em> Switch consumers to generated types (mechanical)</li> <li><em>(tasks)</em> Activate query-owned tasks and boards</li> <li><em>(tasks)</em> Retire legacy task and kanban stacks</li> <li><em>(tasks)</em> Extract quick-add orchestration into useQuickAddTask</li> <li><em>(tasks)</em> Switch quick-add consumers to useQuickAddTask</li> <li><em>(tasks)</em> Give each task consumer the mutations it triggers</li> <li><em>(tasks)</em> Let task rows own only the mutations they trigger</li> <li><em>(tasks)</em> Remove the useTaskActions facade</li> <li><em>(tasks)</em> Opt task reads out of the global error toast</li> <li><em>(tasks)</em> Remove unused Zod repeat schema</li> <li><em>(teams)</em> Use generated team types and fields (mechanical)</li> <li><em>(teams)</em> Read live memberships and preserve edit drafts</li> <li><em>(teams)</em> Move team selectors to query subscriptions</li> <li><em>(teams)</em> Keep embedded team responses in generated form</li> <li><em>(teams)</em> Delete legacy team and member layers</li> <li><em>(teams)</em> Split the team list into paged and search queries</li> <li><em>(teams)</em> Switch team pickers to the first-page search query</li> <li><em>(teams)</em> Paginate the team list page</li> <li><em>(teams)</em> Filter team list by membership subquery instead of DISTINCT join</li> <li><em>(time-tracking)</em> Add entry queries and timer mutations</li> <li><em>(time-tracking)</em> Switch generated fields (mechanical)</li> <li><em>(time-tracking)</em> Activate query-owned timers and entry lists</li> <li><em>(time-tracking)</em> Delete legacy timer store and service</li> <li><em>(totp)</em> Add enrollment queries and mutations</li> <li><em>(totp)</em> Subscribe to status and scope QR object URLs</li> <li><em>(totp)</em> Delete the legacy enrollment stack</li> <li><em>(user)</em> Extract display helpers and auth constants</li> <li><em>(user)</em> Switch imports and wire fields (mechanical)</li> <li><em>(user)</em> Preserve generated user objects in consumers</li> <li><em>(user)</em> Remove legacy user model and interface</li> <li><em>(user-search)</em> Use generated user types (mechanical)</li> <li><em>(user-search)</em> Preserve generated user presentation and fields</li> <li><em>(user-search)</em> Migrate selectors and imperative searches to v2</li> <li><em>(user-search)</em> Remove legacy search services</li> <li><em>(users)</em> Accept display fields in user component</li> <li><em>(utils)</em> Split proxy-aware client from the SSRF guard</li> <li><em>(utils)</em> Rename NewHTTPClient to NewUnguardedHTTPClient</li> <li><em>(web)</em> Read source files through an fs.FS in the error code test</li> <li><em>(webhooks)</em> Add scoped v2 queries and mutations</li> <li><em>(webhooks)</em> Rename wire fields (mechanical)</li> <li><em>(webhooks)</em> Share query-backed subscription management</li> <li><em>(webhooks)</em> Remove legacy resource stack</li> <li><em>(webhooks)</em> Key the webhook list by page instead of fetching every page</li> <li><em>(websocket)</em> Reconcile server events through query mutations</li> <li><em>(websocket)</em> Connect task and timer cache events</li> <li><em>(websocket)</em> Track connection state as a single status</li> <li>Split deleteStaleFilterTasks into collect and delete (<a href="/go-vikunja/vikunja/blob/v2.7.0/7c11e71430b5afba59b564eb07755c688de948d4">7c11e71</a>)</li> </ul> <p>Styling</p> <ul> <li><em>(frontend)</em> Order delayed loading after macros in form components</li> </ul> <p>Testing</p> <ul> <li><em>(admin)</em> Cover mutation invalidation and runtime license gating</li> <li><em>(admin)</em> Make admin project search tests ParadeDB independent</li> <li><em>(admin)</em> Pin user picker invalidation on user updates</li> <li><em>(api)</em> Cover the create path of a retried request</li> <li><em>(api-tokens)</em> Cover sha256 fast path, legacy backfill and null legacy columns</li> <li><em>(api-tokens)</em> Verify scoped token persistence and revocation</li> <li><em>(api-tokens)</em> Pin paged token lists and delete across pages</li> <li><em>(api-tokens)</em> Pin route-driven paging of the token settings page</li> <li><em>(attachments)</em> Pin v2 requests and cache reconciliation</li> <li><em>(attachments)</em> Provide Pinia for date formatting</li> <li><em>(auth)</em> Require an iat claim on issued JWTs</li> <li><em>(auth)</em> Cover token expiry checks with a skewed browser clock</li> <li><em>(auth)</em> Pin login with a skewed browser clock end to end</li> <li><em>(auth)</em> Cover generated refresh and problem responses</li> <li><em>(avatar)</em> Pin request sharing and blob lifecycle</li> <li><em>(bots)</em> Cover management persistence and token cache eviction</li> <li><em>(bots)</em> Reproduce disabled bot management failures</li> <li><em>(bots)</em> Pin the paged bot list and cross-page mutations</li> <li><em>(bots)</em> Cover paging through the bot settings page end to end</li> <li><em>(bots)</em> Cover opening an out-of-range bot page directly</li> <li><em>(caldav)</em> Pin one-time secrets and durable token changes</li> <li><em>(caldav-tokens)</em> Pin paged token list and delete across pages</li> <li><em>(client)</em> Pin the normalized shape of Echo-level error bodies</li> <li><em>(client)</em> Pin the global query error toast</li> <li><em>(client)</em> Pin the shared blob response guard</li> <li><em>(client)</em> Pin that secret mutations drop their variables once settled</li> <li><em>(client)</em> Pin v2 URL upgrade and native request errors</li> <li><em>(comments)</em> Pin paging and mutation bookkeeping</li> <li><em>(config)</em> Cover generated bootstrap and feature name schema</li> <li><em>(datepicker)</em> Cover keyboard navigation and mobile opening</li> <li><em>(db)</em> Let AssertExists and AssertMissing match NULL columns</li> <li><em>(db)</em> Cover the session memo</li> <li><em>(deletion)</em> Verify confirmation links and durable cancellation</li> <li><em>(e2e)</em> Update date picker selectors, cover the mobile sheet, fix the API_URL slash</li> <li><em>(e2e)</em> Verify invite registration and SMTP confirmation</li> <li><em>(e2e)</em> Expect the translated invalid password reset token message</li> <li><em>(e2e)</em> Open the used-up invite link in its own browser context</li> <li><em>(e2e)</em> Allow non-routable IPs through outgoingrequests config</li> <li><em>(e2e)</em> Cover admin project list filters and sorting</li> <li><em>(e2e)</em> Expect the project wording in the remove share dialog</li> <li><em>(e2e)</em> Cover websocket re-authentication</li> <li><em>(email)</em> Pin pending account reconciliation and persistence</li> <li><em>(export)</em> Verify metadata invalidation and ZIP downloads</li> <li><em>(filters)</em> Cover reopening the date picker on another date value</li> <li><em>(filters)</em> Mock async editor to avoid loading TipTap after teardown</li> <li><em>(frontend)</em> Assert the archive modal keeps its document title</li> <li><em>(frontend)</em> Type the api token create mock parameter</li> <li><em>(frontend)</em> Cover UserAvatar and avatar cache invalidation</li> <li><em>(frontend)</em> Wait for the delayed task row spinner</li> <li><em>(kanban)</em> Cover saving the position of a dropped bucket</li> <li><em>(kanban)</em> Cover bucket paging and metadata updates</li> <li><em>(link-sharing)</em> Cover cached shares and view-specific URLs</li> <li><em>(migration)</em> Cover api_tokens sha256 migration, sqlite rebuild and re-runs</li> <li><em>(migration)</em> Build the orphan test data from the real label models</li> <li><em>(migrators)</em> Cover cached progress and persistent CSV imports</li> <li><em>(multiselect)</em> Pin search result and create option rendering</li> <li><em>(notifications)</em> Cover inbox persistence and cache events</li> <li><em>(notifications)</em> Cover single inbox fetch and polling fallback end to end</li> <li><em>(password)</em> Verify reset links and changed login credentials</li> <li><em>(popup)</em> Cover the popup without the Popover API</li> <li><em>(project-sharing)</em> Cover membership caches and permissions</li> <li><em>(project-sharing)</em> Cover user and team share lifecycles</li> <li><em>(project-sharing)</em> Pin keyboard sharing, removal cancel and row details</li> <li><em>(projects)</em> Insert raw test projects through one helper that writes their ancestors</li> <li><em>(queries)</em> Pin optimistic and toast fencing for contextMutationOptions</li> <li><em>(ratelimit)</em> Align basic auth rate limit webtests to a fresh window</li> <li><em>(reactions)</em> Pin generated requests and task cache updates</li> <li><em>(reminders)</em> Exercise the subscriber pass in the IsAssignee test</li> <li><em>(reminders)</em> Include reminders exactly at the cron tick</li> <li><em>(reminders)</em> Exclude notifications for completed tasks</li> <li><em>(richtext)</em> Detect capitalization-only edits</li> <li><em>(richtext)</em> Normalize CRLF in code blocks</li> <li><em>(saved-filters)</em> Cover editing and deleting a saved filter end to end</li> <li><em>(saved-filters)</em> Open filter settings modals from a direct URL</li> <li><em>(session)</em> Pin paginated reads and durable revocation</li> <li><em>(sessions)</em> Pin paged session query and revoke across pages</li> <li><em>(sessions)</em> Cover paging and revoking the last row of a page</li> <li><em>(settings)</em> Pin cache ownership and persisted preferences</li> <li><em>(settings)</em> Cover a setting changed elsewhere while the form is open</li> <li><em>(subscriptions)</em> Pin task subscription cache updates</li> <li><em>(tasks)</em> Pin extracted task domain behavior</li> <li><em>(tasks)</em> Pin query scope and board pagination</li> <li><em>(tasks)</em> Cover reconciliation across task caches</li> <li><em>(tasks)</em> Pin mutation writes rollback and partial bulk results</li> <li><em>(tasks)</em> Verify query-backed consumers and navigation</li> <li><em>(tasks)</em> Verify v2 writes and persisted board edits</li> <li><em>(tasks)</em> Pin the loading state of a task list row</li> <li><em>(teams)</em> Cover pagination membership and cache lifecycle</li> <li><em>(teams)</em> Verify member changes and preserve open drafts</li> <li><em>(teams)</em> Pin paged list and first-page search requests</li> <li><em>(teams)</em> Assert the two team pages cover every seeded team once</li> <li><em>(time-tracking)</em> Pin timer scope and list reconciliation</li> <li><em>(totp)</em> Pin enrollment secret and QR lifecycle</li> <li><em>(user)</em> Pin display and avatar cache behavior</li> <li><em>(user)</em> Reject tokens issued for another purpose</li> <li><em>(user)</em> Enforce CalDAV token deletion ownership</li> <li><em>(user-search)</em> Cover scoped v2 search queries</li> <li><em>(user-search)</em> Pin generated user presentation and embedding</li> <li><em>(utils)</em> Preserve fractional duration components</li> <li><em>(utils)</em> Assert avatar crop source pixels</li> <li><em>(utils)</em> Preserve seconds when stripping nanoseconds</li> <li><em>(web)</em> Fail when two packages claim the same world error code</li> <li><em>(web)</em> Catch ErrorCode-prefixed constants in error code uniqueness check</li> <li><em>(webhooks)</em> Verify scoped cache and stored subscriptions</li> <li><em>(webhooks)</em> Pin paged list requests and delete across pages</li> <li><em>(websocket)</em> Pin cache routing and stale connection rejection</li> <li>Expect ErrFileDoesNotExist from LoadFileByID in s3 integration test (<a href="/go-vikunja/vikunja/blob/v2.7.0/37649d1dd2c6db3a7737f983e4b7ae3c479d9852">37649d1</a>)</li> <li>Remove component tests covered by e2e (<a href="/go-vikunja/vikunja/blob/v2.7.0/40c97e2e5871e70f1ae72daf2640b623c6ce832f">40c97e2</a>)</li> <li>Focus due date action before keyboard shortcut (<a href="/go-vikunja/vikunja/blob/v2.7.0/c9a32645943382966ff0a983e67f92306a58f017">c9a3264</a>)</li> </ul> kolaente tag:github.com,2008:Repository/159556794/v2.6.0 2026-08-31T18:13:15Z
2026-10-02T17:10:44Z tag:github.com,2008:Repository/159556794/v2.7.0 2026-10-02T21:18:37Z

v2.7.0

<p>🦙 Vikunja 2.7.0 is out!</p> <p>🔒 Six security fixes<br> 🤖 An MCP server so your AI assistant can work with your tasks<br> 📅 Plus a new date picker</p> <p><a href="https://vikunja.io/changelog/vikunja-2.7.0-was-released/" rel="nofollow">https://vikunja.io/changelog/vikunja-2.7.0-was-released/</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.6.0 2026-08-31T18:13:15Z

v2.6.0

<p>🚀 Vikunja 2.6.0 is out! 380 commits, 18 of which are security fixes. 🔒</p> <p>Also new: import from Planka 📥, image/audio/video previews for attachments 🖼️, and an email change flow that no longer locks you out on a typo. ✉️</p> <p><a href="https://vikunja.io/changelog/vikunja-2.6.0-was-released/" rel="nofollow">https://vikunja.io/changelog/vikunja-2.6.0-was-released/</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.5.0 2026-08-04T12:46:14Z

v2.5.0

<p>🚀 Vikunja 2.5.0 is out! Small release, 203 commits of cleanup.</p> <p>🔒 One security fix: a share link could act as another user. Please update.</p> <p>⚡ Pasting a list into quick add magic now creates every task in one request, in the order you wrote them.</p> <p>Plus a bunch of CalDAV, notification and import fixes 🦙</p> <p><a href="https://vikunja.io/changelog/vikunja-2.5.0-was-released/" rel="nofollow">https://vikunja.io/changelog/vikunja-2.5.0-was-released/</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.4.0 2026-07-19T19:13:16Z

v2.4.0

<p>🦙 Vikunja 2.4.0 is out! Ten security fixes (please update soon), the first Vikunja Pro features, and a brand-new v2 API. Full rundown: <a href="https://vikunja.io/changelog/vikunja-2.4.0-pro-and-a-new-api" rel="nofollow">https://vikunja.io/changelog/vikunja-2.4.0-pro-and-a-new-api</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.3.0 2026-04-09T19:53:26Z

v2.3.0

<p>🦙 Vikunja 2.3.0 is out! 11 security fixes, a new plugin system, quick-entry window for the desktop app, Vikunja as an OAuth 2.0 provider, WeKan + CSV imports, and more across 277 commits. Updating soon is highly reccomended!</p> <p><a href="https://vikunja.io/changelog/whats-new-in-vikunja-2.3.0" rel="nofollow">https://vikunja.io/changelog/whats-new-in-vikunja-2.3.0</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.2.2 2026-03-23T21:35:07Z

v2.2.2

<p>🔒 Vikunja 2.2.2 is out: nine security fixes including a critical chain that could expose instance-wide data. Also adds centralized SSRF protection and a few nice bug fixes. Please update soon!</p> <p>(2.2.1 has been released as well but did not fix the issues fully, therefore I went and pushed 2.2.2 right after)</p> <p><a href="https://vikunja.io/changelog/vikunja-v2.2.2-was-released" rel="nofollow">https://vikunja.io/changelog/vikunja-v2.2.2-was-released</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.2.1 2026-03-23T18:50:19Z

v2.2.1: [2.2.1] - 2026-03-23

<p>Bug Fixes</p> <ul> <li><em>(auth)</em> Reject disabled/locked users in OIDC callback</li> <li><em>(auth)</em> Reject disabled/locked users in API token middleware</li> <li><em>(auth)</em> Return correct error type for locked users in OIDC callback</li> <li><em>(auth)</em> Reject disabled/locked users in CheckUserCredentials</li> <li><em>(auth)</em> Skip profile updates for disabled LDAP users</li> <li><em>(caldav)</em> Replace href with pathname from parseURL for api base</li> <li><em>(frontend)</em> OrigUrlToCheck references the same object as urlToCheck</li> <li><em>(openid)</em> Merge VikunjaGroups and ExtraSettingsLinks from userinfo</li> <li><em>(user)</em> Reject disabled/locked users in getUser by default</li> <li><em>(user)</em> Handle status errors in pkg/user callers, remove redundant checks</li> <li><em>(user)</em> Handle status errors across the codebase, remove redundant checks</li> <li><em>(user)</em> Use getUser directly for uniqueness checks in UpdateUser</li> <li><em>(user)</em> Use unique error code for ErrCodeAccountLocked</li> <li>Remove small class from preset label (<a href="/go-vikunja/vikunja/blob/v2.2.1/652eb9bba3701b72cbb26f5e60f7fc559c452eb7">652eb9b</a>)</li> <li>Include kanban bucket move permission in tasks preset (<a href="/go-vikunja/vikunja/blob/v2.2.1/0085772b63b12747b804a7caac2ab4c846b664b3">0085772</a>)</li> <li>Prevent TOTP passcode reuse within validity window (<a href="/go-vikunja/vikunja/blob/v2.2.1/5f06e1dce56ca2b1845c9adb7aacab8777296e1f">5f06e1d</a>)</li> <li>Update TOTP reuse test to use user10 matching rebased fixture (<a href="/go-vikunja/vikunja/blob/v2.2.1/acafa6db10b238dae5b66851cc2c5dedbd51bbd1">acafa6d</a>)</li> <li>Add TTL-based expiry and cleanup for used TOTP passcode entries (<a href="/go-vikunja/vikunja/blob/v2.2.1/0f98c19ab66215200facebd8fac58d5aedc8c0ef">0f98c19</a>)</li> <li>Check child project's own IsArchived flag in CheckIsArchived (<a href="/go-vikunja/vikunja/blob/v2.2.1/d0606eadea06669326f9f39747d2fc49191c2e69">d0606ea</a>)</li> <li>Update ParadeDB search test count for new fixture (<a href="/go-vikunja/vikunja/blob/v2.2.1/595002bf96556e9f1d16fb4e2016d16d7a2e2564">595002b</a>)</li> <li>Filter related tasks by project access to prevent cross-project info disclosure (<a href="/go-vikunja/vikunja/blob/v2.2.1/67a47787fa12ff61ff80be0c79032bec71e3e63d">67a4778</a>)</li> <li>Prevent attachment IDOR by validating task_id in ReadOne (<a title="GHSA-jfmm-mjcp-8wq2" data-hovercard-type="advisory" data-hovercard-url="/advisories/GHSA-jfmm-mjcp-8wq2/hovercard" href="https://github.com/advisories/GHSA-jfmm-mjcp-8wq2">GHSA-jfmm-mjcp-8wq2</a>) (<a href="/go-vikunja/vikunja/blob/v2.2.1/b8edc8f17f47222e439bbac8725758a02782e943">b8edc8f</a>)</li> <li>Prevent link share IDOR by validating project_id in Delete and ReadOne (<a href="/go-vikunja/vikunja/blob/v2.2.1/654d2c7042f912f662bb49e05b7f9bb74e6ae1b4">654d2c7</a>)</li> <li>Prevent SSRF via OpenID Connect avatar download (<a title="GHSA-g9xj-752q-xh63" data-hovercard-type="advisory" data-hovercard-url="/advisories/GHSA-g9xj-752q-xh63/hovercard" href="https://github.com/advisories/GHSA-g9xj-752q-xh63">GHSA-g9xj-752q-xh63</a>) (<a href="/go-vikunja/vikunja/blob/v2.2.1/363aa6642352b08fc8bc6aaff2f3a550393af1cf">363aa66</a>)</li> <li>Prevent SSRF via migration file attachment URLs (<a title="GHSA-g66v-54v9-52pr" data-hovercard-type="advisory" data-hovercard-url="/advisories/GHSA-g66v-54v9-52pr/hovercard" href="https://github.com/advisories/GHSA-g66v-54v9-52pr">GHSA-g66v-54v9-52pr</a>) (<a href="/go-vikunja/vikunja/blob/v2.2.1/93297742236e3d33af72c993e5da960db01d259e">9329774</a>)</li> <li>Prevent SSRF via Microsoft Todo migration pagination links (<a href="/go-vikunja/vikunja/blob/v2.2.1/73edbb6d467bb1c01f928568c6f28f3d5eabe807">73edbb6</a>)</li> <li>Prevent SSRF via Unsplash background image download (<a href="/go-vikunja/vikunja/blob/v2.2.1/a94109e1beab683277fb1524514fcd7368cd071d">a94109e</a>)</li> <li>Block link share users from listing link shares in ReadAll (<a href="/go-vikunja/vikunja/blob/v2.2.1/9efe1fadba817923c7c7f5953c3e9e9c5683bbf3">9efe1fa</a>)</li> <li>Correct error message assertion in linkshare ReadAll tests (<a href="/go-vikunja/vikunja/blob/v2.2.1/a0478a0d96befef4583fdf10ac7a02eff4d8e435">a0478a0</a>)</li> <li>Strip BasicAuth credentials from project webhook API responses (<a href="/go-vikunja/vikunja/blob/v2.2.1/75c9b753a8e4feed8f681ad76fe8f125b0016366">75c9b75</a>)</li> <li>Strip BasicAuth credentials from user webhook API responses (<a href="/go-vikunja/vikunja/blob/v2.2.1/6aef5aff62f58edd178d954e30981b18c2348bc2">6aef5af</a>)</li> <li>Use MySQL-compatible CREATE INDEX in migration 20260224215050 (<a href="/go-vikunja/vikunja/blob/v2.2.1/867c52745f595f9fb00e868ed3a81a31e2c89672">867c527</a>)</li> <li>Skip quick add magic parsing when text is wrapped in quotes (<a href="/go-vikunja/vikunja/blob/v2.2.1/07b9742d98d8068ae14f752babfe2715f031fc0b">07b9742</a>)</li> </ul> <p>Dependencies</p> <ul> <li><em>(deps)</em> Update dependency rollup to v4.60.0</li> <li><em>(deps)</em> Update dependency caniuse-lite to v1.0.30001781</li> <li><em>(deps)</em> Update flatted to 3.4.2 to fix prototype pollution vulnerability</li> <li><em>(deps)</em> Update dev-dependencies</li> <li><em>(deps)</em> Update dev-dependencies to v8.57.2</li> </ul> <p>Documentation</p> <ul> <li>Mention mole proxy in outgoingrequests config docs (<a href="/go-vikunja/vikunja/blob/v2.2.1/701e3f952514cb12f4cec5b533b38ce81b1cc60f">701e3f9</a>)</li> </ul> <p>Features</p> <ul> <li><em>(user)</em> Add ErrAccountLocked error type</li> <li>Add quick presets for API token permission selection (<a href="/go-vikunja/vikunja/blob/v2.2.1/68097cf7004f3d7f1d6e5ff57f7adf5b001f513d">68097cf</a>)</li> <li>Add outgoingrequests config keys for centralized SSRF protection (<a href="/go-vikunja/vikunja/blob/v2.2.1/f96b53fe998e9a7484507d4a31dd79f86dd556c6">f96b53f</a>)</li> <li>Add shared SSRF-safe HTTP client utility (<a href="/go-vikunja/vikunja/blob/v2.2.1/0266fffad2fcf9a81c2eb3d0466734633fdf7fb7">0266fff</a>)</li> </ul> <p>Miscellaneous Tasks</p> <ul> <li><em>(ci)</em> Update golangci-lint to v2.10.1</li> <li><em>(i18n)</em> Update translations via Crowdin</li> <li><em>(lint)</em> Suppress known gosec false positives</li> <li><em>(lint)</em> Suppress additional gosec false positives</li> <li><em>(lint)</em> Suppress gosec false positives on SSRF-safe HTTP client calls</li> </ul> <p>Refactor</p> <ul> <li><em>(user)</em> Export IsErrUserStatusError for use across packages</li> <li>Reorganize quick add magic into focused modules (<a href="/go-vikunja/vikunja/blob/v2.2.1/cb81cf1aa83d006ac83f74556c1b195f22a1335f">cb81cf1</a>)</li> <li>Add accessibleProjectIDsSubquery helper for project-level authz filtering (<a href="/go-vikunja/vikunja/blob/v2.2.1/e2683bb2bcffa879054474e702ea8c2c405c8b8d">e2683bb</a>)</li> <li>Use accessibleProjectIDsSubquery in addBucketsToTasks (<a href="/go-vikunja/vikunja/blob/v2.2.1/833f2aec006ac0f6643c41872e45dd79220b9174">833f2ae</a>)</li> <li>Use shared SSRF-safe HTTP client in webhook code (<a href="/go-vikunja/vikunja/blob/v2.2.1/e5a1c057719dd768e5101787830dce585aeaf460">e5a1c05</a>)</li> </ul> <p>Testing</p> <ul> <li><em>(auth)</em> Add comprehensive disabled/locked user auth tests</li> <li>Add TOTP fixture and load it in user test bootstrap (<a href="/go-vikunja/vikunja/blob/v2.2.1/de58f630ee41d8672c7a4c644edb8b0b8b9c97e8">de58f63</a>)</li> <li>Add failing test for TOTP passcode reuse prevention (<a href="/go-vikunja/vikunja/blob/v2.2.1/5591ca94baf8cdece3f5ca6a1968fa96886e7de1">5591ca9</a>)</li> <li>Add API token fixture for disabled user (<a href="/go-vikunja/vikunja/blob/v2.2.1/198322c8e153d41b37ae761fb0ebe71059c87e12">198322c</a>)</li> <li>Verify disabled user's API token is rejected (<a href="/go-vikunja/vikunja/blob/v2.2.1/e4379eff108b4061d39a63dbe7a60fd6ab2793a7">e4379ef</a>)</li> <li>Verify disabled user is rejected via CalDAV auth (<a href="/go-vikunja/vikunja/blob/v2.2.1/8b614a4cb3226a9816da6ec46b81b2234e88760a">8b614a4</a>)</li> <li>Verify GetUserByID rejects disabled users and returns user with error (<a href="/go-vikunja/vikunja/blob/v2.2.1/525f5ee407b74db31d0476882a89d359641f83a6">525f5ee</a>)</li> <li>Add cross-project task relation fixture for authz test (<a href="/go-vikunja/vikunja/blob/v2.2.1/589d2a55561601d26c043db6c8b33893ce738ccc">589d2a5</a>)</li> <li>Add failing test for cross-project task relation info disclosure (<a href="/go-vikunja/vikunja/blob/v2.2.1/50c3eebd235896fce0984a242c97385bc77458c4">50c3eeb</a>)</li> <li>Add attachment fixture on inaccessible task for IDOR test (<a href="/go-vikunja/vikunja/blob/v2.2.1/b2c3c36b6fdf05caefd223067ec7d1ebdf7d66fd">b2c3c36</a>)</li> <li>Add IDOR test for task attachment ReadOne (<a title="GHSA-jfmm-mjcp-8wq2" data-hovercard-type="advisory" data-hovercard-url="/advisories/GHSA-jfmm-mjcp-8wq2/hovercard" href="https://github.com/advisories/GHSA-jfmm-mjcp-8wq2">GHSA-jfmm-mjcp-8wq2</a>) (<a href="/go-vikunja/vikunja/blob/v2.2.1/3111f3d70ce08764b18f887b1824205b9f133503">3111f3d</a>)</li> <li>Use new outgoingrequests config keys in SSRF tests (<a href="/go-vikunja/vikunja/blob/v2.2.1/d4d88c0f5935c51a8f9c0b205e9b517537792228">d4d88c0</a>)</li> <li>Remove redundant webhook SSRF tests (<a href="/go-vikunja/vikunja/blob/v2.2.1/848a4e7f0757bc6a18bcdbc0205f23fe226a1866">848a4e7</a>)</li> <li>Add BasicAuth credentials to webhook fixture (<a href="/go-vikunja/vikunja/blob/v2.2.1/094ff5f1efe403df5c5e63ba99144cddff293059">094ff5f</a>)</li> <li>Add failing test for webhook BasicAuth credential exposure (<a href="/go-vikunja/vikunja/blob/v2.2.1/751ab2c63505119d9c3b1f458100147d26f49b94">751ab2c</a>)</li> <li>Update user count assertions for new locked user fixture (<a href="/go-vikunja/vikunja/blob/v2.2.1/c1418c1619b15fb9a9707ab4820528e087ddd354">c1418c1</a>)</li> <li>Add failing tests for quote-escaped task text parsing (<a href="/go-vikunja/vikunja/blob/v2.2.1/8538b4c885d03789061161772233ea60be8bbe37">8538b4c</a>)</li> </ul> kolaente tag:github.com,2008:Repository/159556794/v2.2.0 2026-03-20T13:42:37Z

v2.2.0

<p>🔒 Vikunja 2.2.0 is out! 10 security fixes (update now!), plus task duplication, an improved Gantt chart with subtask hierarchy & dependency arrows, and user-level webhooks. 237 commits of goodness 🚀</p> <p>Check out the release post for a more in-depth view: <a href="https://vikunja.io/changelog/vikunja-v2.2.0-was-released" rel="nofollow">https://vikunja.io/changelog/vikunja-v2.2.0-was-released</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.1.0 2026-02-27T14:26:53Z

v2.1.0

<p>🎉 Just two days after the last release, Vikunja 2.1.0 is now released!</p> <p>🔒 Fixes a security issue with password reset tokens and adds a nice touch: checklist indicators now turn green when all items are done!</p> <p>Check out the full release post on the website: <a href="https://vikunja.io/changelog/vikunja-v2.1.0-was-released/" rel="nofollow">https://vikunja.io/changelog/vikunja-v2.1.0-was-released/</a></p> github-actions[bot] tag:github.com,2008:Repository/159556794/v2.0.0 2026-02-25T13:58:47Z

v2.0.0

<p>This release fixes 4 critical security issues. Please upgrade as soon as you can!</p> <p>Check out the full release notes here: <a href="https://vikunja.io/changelog/vikunja-v2.0.0-was-released/" rel="nofollow">https://vikunja.io/changelog/vikunja-v2.0.0-was-released/</a></p> github-actions[bot]
Tip: Highlight text to share or add to ignore lists.  — Download difference patch
For now, Differences are performed on text, not graphically, only the latest screenshot is available.
Screenshot requires Playwright/WebDriver enabled