Commit Graph

254 Commits

Author SHA1 Message Date
kolaente c6c57d9d15 refactor(models): remove *Arr helper fields now handled by normalizer 2026-05-31 12:56:57 +00:00
kolaente 9206f98d64 feat(tasks): enforce unique (project_id, index) via migration 2026-04-11 20:44:28 +00:00
kolaente 8f9b50bdcb feat(tasks): add GetTaskByProjectAndIndex resolver 2026-04-11 20:44:28 +00:00
kolaente 6df0d6c8f5 feat(tasks): cap repeat_after at 10 years to harden repeating-task handler
Add MaxTaskRepeatAfterSeconds (10 years in seconds) and reject any
create/update that tries to store a value outside [0, cap] with a new
ErrInvalidTaskRepeatInterval (error code 4029). Defense-in-depth
alongside the arithmetic fix in addRepeatIntervalToTime: keeps stored
values well away from int64 overflow and bounds the range of inputs
a future refactor could trip over.
2026-04-09 16:07:48 +00:00
kolaente 9dc3d7eb4f fix(tasks): replace O(n) loop in repeating-task handler with arithmetic
addRepeatIntervalToTime used to advance t by whole intervals via an
unbounded loop. A repeating task with an ancient due_date and a
one-second interval required billions of iterations per task update,
turning completion of such a task into a trivial denial-of-service
(GHSA-r4fg-73rc-hhh7). Compute the number of intervals directly, with
guards for zero/negative durations, saturated time.Sub, and int64
overflow.

Covered by TestAddRepeatIntervalToTime, including the 1900-01-01 PoC
case.
2026-04-09 16:07:48 +00:00
kolaente f1e12c6f64 fix(caldav): enforce task read authorization on GetTasksByUIDs
Previously GetTasksByUIDs returned any task matching the UID regardless
of the caller's access, letting any authenticated CalDAV user read any
task by guessing or knowing a UID. Filter by accessible project IDs at
the SQL level using the existing accessibleProjectIDsSubquery helper.

