Commit Graph

13954 Commits

Author SHA1 Message Date
kolaente 7145440fe6 test(e2e): assert wrong password blocks email change 2026-04-21 10:50:09 +00:00
kolaente 3dfbcae4d5 test(e2e): cover caldav token deletion 2026-04-21 10:50:09 +00:00
kolaente cd9d2a2245 test(e2e): cover caldav token creation end-to-end 2026-04-21 10:50:09 +00:00
kolaente 912d6a134f test(e2e): assert wrong TOTP passcode is rejected 2026-04-21 10:50:09 +00:00
kolaente 96685fdc5b test(e2e): cover TOTP disable flow 2026-04-21 10:50:09 +00:00
kolaente 5266392bb7 test(e2e): cover TOTP enrollment flow 2026-04-21 10:50:09 +00:00
kolaente 3b7c098c84 test(e2e): add otplib dev dep for TOTP tests 2026-04-21 10:50:09 +00:00
kolaente 3816349258 test(e2e): add TotpFactory with fixed seed 2026-04-21 10:50:09 +00:00
kolaente 3271c8600a test(e2e): add WebhookFactory 2026-04-21 10:50:09 +00:00
kolaente fff7f80994 test(e2e): add SessionFactory with sha256 token hashing 2026-04-21 10:50:09 +00:00
kolaente 726a4df539 test(e2e): add user settings nav helper 2026-04-21 10:50:09 +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
renovate[bot] 73a597345a chore(deps): update dev-dependencies to v4.2.3 2026-04-21 07:41:56 +00:00
kolaente f7dc50faf7 refactor(frontend): port checkbox-radio rules into FormCheckbox and drop Bulma import
The Bulma form/checkbox-radio partial only defined two selectors: .checkbox
(consumed exclusively by FormCheckbox.vue) and .radio (consumed by
ViewEditForm.vue and user/settings/Avatar.vue). Ports the %checkbox-radio
placeholder rules (cursor, line-height, position, hover/disabled states,
and the input cursor override) into FormCheckbox's scoped style for the
.checkbox side, and into scoped style blocks on the two remaining .radio
call-sites for the .radio side (including the 0.5em sibling margin via
margin-inline-start). Drops the now-unused @import. Pixel-perfect verified
on /login, /user/settings/general, and /user/settings/avatar: every
measured label/input getBoundingClientRect and computed style matches the
baseline exactly (0px deltas across all 5 sampled checkboxes and all 5
avatar radios).
2026-04-20 19:55:14 +00:00
renovate[bot] 5a1db90103 chore(deps): update dev-dependencies to v8.59.0 2026-04-20 19:28:55 +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 e8b777d3be fix(ui): make code element background dark-mode aware and harden config store 2026-04-20 18:55:06 +00:00
kolaente db3f5d2daf feat(project): add before-delete slot to ProjectSettingsDropdown 2026-04-20 18:55:06 +00:00
kolaente c7b088ac18 feat(frontend): introduce TimeDisplay component 2026-04-20 18:55:06 +00:00
kolaente 7e4bf83fa0 refactor(frontend): extract SideNavShell for admin and user settings 2026-04-20 18:55:06 +00:00
kolaente 4e805d182a test(frontend): update form primitive tests for admin input usage 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 7df5f127ca feat(admin): add frontend admin shell, views, services, and routes 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 c9b3d4775c feat(admin): add typed models for admin users and overview 2026-04-20 18:55:06 +00:00
kolaente 825e45b4c8 test(admin): add e2e tests for admin panel 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