Commit Graph

2271 Commits

Author SHA1 Message Date
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
kolaente 7c7e060d16 feat(auth): include is_admin in JWT claims 2026-04-20 18:55:06 +00:00
kolaente deccc9d29b feat(user): add IsAdmin field to User struct 2026-04-20 18:55:06 +00:00
kolaente 736773ea77 feat(db): add is_admin column to users 2026-04-20 18:55:06 +00:00
MidoriKurage 3a5ba17ca0 fix(api/docs): Use Base in redoc template 2026-04-20 14:26:49 +00:00
MidoriKurage fb0d0cb32c fix(auth): Cleanup getRefreshTokenCookiePath implementation 2026-04-20 14:26:49 +00:00
MidoriKurage e8615efe8e fix(api/docs): Make redoc load docs.json from public URL 2026-04-20 14:26:49 +00:00
MidoriKurage c027d7ef40 fix(auth): Make refresh token path respect to public URL 2026-04-20 14:26:49 +00:00
Frederick [Bot] 3120c2b12c chore(i18n): update translations via Crowdin 2026-04-16 01:46:56 +00:00
kolaente 35f183979c feat: add license comments for agents and humans 2026-04-15 10:32:37 +00:00
kolaente a82bea567a feat(db): add license_status table migration
Add database migration for the license_status table that stores instance
ID, cached license validation response, and validation timestamps.
2026-04-15 10:32:37 +00:00
kolaente 7dd664fdc4 feat(init): integrate license validation into startup and shutdown
Call license.Init() after database initialization and before the web
server starts. Call license.Shutdown() during graceful shutdown to stop
the background check goroutine.
2026-04-15 10:32:37 +00:00
kolaente ed2632ddb2 feat(license): add license key validation package
Implement the license validation system with:
- Server communication with retry logic and exponential backoff
- In-memory state management for feature flags and user limits
- Cached validation with 72h expiry stored in database
- Background goroutine with adaptive check intervals (24h/1h)
- Graceful degradation to community mode on failure
- Instance ID generation and persistence
2026-04-15 10:32:37 +00:00
kolaente ecc2243513 feat(config): add license.key configuration option
Add license key configuration under the license section. When empty or
absent, Vikunja runs in community mode with no licensed features.
2026-04-15 10:32:37 +00:00
Frederick [Bot] 88528d927e [skip ci] Updated swagger docs 2026-04-13 16:21:02 +00:00
kolaente 85836076be feat(migration/wekan): import attachments from board export
Parse the top-level `attachments` array in WeKan board JSON exports,
group them by card ID, base64-decode the payload, and attach the
resulting files to the generated tasks so they land in Vikunja as
task attachments. Orphaned attachments (cardId with no matching card)
are silently skipped; decode errors are logged and skipped.
2026-04-13 16:04:14 +00:00
kolaente 1eafd31a2a
refactor(projects): use getAllProjectsForUser in getProjectsToDelete (#2616) 2026-04-13 12:32:32 +02:00
Claude 85cfadc5b0 fix: fatal with clear message when keyvalue type is redis but redis is not enabled
Instead of panicking with a nil pointer dereference when keyvalue.type
is set to "redis" but redis.enabled is false, log a fatal error with a
clear, actionable message telling the user to enable redis.

Closes go-vikunja/vikunja#2608

https://claude.ai/code/session_01TRuPTGYDQjxqHRFWQaJGvy
2026-04-12 09:43:31 +00:00
Frederick [Bot] bacee1597a chore(i18n): update translations via Crowdin 2026-04-12 01:43:16 +00:00
Frederick [Bot] 9a12c8f254 [skip ci] Updated swagger docs 2026-04-11 21:00:40 +00:00