Commit Graph

13877 Commits

Author SHA1 Message Date
kolaente
8f920c2db0 test(models): cover v2 API token route collection and verbs
Adds unit coverage for isV2Path, stripAPIVersion, getRouteDetail's
v2 verb mapping (POST->create, PUT->update, GET list/one,
DELETE->delete), and the v2 shadow-table write path.

Also caught a latent bug: AutoPatch synthesises a PATCH counterpart
for every PUT route in /api/v2, and both map to the 'update'
permission. The PATCH write clobbered the PUT write (last-write-wins
on the map), which would have silently broken PUT-with-API-token.
Fixed by skipping PATCH during collection — PUT remains the
authoritative update verb for tokens. JWT clients keep PATCH (it's
not gated on this table).
2026-05-07 11:40:55 +02:00
kolaente
9c2411cc42 refactor(models): dedupe v1/v2 API-token route collection
Pick the target registry map (apiTokenRoutes vs apiTokenRoutesV2)
once based on the route path and use it throughout the collection
function, rather than having a parallel collectV2Route that
duplicates only the CRUD branch and silently drops the non-CRUD /
attachment / bulk / notifications paths. Future v2 resources now
get the same routing logic v1 has had.
2026-05-07 11:40:55 +02:00
kolaente
a4ac8b2a15 fix(models): make API tokens work on /api/v2 routes
Sub-phase G validation caught that a token scoped to e.g.
`labels.read_one` was rejected on /api/v2/labels because the route
collector only stripped /api/v1/ from paths and did not know about
v2's REST-style verbs (POST create, PUT/PATCH update, inverted
from v1 where PUT creates and POST updates).

Introduce a shadow apiTokenRoutesV2 map keyed under the same
(group, permission) names as the v1 entries. Route collection now
routes v2 paths into this shadow map and CanDoAPIRoute consults
both tables, so the same permission bit authorizes the v1 and v2
endpoints for the same resource without changing the data shape
served at /api/v1/routes (which the frontend token UI depends on).

