Commit Graph

2320 Commits

Author SHA1 Message Date
Frederick [Bot]
059958b839 chore(i18n): update translations via Crowdin 2026-02-27 01:10:46 +00:00
kolaente
4cce6ed34c chore(deps): upgrade transitive minimatch from 10.2.1 to 10.2.3+ 2026-02-26 23:33:39 +01:00
kolaente
04590d959c chore(deps): upgrade transitive basic-ftp from 5.0.5 to 5.2.0
Add pnpm override to bump basic-ftp (transitive dependency via
puppeteer/get-uri) from 5.0.5 to 5.2.0.
2026-02-26 23:16:01 +01:00
kolaente
f2a4a40e28 chore(deps): override transitive rollup 2.x to use direct dependency version
Add pnpm override to force all transitive rollup dependencies to use
the direct dependency version (4.59.0), eliminating the old 2.79.2
pulled in by workbox-build.
2026-02-26 23:16:00 +01:00
renovate[bot]
a76ba87939 chore(deps): update dev-dependencies 2026-02-26 22:54:58 +01:00
kolaente
838254bb51 feat(multiselect): add green plus icon and always-visible hint to create option
Make the "create new" option in multiselect dropdowns visually distinct
from regular search results by adding a green plus icon and making the
hint text always visible instead of only on hover.
2026-02-26 17:37:11 +01:00
kolaente
c4ec7f032f feat(checklist): show green progress circle when all checkboxes are done 2026-02-26 17:07:03 +01:00
kolaente
80759831ec fix(editor): use overflow-wrap instead of word-break for text wrapping
word-break: break-all breaks text at any character, causing mid-word
breaks even when the word could fit on the next line. overflow-wrap:
break-word wraps at word boundaries first and only breaks mid-word
when a single word exceeds the container width.
2026-02-26 16:30:55 +01:00
renovate[bot]
b6205bb809 chore(deps): update dependency autoprefixer to v10.4.26 2026-02-25 20:30:07 +01:00
renovate[bot]
89c9209de4 chore(deps): update dependency stylelint to v17.4.0 2026-02-25 15:23:20 +01:00
kolaente
a11d705571 feat(frontend): use Password component in password update settings
Replace FormField with Password component for new password input:
- Provides real-time validation feedback (8-72 char requirement)
- Remove redundant password confirmation field
- Disable save button when form is invalid (validation errors or empty fields)
2026-02-25 13:44:56 +01:00
kolaente
111ac9c726 fix: prevent XSS via innerHTML injection in link edit prompt
Replace innerHTML with DOM API calls in inputPrompt.ts. The oldValue
parameter (sourced from a link's href attribute in the TipTap editor)
was interpolated directly into an HTML string, allowing stored XSS if
an attacker crafted a malicious href. Using document.createElement and
setting .value as a property ensures the value is never parsed as HTML.
2026-02-25 12:01:57 +01:00
kolaente
a42b4f37bd fix: prevent reflected HTML injection via filter URL parameter
TipTap's setContent() parses strings as HTML via DOMParser, allowing
crafted ?filter= URL parameters to inject SVG phishing buttons, anchor
tags, and formatted content into the trusted UI.

Use ProseMirror JSON document format instead of raw strings so the
filter value is always set as a text node, bypassing HTML parsing
entirely.
2026-02-25 12:01:57 +01:00
kolaente
cb091f981d test: add e2e tests for session refresh and retry interceptor
- Verifies transparent retry and JWT rotation on 401 with code 11
- Verifies no retry for 401 with non-JWT error code
- Verifies current session appears on sessions settings page
- Increases rate limit for e2e test API to prevent 429 errors
2026-02-25 10:30:25 +01:00
kolaente
be1db018fe feat: add frontend session management with refresh tokens
- Session model, type interface, and API service
- Sessions settings page showing active sessions with device info,
  IP address, last active time, and current session indicator
- Auth store updated to use cookie-based refresh tokens for user
  sessions and JWT-based renewal for link shares
- refreshToken() uses Web Locks API to coordinate across browser
  tabs — only one tab performs the refresh, others adopt the result
- 401 response interceptor with automatic retry: detects expired JWT
  (error code 11), refreshes the token, and replays the request
- Interceptor gated to user JWTs only (link shares skip refresh)
- checkAuth() attempts cookie refresh when JWT is expired, allowing
  seamless session resumption after short TTL expiry
- Proactive token refresh on page focus/visibility via composable
- renewToken() tolerates refresh failures when JWT is still valid
2026-02-25 10:30:25 +01:00
kolaente
94edaefced chore(deps): update ajv to 6.14.0 2026-02-24 21:52:28 +01:00
kolaente
4325eae4d4 fix(tasks): show drag handle icon on mobile devices (#2286)
Resolves https://github.com/go-vikunja/vikunja/issues/2228
2026-02-24 14:37:33 +01:00
kolaente
7c04d44e2e fix: wait for router before dismissing loading screen
The loading screen was dismissed as soon as auth check completed, but
before Vue Router's initial navigation finished. This caused route.name
to be undefined momentarily, making showAuthLayout evaluate to false
and briefly flashing the NoAuthWrapper (login shell) before the
authenticated layout appeared.

Wait for router.isReady() before setting ready = true so the loading
screen stays visible until the route is fully resolved.
2026-02-24 13:13:30 +01:00
kolaente
f7a93e4ca3 fix: prevent cursor reset when typing in filter input (#2287)
Fixes #2268
2026-02-24 11:50:45 +00:00
kolaente
9e633b3e82 fix(task): disable Confirm button when no date is selected in absolute reminder picker
Prevents emitting a reminder with reminder=null/relativeTo=null when
the user clicks Confirm without selecting a date first.

Refs #2208
2026-02-24 11:57:39 +01:00
kolaente
5dcea199d2 fix(test): update existing reminder tests to click Confirm after date selection
The DatepickerInline quick-select buttons (Tomorrow, etc.) inside the
reminder popup no longer auto-save. Update existing tests to click
Confirm after selecting a date.

Refs #2208
2026-02-24 11:57:39 +01:00
kolaente
f6a35416e5 test(task): add e2e tests for reminder confirm-before-save behavior
- Test that clicking a date in the absolute reminder picker does not
  auto-save, only saves when Confirm is clicked
- Test that the Confirm button is visible when task has no due date
  (defaultRelativeTo is null)

Refs #2208
2026-02-24 11:57:39 +01:00
kolaente
b65773eb8f fix(task): require explicit confirmation before saving reminders
Prevent reminders from being saved to the API until the user clicks
Confirm, matching the behavior of the due/start/end date pickers.

- Remove @update:modelValue handler on DatepickerInline so date/time
  changes only update local state
- Change Confirm button condition from showFormSwitch to activeForm so
  it renders even when defaultRelativeTo is null
- Add confirmAndClose function that handles both absolute and relative
  reminder forms
- Remove debounce (useDebounceFn) since saves are now user-initiated

Refs #2208
2026-02-24 11:57:39 +01:00
kolaente
56eb5d3740 fix: show tasks spanning entire gantt date range
Tasks whose start date is before and end date is after the visible
gantt range were not shown because the API filter only checked whether
individual date fields fell within the range. Add a fourth filter
clause to match tasks that fully encompass the visible date range.

Fixes go-vikunja/vikunja#2269
2026-02-24 11:51:13 +01:00
kolaente
a13ecbd3cc fix: prevent browser from caching API responses
Without explicit Cache-Control headers, browsers may heuristically cache
API JSON responses. This causes stale data to be served on normal page
refresh (F5) — for example, projects newly shared with a team not
appearing until the user performs a hard refresh (Ctrl+Shift+R).

Add Cache-Control: no-store to all API responses via middleware and
configure the service worker's NetworkOnly strategy to explicitly bypass
the browser HTTP cache for API requests.

Ref: https://community.vikunja.io/t/team-members-cannot-see-project/1876
2026-02-24 10:37:49 +01:00
Frederick [Bot]
19ccc3cb8e chore(i18n): update translations via Crowdin 2026-02-24 01:13:27 +00:00
renovate[bot]
f362738e33 chore(deps): update dev-dependencies to v8.56.1 2026-02-23 20:50:07 +01:00
renovate[bot]
524d8f522d chore(deps): update dependency caniuse-lite to v1.0.30001774 2026-02-23 10:24:42 +01:00
renovate[bot]
5ff1596314 chore(deps): update dev-dependencies 2026-02-23 10:14:21 +01:00
renovate[bot]
4babc477ef chore(deps): update dev-dependencies 2026-02-21 23:12:36 +01:00
kolaente
4cee2cf128 fix: reset throttle on logout so checkAuth clears auth state
logout() calls checkAuth() to clear the authenticated flag and user
info. But since checkAuth() likely ran within the last minute (on the
navigation that triggered logout), the now-working throttle would
return early, leaving authenticated=true in the store despite the
token being removed. This could cause Login.vue to redirect back
to home.

Resetting lastUserInfoRefresh to null before checkAuth() ensures
the logout flow always runs fully.
2026-02-21 23:08:24 +01:00
kolaente
65806df605 fix: keep token expiry in sync when skipping setUser from JWT
When the setUser call is skipped for an already-loaded user,
info.value.exp was never updated with the renewed token's expiry.
This caused useRenewTokenOnFocus to compute a stale expiresIn,
eventually forcing a logout even though the token was still valid.

Now we always update exp from the JWT, even when skipping the
full setUser call.
2026-02-21 23:08:24 +01:00
kolaente
1d420dd1dc fix: don't overwrite user info with incomplete JWT data on navigation
The JWT token only contains id, username, type, and exp — not the
display name. Previously, every route navigation called setUser() with
this incomplete data, causing the display name to flash to the username
before the API call completed and restored the full name.

Now we skip setUser() if a complete user object with the same ID is
already loaded.

Fixes https://github.com/go-vikunja/vikunja/issues/2270
2026-02-21 23:08:24 +01:00
kolaente
a11cde1afc fix: correct broken throttle in checkAuth that never triggered
The throttle checked `lastUserInfoRefresh > now + 1 minute` which is
never true since lastUserInfoRefresh is set to the current time.
Changed to `now - 1 minute` so the check actually prevents redundant
API calls within a one-minute window.
2026-02-21 23:08:24 +01:00
kolaente
1dc625f9e8 test: add unit tests for getDisplayName 2026-02-21 23:08:24 +01:00
kolaente
6a4401eb7c feat(frontend): make dev server port configurable via VIKUNJA_FRONTEND_PORT env var 2026-02-21 22:32:09 +01:00
Frederick [Bot]
05ff67b681 chore(i18n): update translations via Crowdin 2026-02-21 01:09:54 +00:00
Massimo Nadalin
8fd256a5d9 feat: clickable task notifications (#2258)
Make task-related notifications clickable, allowing users to directly
open the corresponding task.
2026-02-20 22:34:53 +00:00
renovate[bot]
d00bb999b5 chore(deps): update dev-dependencies 2026-02-20 22:44:24 +01:00
renovate[bot]
1c8b9e8810 chore(deps): update dependency rollup-plugin-visualizer to v6.0.8 2026-02-20 11:32:32 +01:00
Frederick [Bot]
a8d3594ceb chore(i18n): update translations via Crowdin 2026-02-20 01:12:20 +00:00
kolaente
bc2f7e5840 fix: break long continuous strings in editor to prevent overflow
Fixes https://github.com/go-vikunja/vikunja/issues/2266
2026-02-19 16:11:43 +01:00
kolaente
df05c51457 fix: clamp gantt bar title position when task starts before visible range
Resolves go-vikunja/vikunja#149
2026-02-19 16:08:52 +01:00
kolaente
7862651b12 fix: don't show export ready message when no export exists
The API returns an empty object {} with 200 status when no export
exists. This truthy value was being set as exportInfo, causing the
"ready for download" message and button to render with a blank date.
2026-02-19 16:01:32 +01:00
William Guinaudie
bf8138ec3c feat: add discard and reload confirmation modal (#2154) 2026-02-19 14:27:27 +01:00
kolaente
8144560dd7 test(comments): add e2e tests for comment sort order
Cover default order, toggle to newest-first, new comment insertion
position, scroll-into-view behaviour, pagination with sort order,
initial-load shortcut, setting persistence across reloads, and
pre-saved setting on page load.
2026-02-19 14:20:52 +01:00
kolaente
6555595a5c feat(comments): add sort order toggle for task comments
Allow users to switch between oldest-first and newest-first comment
ordering via a toggle button in the comments heading. The preference is
persisted as a frontend setting (commentSortOrder) and passed to the API
as the order_by query parameter so pagination works correctly.

When all comments fit on a single page, toggling reverses them
client-side to avoid an extra API call. New comments are inserted at the
correct position based on the active sort order, and in newest-first
mode the view scrolls to the top after adding a comment.

Link-share users fall back to a local (non-persisted) sort order since
they cannot save user settings.
2026-02-19 14:20:52 +01:00
kolaente
b64926be73 chore(deps): update minimatch to ^10.2.1 via pnpm overrides
Add pnpm overrides in frontend and desktop to consolidate all
transitive minimatch versions (3.1.2, 5.1.6, 9.0.1, 9.0.5, 10.1.1)
to 10.2.1, resolving the known ReDoS vulnerability in older versions.
2026-02-19 14:20:29 +01:00
renovate[bot]
37a013c472 chore(deps): update dev-dependencies 2026-02-19 13:08:14 +01:00
kolaente
50d7458519 feat(attachments): open file picker directly from sidebar button
Clicking the sidebar "Attachments" button (or pressing `f`) now opens
the browser file picker directly, eliminating the redundant two-step
flow of first revealing the section and then clicking upload.
2026-02-19 12:56:46 +01:00