Commit Graph

2290 Commits

Author SHA1 Message Date
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
kolaente
73a0f691ec fix(license): degrade to free when servers unreachable or key rejected
On startup, if the license server was unreachable with no usable cached status, or the server rejected the key, we only logged a warning without clearing persisted license.state. On Redis/keyvalue deployments a previous run's Licensed=true could remain active even though pro features were advertised as unavailable. Route both paths through degradeToFree so the persisted state is cleared.
2026-04-20 18:55:06 +00:00
kolaente
c8893f4533 fix(cli): guard last admin on scheduled CLI deletion path
The last-admin guard was only enforced in the --now branch of 'user delete'. The default scheduled path called user.RequestDeletion without the guard, letting an operator schedule deletion of the last reachable admin via the CLI; the cron flow would then confirm and execute it, violating the invariant the HTTP admin API already enforces.
2026-04-20 18:55:06 +00:00
kolaente
d64ca0c777 fix(admin): reload created user before returning in admin create handler
The admin create-user handler returned the in-memory newUser struct directly. On mail-enabled instances with skip_email_confirm=false, user.CreateUser persists the account as email-confirmation-required, but the returned struct still reflects the pre-persist status, so the admin API reported a misleading active status immediately after creation.
2026-04-20 18:55:06 +00:00
kolaente
f90ebbf0f4 refactor(license): return typed feature slice for JSON encoding 2026-04-20 18:55:06 +00:00
kolaente
d5f4928034 feat(admin): wire up /admin route group with all endpoints 2026-04-20 18:55:06 +00:00
kolaente
9ad9a1e987 refactor(register): use models.RegisterUser helper 2026-04-20 18:55:06 +00:00
kolaente
d24b96b99c feat(user): extract last-admin guard and close invariant gaps 2026-04-20 18:55:06 +00:00
kolaente
23c82bd5fa feat(frontend): expose isAdmin on current user and add config feature check 2026-04-20 18:55:06 +00:00
kolaente
3498dfe7fb test(admin): add webtests for /admin/* endpoints and share bypass 2026-04-20 18:55:06 +00:00
kolaente
d32dcf3a78 feat(license): add runtime state snapshot and reload helpers 2026-04-20 18:55:06 +00:00
kolaente
803f625ed7 feat(admin): add create-user endpoint 2026-04-20 18:55:06 +00:00
kolaente
128c0abf59 feat(admin): add user status and delete endpoints with reassign owner 2026-04-20 18:55:06 +00:00
kolaente
4a7cb6a7bf feat(admin): add users/projects list endpoints and is_admin patch 2026-04-20 18:55:06 +00:00
kolaente
e7fcbff827 feat(admin): add /admin route group and overview endpoint 2026-04-20 18:55:06 +00:00
kolaente
ec1833dbeb feat(license): expose enabled_pro_features on /info 2026-04-20 18:55:06 +00:00
kolaente
d208629909 feat(middleware): add RequireFeature and RequireSiteAdmin 404 gates 2026-04-20 18:55:06 +00:00
kolaente
3b3bc4c775 feat(cli): add user set-admin command (license-gated) 2026-04-20 18:55:06 +00:00
kolaente
87a06d6cb9 feat(permissions): site admins bypass all Can* checks (license-gated) 2026-04-20 18:55:06 +00:00