Commit Graph

8 Commits

Author SHA1 Message Date
kolaente 7c11c2dc29 feat(api/v2): port refresh-token endpoint to /api/v2
POST /api/v2/user/token/refresh reads the HttpOnly refresh cookie, rotates
the session, mints a new JWT, and sets the new cookie — reusing the shared
auth.RefreshSession core (no v1 change) and the #2912 cookie helpers /
authTokenBody response shape. The cookie is set via the unwrapped echo ctx,
not the OpenAPI spec.

translateDomainError now maps *echo.HTTPError (which RefreshSession returns
for missing/invalid/expired/replayed tokens) so those land as the right
status instead of a 500. Completes the v1→v2 REST migration.
2026-06-17 20:34:38 +00:00
kolaente 24188480c4 feat(api/v2): return 422 with invalid_fields for validation errors 2026-06-06 21:09:56 +00:00
kolaente d76c009808 fix(api/v2): map ValidationHTTPError to its HTTP status
translateDomainError only recognized web.HTTPErrorProcessor, so a
ValidationHTTPError from InvalidFieldError (e.g. an unknown webhook
event) leaked as a 500 instead of the 412 v1 returns. It carries the
status via GetHTTPCode() but cannot implement HTTPErrorProcessor because
the embedded web.HTTPError field shadows the method name. Add a
GetHTTPCode/GetCode branch so v2 surfaces the right status and preserves
the v1 numeric code on the body.
2026-06-06 19:50:41 +00:00
kolaente 2488478f69
docs(api/v2): mark error code field read-only 2026-05-31 15:29:46 +02:00
kolaente 3347180f31 fix(api/v2): don't leak internal error detail in 5xx responses
Huma's handler-error path wraps raw errors as NewErrorWithContext(ctx,
500, "unexpected error occurred", err), and since the humaecho5 adapter
writes Huma's response directly it bypasses Vikunja's
CreateHTTPErrorHandler — which returns a generic 500 with no detail for
non-domain errors. The huma.NewError override then copied err.Error()
(raw DB/driver messages, SQL, table/column names) into the problem+json
errors[], a regression vs v1.

Override huma.NewErrorWithContext to drop errs for status >= 500, log
the real cause server-side, and return a generic body. 4xx detail
(validation errors, domain messages) is unaffected.
2026-05-31 12:56:57 +00:00
kolaente 8532016a2d feat(api/v2): preserve Vikunja numeric error code in problem+json
translateDomainError discarded web.HTTPError.Code, so v2 error bodies
always read code 0 — losing the v1 contract the error docs key off.
Override huma.NewError with a VikunjaErrorModel that adds a code field,
so both the generated OpenAPI schema and runtime responses carry it.
Domain errors with a numeric code now surface it (e.g. 8002 for a
missing label, matching v1); errors without one omit it.
2026-05-31 12:56:57 +00:00
kolaente e257823cef fix(api/v2): return generic 401 instead of leaking internal auth error
authFromCtx surfaced the underlying GetAuthFromContext error message
(e.g. the internal 'no echo.Context' adapter detail) straight to the
client. Log the real error and return a generic 401 instead.
2026-05-31 12:56:57 +00:00
kolaente a2156e7231 feat(api/v2): port Label to per-operation Huma handlers
Wires five hand-written huma.Register calls for Label CRUD onto the
existing /api/v2 group: list, read, create, update, delete. Uses
concrete type cast on ReadAll to avoid the generic-any silent-empty
trap. The read operation exposes an ETag via a header-tagged output
struct field and honours conditional.Params so clients can get 304
Not Modified on subsequent reads.

Also closes a prior-phase gap: SetupTokenMiddleware was intended to
run on the /api/v2 group (per task B4 of the plan) but was never
wired. Attach it now and teach the skipper to consult
unauthenticatedAPIPaths so spec + docs remain public.
2026-05-31 12:56:57 +00:00