From a1c3e416b65628be4e31aef4145bc11b93e4df3a Mon Sep 17 00:00:00 2001 From: Stavros Date: Fri, 26 Dec 2025 17:53:24 +0200 Subject: [PATCH 1/7] refactor: use proper module name (#542) * chore: reorganize go mod * refactor: use proper module name --- cmd/tinyauth/generate.go | 3 +- cmd/tinyauth/tinyauth.go | 7 +- cmd/tinyauth/verify.go | 3 +- cmd/tinyauth/version.go | 3 +- go.mod | 83 +++++++++---------- internal/bootstrap/app_bootstrap.go | 9 +- internal/bootstrap/router_bootstrap.go | 5 +- internal/bootstrap/service_bootstrap.go | 2 +- internal/controller/context_controller.go | 3 +- .../controller/context_controller_test.go | 5 +- internal/controller/oauth_controller.go | 7 +- internal/controller/proxy_controller.go | 7 +- internal/controller/proxy_controller_test.go | 7 +- .../controller/resources_controller_test.go | 3 +- internal/controller/user_controller.go | 7 +- internal/controller/user_controller_test.go | 7 +- internal/middleware/context_middleware.go | 7 +- internal/middleware/ui_middleware.go | 3 +- internal/service/access_controls_service.go | 2 +- internal/service/auth_service.go | 7 +- internal/service/database_service.go | 3 +- internal/service/docker_service.go | 5 +- internal/service/generic_oauth_service.go | 3 +- internal/service/github_oauth_service.go | 3 +- internal/service/google_oauth_service.go | 3 +- internal/service/oauth_broker_service.go | 3 +- internal/utils/app_utils.go | 3 +- internal/utils/app_utils_test.go | 5 +- internal/utils/decoders/label_decoder_test.go | 5 +- internal/utils/label_utils_test.go | 3 +- internal/utils/loaders/loader_env.go | 3 +- internal/utils/security_utils_test.go | 3 +- internal/utils/string_utils_test.go | 3 +- internal/utils/user_utils.go | 3 +- internal/utils/user_utils_test.go | 3 +- 35 files changed, 130 insertions(+), 101 deletions(-) diff --git a/cmd/tinyauth/generate.go b/cmd/tinyauth/generate.go index 0c0755b..63eb671 100644 --- a/cmd/tinyauth/generate.go +++ b/cmd/tinyauth/generate.go @@ -6,7 +6,8 @@ import ( "os" "strings" "time" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/charmbracelet/huh" "github.com/mdp/qrterminal/v3" diff --git a/cmd/tinyauth/tinyauth.go b/cmd/tinyauth/tinyauth.go index 8642eed..f014fac 100644 --- a/cmd/tinyauth/tinyauth.go +++ b/cmd/tinyauth/tinyauth.go @@ -5,9 +5,10 @@ import ( "os" "strings" "time" - "tinyauth/internal/bootstrap" - "tinyauth/internal/config" - "tinyauth/internal/utils/loaders" + + "github.com/steveiliop56/tinyauth/internal/bootstrap" + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/utils/loaders" "github.com/rs/zerolog" "github.com/rs/zerolog/log" diff --git a/cmd/tinyauth/verify.go b/cmd/tinyauth/verify.go index ddb114e..9634808 100644 --- a/cmd/tinyauth/verify.go +++ b/cmd/tinyauth/verify.go @@ -5,7 +5,8 @@ import ( "fmt" "os" "time" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/charmbracelet/huh" "github.com/pquerna/otp/totp" diff --git a/cmd/tinyauth/version.go b/cmd/tinyauth/version.go index 22aae14..aad6b55 100644 --- a/cmd/tinyauth/version.go +++ b/cmd/tinyauth/version.go @@ -2,7 +2,8 @@ package main import ( "fmt" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" "github.com/traefik/paerser/cli" ) diff --git a/go.mod b/go.mod index 092a6b6..5979f36 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module tinyauth +module github.com/steveiliop56/tinyauth go 1.24.0 @@ -6,17 +6,22 @@ toolchain go1.24.3 require ( github.com/cenkalti/backoff/v5 v5.0.3 + github.com/charmbracelet/huh v0.8.0 + github.com/docker/docker v28.5.2+incompatible github.com/gin-gonic/gin v1.11.0 github.com/glebarez/sqlite v1.11.0 + github.com/go-ldap/ldap/v3 v3.4.12 github.com/golang-migrate/migrate/v4 v4.19.1 github.com/google/go-querystring v1.1.0 github.com/google/uuid v1.6.0 github.com/mdp/qrterminal/v3 v3.2.1 + github.com/pquerna/otp v1.5.0 github.com/rs/zerolog v1.34.0 github.com/traefik/paerser v0.2.2 github.com/weppos/publicsuffix-go v0.50.1 golang.org/x/crypto v0.46.0 golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b + golang.org/x/oauth2 v0.34.0 gorm.io/gorm v1.31.1 gotest.tools/v3 v3.5.2 ) @@ -27,43 +32,6 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect - github.com/charmbracelet/x/cellbuf v0.0.13 // indirect - github.com/containerd/errdefs v1.0.0 // indirect - github.com/containerd/errdefs/pkg v0.3.0 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/glebarez/go-sqlite v1.21.2 // indirect - github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect - github.com/go-playground/validator/v10 v10.28.0 // indirect - github.com/goccy/go-yaml v1.18.0 // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/huandu/xstrings v1.5.0 // indirect - github.com/imdario/mergo v0.3.11 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-sqlite3 v1.14.32 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/sys/atomicwriter v0.1.0 // indirect - github.com/moby/term v0.5.2 // indirect - github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/quic-go/qpack v0.6.0 // indirect - github.com/quic-go/quic-go v0.57.0 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/shopspring/decimal v1.4.0 // indirect - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect - golang.org/x/term v0.38.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.66.3 // indirect - modernc.org/mathutil v1.7.1 // indirect - modernc.org/memory v1.11.0 // indirect - modernc.org/sqlite v1.38.2 // indirect - rsc.io/qr v0.2.0 // indirect -) - -require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect @@ -73,14 +41,17 @@ require ( github.com/catppuccin/go v0.3.0 // indirect github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 // indirect github.com/charmbracelet/bubbletea v1.3.6 // indirect - github.com/charmbracelet/huh v0.8.0 + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect github.com/charmbracelet/x/ansi v0.9.3 // indirect + github.com/charmbracelet/x/cellbuf v0.0.13 // indirect github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect github.com/charmbracelet/x/term v0.2.1 // indirect github.com/cloudwego/base64x v0.1.6 // indirect + github.com/containerd/errdefs v1.0.0 // indirect + github.com/containerd/errdefs/pkg v0.3.0 // indirect + github.com/containerd/log v0.1.0 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/docker v28.5.2+incompatible github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -88,12 +59,20 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gabriel-vasile/mimetype v1.4.10 // indirect github.com/gin-contrib/sse v1.1.0 // indirect - github.com/go-ldap/ldap/v3 v3.4.12 + github.com/glebarez/go-sqlite v1.21.2 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.28.0 // indirect github.com/goccy/go-json v0.10.4 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/imdario/mergo v0.3.11 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -102,31 +81,49 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-sqlite3 v1.14.32 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/sys/atomicwriter v0.1.0 // indirect + github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pquerna/otp v1.5.0 + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.57.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.3.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect golang.org/x/arch v0.20.0 // indirect golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.34.0 golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect golang.org/x/text v0.32.0 // indirect google.golang.org/protobuf v1.36.9 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + modernc.org/libc v1.66.3 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.11.0 // indirect + modernc.org/sqlite v1.38.2 // indirect + rsc.io/qr v0.2.0 // indirect ) diff --git a/internal/bootstrap/app_bootstrap.go b/internal/bootstrap/app_bootstrap.go index a4d8024..4126f5d 100644 --- a/internal/bootstrap/app_bootstrap.go +++ b/internal/bootstrap/app_bootstrap.go @@ -11,10 +11,11 @@ import ( "sort" "strings" "time" - "tinyauth/internal/config" - "tinyauth/internal/controller" - "tinyauth/internal/model" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/controller" + "github.com/steveiliop56/tinyauth/internal/model" + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/rs/zerolog/log" "gorm.io/gorm" diff --git a/internal/bootstrap/router_bootstrap.go b/internal/bootstrap/router_bootstrap.go index 9318561..531f5e0 100644 --- a/internal/bootstrap/router_bootstrap.go +++ b/internal/bootstrap/router_bootstrap.go @@ -3,8 +3,9 @@ package bootstrap import ( "fmt" "strings" - "tinyauth/internal/controller" - "tinyauth/internal/middleware" + + "github.com/steveiliop56/tinyauth/internal/controller" + "github.com/steveiliop56/tinyauth/internal/middleware" "github.com/gin-gonic/gin" ) diff --git a/internal/bootstrap/service_bootstrap.go b/internal/bootstrap/service_bootstrap.go index e18d832..6110aeb 100644 --- a/internal/bootstrap/service_bootstrap.go +++ b/internal/bootstrap/service_bootstrap.go @@ -1,7 +1,7 @@ package bootstrap import ( - "tinyauth/internal/service" + "github.com/steveiliop56/tinyauth/internal/service" "github.com/rs/zerolog/log" ) diff --git a/internal/controller/context_controller.go b/internal/controller/context_controller.go index 5b3b30d..62e8582 100644 --- a/internal/controller/context_controller.go +++ b/internal/controller/context_controller.go @@ -3,7 +3,8 @@ package controller import ( "fmt" "net/url" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" diff --git a/internal/controller/context_controller_test.go b/internal/controller/context_controller_test.go index bfefd13..a558abd 100644 --- a/internal/controller/context_controller_test.go +++ b/internal/controller/context_controller_test.go @@ -4,8 +4,9 @@ import ( "encoding/json" "net/http/httptest" "testing" - "tinyauth/internal/config" - "tinyauth/internal/controller" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/controller" "github.com/gin-gonic/gin" "gotest.tools/v3/assert" diff --git a/internal/controller/oauth_controller.go b/internal/controller/oauth_controller.go index c58c6c4..e2353fe 100644 --- a/internal/controller/oauth_controller.go +++ b/internal/controller/oauth_controller.go @@ -5,9 +5,10 @@ import ( "net/http" "strings" "time" - "tinyauth/internal/config" - "tinyauth/internal/service" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/service" + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/gin-gonic/gin" "github.com/google/go-querystring/query" diff --git a/internal/controller/proxy_controller.go b/internal/controller/proxy_controller.go index eed127e..50e4ed2 100644 --- a/internal/controller/proxy_controller.go +++ b/internal/controller/proxy_controller.go @@ -5,9 +5,10 @@ import ( "net/http" "slices" "strings" - "tinyauth/internal/config" - "tinyauth/internal/service" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/service" + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/gin-gonic/gin" "github.com/google/go-querystring/query" diff --git a/internal/controller/proxy_controller_test.go b/internal/controller/proxy_controller_test.go index 452155f..f2999c1 100644 --- a/internal/controller/proxy_controller_test.go +++ b/internal/controller/proxy_controller_test.go @@ -3,9 +3,10 @@ package controller_test import ( "net/http/httptest" "testing" - "tinyauth/internal/config" - "tinyauth/internal/controller" - "tinyauth/internal/service" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/controller" + "github.com/steveiliop56/tinyauth/internal/service" "github.com/gin-gonic/gin" "gotest.tools/v3/assert" diff --git a/internal/controller/resources_controller_test.go b/internal/controller/resources_controller_test.go index 8e4f843..c27b0a3 100644 --- a/internal/controller/resources_controller_test.go +++ b/internal/controller/resources_controller_test.go @@ -4,7 +4,8 @@ import ( "net/http/httptest" "os" "testing" - "tinyauth/internal/controller" + + "github.com/steveiliop56/tinyauth/internal/controller" "github.com/gin-gonic/gin" "gotest.tools/v3/assert" diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go index ff26de1..a607c4a 100644 --- a/internal/controller/user_controller.go +++ b/internal/controller/user_controller.go @@ -3,9 +3,10 @@ package controller import ( "fmt" "strings" - "tinyauth/internal/config" - "tinyauth/internal/service" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/service" + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/gin-gonic/gin" "github.com/pquerna/otp/totp" diff --git a/internal/controller/user_controller_test.go b/internal/controller/user_controller_test.go index 6065521..1ec7197 100644 --- a/internal/controller/user_controller_test.go +++ b/internal/controller/user_controller_test.go @@ -7,9 +7,10 @@ import ( "strings" "testing" "time" - "tinyauth/internal/config" - "tinyauth/internal/controller" - "tinyauth/internal/service" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/controller" + "github.com/steveiliop56/tinyauth/internal/service" "github.com/gin-gonic/gin" "github.com/pquerna/otp/totp" diff --git a/internal/middleware/context_middleware.go b/internal/middleware/context_middleware.go index 2c903be..c763ae3 100644 --- a/internal/middleware/context_middleware.go +++ b/internal/middleware/context_middleware.go @@ -3,9 +3,10 @@ package middleware import ( "fmt" "strings" - "tinyauth/internal/config" - "tinyauth/internal/service" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/service" + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" diff --git a/internal/middleware/ui_middleware.go b/internal/middleware/ui_middleware.go index adcb784..59a5da9 100644 --- a/internal/middleware/ui_middleware.go +++ b/internal/middleware/ui_middleware.go @@ -7,7 +7,8 @@ import ( "os" "strings" "time" - "tinyauth/internal/assets" + + "github.com/steveiliop56/tinyauth/internal/assets" "github.com/gin-gonic/gin" ) diff --git a/internal/service/access_controls_service.go b/internal/service/access_controls_service.go index f6e4b56..e5af779 100644 --- a/internal/service/access_controls_service.go +++ b/internal/service/access_controls_service.go @@ -1,7 +1,7 @@ package service import ( - "tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/config" ) /* diff --git a/internal/service/auth_service.go b/internal/service/auth_service.go index bcba481..2bfd29e 100644 --- a/internal/service/auth_service.go +++ b/internal/service/auth_service.go @@ -8,9 +8,10 @@ import ( "strings" "sync" "time" - "tinyauth/internal/config" - "tinyauth/internal/model" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/model" + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/gin-gonic/gin" "github.com/google/uuid" diff --git a/internal/service/database_service.go b/internal/service/database_service.go index 30d8803..d3ac9b5 100644 --- a/internal/service/database_service.go +++ b/internal/service/database_service.go @@ -5,7 +5,8 @@ import ( "fmt" "os" "path/filepath" - "tinyauth/internal/assets" + + "github.com/steveiliop56/tinyauth/internal/assets" "github.com/glebarez/sqlite" "github.com/golang-migrate/migrate/v4" diff --git a/internal/service/docker_service.go b/internal/service/docker_service.go index 1c39778..a0693b2 100644 --- a/internal/service/docker_service.go +++ b/internal/service/docker_service.go @@ -3,8 +3,9 @@ package service import ( "context" "strings" - "tinyauth/internal/config" - "tinyauth/internal/utils/decoders" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/utils/decoders" container "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" diff --git a/internal/service/generic_oauth_service.go b/internal/service/generic_oauth_service.go index d68f8ae..ac3252c 100644 --- a/internal/service/generic_oauth_service.go +++ b/internal/service/generic_oauth_service.go @@ -10,7 +10,8 @@ import ( "io" "net/http" "time" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" "github.com/rs/zerolog/log" "golang.org/x/oauth2" diff --git a/internal/service/github_oauth_service.go b/internal/service/github_oauth_service.go index 11dcf61..a06abdb 100644 --- a/internal/service/github_oauth_service.go +++ b/internal/service/github_oauth_service.go @@ -10,7 +10,8 @@ import ( "io" "net/http" "time" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" "golang.org/x/oauth2" "golang.org/x/oauth2/endpoints" diff --git a/internal/service/google_oauth_service.go b/internal/service/google_oauth_service.go index 0ece6f2..80b7ab8 100644 --- a/internal/service/google_oauth_service.go +++ b/internal/service/google_oauth_service.go @@ -10,7 +10,8 @@ import ( "net/http" "strings" "time" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" "golang.org/x/oauth2" "golang.org/x/oauth2/endpoints" diff --git a/internal/service/oauth_broker_service.go b/internal/service/oauth_broker_service.go index e15d9c6..2c7d4cf 100644 --- a/internal/service/oauth_broker_service.go +++ b/internal/service/oauth_broker_service.go @@ -2,7 +2,8 @@ package service import ( "errors" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" "github.com/rs/zerolog/log" "golang.org/x/exp/slices" diff --git a/internal/utils/app_utils.go b/internal/utils/app_utils.go index a2b23c8..28d815d 100644 --- a/internal/utils/app_utils.go +++ b/internal/utils/app_utils.go @@ -5,7 +5,8 @@ import ( "net" "net/url" "strings" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" "github.com/gin-gonic/gin" "github.com/weppos/publicsuffix-go/publicsuffix" diff --git a/internal/utils/app_utils_test.go b/internal/utils/app_utils_test.go index 55fde36..08bb893 100644 --- a/internal/utils/app_utils_test.go +++ b/internal/utils/app_utils_test.go @@ -2,8 +2,9 @@ package utils_test import ( "testing" - "tinyauth/internal/config" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/utils" "github.com/gin-gonic/gin" "gotest.tools/v3/assert" diff --git a/internal/utils/decoders/label_decoder_test.go b/internal/utils/decoders/label_decoder_test.go index c8874f4..fb63552 100644 --- a/internal/utils/decoders/label_decoder_test.go +++ b/internal/utils/decoders/label_decoder_test.go @@ -2,8 +2,9 @@ package decoders_test import ( "testing" - "tinyauth/internal/config" - "tinyauth/internal/utils/decoders" + + "github.com/steveiliop56/tinyauth/internal/config" + "github.com/steveiliop56/tinyauth/internal/utils/decoders" "gotest.tools/v3/assert" ) diff --git a/internal/utils/label_utils_test.go b/internal/utils/label_utils_test.go index f38302d..8edac79 100644 --- a/internal/utils/label_utils_test.go +++ b/internal/utils/label_utils_test.go @@ -2,7 +2,8 @@ package utils_test import ( "testing" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/utils" "gotest.tools/v3/assert" ) diff --git a/internal/utils/loaders/loader_env.go b/internal/utils/loaders/loader_env.go index 9811974..608ae10 100644 --- a/internal/utils/loaders/loader_env.go +++ b/internal/utils/loaders/loader_env.go @@ -3,7 +3,8 @@ package loaders import ( "fmt" "os" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" "github.com/traefik/paerser/cli" "github.com/traefik/paerser/env" diff --git a/internal/utils/security_utils_test.go b/internal/utils/security_utils_test.go index 9adcd7c..3ebd681 100644 --- a/internal/utils/security_utils_test.go +++ b/internal/utils/security_utils_test.go @@ -3,7 +3,8 @@ package utils_test import ( "os" "testing" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/utils" "gotest.tools/v3/assert" ) diff --git a/internal/utils/string_utils_test.go b/internal/utils/string_utils_test.go index 3677eb6..5ea1b47 100644 --- a/internal/utils/string_utils_test.go +++ b/internal/utils/string_utils_test.go @@ -2,7 +2,8 @@ package utils_test import ( "testing" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/utils" "gotest.tools/v3/assert" ) diff --git a/internal/utils/user_utils.go b/internal/utils/user_utils.go index 0044db4..8ee8e94 100644 --- a/internal/utils/user_utils.go +++ b/internal/utils/user_utils.go @@ -3,7 +3,8 @@ package utils import ( "errors" "strings" - "tinyauth/internal/config" + + "github.com/steveiliop56/tinyauth/internal/config" ) func ParseUsers(users string) ([]config.User, error) { diff --git a/internal/utils/user_utils_test.go b/internal/utils/user_utils_test.go index d04636a..3cc23c3 100644 --- a/internal/utils/user_utils_test.go +++ b/internal/utils/user_utils_test.go @@ -3,7 +3,8 @@ package utils_test import ( "os" "testing" - "tinyauth/internal/utils" + + "github.com/steveiliop56/tinyauth/internal/utils" "gotest.tools/v3/assert" ) From 2d8af0510ea8e41591416d432fa9df288745592f Mon Sep 17 00:00:00 2001 From: Stavros Date: Fri, 26 Dec 2025 17:55:54 +0200 Subject: [PATCH 2/7] feat: refresh session cookie when session is active (#540) * feat: refresh session cookie when session is active * refactor: use current time to set new expiry --- .gitignore | 5 ++- internal/controller/proxy_controller.go | 12 +----- internal/controller/proxy_controller_test.go | 7 --- internal/middleware/context_middleware.go | 2 + internal/service/auth_service.go | 45 +++++++++++++++++--- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 576aeee..0eefed8 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,7 @@ # binary out /tinyauth.db -/resources \ No newline at end of file +/resources + +# debug files +__debug_* \ No newline at end of file diff --git a/internal/controller/proxy_controller.go b/internal/controller/proxy_controller.go index 50e4ed2..431c988 100644 --- a/internal/controller/proxy_controller.go +++ b/internal/controller/proxy_controller.go @@ -43,7 +43,8 @@ func NewProxyController(config ProxyControllerConfig, router *gin.RouterGroup, a func (controller *ProxyController) SetupRoutes() { proxyGroup := controller.router.Group("/auth") - proxyGroup.Any("/:proxy", controller.proxyHandler) + proxyGroup.GET("/:proxy", controller.proxyHandler) + proxyGroup.POST("/:proxy", controller.proxyHandler) } func (controller *ProxyController) proxyHandler(c *gin.Context) { @@ -68,15 +69,6 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) { return } - if req.Proxy != "envoy" && c.Request.Method != http.MethodGet { - log.Warn().Str("method", c.Request.Method).Msg("Invalid method for proxy") - c.JSON(405, gin.H{ - "status": 405, - "message": "Method Not Allowed", - }) - return - } - isBrowser := strings.Contains(c.Request.Header.Get("Accept"), "text/html") if isBrowser { diff --git a/internal/controller/proxy_controller_test.go b/internal/controller/proxy_controller_test.go index f2999c1..d0de555 100644 --- a/internal/controller/proxy_controller_test.go +++ b/internal/controller/proxy_controller_test.go @@ -81,13 +81,6 @@ func TestProxyHandler(t *testing.T) { assert.Equal(t, 400, recorder.Code) - // Test invalid method - recorder = httptest.NewRecorder() - req = httptest.NewRequest("POST", "/api/auth/traefik", nil) - router.ServeHTTP(recorder, req) - - assert.Equal(t, 405, recorder.Code) - // Test logged out user (traefik/caddy) recorder = httptest.NewRecorder() req = httptest.NewRequest("GET", "/api/auth/traefik", nil) diff --git a/internal/middleware/context_middleware.go b/internal/middleware/context_middleware.go index c763ae3..3101bd9 100644 --- a/internal/middleware/context_middleware.go +++ b/internal/middleware/context_middleware.go @@ -66,6 +66,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc { goto basic } + m.auth.RefreshSessionCookie(c) c.Set("context", &config.UserContext{ Username: cookie.Username, Name: cookie.Name, @@ -90,6 +91,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc { goto basic } + m.auth.RefreshSessionCookie(c) c.Set("context", &config.UserContext{ Username: cookie.Username, Name: cookie.Name, diff --git a/internal/service/auth_service.go b/internal/service/auth_service.go index 2bfd29e..b55d77e 100644 --- a/internal/service/auth_service.go +++ b/internal/service/auth_service.go @@ -1,7 +1,6 @@ package service import ( - "context" "errors" "fmt" "regexp" @@ -44,7 +43,6 @@ type AuthService struct { loginMutex sync.RWMutex ldap *LdapService database *gorm.DB - ctx context.Context } func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, database *gorm.DB) *AuthService { @@ -58,7 +56,6 @@ func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapS } func (auth *AuthService) Init() error { - auth.ctx = context.Background() return nil } @@ -218,7 +215,7 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio OAuthName: data.OAuthName, } - err = gorm.G[model.Session](auth.database).Create(auth.ctx, &session) + err = gorm.G[model.Session](auth.database).Create(c, &session) if err != nil { return err @@ -229,6 +226,40 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio return nil } +func (auth *AuthService) RefreshSessionCookie(c *gin.Context) error { + cookie, err := c.Cookie(auth.config.SessionCookieName) + + if err != nil { + return err + } + + session, err := gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).First(c) + + if err != nil { + return err + } + + currentTime := time.Now().Unix() + + if session.Expiry-currentTime > int64(time.Hour.Seconds()) { + return nil + } + + newExpiry := currentTime + int64(time.Hour.Seconds()) + + _, err = gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).Updates(c, model.Session{ + Expiry: newExpiry, + }) + + if err != nil { + return err + } + + c.SetCookie(auth.config.SessionCookieName, cookie, int(time.Hour.Seconds()), "/", fmt.Sprintf(".%s", auth.config.CookieDomain), auth.config.SecureCookie, true) + + return nil +} + func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error { cookie, err := c.Cookie(auth.config.SessionCookieName) @@ -236,7 +267,7 @@ func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error { return err } - _, err = gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).Delete(auth.ctx) + _, err = gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).Delete(c) if err != nil { return err @@ -254,7 +285,7 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie, return config.SessionCookie{}, err } - session, err := gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).First(auth.ctx) + session, err := gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).First(c) if err != nil { return config.SessionCookie{}, err @@ -267,7 +298,7 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie, currentTime := time.Now().Unix() if currentTime > session.Expiry { - _, err = gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).Delete(auth.ctx) + _, err = gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).Delete(c) if err != nil { log.Error().Err(err).Msg("Failed to delete expired session") } From 43487d44f759520a453b97d2faf3fcec2d671826 Mon Sep 17 00:00:00 2001 From: Stavros Date: Fri, 26 Dec 2025 19:02:51 +0200 Subject: [PATCH 3/7] feat: forward sub from oidc providers (#543) * feat: forward sub from oidc providers * fix: review comments --- .../assets/migrations/000003_oauth_sub.down.sql | 1 + .../assets/migrations/000003_oauth_sub.up.sql | 1 + internal/config/config.go | 3 +++ internal/controller/context_controller.go | 2 ++ internal/controller/context_controller_test.go | 1 + internal/controller/oauth_controller.go | 1 + internal/controller/proxy_controller.go | 1 + internal/middleware/context_middleware.go | 1 + internal/model/session_model.go | 1 + internal/service/auth_service.go | 2 ++ internal/service/github_oauth_service.go | 3 +++ internal/service/google_oauth_service.go | 17 ++++------------- 12 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 internal/assets/migrations/000003_oauth_sub.down.sql create mode 100644 internal/assets/migrations/000003_oauth_sub.up.sql diff --git a/internal/assets/migrations/000003_oauth_sub.down.sql b/internal/assets/migrations/000003_oauth_sub.down.sql new file mode 100644 index 0000000..0260a7b --- /dev/null +++ b/internal/assets/migrations/000003_oauth_sub.down.sql @@ -0,0 +1 @@ +ALTER TABLE "sessions" DROP COLUMN "oauth_sub"; \ No newline at end of file diff --git a/internal/assets/migrations/000003_oauth_sub.up.sql b/internal/assets/migrations/000003_oauth_sub.up.sql new file mode 100644 index 0000000..def471e --- /dev/null +++ b/internal/assets/migrations/000003_oauth_sub.up.sql @@ -0,0 +1 @@ +ALTER TABLE "sessions" ADD COLUMN "oauth_sub" TEXT; diff --git a/internal/config/config.go b/internal/config/config.go index e664c4d..f69c473 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -79,6 +79,7 @@ const DefaultNamePrefix = "TINYAUTH_" // OAuth/OIDC config type Claims struct { + Sub string `json:"sub"` Name string `json:"name"` Email string `json:"email"` PreferredUsername string `json:"preferred_username"` @@ -125,6 +126,7 @@ type SessionCookie struct { TotpPending bool OAuthGroups string OAuthName string + OAuthSub string } type UserContext struct { @@ -138,6 +140,7 @@ type UserContext struct { OAuthGroups string TotpEnabled bool OAuthName string + OAuthSub string } // API responses and queries diff --git a/internal/controller/context_controller.go b/internal/controller/context_controller.go index 62e8582..181c2f6 100644 --- a/internal/controller/context_controller.go +++ b/internal/controller/context_controller.go @@ -21,6 +21,7 @@ type UserContextResponse struct { OAuth bool `json:"oauth"` TotpPending bool `json:"totpPending"` OAuthName string `json:"oauthName"` + OAuthSub string `json:"oauthSub"` } type AppContextResponse struct { @@ -89,6 +90,7 @@ func (controller *ContextController) userContextHandler(c *gin.Context) { OAuth: context.OAuth, TotpPending: context.TotpPending, OAuthName: context.OAuthName, + OAuthSub: context.OAuthSub, } if err != nil { diff --git a/internal/controller/context_controller_test.go b/internal/controller/context_controller_test.go index a558abd..7dee2c8 100644 --- a/internal/controller/context_controller_test.go +++ b/internal/controller/context_controller_test.go @@ -44,6 +44,7 @@ var userContext = config.UserContext{ TotpPending: false, OAuthGroups: "", TotpEnabled: false, + OAuthSub: "", } func setupContextController(middlewares *[]gin.HandlerFunc) (*gin.Engine, *httptest.ResponseRecorder) { diff --git a/internal/controller/oauth_controller.go b/internal/controller/oauth_controller.go index e2353fe..3635e85 100644 --- a/internal/controller/oauth_controller.go +++ b/internal/controller/oauth_controller.go @@ -197,6 +197,7 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) { Provider: req.Provider, OAuthGroups: utils.CoalesceToString(user.Groups), OAuthName: service.GetName(), + OAuthSub: user.Sub, } log.Trace().Interface("session_cookie", sessionCookie).Msg("Creating session cookie") diff --git a/internal/controller/proxy_controller.go b/internal/controller/proxy_controller.go index 431c988..40f8374 100644 --- a/internal/controller/proxy_controller.go +++ b/internal/controller/proxy_controller.go @@ -239,6 +239,7 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) { c.Header("Remote-Name", utils.SanitizeHeader(userContext.Name)) c.Header("Remote-Email", utils.SanitizeHeader(userContext.Email)) c.Header("Remote-Groups", utils.SanitizeHeader(userContext.OAuthGroups)) + c.Header("Remote-Sub", utils.SanitizeHeader(userContext.OAuthSub)) controller.setHeaders(c, acls) diff --git a/internal/middleware/context_middleware.go b/internal/middleware/context_middleware.go index 3101bd9..16f7c05 100644 --- a/internal/middleware/context_middleware.go +++ b/internal/middleware/context_middleware.go @@ -99,6 +99,7 @@ func (m *ContextMiddleware) Middleware() gin.HandlerFunc { Provider: cookie.Provider, OAuthGroups: cookie.OAuthGroups, OAuthName: cookie.OAuthName, + OAuthSub: cookie.OAuthSub, IsLoggedIn: true, OAuth: true, }) diff --git a/internal/model/session_model.go b/internal/model/session_model.go index 0fdb6c3..283dd6b 100644 --- a/internal/model/session_model.go +++ b/internal/model/session_model.go @@ -10,4 +10,5 @@ type Session struct { OAuthGroups string `gorm:"column:oauth_groups"` Expiry int64 `gorm:"column:expiry"` OAuthName string `gorm:"column:oauth_name"` + OAuthSub string `gorm:"column:oauth_sub"` } diff --git a/internal/service/auth_service.go b/internal/service/auth_service.go index b55d77e..94fc1e6 100644 --- a/internal/service/auth_service.go +++ b/internal/service/auth_service.go @@ -213,6 +213,7 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio OAuthGroups: data.OAuthGroups, Expiry: time.Now().Add(time.Duration(expiry) * time.Second).Unix(), OAuthName: data.OAuthName, + OAuthSub: data.OAuthSub, } err = gorm.G[model.Session](auth.database).Create(c, &session) @@ -314,6 +315,7 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie, TotpPending: session.TOTPPending, OAuthGroups: session.OAuthGroups, OAuthName: session.OAuthName, + OAuthSub: session.OAuthSub, }, nil } diff --git a/internal/service/github_oauth_service.go b/internal/service/github_oauth_service.go index a06abdb..35b552a 100644 --- a/internal/service/github_oauth_service.go +++ b/internal/service/github_oauth_service.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "net/http" + "strconv" "time" "github.com/steveiliop56/tinyauth/internal/config" @@ -27,6 +28,7 @@ type GithubEmailResponse []struct { type GithubUserInfoResponse struct { Login string `json:"login"` Name string `json:"name"` + ID int `json:"id"` } type GithubOAuthService struct { @@ -172,6 +174,7 @@ func (github *GithubOAuthService) Userinfo() (config.Claims, error) { user.PreferredUsername = userInfo.Login user.Name = userInfo.Name + user.Sub = strconv.Itoa(userInfo.ID) return user, nil } diff --git a/internal/service/google_oauth_service.go b/internal/service/google_oauth_service.go index 80b7ab8..6dfbeaf 100644 --- a/internal/service/google_oauth_service.go +++ b/internal/service/google_oauth_service.go @@ -17,12 +17,7 @@ import ( "golang.org/x/oauth2/endpoints" ) -var GoogleOAuthScopes = []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"} - -type GoogleUserInfoResponse struct { - Email string `json:"email"` - Name string `json:"name"` -} +var GoogleOAuthScopes = []string{"openid", "email", "profile"} type GoogleOAuthService struct { config oauth2.Config @@ -91,7 +86,7 @@ func (google *GoogleOAuthService) Userinfo() (config.Claims, error) { client := google.config.Client(google.context, google.token) - res, err := client.Get("https://www.googleapis.com/userinfo/v2/me") + res, err := client.Get("https://openidconnect.googleapis.com/v1/userinfo") if err != nil { return config.Claims{}, err } @@ -106,16 +101,12 @@ func (google *GoogleOAuthService) Userinfo() (config.Claims, error) { return config.Claims{}, err } - var userInfo GoogleUserInfoResponse - - err = json.Unmarshal(body, &userInfo) + err = json.Unmarshal(body, &user) if err != nil { return config.Claims{}, err } - user.PreferredUsername = strings.Split(userInfo.Email, "@")[0] - user.Name = userInfo.Name - user.Email = userInfo.Email + user.PreferredUsername = strings.SplitN(user.Email, "@", 2)[0] return user, nil } From b159f4472902eba1dec9461e713dcbb73de5803c Mon Sep 17 00:00:00 2001 From: Stavros Date: Mon, 29 Dec 2025 19:46:33 +0200 Subject: [PATCH 4/7] fix: add missing ldap search filter --- cmd/tinyauth/tinyauth.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/tinyauth/tinyauth.go b/cmd/tinyauth/tinyauth.go index f014fac..33b4015 100644 --- a/cmd/tinyauth/tinyauth.go +++ b/cmd/tinyauth/tinyauth.go @@ -34,6 +34,10 @@ func NewTinyauthCmdConfiguration() *config.Config { ForgotPasswordMessage: "You can change your password by changing the configuration.", BackgroundImage: "/background.jpg", }, + Ldap: config.LdapConfig{ + Insecure: false, + SearchFilter: "(uid=%s)", + }, Experimental: config.ExperimentalConfig{ ConfigFile: "", }, From 9a3fecd5653064f9997ffc5e66f7c99f84a2176c Mon Sep 17 00:00:00 2001 From: Stavros Date: Tue, 30 Dec 2025 18:26:57 +0200 Subject: [PATCH 5/7] feat: non-docker acls (#549) * wip * feat: add paerser as submodule and apply patch for nested maps * refactor: update release workflows to include submodule and patches * chore: update contributing instructions --- .github/workflows/ci.yml | 11 +- .github/workflows/nightly.yml | 58 ++++++++- .github/workflows/release.yml | 58 ++++++++- .gitmodules | 4 + CONTRIBUTING.md | 29 ++++- Dockerfile | 6 +- Dockerfile.dev | 4 +- Dockerfile.distroless | 6 +- docker-compose.dev.yml | 1 - go.mod | 2 + go.sum | 2 - internal/bootstrap/service_bootstrap.go | 2 +- internal/config/config.go | 53 ++++---- internal/controller/proxy_controller_test.go | 2 +- internal/service/access_controls_service.go | 128 +++++-------------- paerser | 1 + patches/nested_maps.diff | 95 ++++++++++++++ 17 files changed, 314 insertions(+), 148 deletions(-) create mode 100644 .gitmodules create mode 160000 paerser create mode 100644 patches/nested_maps.diff diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c67bed..6e70165 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,16 @@ jobs: - name: Setup go uses: actions/setup-go@v5 with: - go-version: "^1.23.2" + go-version: "^1.24.0" + + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff - name: Install frontend dependencies run: | diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5bc3e09..05563b6 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -61,7 +61,16 @@ jobs: - name: Install go uses: actions/setup-go@v5 with: - go-version: "^1.23.2" + go-version: "^1.24.0" + + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff - name: Install frontend dependencies run: | @@ -107,7 +116,16 @@ jobs: - name: Install go uses: actions/setup-go@v5 with: - go-version: "^1.23.2" + go-version: "^1.24.0" + + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff - name: Install frontend dependencies run: | @@ -147,6 +165,15 @@ jobs: with: ref: nightly + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -205,6 +232,15 @@ jobs: with: ref: nightly + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -263,6 +299,15 @@ jobs: with: ref: nightly + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -321,6 +366,15 @@ jobs: with: ref: nightly + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c6896c2..1edf09d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,7 +39,16 @@ jobs: - name: Install go uses: actions/setup-go@v5 with: - go-version: "^1.23.2" + go-version: "^1.24.0" + + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff - name: Install frontend dependencies run: | @@ -82,7 +91,16 @@ jobs: - name: Install go uses: actions/setup-go@v5 with: - go-version: "^1.23.2" + go-version: "^1.24.0" + + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff - name: Install frontend dependencies run: | @@ -119,6 +137,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -174,6 +201,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -229,6 +265,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -284,6 +329,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Initialize submodules + run: | + git submodule init + git submodule update + + - name: Apply patches + run: | + git apply --directory paerser/ patches/nested_maps.diff + - name: Docker meta id: meta uses: docker/metadata-action@v5 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c3cedbc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "paerser"] + path = paerser + url = https://github.com/traefik/paerser + ignore = all diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 079d181..1440bc9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ Contributing is relatively easy, you just need to follow the steps below and you ## Requirements - Bun -- Golang v1.23.2 and above +- Golang 1.24.0+ - Git - Docker @@ -18,12 +18,21 @@ git clone https://github.com/steveiliop56/tinyauth cd tinyauth ``` -## Install requirements +## Initialize submodules -Although you will not need the requirements in your machine since the development will happen in docker, I still recommend to install them because this way you will not have import errors. To install the go requirements run: +The project uses Git submodules for some dependencies, so you need to initialize them with: ```sh -go mod tidy +git submodule init +git submodule update +``` + +## Install requirements + +Although you will not need the requirements in your machine since the development will happen in Docker, I still recommend to install them because this way you will not have import errors. To install the Go requirements run: + +```sh +go mod download ``` You also need to download the frontend dependencies, this can be done like so: @@ -33,13 +42,21 @@ cd frontend/ bun install ``` +## Apply patches + +Some of the dependencies need to be patched in order to work correctly with the project, you can apply the patches by running: + +```sh +git apply --directory paerser/ patches/nested_maps.diff +``` + ## Create your `.env` file In order to configure the app you need to create an environment file, this can be done by copying the `.env.example` file to `.env` and modifying the environment variables to suit your needs. ## Developing -I have designed the development workflow to be entirely in docker, this is because it will directly work with traefik and you will not need to do any building in your host machine. The recommended development setup is to have a subdomain pointing to your machine like this: +I have designed the development workflow to be entirely in Docker, this is because it will directly work with Traefik and you will not need to do any building in your host machine. The recommended development setup is to have a subdomain pointing to your machine like this: ``` *.dev.example.com -> 127.0.0.1 @@ -49,7 +66,7 @@ dev.example.com -> 127.0.0.1 > [!TIP] > You can use [sslip.io](https://sslip.io) as a domain if you don't have one to develop with. -Then you can just make sure the domains are correct in the development docker compose file and run: +Then you can just make sure the domains are correct in the development Docker compose file and run: ```sh docker compose -f docker-compose.dev.yml up --build diff --git a/Dockerfile b/Dockerfile index 41500ed..aae8e0e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,8 @@ ARG BUILD_TIMESTAMP WORKDIR /tinyauth +COPY ./paerser ./paerser + COPY go.mod ./ COPY go.sum ./ @@ -38,7 +40,7 @@ COPY ./internal ./internal COPY --from=frontend-builder /frontend/dist ./internal/assets/dist RUN CGO_ENABLED=0 go build -ldflags "-s -w -X tinyauth/internal/config.Version=${VERSION} -X tinyauth/internal/config.CommitHash=${COMMIT_HASH} -X tinyauth/internal/config.BuildTimestamp=${BUILD_TIMESTAMP}" ./cmd/tinyauth - + # Runner FROM alpine:3.23 AS runner @@ -62,4 +64,4 @@ ENV PATH=$PATH:/tinyauth HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 CMD ["tinyauth", "healthcheck"] -ENTRYPOINT ["tinyauth"] \ No newline at end of file +ENTRYPOINT ["tinyauth"] diff --git a/Dockerfile.dev b/Dockerfile.dev index 96ea9b9..7efe722 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -2,6 +2,8 @@ FROM golang:1.25-alpine3.21 WORKDIR /tinyauth +COPY ./paerser ./paerser + COPY go.mod ./ COPY go.sum ./ @@ -20,4 +22,4 @@ ENV TINYAUTH_DATABASEPATH=/data/tinyauth.db ENV TINYAUTH_RESOURCESDIR=/data/resources -ENTRYPOINT ["air", "-c", "air.toml"] \ No newline at end of file +ENTRYPOINT ["air", "-c", "air.toml"] diff --git a/Dockerfile.distroless b/Dockerfile.distroless index 9806bea..52fb344 100644 --- a/Dockerfile.distroless +++ b/Dockerfile.distroless @@ -28,6 +28,8 @@ ARG BUILD_TIMESTAMP WORKDIR /tinyauth +COPY ./paerser ./paerser + COPY go.mod ./ COPY go.sum ./ @@ -40,7 +42,7 @@ COPY --from=frontend-builder /frontend/dist ./internal/assets/dist RUN mkdir -p data RUN CGO_ENABLED=0 go build -ldflags "-s -w -X tinyauth/internal/config.Version=${VERSION} -X tinyauth/internal/config.CommitHash=${COMMIT_HASH} -X tinyauth/internal/config.BuildTimestamp=${BUILD_TIMESTAMP}" ./cmd/tinyauth - + # Runner FROM gcr.io/distroless/static-debian12:latest AS runner @@ -65,4 +67,4 @@ ENV PATH=$PATH:/tinyauth HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 CMD ["tinyauth", "healthcheck"] -ENTRYPOINT ["tinyauth"] \ No newline at end of file +ENTRYPOINT ["tinyauth"] diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index cc454f6..8ffd6fd 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -42,7 +42,6 @@ services: volumes: - ./internal:/tinyauth/internal - ./cmd:/tinyauth/cmd - - ./main.go:/tinyauth/main.go - /var/run/docker.sock:/var/run/docker.sock - ./data:/data ports: diff --git a/go.mod b/go.mod index 5979f36..57f7720 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.24.0 toolchain go1.24.3 +replace github.com/traefik/paerser v0.2.2 => ./paerser + require ( github.com/cenkalti/backoff/v5 v5.0.3 github.com/charmbracelet/huh v0.8.0 diff --git a/go.sum b/go.sum index 4a44d52..b6d649b 100644 --- a/go.sum +++ b/go.sum @@ -271,8 +271,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/traefik/paerser v0.2.2 h1:cpzW/ZrQrBh3mdwD/jnp6aXASiUFKOVr6ldP+keJTcQ= -github.com/traefik/paerser v0.2.2/go.mod h1:7BBDd4FANoVgaTZG+yh26jI6CA2nds7D/4VTEdIsh24= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= diff --git a/internal/bootstrap/service_bootstrap.go b/internal/bootstrap/service_bootstrap.go index 6110aeb..e4abc8d 100644 --- a/internal/bootstrap/service_bootstrap.go +++ b/internal/bootstrap/service_bootstrap.go @@ -57,7 +57,7 @@ func (app *BootstrapApp) initServices() (Services, error) { services.dockerService = dockerService - accessControlsService := service.NewAccessControlsService(dockerService) + accessControlsService := service.NewAccessControlsService(dockerService, app.config.Apps) err = accessControlsService.Init() diff --git a/internal/config/config.go b/internal/config/config.go index f69c473..d3e00de 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -25,6 +25,7 @@ type Config struct { LogJSON bool `description:"Enable JSON formatted logs." yaml:"logJSON"` Server ServerConfig `description:"Server configuration." yaml:"server"` Auth AuthConfig `description:"Authentication configuration." yaml:"auth"` + Apps map[string]App `description:"Application ACLs configuration." yaml:"apps"` OAuth OAuthConfig `description:"OAuth configuration." yaml:"oauth"` UI UIConfig `description:"UI customization." yaml:"ui"` Ldap LdapConfig `description:"LDAP configuration." yaml:"ldap"` @@ -156,61 +157,55 @@ type RedirectQuery struct { RedirectURI string `url:"redirect_uri"` } -// Labels +// ACLs type Apps struct { - Apps map[string]App + Apps map[string]App `description:"App ACLs configuration." yaml:"apps"` } type App struct { - Config AppConfig - Users AppUsers - OAuth AppOAuth - IP AppIP - Response AppResponse - Path AppPath + Config AppConfig `description:"App configuration." yaml:"config"` + Users AppUsers `description:"User access configuration." yaml:"users"` + OAuth AppOAuth `description:"OAuth access configuration." yaml:"oauth"` + IP AppIP `description:"IP access configuration." yaml:"ip"` + Response AppResponse `description:"Response customization." yaml:"response"` + Path AppPath `description:"Path access configuration." yaml:"path"` } type AppConfig struct { - Domain string + Domain string `description:"The domain of the app." yaml:"domain"` } type AppUsers struct { - Allow string - Block string + Allow string `description:"Comma-separated list of allowed users." yaml:"allow"` + Block string `description:"Comma-separated list of blocked users." yaml:"block"` } type AppOAuth struct { - Whitelist string - Groups string + Whitelist string `description:"Comma-separated list of allowed OAuth groups." yaml:"whitelist"` + Groups string `description:"Comma-separated list of required OAuth groups." yaml:"groups"` } type AppIP struct { - Allow []string - Block []string - Bypass []string + Allow []string `description:"List of allowed IPs or CIDR ranges." yaml:"allow"` + Block []string `description:"List of blocked IPs or CIDR ranges." yaml:"block"` + Bypass []string `description:"List of IPs or CIDR ranges that bypass authentication." yaml:"bypass"` } type AppResponse struct { - Headers []string - BasicAuth AppBasicAuth + Headers []string `description:"Custom headers to add to the response." yaml:"headers"` + BasicAuth AppBasicAuth `description:"Basic authentication for the app." yaml:"basicAuth"` } type AppBasicAuth struct { - Username string - Password string - PasswordFile string + Username string `description:"Basic auth username." yaml:"username"` + Password string `description:"Basic auth password." yaml:"password"` + PasswordFile string `description:"Path to the file containing the basic auth password." yaml:"passwordFile"` } type AppPath struct { - Allow string - Block string -} - -// Flags - -type Providers struct { - Providers map[string]OAuthServiceConfig + Allow string `description:"Comma-separated list of allowed paths." yaml:"allow"` + Block string `description:"Comma-separated list of blocked paths." yaml:"block"` } // API server diff --git a/internal/controller/proxy_controller_test.go b/internal/controller/proxy_controller_test.go index d0de555..54bb888 100644 --- a/internal/controller/proxy_controller_test.go +++ b/internal/controller/proxy_controller_test.go @@ -41,7 +41,7 @@ func setupProxyController(t *testing.T, middlewares *[]gin.HandlerFunc) (*gin.En assert.NilError(t, dockerService.Init()) // Access controls - accessControlsService := service.NewAccessControlsService(dockerService) + accessControlsService := service.NewAccessControlsService(dockerService, map[string]config.App{}) assert.NilError(t, accessControlsService.Init()) diff --git a/internal/service/access_controls_service.go b/internal/service/access_controls_service.go index e5af779..74117ea 100644 --- a/internal/service/access_controls_service.go +++ b/internal/service/access_controls_service.go @@ -1,122 +1,54 @@ package service import ( + "errors" + "strings" + + "github.com/rs/zerolog/log" "github.com/steveiliop56/tinyauth/internal/config" ) -/* -Environment variable/flag based ACLs are disabled until v5 due to a technical challenge -with the current parsing logic. - -The current parser works for simple OAuth provider configs like: -- PROVIDERS_MY_AMAZING_PROVIDER_CLIENT_ID - -However, it breaks down when handling nested structs required for ACLs. The custom parsing -solution that worked for v4 OAuth providers is incompatible with the ACL parsing logic, -making the codebase unmaintainable and fragile. - -A solution is being considered for v5 that would standardize the format to something like: -- TINYAUTH_PROVIDERS_GOOGLE_CLIENTSECRET -- TINYAUTH_APPS_MYAPP_CONFIG_DOMAIN - -This would allow the Traefik parser to handle everything consistently, but requires a -config migration. Until this is resolved, environment-based ACLs are disabled and only -Docker label-based ACLs are supported. - -See: https://discord.com/channels/1337450123600465984/1337459086270271538/1434986689935179838 for more information -*/ - type AccessControlsService struct { docker *DockerService - // envACLs config.Apps + static map[string]config.App } -func NewAccessControlsService(docker *DockerService) *AccessControlsService { +func NewAccessControlsService(docker *DockerService, static map[string]config.App) *AccessControlsService { return &AccessControlsService{ docker: docker, + static: static, } } func (acls *AccessControlsService) Init() error { - // acls.envACLs = config.Apps{} - // env := os.Environ() - // appEnvVars := []string{} - - // for _, e := range env { - // if strings.HasPrefix(e, "TINYAUTH_APPS_") { - // appEnvVars = append(appEnvVars, e) - // } - // } - - // err := acls.loadEnvACLs(appEnvVars) - - // if err != nil { - // return err - // } - - // return nil - - return nil - + return nil // No initialization needed } -// func (acls *AccessControlsService) loadEnvACLs(appEnvVars []string) error { -// if len(appEnvVars) == 0 { -// return nil -// } +func (acls *AccessControlsService) lookupStaticACLs(domain string) (config.App, error) { + for app, config := range acls.static { + if config.Config.Domain == domain { + log.Debug().Str("name", app).Msg("Found matching container by domain") + return config, nil + } -// envAcls := map[string]string{} + if strings.SplitN(domain, ".", 2)[0] == app { + log.Debug().Str("name", app).Msg("Found matching container by app name") + return config, nil + } + } + return config.App{}, errors.New("no results") +} -// for _, e := range appEnvVars { -// parts := strings.SplitN(e, "=", 2) -// if len(parts) != 2 { -// continue -// } +func (acls *AccessControlsService) GetAccessControls(domain string) (config.App, error) { + // First check in the static config + app, err := acls.lookupStaticACLs(domain) -// key := parts[0] -// key = strings.ToLower(key) -// key = strings.ReplaceAll(key, "_", ".") -// value := parts[1] -// envAcls[key] = value -// } - -// apps, err := decoders.DecodeLabels(envAcls) - -// if err != nil { -// return err -// } - -// acls.envACLs = apps -// return nil -// } - -// func (acls *AccessControlsService) lookupEnvACLs(appDomain string) *config.App { -// if len(acls.envACLs.Apps) == 0 { -// return nil -// } - -// for appName, appACLs := range acls.envACLs.Apps { -// if appACLs.Config.Domain == appDomain { -// return &appACLs -// } - -// if strings.SplitN(appDomain, ".", 2)[0] == appName { -// return &appACLs -// } -// } - -// return nil -// } - -func (acls *AccessControlsService) GetAccessControls(appDomain string) (config.App, error) { - // First check environment variables - // envACLs := acls.lookupEnvACLs(appDomain) - - // if envACLs != nil { - // log.Debug().Str("domain", appDomain).Msg("Found matching access controls in environment variables") - // return *envACLs, nil - // } + if err == nil { + log.Debug().Msg("Using ACls from static configuration") + return app, nil + } // Fallback to Docker labels - return acls.docker.GetLabels(appDomain) + log.Debug().Msg("Falling back to Docker labels for ACLs") + return acls.docker.GetLabels(domain) } diff --git a/paerser b/paerser new file mode 160000 index 0000000..7e1b633 --- /dev/null +++ b/paerser @@ -0,0 +1 @@ +Subproject commit 7e1b633ba9fd73f136891ddfec372b2e94d9e9c8 diff --git a/patches/nested_maps.diff b/patches/nested_maps.diff new file mode 100644 index 0000000..91c883f --- /dev/null +++ b/patches/nested_maps.diff @@ -0,0 +1,95 @@ +diff --git a/env/env_test.go b/env/env_test.go +index 7045569..365dc00 100644 +--- a/env/env_test.go ++++ b/env/env_test.go +@@ -166,6 +166,38 @@ func TestDecode(t *testing.T) { + Foo: &struct{ Field string }{}, + }, + }, ++ { ++ desc: "map under the root key", ++ environ: []string{"TRAEFIK_FOO_BAR_FOOBAR_BARFOO=foo"}, ++ element: &struct { ++ Foo map[string]struct { ++ Foobar struct { ++ Barfoo string ++ } ++ } ++ }{}, ++ expected: &struct { ++ Foo map[string]struct { ++ Foobar struct { ++ Barfoo string ++ } ++ } ++ }{ ++ Foo: map[string]struct { ++ Foobar struct { ++ Barfoo string ++ } ++ }{ ++ "bar": { ++ Foobar: struct { ++ Barfoo string ++ }{ ++ Barfoo: "foo", ++ }, ++ }, ++ }, ++ }, ++ }, + } + + for _, test := range testCases { +diff --git a/parser/nodes_metadata.go b/parser/nodes_metadata.go +index 36946c1..0279705 100644 +--- a/parser/nodes_metadata.go ++++ b/parser/nodes_metadata.go +@@ -75,8 +75,13 @@ func (m metadata) add(rootType reflect.Type, node *Node) error { + node.Kind = fType.Kind() + node.Tag = field.Tag + +- if fType.Kind() == reflect.Struct || fType.Kind() == reflect.Pointer && fType.Elem().Kind() == reflect.Struct || +- fType.Kind() == reflect.Map { ++ if node.Kind == reflect.String && len(node.Children) > 0 { ++ fType = reflect.TypeOf(struct{}{}) ++ node.Kind = reflect.Struct ++ } ++ ++ if node.Kind == reflect.Struct || node.Kind == reflect.Pointer && fType.Elem().Kind() == reflect.Struct || ++ node.Kind == reflect.Map { + if len(node.Children) == 0 && !(field.Tag.Get(m.TagName) == TagLabelAllowEmpty || field.Tag.Get(m.TagName) == "-") { + return fmt.Errorf("%s cannot be a standalone element (type %s)", node.Name, fType) + } +@@ -90,11 +95,11 @@ func (m metadata) add(rootType reflect.Type, node *Node) error { + return nil + } + +- if fType.Kind() == reflect.Struct || fType.Kind() == reflect.Pointer && fType.Elem().Kind() == reflect.Struct { ++ if node.Kind == reflect.Struct || node.Kind == reflect.Pointer && fType.Elem().Kind() == reflect.Struct { + return m.browseChildren(fType, node) + } + +- if fType.Kind() == reflect.Map { ++ if node.Kind == reflect.Map { + if fType.Elem().Kind() == reflect.Interface { + addRawValue(node) + return nil +@@ -115,7 +120,7 @@ func (m metadata) add(rootType reflect.Type, node *Node) error { + return nil + } + +- if fType.Kind() == reflect.Slice { ++ if node.Kind == reflect.Slice { + if m.AllowSliceAsStruct && field.Tag.Get(TagLabelSliceAsStruct) != "" { + return m.browseChildren(fType.Elem(), node) + } +@@ -129,7 +134,7 @@ func (m metadata) add(rootType reflect.Type, node *Node) error { + return nil + } + +- return fmt.Errorf("invalid node %s: %v", node.Name, fType.Kind()) ++ return fmt.Errorf("invalid node %s: %v", node.Name, node.Kind) + } + + func (m metadata) findTypedField(rType reflect.Type, node *Node) (reflect.StructField, error) { From afddb2c3537c1d5c10b11dc2e2d116c56ad39177 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 18:27:34 +0200 Subject: [PATCH 6/7] chore(deps): bump github.com/google/go-querystring (#547) Bumps the minor-patch group with 1 update: [github.com/google/go-querystring](https://github.com/google/go-querystring). Updates `github.com/google/go-querystring` from 1.1.0 to 1.2.0 - [Release notes](https://github.com/google/go-querystring/releases) - [Commits](https://github.com/google/go-querystring/compare/v1.1.0...v1.2.0) --- updated-dependencies: - dependency-name: github.com/google/go-querystring dependency-version: 1.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 57f7720..1879d0a 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/glebarez/sqlite v1.11.0 github.com/go-ldap/ldap/v3 v3.4.12 github.com/golang-migrate/migrate/v4 v4.19.1 - github.com/google/go-querystring v1.1.0 + github.com/google/go-querystring v1.2.0 github.com/google/uuid v1.6.0 github.com/mdp/qrterminal/v3 v3.2.1 github.com/pquerna/otp v1.5.0 diff --git a/go.sum b/go.sum index b6d649b..e0d1cc5 100644 --- a/go.sum +++ b/go.sum @@ -129,11 +129,11 @@ github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7Lk github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA= github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0= +github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= @@ -357,7 +357,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c h1:AtEkQdl5b6zsybXcbz00j1LwNodDuH6hVifIaNqk7NQ= google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c/go.mod h1:ea2MjsO70ssTfCjiwHgI0ZFqcw45Ksuk2ckf9G468GA= From 3c6bd449068e3b1c32cf812fe04106160d68a782 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 18:28:04 +0200 Subject: [PATCH 7/7] chore(deps): bump the minor-patch group across 1 directory with 3 updates (#545) Bumps the minor-patch group with 3 updates in the /frontend directory: [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query), [react-hook-form](https://github.com/react-hook-form/react-hook-form) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint). Updates `@tanstack/react-query` from 5.90.12 to 5.90.14 - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.90.14/packages/react-query) Updates `react-hook-form` from 7.68.0 to 7.69.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.68.0...v7.69.0) Updates `typescript-eslint` from 8.50.0 to 8.50.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.50.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: "@tanstack/react-query" dependency-version: 5.90.14 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-patch - dependency-name: react-hook-form dependency-version: 7.69.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-patch - dependency-name: typescript-eslint dependency-version: 8.50.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/bun.lock | 62 ++++++++++++++++++++++--------------------- frontend/package.json | 6 ++--- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/frontend/bun.lock b/frontend/bun.lock index 0a35de7..cfbc8ea 100644 --- a/frontend/bun.lock +++ b/frontend/bun.lock @@ -12,7 +12,7 @@ "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.1.18", - "@tanstack/react-query": "^5.90.12", + "@tanstack/react-query": "^5.90.15", "axios": "^1.13.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -24,7 +24,7 @@ "next-themes": "^0.4.6", "react": "^19.2.3", "react-dom": "^19.2.3", - "react-hook-form": "^7.68.0", + "react-hook-form": "^7.69.0", "react-i18next": "^16.5.0", "react-markdown": "^10.1.0", "react-router": "^7.11.0", @@ -47,7 +47,7 @@ "prettier": "3.7.4", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", - "typescript-eslint": "^8.50.0", + "typescript-eslint": "^8.51.0", "vite": "^7.3.0", }, }, @@ -339,9 +339,9 @@ "@tanstack/eslint-plugin-query": ["@tanstack/eslint-plugin-query@5.91.2", "", { "dependencies": { "@typescript-eslint/utils": "^8.44.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" } }, "sha512-UPeWKl/Acu1IuuHJlsN+eITUHqAaa9/04geHHPedY8siVarSaWprY0SVMKrkpKfk5ehRT7+/MZ5QwWuEtkWrFw=="], - "@tanstack/query-core": ["@tanstack/query-core@5.90.12", "", {}, "sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg=="], + "@tanstack/query-core": ["@tanstack/query-core@5.90.15", "", {}, "sha512-mInIZNUZftbERE+/Hbtswfse49uUQwch46p+27gP9DWJL927UjnaWEF2t3RMOqBcXbfMdcNkPe06VyUIAZTV1g=="], - "@tanstack/react-query": ["@tanstack/react-query@5.90.12", "", { "dependencies": { "@tanstack/query-core": "5.90.12" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg=="], + "@tanstack/react-query": ["@tanstack/react-query@5.90.15", "", { "dependencies": { "@tanstack/query-core": "5.90.15" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-uQvnDDcTOgJouNtAyrgRej+Azf0U5WDov3PXmHFUBc+t1INnAYhIlpZtCGNBLwCN41b43yO7dPNZu8xWkUFBwQ=="], "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], @@ -373,25 +373,25 @@ "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], - "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.50.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.50.0", "@typescript-eslint/type-utils": "8.50.0", "@typescript-eslint/utils": "8.50.0", "@typescript-eslint/visitor-keys": "8.50.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.50.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.51.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.51.0", "@typescript-eslint/type-utils": "8.51.0", "@typescript-eslint/utils": "8.51.0", "@typescript-eslint/visitor-keys": "8.51.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.2.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.51.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-XtssGWJvypyM2ytBnSnKtHYOGT+4ZwTnBVl36TA4nRO2f4PRNGz5/1OszHzcZCvcBMh+qb7I06uoCmLTRdR9og=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.50.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.50.0", "@typescript-eslint/types": "8.50.0", "@typescript-eslint/typescript-estree": "8.50.0", "@typescript-eslint/visitor-keys": "8.50.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q=="], + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.51.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.51.0", "@typescript-eslint/types": "8.51.0", "@typescript-eslint/typescript-estree": "8.51.0", "@typescript-eslint/visitor-keys": "8.51.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-3xP4XzzDNQOIqBMWogftkwxhg5oMKApqY0BAflmLZiFYHqyhSOxv/cd/zPQLTcCXr4AkaKb25joocY0BD1WC6A=="], - "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.50.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.50.0", "@typescript-eslint/types": "^8.50.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ=="], + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.51.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.51.0", "@typescript-eslint/types": "^8.51.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Luv/GafO07Z7HpiI7qeEW5NW8HUtZI/fo/kE0YbtQEFpJRUuR0ajcWfCE5bnMvL7QQFrmT/odMe8QZww8X2nfQ=="], "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1" } }, "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A=="], - "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.50.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.51.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Qi5bSy/vuHeWyir2C8u/uqGMIlIDu8fuiYWv48ZGlZ/k+PRPHtaAu7erpc7p5bzw2WNNSniuxoMSO4Ar6V9OXw=="], - "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.50.0", "", { "dependencies": { "@typescript-eslint/types": "8.50.0", "@typescript-eslint/typescript-estree": "8.50.0", "@typescript-eslint/utils": "8.50.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw=="], + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.51.0", "", { "dependencies": { "@typescript-eslint/types": "8.51.0", "@typescript-eslint/typescript-estree": "8.51.0", "@typescript-eslint/utils": "8.51.0", "debug": "^4.3.4", "ts-api-utils": "^2.2.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-0XVtYzxnobc9K0VU7wRWg1yiUrw4oQzexCG2V2IDxxCxhqBMSMbjB+6o91A+Uc0GWtgjCa3Y8bi7hwI0Tu4n5Q=="], "@typescript-eslint/types": ["@typescript-eslint/types@8.46.1", "", {}, "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.50.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.50.0", "@typescript-eslint/tsconfig-utils": "8.50.0", "@typescript-eslint/types": "8.50.0", "@typescript-eslint/visitor-keys": "8.50.0", "debug": "^4.3.4", "minimatch": "^9.0.4", "semver": "^7.6.0", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.51.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.51.0", "@typescript-eslint/tsconfig-utils": "8.51.0", "@typescript-eslint/types": "8.51.0", "@typescript-eslint/visitor-keys": "8.51.0", "debug": "^4.3.4", "minimatch": "^9.0.4", "semver": "^7.6.0", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.2.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-1qNjGqFRmlq0VW5iVlcyHBbCjPB7y6SxpBkrbhNWMy/65ZoncXCEPJxkRZL8McrseNH6lFhaxCIaX+vBuFnRng=="], "@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", "@typescript-eslint/typescript-estree": "8.46.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ=="], - "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.50.0", "", { "dependencies": { "@typescript-eslint/types": "8.50.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.51.0", "", { "dependencies": { "@typescript-eslint/types": "8.51.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-mM/JRQOzhVN1ykejrvwnBRV3+7yTKK8tVANVN3o1O0t0v7o+jqdVu9crPy5Y9dov15TJk/FTIgoUGHrTOVL3Zg=="], "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], @@ -795,7 +795,7 @@ "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="], - "react-hook-form": ["react-hook-form@7.68.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-oNN3fjrZ/Xo40SWlHf1yCjlMK417JxoSJVUXQjGdvdRCU07NTFei1i1f8ApUAts+IVh14e4EdakeLEA+BEAs/Q=="], + "react-hook-form": ["react-hook-form@7.69.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-yt6ZGME9f4F6WHwevrvpAjh42HMvocuSnSIHUGycBqXIJdhqGSPQzTpGF+1NLREk/58IdPxEMfPcFCjlMhclGw=="], "react-i18next": ["react-i18next@16.5.0", "", { "dependencies": { "@babel/runtime": "^7.27.6", "html-parse-stringify": "^3.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "i18next": ">= 25.6.2", "react": ">= 16.8.0", "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-IMpPTyCTKxEj8klCrLKUTIUa8uYTd851+jcu2fJuUB9Agkk9Qq8asw4omyeHVnOXHrLgQJGTm5zTvn8HpaPiqw=="], @@ -863,7 +863,7 @@ "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], - "ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], + "ts-api-utils": ["ts-api-utils@2.3.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-6eg3Y9SF7SsAvGzRHQvvc1skDAhwI4YQ32ui1scxD1Ccr0G5qIIbUBT3pFTKX8kmWIQClHobtUdNuaBgwdfdWg=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -873,7 +873,7 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "typescript-eslint": ["typescript-eslint@8.50.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.50.0", "@typescript-eslint/parser": "8.50.0", "@typescript-eslint/typescript-estree": "8.50.0", "@typescript-eslint/utils": "8.50.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A=="], + "typescript-eslint": ["typescript-eslint@8.51.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.51.0", "@typescript-eslint/parser": "8.51.0", "@typescript-eslint/typescript-estree": "8.51.0", "@typescript-eslint/utils": "8.51.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-jh8ZuM5oEh2PSdyQG9YAEM1TCGuWenLSuSUhf/irbVUNW9O5FhbFVONviN2TgMTBnUmyHv7E56rYnfLZK6TkiA=="], "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], @@ -995,25 +995,25 @@ "@types/estree-jsx/@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="], - "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.50.0", "", { "dependencies": { "@typescript-eslint/types": "8.50.0", "@typescript-eslint/visitor-keys": "8.50.0" } }, "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A=="], + "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.51.0", "", { "dependencies": { "@typescript-eslint/types": "8.51.0", "@typescript-eslint/visitor-keys": "8.51.0" } }, "sha512-JhhJDVwsSx4hiOEQPeajGhCWgBMBwVkxC/Pet53EpBVs7zHHtayKefw1jtPaNRXpI9RA2uocdmpdfE7T+NrizA=="], - "@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.50.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.50.0", "@typescript-eslint/types": "8.50.0", "@typescript-eslint/typescript-estree": "8.50.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg=="], + "@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.51.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.51.0", "@typescript-eslint/types": "8.51.0", "@typescript-eslint/typescript-estree": "8.51.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-11rZYxSe0zabiKaCP2QAwRf/dnmgFgvTmeDTtZvUvXG3UuAdg/GU02NExmmIXzz3vLGgMdtrIosI84jITQOxUA=="], "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="], - "@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.50.0", "", { "dependencies": { "@typescript-eslint/types": "8.50.0", "@typescript-eslint/visitor-keys": "8.50.0" } }, "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A=="], + "@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.51.0", "", { "dependencies": { "@typescript-eslint/types": "8.51.0", "@typescript-eslint/visitor-keys": "8.51.0" } }, "sha512-JhhJDVwsSx4hiOEQPeajGhCWgBMBwVkxC/Pet53EpBVs7zHHtayKefw1jtPaNRXpI9RA2uocdmpdfE7T+NrizA=="], - "@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], - "@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], "@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA=="], - "@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "@typescript-eslint/type-utils/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], - "@typescript-eslint/type-utils/@typescript-eslint/utils": ["@typescript-eslint/utils@8.50.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.50.0", "@typescript-eslint/types": "8.50.0", "@typescript-eslint/typescript-estree": "8.50.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg=="], + "@typescript-eslint/type-utils/@typescript-eslint/utils": ["@typescript-eslint/utils@8.51.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.51.0", "@typescript-eslint/types": "8.51.0", "@typescript-eslint/typescript-estree": "8.51.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-11rZYxSe0zabiKaCP2QAwRf/dnmgFgvTmeDTtZvUvXG3UuAdg/GU02NExmmIXzz3vLGgMdtrIosI84jITQOxUA=="], - "@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], @@ -1021,7 +1021,7 @@ "@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.1", "@typescript-eslint/tsconfig-utils": "8.46.1", "@typescript-eslint/types": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg=="], - "@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], "eslint-plugin-react-hooks/@babel/core": ["@babel/core@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.4", "@babel/types": "^7.28.4", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA=="], @@ -1039,7 +1039,7 @@ "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.50.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.50.0", "@typescript-eslint/types": "8.50.0", "@typescript-eslint/typescript-estree": "8.50.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg=="], + "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.51.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.51.0", "@typescript-eslint/types": "8.51.0", "@typescript-eslint/typescript-estree": "8.51.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-11rZYxSe0zabiKaCP2QAwRf/dnmgFgvTmeDTtZvUvXG3UuAdg/GU02NExmmIXzz3vLGgMdtrIosI84jITQOxUA=="], "@babel/helper-module-imports/@babel/traverse/@babel/generator": ["@babel/generator@7.27.1", "", { "dependencies": { "@babel/parser": "^7.27.1", "@babel/types": "^7.27.1", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w=="], @@ -1057,11 +1057,11 @@ "@eslint/eslintrc/espree/eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="], - "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], - "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], - "@typescript-eslint/type-utils/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.50.0", "", { "dependencies": { "@typescript-eslint/types": "8.50.0", "@typescript-eslint/visitor-keys": "8.50.0" } }, "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A=="], + "@typescript-eslint/type-utils/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.51.0", "", { "dependencies": { "@typescript-eslint/types": "8.51.0", "@typescript-eslint/visitor-keys": "8.51.0" } }, "sha512-JhhJDVwsSx4hiOEQPeajGhCWgBMBwVkxC/Pet53EpBVs7zHHtayKefw1jtPaNRXpI9RA2uocdmpdfE7T+NrizA=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], @@ -1075,15 +1075,17 @@ "@typescript-eslint/utils/@typescript-eslint/typescript-estree/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], + "@typescript-eslint/utils/@typescript-eslint/typescript-estree/ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], + "eslint-plugin-react-hooks/@babel/core/@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], "eslint-plugin-react-hooks/@babel/core/@babel/traverse": ["@babel/traverse@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/types": "^7.28.4", "debug": "^4.3.1" } }, "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ=="], "eslint-plugin-react-hooks/@babel/core/@babel/types": ["@babel/types@7.28.4", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q=="], - "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.50.0", "", { "dependencies": { "@typescript-eslint/types": "8.50.0", "@typescript-eslint/visitor-keys": "8.50.0" } }, "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.51.0", "", { "dependencies": { "@typescript-eslint/types": "8.51.0", "@typescript-eslint/visitor-keys": "8.51.0" } }, "sha512-JhhJDVwsSx4hiOEQPeajGhCWgBMBwVkxC/Pet53EpBVs7zHHtayKefw1jtPaNRXpI9RA2uocdmpdfE7T+NrizA=="], - "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.50.0", "", {}, "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.51.0", "", {}, "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag=="], "@babel/helper-module-imports/@babel/traverse/@babel/generator/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="], diff --git a/frontend/package.json b/frontend/package.json index 66a817e..59fb72f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,7 +18,7 @@ "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.1.18", - "@tanstack/react-query": "^5.90.12", + "@tanstack/react-query": "^5.90.15", "axios": "^1.13.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -30,7 +30,7 @@ "next-themes": "^0.4.6", "react": "^19.2.3", "react-dom": "^19.2.3", - "react-hook-form": "^7.68.0", + "react-hook-form": "^7.69.0", "react-i18next": "^16.5.0", "react-markdown": "^10.1.0", "react-router": "^7.11.0", @@ -53,7 +53,7 @@ "prettier": "3.7.4", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", - "typescript-eslint": "^8.50.0", + "typescript-eslint": "^8.51.0", "vite": "^7.3.0" } }