From 1d7b878d99b5f47a5a59ec879f958d80a70a0970 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 10 Jun 2026 21:05:07 +0200 Subject: [PATCH] feat(audit): wire request-meta middleware and writer initialization --- pkg/initialize/init.go | 7 +++++ pkg/routes/middleware/request_meta.go | 45 +++++++++++++++++++++++++++ pkg/routes/routes.go | 4 +++ 3 files changed, 56 insertions(+) create mode 100644 pkg/routes/middleware/request_meta.go diff --git a/pkg/initialize/init.go b/pkg/initialize/init.go index dca17cb60..7210feb1e 100644 --- a/pkg/initialize/init.go +++ b/pkg/initialize/init.go @@ -19,6 +19,7 @@ package initialize import ( "time" + "code.vikunja.io/api/pkg/audit" "code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/cron" "code.vikunja.io/api/pkg/db" @@ -98,6 +99,12 @@ func FullInitWithoutAsync() { // See the package comment in pkg/license/license.go before removing. license.Init() + if config.AuditEnabled.GetBool() { + if err := audit.Init(); err != nil { + log.Fatalf("Could not initialize audit logging: %s", err) + } + } + // Start the mail daemon mail.StartMailDaemon() diff --git a/pkg/routes/middleware/request_meta.go b/pkg/routes/middleware/request_meta.go new file mode 100644 index 000000000..747a37826 --- /dev/null +++ b/pkg/routes/middleware/request_meta.go @@ -0,0 +1,45 @@ +// Vikunja is a to-do list application to facilitate your life. +// Copyright 2018-present Vikunja and contributors. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package middleware + +import ( + "code.vikunja.io/api/pkg/events" + + "github.com/labstack/echo/v5" +) + +// RequestMeta stashes IP, User-Agent and X-Request-ID on the request context +// so events dispatched while handling the request carry them as message +// metadata (consumed by the audit listeners). +func RequestMeta() echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c *echo.Context) error { + req := c.Request() + requestID := req.Header.Get(echo.HeaderXRequestID) + if requestID == "" { + requestID = c.Response().Header().Get(echo.HeaderXRequestID) + } + ctx := events.WithRequestMeta(req.Context(), &events.RequestMeta{ + IP: c.RealIP(), + UserAgent: req.UserAgent(), + RequestID: requestID, + }) + c.SetRequest(req.WithContext(ctx)) + return next(c) + } + } +} diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index 4c070fd49..f8fc1609f 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -199,6 +199,10 @@ func NewEcho() *echo.Echo { // handler binds them. Runs globally so both /api/v1 and /api/v2 benefit. e.Use(vmiddleware.NormalizeArrayParams()) + if config.AuditEnabled.GetBool() { + e.Use(vmiddleware.RequestMeta()) + } + setupSentry(e) // Validation