Commit Graph

13263 Commits

Author SHA1 Message Date
kolaente
f60f3af70b test: add failing test for project background delete with read-only access
Proves that a user with read-only access to a project can delete its
background image. The test expects a 403 Forbidden but the operation
proceeds because RemoveProjectBackground only checks CanRead.

Adds fixture entry giving user 15 read-only access to project 35
(which has a background_file_id).

Ref: GHSA-564f-wx8x-878h
2026-03-20 11:41:28 +00:00
kolaente
bc6d843ed4 fix: verify comment belongs to task in URL to prevent IDOR
Add task_id check to getTaskCommentSimple so that a comment can only
be loaded if it actually belongs to the task specified in the URL.
Previously, any valid comment ID could be read through any accessible
task endpoint.

Ref: GHSA-mr3j-p26x-72x4
2026-03-20 11:41:28 +00:00
kolaente
2da89258e5 test: add failing test for task comment IDOR
Proves that a user can read a comment from an inaccessible task by
supplying an accessible task ID in the URL. Comment 18 belongs to
task 34 (owned by user 13), but testuser1 can read it via task 1.

Ref: GHSA-mr3j-p26x-72x4
2026-03-20 11:41:28 +00:00
kolaente
be0aaa7060 fix: adapt image preview DoS protection to new FileStorage interface
File.File is now io.ReadCloser (no Seek). Buffer the file bytes
once via io.ReadAll, then use bytes.NewReader for both DecodeConfig
and Decode. Test updated to use io.NopCloser instead of afero.
2026-03-20 11:34:41 +00:00
kolaente
af61d0f1a0 fix: reject images exceeding 50M pixels before decode 2026-03-20 11:34:41 +00:00
kolaente
f7592e2cfd test: add failing test for image preview with oversized dimensions 2026-03-20 11:34:41 +00:00
kolaente
82c24a826a fix(desktop): block same-window navigation to external origins 2026-03-20 11:30:09 +00:00
kolaente
b9d4d5e4ac fix(desktop): validate URL schemes before shell.openExternal 2026-03-20 11:30:09 +00:00
kolaente
23de2197fd fix(desktop): disable nodeIntegration and enable contextIsolation/sandbox 2026-03-20 11:30:09 +00:00
kolaente
89923ebe70 fix: update test expectations for new disabled user fixture
- TestListUsers expects 17 users (was 16)
- TestCleanupOldTokens expects 3 old tokens deleted (was 2)
2026-03-20 11:23:21 +00:00
kolaente
049f4a6be4 fix: prevent email confirmation from re-enabling admin-disabled accounts 2026-03-20 11:23:21 +00:00
kolaente
2260d763b5 test: add web test for disabled user password reset rejection 2026-03-20 11:23:21 +00:00
kolaente
241b0e80b6 test: add tests for disabled user password reset prevention 2026-03-20 11:23:21 +00:00
kolaente
708ccab895 fix: reject password reset token requests for disabled users 2026-03-20 11:23:21 +00:00
kolaente
d8570c603d fix: prevent password reset from re-enabling admin-disabled accounts 2026-03-20 11:23:21 +00:00
kolaente
4c80932b64 fix: block login for StatusAccountLocked users 2026-03-20 11:23:21 +00:00
kolaente
7792bf6cea refactor: use StatusAccountLocked for TOTP lockouts 2026-03-20 11:23:21 +00:00
kolaente
f42a045bdc feat: add StatusAccountLocked user status for TOTP lockouts 2026-03-20 11:23:21 +00:00
kolaente
ddd9ef5f22 style: fix alignment in config key declarations 2026-03-20 11:08:00 +00:00
kolaente
015a172c2a docs: document IP extraction and trusted proxy config options 2026-03-20 11:08:00 +00:00
kolaente
a498dd6991 fix: configure Echo IPExtractor to prevent rate limit bypass via spoofed headers 2026-03-20 11:08:00 +00:00
kolaente
26324a740a feat: add service.ipextractionmethod and service.trustedproxies config options 2026-03-20 11:08:00 +00:00
kolaente
763d25ca18 feat(ci): enable merge queue trigger 2026-03-20 11:53:08 +01:00
kolaente
17eccd848f test: add FileStat assertion to validate storage path in attachment test 2026-03-20 10:59:44 +01:00
kolaente
4cd63f93a4 fix: use file mime type instead of hardcoded application/zip in S3 export 2026-03-20 10:59:44 +01:00
kolaente
0e1f44e57e refactor: replace afero with FileStorage interface
Replace the github.com/spf13/afero dependency with a purpose-built
FileStorage interface (Open, Write, Stat, Remove, MkdirAll) with three
implementations: localStorage (with basePath), s3Storage (with key
prefix), and memStorage (for tests).

Each implementation owns its base path — callers pass only file IDs.
Delete s3fs.go, change File.File from afero.File to io.ReadCloser,
and fix duplication flows to buffer content for seeking.
2026-03-20 10:59:44 +01:00
maggch
b0ede53c05 fix: handle S3 backend in user export download
http.ServeContent requires io.ReadSeeker which S3 files don't support.
Add S3 branch using io.Copy with explicit headers, matching the pattern
already used in task attachment downloads.

Refs: #2347

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-20 10:59:44 +01:00
maggch
b065c62007 feat: replace afero-s3 with minimal S3 afero.Fs implementation
Replace the third-party afero-s3 library (and its temporary fork) with
a minimal in-tree afero.Fs implementation (~200 lines) that only supports
the three S3 operations Vikunja actually uses: Open (GetObject), Remove
(DeleteObject), and Stat (HeadObject).

