Commit Graph

2308 Commits

Author SHA1 Message Date
kolaente 6fc36cb700 feat(comments): treat quoted comment authors as implicit mentions
A comment whose body contains <blockquote data-comment-id="…"> nodes
now triggers the same task-comment mention notification for the
quoted comments' authors, respecting CanRead, subscription, and
existing dedup. Self-quotes, wrong-task quotes, and malformed ids
are silently skipped.
2026-05-20 21:02:14 +00:00
Tink bot a1f81524ab feat(i18n): make Greek available in the language selector
el-GR translations are around 36% complete but were not yet listed in the
UI. Add it to the supported locales list (frontend and backend) and wire
up the dayjs locale mapping.
2026-05-20 20:25:17 +00:00
Frederick [Bot] 2fca6a46e5 [skip ci] Updated swagger docs 2026-05-19 09:43:17 +00:00
Tink bot fa6e1f8e49 fix(migration): reuse existing labels on re-import
Seed the dedup map at the start of insertFromStructure with the importing
user's existing labels, keyed by title + normalized hex color. Previously
the map was empty on each run, so importing the same CSV (or any other
migration format) twice would create a second copy of every label.

Scoped to the user's own labels so imports don't silently link to other
users' labels visible via shared projects.

Fixes #2742
2026-05-19 09:09:59 +00:00
Tink bot 15badb382a test(api): cover positive project-identifier resolution
Adds back the by-identifier and case-insensitive-input cases now that
project identifiers are stored uppercase across the codebase.
2026-05-19 08:53:25 +00:00
Tink bot c6fa7991d6 fix(api): uppercase project identifier before by-index lookup
Switches the input normalisation from lower- to uppercase so identifiers
canonicalise the same way GitHub-style refs do (e.g. "PROJ-42"). The
positive identifier tests are dropped for now because the existing
fixtures store identifiers as lowercase ("test1") and the SQL comparison
remains case-sensitive — once the column-side case-insensitive match
lands, full coverage can be reinstated.
2026-05-19 08:53:25 +00:00
Tink bot 04148e14db feat(api): lowercase project identifier before by-index lookup
Normalises the input side so GitHub-style references like "TEST1-42" and
"test1-42" resolve to the same project. The SQL comparison itself remains
case-sensitive for now; case-insensitive matching on the column will be
addressed separately.
2026-05-19 08:53:25 +00:00
Tink bot 466d39e6de feat(api): accept project identifier in by-index task route
Allows GET /projects/{project}/tasks/by-index/{index} to resolve {project}
as either a numeric id or a project identifier (e.g. "PROJ"), so callers
can build GitHub-style task references like "PROJ-42" without first
looking up the project's numeric id. Pure-digit values remain interpreted
as ids, which makes identifiers consisting solely of digits unreachable
via this route.
2026-05-19 08:53:25 +00:00
kolaente 21ce33f8fd
feat(projects): always store identifiers as uppercase (#2775) 2026-05-19 10:35:43 +02:00
Frederick [Bot] c761ab9761 chore(i18n): update translations via Crowdin 2026-05-19 02:26:35 +00:00
Tink bot fee2d2ea58 fix(notifications): skip logo attachment for conversational mails
The conversational mail template does not reference cid:logo.png, but
RenderMail still attached the embedded logo to every outgoing mail.
That left an orphan inline part that some clients render as a stray
attachment. Only embed logo.png when the formal template is in use.
2026-05-18 19:06:49 +00:00
Tink bot 6b14307896 test(trello): drop redundant BackgroundImage assignment in getTestBoard 2026-05-15 15:16:11 +00:00
Tink bot fc373ae963 test(trello): serve testimage from local server instead of vikunja.io
Mirrors the Todoist migration test setup so TestConvertTrelloToVikunja
no longer depends on https://vikunja.io/testimage.jpg being reachable.
2026-05-15 15:16:11 +00:00
kolaente 70393f38d2
feat: add Atom feed for user notifications with API token auth (#2758) 2026-05-15 17:25:09 +02:00
Tink bot aa1956e1aa fix(oauth2server): accept all loopback redirect forms
Hardcoding the three exact strings localhost / 127.0.0.1 / ::1 rejected
legitimate loopback redirects like 127.0.0.2:1234 (anywhere in 127.0.0.0/8)
or [0:0:0:0:0:0:0:1]:1234 (expanded IPv6 loopback). Use net.IP.IsLoopback()
to cover the full loopback ranges, and match "localhost" case-insensitively.
0.0.0.0 stays rejected as it is not a loopback address.

https://claude.ai/code/session_01LsTDrCJ7trE6WQ4FYf78UB
2026-05-07 22:03:49 +00:00
Tink bot c6bda7a2dd feat(oauth2server): accept loopback redirect URIs
Previously the OAuth server rejected every redirect_uri that did not start
with a vikunja- custom scheme. Native apps that cannot register a custom
scheme (e.g. CLIs, desktop tools) need loopback redirects per RFC 8252, so
also allow http://localhost, http://127.0.0.1 and http://[::1] (any port).
Non-loopback http:// and https:// targets remain rejected.

https://claude.ai/code/session_01LsTDrCJ7trE6WQ4FYf78UB
2026-05-07 22:03:49 +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
Frederick [Bot] 6a604dd949 [skip ci] Updated swagger docs 2026-05-04 11:19:21 +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
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 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
Timh e97b629d6c feat: support filter_include_nulls in project view configuration 2026-04-28 14:16:51 +00:00
Xela 2b76a6b3fe fix(user): correct week_start validation range 2026-04-24 11:24:34 +02:00
Frederick [Bot] 879f839729 chore(i18n): update translations via Crowdin 2026-04-24 01:46:52 +00:00
kolaente 1f871d4dbd chore(i18n): remove unused backend translation keys
Remove five keys from pkg/i18n/lang/en.json that are no longer
referenced by any i18n.T / i18n.TP call. These surfaced once the
translation check started reporting dead keys. The sibling translation
files will be reconciled on the next Crowdin sync.

Removed keys:
- notifications.task.comment.mentioned_message
- notifications.task.mentioned.message
- notifications.common.actions.assigned_you
- notifications.common.actions.assigned_themselves
- notifications.common.actions.assigned_user
2026-04-23 13:30:51 +02:00
kolaente 138a545523 fix(notifications): pass lang to overdue reminder translation
The call to i18n.T for notifications.task.overdue.overdue was missing
its first positional argument, so the translation key was being passed
as the language code. This surfaced as a "dead key" once the
translation check learned to look for unused entries. Fix the call so
the reminder line is properly localised.
2026-04-23 13:30:51 +02:00
Frederick [Bot] 413e3dec1c chore(i18n): update translations via Crowdin 2026-04-22 01:28:34 +00:00
kolaente 2fc6f033f2 refactor(handler): return domain error for forbidden instead of echo.HTTPError
Keeps the Do* helpers framework-neutral so non-Echo callers (upcoming
Huma /v2 handlers) don't need a translation shim.

Addresses review feedback on #2670.
2026-04-21 09:23:13 +00:00
kolaente 939381fb12 refactor(handler): extract DoDelete from DeleteWeb 2026-04-21 09:23:13 +00:00
kolaente 1f4471c38f refactor(handler): extract DoUpdate from UpdateWeb 2026-04-21 09:23:13 +00:00
kolaente 0e800b4936 refactor(handler): extract DoReadAll from ReadAllWeb 2026-04-21 09:23:13 +00:00
kolaente 9ec5c2672f refactor(handler): extract DoReadOne from ReadOneWeb 2026-04-21 09:23:13 +00:00
kolaente 11c9137080 refactor(handler): extract DoCreate from CreateWeb 2026-04-21 09:23:13 +00:00
Frederick [Bot] 5d3e34e870 [skip ci] Updated swagger docs 2026-04-20 19:16:29 +00:00
kolaente af8beb5758 fix(user): skip last-admin guard when target is already unreachable
GuardLastAdmin counted only active, non-deletion-scheduled admins, but gated only on target.IsAdmin. Demoting or deleting an already-disabled or deletion-scheduled admin would then be blocked whenever exactly one active admin remained, even though removing a user who isn't in the reachable set can't reduce the count. Return early when the target isn't part of the counted set.
2026-04-20 18:55:06 +00:00