Also teach getRouteDetail about PATCH so Huma's AutoPatch-synthesized
PATCH routes collapse to the `update` permission instead of being
dropped.
2026-05-07 11:40:55 +02:00
kolaente
ce9adbacb2 refactor(auth): drop redundant note on GetAuthFromContext test 2026-05-07 11:36:49 +02:00
kolaente
dd3e7017e8 chore: add AGPL license headers and gofmt alignment to new files 2026-05-07 11:36:49 +02:00
kolaente
05215ef354 feat(auth): add GetAuthFromContext for Huma handlers 2026-05-07 11:36:34 +02:00
kolaente
a7e2a0e7c0 fix: set vikunja version 2026-05-07 11:35:36 +02:00
kolaente
2eb1fb4d41 chore(deps): add huma/v2 and align transitive deps
Promotes huma/v2 to a direct dep (now imported by pkg/routes/api/v2 and
pkg/modules/humaecho5) and bumps clipperhouse/displaywidth to v0.11.0,
which is required for compatibility with uax29/v2 v2.7.0 that huma pulls
in. Other version bumps are go-mod-tidy consequences of MVS.
2026-05-07 11:33:55 +02:00
kolaente
d665de34d8 fix(api/v2): align NewAPI with humaecho5 4-arg NewWithGroup
The vendored humaecho5 already takes a groupPrefix string for autopatch
dispatch rewriting; pass GroupPrefix instead of dropping the arg.
2026-05-07 11:29:25 +02:00
kolaente
314922dda4 feat(routes): wire Huma API under /api/v2 2026-05-07 11:26:47 +02:00
kolaente
21d4db2434 feat(routes): scaffold /api/v2 Echo group 2026-05-07 11:26:47 +02:00
kolaente
f4ccd79810 docs(humaecho5): explain vendoring and upstream PR #959 2026-05-07 11:22:15 +02:00
kolaente
d34864241c test: humaecho5 adapter roundtrip and spec serving 2026-05-07 11:22:01 +02:00
kolaente
e6d7b9d5d5 feat: vendor humaecho adapter for echo/v5 2026-05-07 11:22:01 +02:00
renovate[bot]
812fa11b9b chore(deps): update dependency vite to v7.3.3 2026-05-07 07:38:48 +00:00
MidoriKurage
beaf4e9e65 fix(static): Correct the API_URL value to replace in index.html 2026-05-06 16:31:48 +00:00
kolaente
7800102f93 fix(models): allow user-delete cascade to complete for disabled creators
TaskAttachment.ReadOne now swallows ErrAccountDisabled/ErrAccountLocked
from the creator lookup, matching the existing ErrUserDoesNotExist
swallow. Without this, deleting a disabled user that owned a project
with task attachments would fail when the cascade re-loaded the
attachment to delete it.
2026-05-06 16:08:16 +02:00
dependabot[bot]
fc9a9a6c71 chore(deps): bump axios from 1.15.0 to 1.15.2 in /frontend
Bumps [axios](https://github.com/axios/axios) from 1.15.0 to 1.15.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.15.0...v1.15.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.15.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-06 12:37:48 +00:00
renovate[bot]
4754230ef0 chore(deps): update dev-dependencies 2026-05-06 12:37:26 +00:00
kolaente
3d594db725 fix(frontend): scope checkbox hit-area pseudo to the task row
The pseudo-element that extends the checkbox hit target also covered
label text content, which broke Playwright actionability checks for
clicks on text inside wider FancyCheckbox labels (e.g. the "Show
Archived" toggle on the projects list page).

Move the rule out of BaseCheckbox and into SingleTaskInProject's deep
override, where the label slot is already hidden via display: none, so
no neighboring content can be intercepted.
2026-05-05 15:42:10 +00:00
kolaente
9bea92bb6f fix(frontend): skip task detail on label and checkbox clicks
Defense in depth for the list-view row click handler: a click that
lands on a label or checkbox input no longer bubbles up to open the
task detail.
2026-05-05 15:42:10 +00:00
kolaente
1ea5675e1b fix(frontend): extend checkbox hit target to 44x44
A pseudo-element on the label provides a 44x44 minimum hit area
centered on the visible icon. Visible size and surrounding layout
are unchanged. Addresses misclicks on the task list view checkbox
where ~50% of taps would open the task detail instead of toggling
done.
2026-05-05 15:42:10 +00:00
kolaente
469ee8f364 fix(frontend): respect user's 12h/24h time format in date pickers
The flatpickr time inputs hardcoded `time_24hr: true`, so users who
selected the 12-hour format in their settings still got a 24-hour
picker — even though the displayed dates respected the preference.

Bind `time_24hr` to the existing `useTimeFormat` composable in:
- DatepickerInline (start/end/due dates and absolute reminders)
- DeferTask (defer due date)
- ApiTokenForm (API token expiry)

Reported at https://community.vikunja.io/t/4492.
2026-05-05 14:47:24 +00:00
kolaente
926e163089 chore(deps): bump workbox-precaching to 7.4.1 to match workbox-cli 2026-05-05 08:31:42 +00:00
renovate[bot]
7ed0e3ecd6 chore(deps): update dev-dependencies 2026-05-05 08:31:42 +00:00
Frederick [Bot]
65a6fc7b4b chore(i18n): update translations via Crowdin 2026-05-05 01:57:03 +00:00
kolaente
459dbe71ca Improve modal responsive sizing with inline-size constraints (#2716) 2026-05-04 15:33:59 +02:00
Frederick [Bot]
6a604dd949 [skip ci] Updated swagger docs 2026-05-04 11:19:21 +00:00
renovate[bot]
55e96018f3 chore(deps): update dev-dependencies 2026-05-04 10:55:46 +00:00
Claude
d9a5958bb8 feat: always enable bot users
Removes the `service.enablebotusers` config flag, the matching
`bot_users_enabled` field on /info, and the now-unused
`ErrBotUsersDisabled` error. Bot user routes and the frontend
settings tab are now always available.

https://claude.ai/code/session_01VhAR6xnoCdG1fpX52bzaCC
2026-05-04 10:38:53 +00:00
renovate[bot]
0f1bf6fab2 chore(deps): update dev-dependencies 2026-05-04 10:21:25 +00:00
Frederick [Bot]
935c950942 chore(i18n): update translations via Crowdin 2026-05-04 01:56:28 +00:00
Frederick [Bot]
0adf85dc2d [skip ci] Updated swagger docs 2026-05-01 15:01:51 +00:00
kolaente
22d82e292b feat(user): always include own bots in user search
User search previously filtered bots only when they happened to match the
search string. That produced two bad behaviours:

1. Bots owned by other users could surface on an exact-username match,
   leaking them into assignee pickers and similar UI.
2. A user could not reliably find their own bots by typing a partial
   name, so bots became awkward to assign to tasks.

Change ListUsers to treat bot ownership explicitly: the existing match
branch excludes rows owned by someone else, and a second branch always
returns bots owned by the calling user. The own-bots branch also
respects any AdditionalCond passed in so project-scoped listings don't
start leaking bots from outside the project.
2026-05-01 14:44:10 +00:00
kolaente
999e28435e feat(avatar): use distinct marble palette for bot users
Bot users now render with a cool-toned (blue/cyan/violet/teal/indigo)
marble variant so they're visually distinguishable from human users.
Marble's rendering logic is parameterized with a palette; the route
forces the bot palette whenever the resolved user is a bot, overriding
whatever avatar provider they'd otherwise inherit.
2026-05-01 14:44:10 +00:00
kolaente
d467a06e72 feat(frontend): add bot settings page and services 2026-05-01 14:44:10 +00:00
kolaente
c4e5f55b6d feat(frontend): add bot user model support and badge 2026-05-01 14:44:10 +00:00
kolaente
05acc2b660 feat(api): bot token support via /tokens CRUD and bot_users_enabled flag 2026-05-01 14:44:10 +00:00
kolaente
3415981d1c feat(models): add BotUser CRUD wrapper 2026-05-01 14:44:10 +00:00
kolaente
74af7af2e3 refactor(api_tokens): preserve pre-set OwnerID in Create 2026-05-01 14:44:10 +00:00
kolaente
2e6bcec72a feat(caldav): reject basic auth for bot users 2026-05-01 14:44:10 +00:00
kolaente
8d3ac47605 feat(auth): reject password login for bot users 2026-05-01 14:44:10 +00:00
kolaente
1637ecd0c7 feat(user): add CreateBotUser 2026-05-01 14:44:10 +00:00
kolaente
506bfa2549 feat(user): reserve bot- username prefix for regular signup 2026-05-01 14:44:10 +00:00
kolaente
a262c6a848 feat(user): add bot-related error types 2026-05-01 14:44:10 +00:00
kolaente
c239834070 feat(migration): add bot_owner_id column to users 2026-05-01 14:44:10 +00:00
kolaente
83c5190c9b feat(user): add BotOwnerID field and IsBot helper 2026-05-01 14:44:10 +00:00
kolaente
4c3f0231e9 feat(config): add service.enablebotusers flag 2026-05-01 14:44:10 +00:00
kolaente
3d75ca049b fix(auth): don't panic on /token/test with API token
The JWT skipper bypassed validation entirely for /token/test when the
bearer was an API token, leaving "user" unset in the context. CheckToken
then type-asserted it to *jwt.Token and panicked.

Validate the API token in the skipper but skip the route permission
check (since /token/test is not exposed in the API token route registry,
no token can hold explicit permission for it). Drop the now-redundant
JWT assertion in CheckToken — auth has already passed by the time the
handler runs.
2026-05-01 11:13:12 +02:00
Claude
01fff665c6 fix(frontend): focus quick actions input after modal opens
The Modal mounts the <dialog> via v-if and calls showModal() in a
follow-up flush, so v-focus runs while the dialog is still closed and
its focus() call is dropped. The existing rAF retry was gated on
quick-add mode, leaving Ctrl+K in the regular app with no focused
input. Run the retry whenever the quick actions become active and keep
the command pre-selection scoped to quick-add mode.
2026-04-30 14:06:07 +00:00