The s3File implementation lazily opens a GetObject stream on first Read
and supports Seek by closing and re-opening the stream from the new offset,
matching the behavior of the fixed afero-s3 fork.

All other afero.Fs/File methods return ErrS3NotSupported since they are
never called in the S3 code path (writes already use direct PutObject).

This removes the fclairamb/afero-s3 dependency and the temporary replace
directive in go.mod entirely.

Closes #2347

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-20 10:59:44 +01:00
kolaente
c81b0eb463 fix(attachments): sync kanban store and task ref on attachment changes
When attachments are uploaded (either via file picker or pasting into
the description editor), update both the local task ref and the kanban
store so that the attachment list and kanban card icons stay in sync.
2026-03-20 10:38:47 +01:00
kolaente
ade91c92db refactor(attachments): remove global attachment store
The attachment store was a global singleton shared between concurrent
TaskDetailView instances, causing a race condition when navigating
between tasks via related tasks from the Kanban view. Attachments
now live on the task ref like every other task field.
2026-03-20 10:38:47 +01:00
kolaente
2675bcb56c refactor(attachments): use local state instead of global attachment store
TaskDetailView now computes hasAttachments from the task ref and
handles the update:attachments emit from the Attachments component.
2026-03-20 10:38:47 +01:00
kolaente
eaec206301 refactor(attachments): return uploaded attachments instead of writing to store
uploadFiles now returns the array of uploaded IAttachment objects
so callers can handle state updates themselves.
2026-03-20 10:38:47 +01:00
kolaente
5dbc906d47 refactor(attachments): read from task prop instead of global store
The Attachments component now reads attachments from its task prop
and emits update:attachments events instead of using the global
attachment store singleton.
2026-03-20 10:38:47 +01:00
Henry Cole
e7f1e99878 fix(caldav): use /dav/projects/ as home to make iOS/MacOS reminders work (#2417)
Resolves issue #475 by modifying CalDAV discovery so Apple Reminders can
use /dav/projects/ as the home set without exposing that synthetic path
as a real task list, preserving the existing principal-based flow. This
is because Apple Reminders defaults back to the /dav/projects/ URL,
rather than accepting the /dav/principals/username/ URL specified in
Vikunja.

Resolves #475
2026-03-20 09:33:56 +00:00
renovate[bot]
9c3fa8e91b chore(deps): update dependency stylelint to v17.5.0 2026-03-20 10:17:24 +01:00
Frederick [Bot]
de1d5d1241 chore(i18n): update translations via Crowdin 2026-03-20 01:14:18 +00:00
kolaente
629b6d447c test(webhooks): allow non-routable IPs in E2E tests
E2E tests use httptest.NewServer bound to 127.0.0.1, which is now
blocked by default SSRF protection. Opt in to non-routable IPs.
2026-03-19 15:18:06 +01:00
kolaente
8d9bc3e65e feat(webhooks): add built-in SSRF protection using daenney/ssrf
Block webhook requests to non-globally-routable IP addresses by default.
Uses net.Dialer.Control hook to validate resolved IPs against IANA
Special Purpose Registries after DNS resolution, preventing DNS rebinding.

Configurable via webhooks.allownonroutableips (default: false).
2026-03-19 15:18:06 +01:00
kolaente
d5dbf04bd0 test(webhooks): add SSRF protection tests 2026-03-19 15:18:06 +01:00
kolaente
37fdd088d6 feat(config): add webhooks.allownonroutableips setting 2026-03-19 15:18:06 +01:00
kolaente
0ce3d0374d feat(deps): add daenney/ssrf for webhook SSRF protection 2026-03-19 15:18:06 +01:00
kolaente
c62b7e680f fix: ensure frontend dist directory exists for lint and fmt commands
Extract ensureFrontendDistExists() from Build.Build and add it as a
dependency to Fmt, lint, and lint:fix so they no longer fail when the
frontend dist folder is missing.
2026-03-19 12:56:11 +01:00
kolaente
e74265d921 fix: make mage fmt skip gitignored files
Use git ls-files instead of filepath.Walk to collect Go files,
so that gitignored files are no longer formatted.
2026-03-19 12:31:55 +01:00
kolaente
3bc0093686 fix: invalidate all sessions when enabling TOTP
When a user enables two factor authentication, all existing sessions are
now invalidated, requiring re-authentication. This prevents pre-existing
sessions from bypassing 2FA. The frontend now shows a notice explaining
the logout before the user confirms, and properly logs out after enabling.

Ref: GHSA-pgc7-cmvg-mvp4
2026-03-19 12:27:44 +01:00
Frederick [Bot]
369b456d64 [skip ci] Updated swagger docs 2026-03-19 09:26:05 +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
Weijie Zhao
7b6b432301 fix: collapse view buttons into dropdown when overflowing (#2306) 2026-03-19 00:09:29 +01:00
renovate[bot]
aed93b9389 chore(deps): update dev-dependencies to v4.2.2 2026-03-18 17:57:57 +01:00
kolaente
8868b214ca docs: document database.schema config option for PostgreSQL
The database.schema setting was missing from config-raw.json, making it
undiscoverable for users who need to set it when their PostgreSQL tables
live in a non-public schema (e.g. via the database user's search_path).

Refs go-vikunja/vikunja#2397
2026-03-18 16:38:10 +01:00
renovate[bot]
4442a9ca92 chore(deps): update dependency electron to v40.8.3 2026-03-18 16:36:37 +01:00