vikunja/pkg/user
Evan Baker 94e1504e2b fix(user): stop double-encoding FrontendSettings on UpdateUser
UpdateUser was manually json.Marshal'ing user.FrontendSettings and
re-assigning the []byte back to the interface{} field before passing
the user to xorm. The column is declared:

  FrontendSettings interface{} `xorm:"json null" json:"-"`

xorm's `json` modifier already marshals the field on write. Pre-marshalling
to []byte and stuffing it back into the interface causes xorm to JSON-encode
a []byte (which serializes as a base64 string). The DB ends up storing
`"bnVsbA=="` (base64 of "null") for users whose FrontendSettings is nil,
or a double-encoded blob for users with real settings.

On read, xorm unmarshals that string back into the interface as a Go
`string`, and the API response then contains:

  "frontend_settings": "bnVsbA=="

instead of a JSON object or null. The Flutter mobile client
(go-vikunja/app) typed-casts `frontend_settings` to
`Map<String, dynamic>?` and crashes with:

  type 'String' is not a subtype of type 'Map<String, dynamic>?'

which the app surfaces as "could not connect to this server". The web
client tolerates it silently (JS spread over a string).

Trigger path: every OIDC login of an existing user calls UpdateUser
(pkg/modules/auth/openid/openid.go), so the row is corrupted on every
re-login. See go-vikunja/app#265.

Fix: let xorm handle the JSON marshalling as the struct tag advertises.
Drop the now-unused encoding/json import.
2026-06-27 15:17:41 -07:00
..
caldav_token.go fix(caldav): eliminate nested db session in CalDAV auth 2026-03-03 10:41:19 +01:00
db.go feat: register Vikunja tables with db package at init 2026-03-04 15:37:54 +01:00
delete.go fix: address review comments on session lifecycle 2026-02-25 11:03:02 +01:00
error.go feat: always enable bot users 2026-05-04 10:38:53 +00:00
error_test.go feat: always enable bot users 2026-05-04 10:38:53 +00:00
events.go feat(events): add auth boundary events 2026-06-12 08:56:08 +00:00
is_admin_test.go feat(user): extract last-admin guard and close invariant gaps 2026-04-20 18:55:06 +00:00
main_test.go feat: move to slog for logging 2025-07-21 18:15:39 +02:00
notifications.go fix: correct license header references (#882) 2025-06-10 12:18:38 +02:00
test.go test: add TOTP fixture and load it in user test bootstrap 2026-03-23 10:34:49 +00:00
token.go docs(api/v2): tag CalDAV token fields for the v2 schema 2026-06-10 17:55:52 +00:00
totp.go feat(api/v2): add totp qr code endpoint 2026-06-17 18:39:38 +00:00
totp_test.go test(user): cover TOTP lockout persistence and password-reset unlock 2026-04-09 16:08:26 +00:00
update_email.go feat(audit): attribute failed logins to the originating request 2026-06-12 08:56:08 +00:00
update_email_test.go fix(user): persist status on email updates (#1084) 2025-08-04 14:07:00 +00:00
user.go fix(user): stop double-encoding FrontendSettings on UpdateUser 2026-06-27 15:17:41 -07:00
user_claims_test.go feat(user): extract last-admin guard and close invariant gaps 2026-04-20 18:55:06 +00:00
user_create.go feat(user): add CreateBotUser 2026-05-01 14:44:10 +00:00
user_email_confirm.go fix(user): handle status errors in pkg/user callers, remove redundant checks 2026-03-23 12:06:16 +00:00
user_email_confirm_test.go fix: correct license header references (#882) 2025-06-10 12:18:38 +02:00
user_password_reset.go fix(user): handle status errors in pkg/user callers, remove redundant checks 2026-03-23 12:06:16 +00:00
user_test.go feat(audit): attribute failed logins to the originating request 2026-06-12 08:56:08 +00:00
users_project.go refactor(user): share user-search logic between v1 and v2 2026-06-11 20:07:43 +00:00
validator.go feat(api): enforce password validation on reset and update flows 2026-02-25 13:44:56 +01:00