In filter bucket mode a bucket's search was written into the shared search options and never reset, so buckets processed afterwards (random map order) inherited it.
TaskCollection.ReadAll built the saved filter's collection but recursed with the request search only, so filters.s was never applied. The stored search now takes precedence, matching view and bucket filter searches.
Moving a project to a position below 0.1 respread the positions of all
sibling projects on the instance. It now only touches the siblings the
user can write, plus the moved project itself.
A migration clears the background of projects whose background file is
also a task attachment, an avatar, a data export, a pending import upload
or another project's background. Of projects sharing a file, the oldest
keeps it.
The Unsplash and upload providers now remove the old background through
DeleteBackgroundFileIfExists.
The background of a new project is only ever set by the background
endpoints. Duplicating a project now hands the source background to the
copy step explicitly instead of relying on the field surviving creation.
Images longer than MaxSide (65535) pixels on either side are now rejected
before decoding, like images over the pixel limit.
Attachments with such images are still stored; only their preview is not
generated. Project backgrounds and avatars reject them with the existing
image too large error.
The user data export embedded every related task in full, repeating its
description once per relation. Related tasks are now exported as id and
project id only, since every related task is part of the export anyway.
The importer resolves such references across all imported projects and
creates relations once every project exists, so relations between
projects survive the round trip instead of duplicating the related task.
Exports with the full related task shape import as before.
- Reject a config that maps a column more than once, already when the
import is started or previewed.
- Import repeated labels of a row once and reject rows with more than
MaxLabelsPerTask (100) labels.
- Count items while converting rows so a file over the import item limit
fails before the whole structure is built.
- Walk mappings sorted by column so a row only visits the cells it has.
Lists, cards, checklists and attachments are looked up by id while
converting a board, so a repeated id imported the whole group once per
copy. Keep the first entry of each id and stop the conversion as soon as
the import item limit is exceeded instead of after building everything.
Updates caldav-go, which answered every property in <prop> as often as it
was listed, rendering its value again each time, and passed repeated
multiget hrefs to storage again. It now answers each property and href
once and rejects requests for more than 200 properties.
Task bodies sent to a collection URL are now only parsed for PUT and
after the read check.
Calendar bodies are also limited in size (1 MiB) and in parameters per
property (100) before golang-ical sees them. Violations are answered with
413/400.
Every VALARM repeats the task title and the output was built with string
concatenation, so rendering cost grew quadratically with the number of
reminders. Build it with a strings.Builder instead.
Tasks may now have at most MaxRemindersPerTask (100) reminders and a
title of at most MaxTaskTitleLength (1000) characters, checked through
v1, v2 and CalDAV. On update the reminder limit only applies when the
count grows and the title limit only when the title changes, so existing
tasks stay editable.
Rowspan/colspan and short-row padding make both converters materialize
far more cells than the input contains. HTML to markdown now renders
tables past MaxTableCells as plain rows, so stored descriptions still
read fine. Markdown to HTML rejects such input, which the v2 API reports
as invalid data.
The business day offsets in the date values of a task or time entry
filter may now add up to at most MaxDatemathBusinessDays (10000). Larger
filters are rejected with the invalid filter value error before any value
is evaluated. The frontend date math parser applies the same limit.
An empty find_action result looked identical to "not authorized", so
agents guessing a wrong resource prefix (task_relations instead of
tasks_relations) concluded their token lacked permission.
Refs #4342
Adds a mock OpenID provider issuing signed ID tokens so AuthenticateCallback
can be tested end to end, and pins the current behaviour for OIDC-created
users (email/name/avatar/team sync, disabled user refused). The proxy test
reuses the same mock instead of its inline copy.
Address PR Swarm lock-order decision across task writes, restoration, and project/user purges. Reject moves discovered after view locks without acquiring views out of order.
Covers comments, attachments, labels, assignees, relations, reactions and task duplication. Assignee access is now checked against the project the task is in after the lock.