Fixes GHSA-48ch-p4gq-x46x.
2026-04-09 16:07:32 +00:00
kolaente 1e784aa194 fix(tasks): route repeating tasks to default bucket when marked done (#2573) 2026-04-09 10:45:34 +00:00
kolaente 007379cff1 refactor(tasks): add moveTaskToDefaultBuckets helper (#2573) 2026-04-09 10:45:34 +00:00
kolaente 0c3d01099f fix: detect and resolve position conflicts during task creation
Fixes #2495, fixes #2400

When tasks are created, setTaskInBucketInViews() assigns positions
without checking for conflicts. If two tasks get the same position value,
their order scrambles on reload. This adds a conflict check after
bulk-inserting positions, reusing the existing resolution logic from the
update path.
2026-04-03 17:26:55 +00:00
kolaente 833f2aec00 refactor: use accessibleProjectIDsSubquery in addBucketsToTasks 2026-03-23 16:26:37 +00:00
kolaente 67a47787fa fix: filter related tasks by project access to prevent cross-project info disclosure 2026-03-23 16:26:37 +00:00
Tink d11f097eee
fix(tasks): support both expand and expand[] query parameter formats (#2415)
The `expand` query parameter only supported the `expand[]=foo` array
format, but the swagger docs described it as a plain string parameter.
This adds support for both formats (`expand=foo` and `expand[]=foo`),
matching the existing pattern used by `sort_by` and `order_by`
parameters.

Closes #2408

---------

Co-authored-by: kolaente <k@knt.li>
2026-03-19 09:18:11 +00:00
kolaente 3eb289262f fix(events): defer task event dispatch until after transaction commit
Convert events.Dispatch to events.DispatchOnCommit in Task.Create,
updateSingleTask, Task.Delete, and triggerTaskUpdatedEventForTaskID.
Events are now dispatched by the handler after s.Commit(), ensuring
webhook listeners see committed data.

Fixes #2315
2026-03-03 12:46:34 +01:00
kolaente a5b1a90c42 refactor: remove typesense support
Typesense was an optional external search backend. This commit fully
removes the integration, leaving the database searcher as the only
search implementation.

Changes:
- Delete pkg/models/typesense.go (core integration)
- Delete pkg/cmd/index.go (CLI command for indexing)
- Simplify task search to always use database searcher
- Remove Typesense event listeners for task sync
- Remove TypesenseSync model registration
- Remove Typesense config keys and defaults
- Remove Typesense doctor health check
- Remove Typesense initialization from startup
- Clean up benchmark test
- Add migration to drop typesense_sync table
- Remove golangci-lint suppression for typesense.go
- Remove typesense-go dependency
2026-02-25 12:15:28 +01:00
kolaente cbfd0e63ed fix: pass pointer to xorm Update to avoid hash panic in transaction mode
In transaction mode, xorm stores the bean argument as a map key in
afterUpdateBeans. Since Task contains slices and maps (unhashable
types), passing a Task value causes "hash of unhashable type" panic.
Passing a pointer (&ot) fixes this since pointers are always hashable.
2026-02-25 11:03:02 +01:00
renovate[bot] 9a61453e86
fix(deps): update module github.com/labstack/echo/v4 to v5 (#2131)
Closes https://github.com/go-vikunja/vikunja/pull/2133

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kolaente <k@knt.li>
2026-01-24 20:38:32 +01:00
kolaente 82558dba87
fix(filters): ensure saved filter views never have position=0 (#1996)
Fixes #724 - Tasks in saved filter views get `position: 0` when they first appear in the filter, causing drag-and-drop sorting to not persist correctly.

**Changes:**
- Remove harmful `Position: 0` inserts from cron job and
`SavedFilter.Update` - `RecalculateTaskPositions` already creates
positions with proper values, so the intermediate inserts created a race
window
- Add on-demand position creation when fetching tasks for saved filter
views - safety net for newly matching tasks before the cron runs
- Add 5 new tests covering the fix and regression scenarios

🐰 Positions once zero, now bloom with care,
Sorted with grace, no more despair,
When filters call and tasks appear,
Numbers spring up, crystal clear!
Issue 724 hops away—
Sorting's fixed to stay, hooray! 🎉
2025-12-16 22:13:40 +00:00
kolaente 0b3decd869
fix: ensure API consistency for /tasks and empty array responses (#1988)
- Renames the `/tasks/all` endpoint to `/tasks` for consistency with
other collection endpoints like `/projects` and `/labels`
- Returns `[]` instead of `null` for empty pagination results across all
list endpoints
- Updates the frontend service to use the new endpoint path
- Updates API token tests to use the new endpoint path

Fixes #1984
2025-12-15 15:34:13 +00:00
Mithilesh Gupta 7dddc5dfa2
feat: task unread tracking (#1857)
---------

Co-authored-by: Mithilesh Gupta <guptamithilesh@protonmail.com>
Co-authored-by: kolaente <k@knt.li>
2025-11-27 15:14:42 +01:00
kolaente 9b78584734
fix(events): only trigger task.updated once when marking task done
Resolves https://github.com/go-vikunja/vikunja/issues/1724
2025-11-16 11:01:15 +01:00
Biagio00 5b42724205
fix(kanban): repeating tasks dates won't update when moved in done bucket (#1638) 2025-11-14 16:57:53 +00:00
Mithilesh Gupta 01a84dd2d5
feat: add comment count to tasks (#1771) 2025-11-11 23:00:05 +01:00
kolaente d33e742961
chore: make condition simpler 2025-10-07 10:56:03 +02:00
kolaente e5e0413b70
fix(task): ensure done_at can never be set by user (#1461) 2025-09-11 07:45:42 +00:00
kolaente db123674a7
feat: share logic for bulk update (#1456)
This change refactors the bulk task update logic so that it updates all fields a single task update would update as well.

Could be improved in the future so that it is more efficient, instead of calling the update function repeatedly. Right now, this reduces the complexity by a lot and it should be fast enough for most cases using this.

Resolves #1452
2025-09-10 16:40:59 +00:00
kolaente a81a3ee0e5
feat!: rename right to permission (#1277) 2025-08-13 11:05:05 +02:00
kolaente a8025a9e36
fix: guard invalid user lookups (#1034) 2025-06-26 21:58:47 +00:00
kolaente 53264d350e
fix(kanban): make bucket query fixed per-view (#1007) 2025-06-25 11:38:24 +00:00
Dominik Pschenitschni 296577a875
fix: correct license header references (#882)
See originals:
- https://www.gnu.org/licenses/agpl-3.0.txt
- https://www.gnu.org/licenses/gpl-3.0.txt
2025-06-10 12:18:38 +02:00
Dominik Pschenitschni 508cdf027c
fix: param type (#895) 2025-06-10 12:06:41 +02:00
Vladimir c3fffefcf4
fix(db): refactor filtering with subqueries (#701)
Resolves #285
2025-05-12 10:52:48 +02:00
renovate[bot] 4a75f7d4da
chore(deps): update golangci/golangci-lint-action action to v7 (#462)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kolaente <k@knt.li>
2025-04-02 09:28:56 +02:00
kolaente 0585045260
fix(kanban): Mark tasks done when creating them in the done bucket
Resolves https://community.vikunja.io/t/bugs-around-project-duplication-with-kanban-buckets/3433/6
2025-03-21 17:32:50 +01:00
kolaente 617070f9f7
fix(kanban): use full updated kanban bucket when moving task 2025-03-19 16:06:20 +01:00
kolaente 134c2a1a80
fix(kanban): do not allow creating tasks in full bucket 2025-03-19 15:18:55 +01:00
kolaente 5c6be117fe
fix(kanban): increase dates when moving a task into the done bucket
Resolves https://community.vikunja.io/t/unable-to-drag-a-repeating-task-to-done-bucket/3321/2
Resolves https://github.com/go-vikunja/vikunja/issues/402
2025-03-16 17:19:51 +01:00
kolaente 4e90c6bb78
chore(deps): update golangci-lint 2025-03-02 13:00:18 +01:00
kolaente 9aa197b196
fix: swagger docs 2025-01-24 14:20:07 +01:00
kolaente 6b7c3ffef3
feat(tasks): add parameter to expand comments on a task 2025-01-24 13:00:06 +01:00
kolaente e887cdeb5e
feat(task): expand reactions via parameter 2025-01-24 11:39:51 +01:00
kolaente 333e35e648
feat: add expand property to read one task 2025-01-24 11:20:23 +01:00
kolaente 7f6cb1e06e
feat: expand buckets 2025-01-24 11:03:40 +01:00
kolaente 6673adf0b5
fix(filter): do not show tasks in filter results when they are filtered out by labels
This fixes a bug where tasks which were filtered out by their label would still be shown. That was caused by the way the filter query was translated to sql under the hood.

Resolves https://github.com/go-vikunja/vikunja/issues/394
2025-01-20 14:05:42 +01:00
kolaente 1db99dba47
fix(kanban): correctly check bucket limit for saved filters or view filters
Resolves https://github.com/go-vikunja/vikunja/issues/355
2025-01-09 16:21:28 +01:00
kolaente 25fd0f6108
fix(filter): correctly create task positions during filter creation
This fixes a bug where a saved filter would contain many "dead" entries for tasks which are not part of that filter. These entries were "dead" because the filter would not match for them and thus they were not shown.
The problem was caused by a routine during the creation of the filter where all projects from all matching tasks would be used as input for fetching the tasks to add to task_positions.

https://community.vikunja.io/t/not-able-to-move-task-between-buckets-within-a-kanban-view-for-saved-filter/2882/3
2024-12-09 19:21:13 +01:00
Maximilian Bosch 3bafaa7101 fix(tasks): also delete corresponding task positions (#2840)
Closes [#348](https://github.com/go-vikunja/vikunja/issues/348)

When moving a project, the old task bucket entries (project, saved
filters) will be removed, but not the corresponding position. This has
the effect that the saved_filter event hook UpdateTaskInSavedFilterViews
wrongly assumes that the task doesn't need to be re-added to the saved
filter since the position part still exists.

Reviewed-on: https://kolaente.dev/vikunja/vikunja/pulls/2840
Co-authored-by: Maximilian Bosch <maximilian@mbosch.me>
Co-committed-by: Maximilian Bosch <maximilian@mbosch.me>
2024-11-18 16:02:05 +00:00
kolaente 57c6f2cd10
feat(filters): add "not in" operator for filters
Resolves https://community.vikunja.io/t/feature-requests-regarding-view-ordering-project-reference-in-kanban-and-a-notin-operator/2728
2024-10-29 12:03:16 +01:00
kolaente 3ad5797307
fix: do not prefix tasks all the time
Fixes a regression from 29b9001078
2024-10-21 10:32:14 +02:00
kolaente 29b9001078
feat(filters): allow filtering by created and updated task fields
Resolves https://kolaente.dev/vikunja/vikunja/issues/2768
2024-10-18 15:15:19 +02:00
kolaente c54181eeda
fix(deps): update module github.com/typesense/typesense-go to v2 2024-09-19 15:30:13 +02:00